Week12 [14/12]

Added UVCheck texture file
Added UV perspective Variables to the Vertex Class
Added Texture Draw method to the Rasteriser
This commit is contained in:
IDunnoDev
2021-12-14 13:50:09 +00:00
committed by iDunnoDev
parent cdb940f6aa
commit eeea920e45
4 changed files with 161 additions and 56 deletions

View File

@ -52,10 +52,10 @@ bool Rasteriser::Initialise()
}
}
//_lights.push_back(new AmbientLight(50, 50, 50));
_lights.push_back(new AmbientLight(255, 255, 255));
//_lights.push_back(new DirectionalLight(Vector3D(-1, 0, 0), 150, 150, 150));
_lights.push_back(new PointLight(Vertex(0, 0, -10), 0, 1, 0.01f, 150, 0, 0));
_lights.push_back(new AmbientLight(50, 50, 50));
//_lights.push_back(new AmbientLight(255, 255, 255));
_lights.push_back(new DirectionalLight(Vector3D(-1, 0, -1), 150, 150, 150));
//_lights.push_back(new PointLight(Vertex(0, 0, -10), 0, 1, 0.01f, 150, 0, 0));
_cameras.push_back(Camera(0.0f, 0.0f, 0.0f, Vertex(0.0f, 0.0f, -50.0f)));
_screenMinimized = false;
@ -132,7 +132,7 @@ float Rasteriser::Interpolate(int y, int x0, int x1, int y0, int y1)
float Rasteriser::Lerp(float a, float b, float t)
{
return a + (b - a) * t;
return (1 - t) * a + t * b;
}
float Rasteriser::Lerp(int a, int b, float t)
@ -140,8 +140,12 @@ float Rasteriser::Lerp(int a, int b, float t)
return Lerp((float)a, (float)b, t);
}
int toDraw = 1;
int drawn = 0;
void Rasteriser::Update(const Bitmap& bitmap)
{
drawn = 0;
if (bitmap.GetWidth() == 0 || bitmap.GetHeight() == 0)
{
_screenMinimized = true;
@ -153,7 +157,7 @@ void Rasteriser::Update(const Bitmap& bitmap)
if (!_screenMinimized)
{
int currentRot = (_rotation % 360);
int currentRot = 0;// 45; // (_rotation % 360);
Vertex startPos = Vertex(0, 0, 20);
int currentZOff = 0;
int currentModelIndex = 0;
@ -569,7 +573,7 @@ void Rasteriser::FillPolygonGouraud(HDC hDc, vector<Vertex>& verts)
float cBlue = Lerp(verts[0].GetB(), verts[2].GetB(), vDiff);
temp.SetColor(BoundsCheck(0, 255, (int)cRed), BoundsCheck(0, 255, (int)cGreen), BoundsCheck(0, 255, (int)cBlue));
if (verts[1].GetX() <= temp.GetX())
if (verts[1].GetX() < temp.GetX())
{
FillGouraudSideTriangle(hDc, verts[0], verts[1], temp);
FillGouraudSideTriangle(hDc, verts[2], verts[1], temp);
@ -628,15 +632,26 @@ void Rasteriser::FillGouraudSideTriangle(HDC hDc, const Vertex& v1, const Vertex
if (tempA.GetX() < tempB.GetX())
{
leftEndPoint = tempA.GetX() - 1.0f;
leftEndPoint = tempA.GetX();
rightEndPoint = tempB.GetX() + 1.0f;
}
else
{
leftEndPoint = tempB.GetX() - 1.0f;
leftEndPoint = tempB.GetX();
rightEndPoint = tempA.GetX() + 1.0f;
}
//float iRedA = Interpolate(tempA.GetY(), (float)v1.GetR(), (float)v2.GetR(), v1.GetY(), v2.GetY());
//float iRedB = Interpolate(tempA.GetY(), (float)v1.GetR(), (float)v3.GetR(), v1.GetY(), v3.GetY());
//float iGreenA = Interpolate(tempA.GetY(), (float)v1.GetG(), (float)v2.GetG(), v1.GetY(), v2.GetY());
//float iGreenB = Interpolate(tempA.GetY(), (float)v1.GetG(), (float)v3.GetG(), v1.GetY(), v3.GetY());
//float iBlueA = Interpolate(tempA.GetY(), (float)v1.GetB(), (float)v2.GetB(), v1.GetY(), v2.GetY());
//float iBlueB = Interpolate(tempA.GetY(), (float)v1.GetB(), (float)v3.GetB(), v1.GetY(), v3.GetY());
// Interpolate the Edge Colors of the 3 Vertex, Lerping seems to give better results given the
// non precise nature of converting the floats into ints since it works on the start and end, and
// interpolates fixed between those values (regular interpolation would sometimes overflow and cause
// a value higher then 255 to be used.
float iRedA = Lerp(v1.GetR(), v2.GetR(), (float)i / (float)dx1);
float iRedB = Lerp(v1.GetR(), v3.GetR(), (float)i / (float)dx1);
float iGreenA = Lerp(v1.GetG(), v2.GetG(), (float)i / (float)dx1);
@ -647,7 +662,7 @@ void Rasteriser::FillGouraudSideTriangle(HDC hDc, const Vertex& v1, const Vertex
int xLength = (int)ceil(rightEndPoint) - (int)ceil(leftEndPoint);
int ci = 0;
for (int xi = (int)ceil(leftEndPoint); xi <= (int)ceil(rightEndPoint); xi++)
for (int xi = (int)leftEndPoint; xi <= (int)rightEndPoint; xi++)
{
float ti = (float)ci / (float)xLength;
float redTmp = Lerp(iRedA, iRedB, ti);
@ -690,22 +705,22 @@ void Rasteriser::FillGouraudSideTriangle(HDC hDc, const Vertex& v1, const Vertex
{
if (changed2)
{
tempB.SetX((float)tempB.GetXInt() + (float)signx2);
tempB.SetX((float)tempB.GetX() + (float)signx2);
}
else
{
tempB.SetY((float)tempB.GetYInt() + (float)signy2);
tempB.SetY((float)tempB.GetY() + (float)signy2);
}
e2 = e2 - 2 * dx2;
}
if (changed2)
{
tempB.SetY((float)tempB.GetYInt() + (float)signy2);
tempB.SetY((float)tempB.GetY() + (float)signy2);
}
else
{
tempB.SetX((float)tempB.GetXInt() + (float)signx2);
tempB.SetX((float)tempB.GetX() + (float)signx2);
}
e2 = e2 + 2 * dy2;
}
@ -727,10 +742,18 @@ void Rasteriser::FillPolygonTextured(HDC hDc, Model& model, vector<Vertex>& vert
{
Vertex temp = Vertex(verts[0].GetX() + ((verts[1].GetY() - verts[0].GetY()) / (verts[2].GetY() - verts[0].GetY())) * (verts[2].GetX() - verts[0].GetX()), verts[1].GetY(), verts[1].GetZ());
temp.SetNormal(verts[1].GetNormal());
//model.GetUVCoord(verts[1].GetUVIndex()).GetU() + ((model.GetUVCoord(verts[1].GetUVIndex()).GetV() - model.GetUVCoord(verts[0].GetUVIndex()).GetV()) / (model.GetUVCoord(verts[2].GetUVIndex()).GetV() - model.GetUVCoord(verts[0].GetUVIndex()).GetV())) * (model.GetUVCoord(verts[2].GetUVIndex()).GetU() - model.GetUVCoord(verts[0].GetUVIndex()).GetU());
float tempU = model.GetUVCoord(verts[0].GetUVIndex()).GetU() + ((verts[1].GetY() - verts[0].GetY()) / (verts[2].GetY() - verts[0].GetY())) * (model.GetUVCoord(verts[2].GetUVIndex()).GetU() - model.GetUVCoord(verts[0].GetUVIndex()).GetU());
float tempV = model.GetUVCoord(verts[0].GetUVIndex()).GetV() + ((verts[1].GetY() - verts[0].GetY()) / (verts[2].GetY() - verts[0].GetY())) * (model.GetUVCoord(verts[2].GetUVIndex()).GetV() - model.GetUVCoord(verts[0].GetUVIndex()).GetV());
float uc0 = model.GetUVCoord(verts[0].GetUVIndex()).GetU();
float vc0 = model.GetUVCoord(verts[0].GetUVIndex()).GetV();
float uc1 = model.GetUVCoord(verts[1].GetUVIndex()).GetU();
float vc1 = model.GetUVCoord(verts[1].GetUVIndex()).GetV();
float uc2 = model.GetUVCoord(verts[2].GetUVIndex()).GetU();
float vc2 = model.GetUVCoord(verts[2].GetUVIndex()).GetV();
float tempU = uc0 + ((verts[1].GetY() - verts[0].GetY()) / (verts[2].GetY() - verts[0].GetY())) * (uc2 - uc0);
float tempV = vc0 + ((verts[1].GetY() - verts[0].GetY()) / (verts[2].GetY() - verts[0].GetY())) * (vc2 - vc0);
UVCoord tempCoords = UVCoord(tempU, tempV);
float cRed = verts[0].GetR() + ((verts[1].GetY() - verts[0].GetY()) / (verts[2].GetY() - verts[0].GetY())) * (verts[2].GetR() - verts[0].GetR());
@ -738,19 +761,20 @@ void Rasteriser::FillPolygonTextured(HDC hDc, Model& model, vector<Vertex>& vert
float cBlue = verts[0].GetB() + ((verts[1].GetY() - verts[0].GetY()) / (verts[2].GetY() - verts[0].GetY())) * (verts[2].GetB() - verts[0].GetB());
temp.SetColor(BoundsCheck(0, 255, (int)cRed), BoundsCheck(0, 255, (int)cGreen), BoundsCheck(0, 255, (int)cBlue));
if (verts[1].GetX() <= temp.GetX())
if (drawn < toDraw + 100)
{
temp.SetUVIndex(verts[2].GetUVIndex());
FillTexturedSideTriangle(hDc, model, verts[0], verts[1], temp, model.GetUVCoord(verts[0].GetUVIndex()), model.GetUVCoord(verts[1].GetUVIndex()), tempCoords);
temp.SetUVIndex(verts[0].GetUVIndex());
FillTexturedSideTriangle(hDc, model, verts[2], verts[1], temp, model.GetUVCoord(verts[2].GetUVIndex()), model.GetUVCoord(verts[1].GetUVIndex()), tempCoords);
}
else
{
temp.SetUVIndex(verts[2].GetUVIndex());
FillTexturedSideTriangle(hDc, model, verts[0], temp, verts[1], model.GetUVCoord(verts[0].GetUVIndex()), tempCoords, model.GetUVCoord(verts[1].GetUVIndex()));
temp.SetUVIndex(verts[0].GetUVIndex());
FillTexturedSideTriangle(hDc, model, verts[2], temp, verts[1], model.GetUVCoord(verts[2].GetUVIndex()), tempCoords, model.GetUVCoord(verts[1].GetUVIndex()));
if (verts[1].GetX() < temp.GetX())
{
FillTexturedSideTriangle(hDc, model, verts[0], verts[1], temp, model.GetUVCoord(verts[0].GetUVIndex()), model.GetUVCoord(verts[1].GetUVIndex()), tempCoords);
FillTexturedSideTriangle(hDc, model, verts[2], verts[1], temp, model.GetUVCoord(verts[2].GetUVIndex()), model.GetUVCoord(verts[1].GetUVIndex()), tempCoords);
drawn++;
}
else
{
FillTexturedSideTriangle(hDc, model, verts[0], temp, verts[1], model.GetUVCoord(verts[0].GetUVIndex()), tempCoords, model.GetUVCoord(verts[1].GetUVIndex()));
FillTexturedSideTriangle(hDc, model, verts[2], temp, verts[1], model.GetUVCoord(verts[2].GetUVIndex()), tempCoords, model.GetUVCoord(verts[1].GetUVIndex()));
drawn++;
}
}
}
}
@ -798,10 +822,6 @@ void Rasteriser::FillTexturedSideTriangle(HDC hDc, Model& model, const Vertex& v
dx1 = dy1;
dy1 = tempDx;
int tempDu = du1;
du1 = dv1;
dv1 = tempDu;
changed1 = true;
}
@ -811,10 +831,6 @@ void Rasteriser::FillTexturedSideTriangle(HDC hDc, Model& model, const Vertex& v
dx2 = dy2;
dy2 = tempDx;
int tempDu = du2;
du2 = dv2;
dv2 = tempDu;
changed2 = true;
}
@ -825,27 +841,42 @@ void Rasteriser::FillTexturedSideTriangle(HDC hDc, Model& model, const Vertex& v
{
float leftEndPoint;
float rightEndPoint;
float leftUV;
float rightUV;
float leftU;
float rightU;
float leftV;
float rightV;
if (tempA.GetX() < tempB.GetX())
{
leftEndPoint = tempA.GetX() - 1.0f;
rightEndPoint = tempB.GetX() + 1.0f;
leftUV = tempUVA.GetU();
rightUV = tempUVB.GetU();
leftU = tempUVA.GetU();
rightU = tempUVB.GetU();
leftV = tempUVA.GetV();
rightV = tempUVB.GetV();
}
else
{
leftEndPoint = tempB.GetX() - 1.0f;
rightEndPoint = tempA.GetX() + 1.0f;
leftUV = tempUVB.GetU();
rightUV = tempUVA.GetU();
leftU = tempUVB.GetU();
rightU = tempUVA.GetU();
leftV = tempUVB.GetV();
rightV = tempUVA.GetV();
}
float uy1 = Lerp(uv1.GetV(), uv2.GetV(), (float)i / (float)dx1);
float uy2 = Lerp(uv1.GetV(), uv3.GetV(), (float)i / (float)dx1);
float UCoordA = Interpolate(uv1.GetV() + i, uv1.GetU(), uv2.GetU(), uv1.GetV(), uv2.GetV());
float UCoordB = Interpolate(uv1.GetV() + i, uv1.GetU(), uv3.GetU(), uv1.GetV(), uv3.GetV());
//x0 + (y - y0) * ((x1 - x0) / (y1 - y0))
//a + (b - a) * t
float UCoordA = Interpolate(tempA.GetY(), uv1.GetU(), uv2.GetU(), v1.GetY(), v2.GetY());
float UCoordB = Interpolate(tempA.GetY(), uv1.GetU(), uv3.GetU(), v1.GetY(), v3.GetY());
float VCoordA = Interpolate(tempA.GetY(), uv1.GetV(), uv2.GetV(), v1.GetY(), v2.GetY());
float VCoordB = Interpolate(tempA.GetY(), uv1.GetV(), uv3.GetV(), v1.GetY(), v3.GetY());
float UCoord = (rightU - leftU) / (rightEndPoint - leftEndPoint);
float VCoord = (rightV - leftV) / (rightEndPoint - leftEndPoint);
float iRedA = Lerp(v1.GetR(), v2.GetR(), (float)i / (float)dx1);
float iRedB = Lerp(v1.GetR(), v3.GetR(), (float)i / (float)dx1);
@ -857,19 +888,23 @@ void Rasteriser::FillTexturedSideTriangle(HDC hDc, Model& model, const Vertex& v
int xLength = (int)ceil(rightEndPoint) - (int)ceil(leftEndPoint);
int ci = 0;
for (int xi = (int)ceil(leftEndPoint); xi <= (int)ceil(rightEndPoint); xi++)
{
float ti = (float)ci / (float)xLength;
float UCoordTmp = Lerp(leftUV, rightUV, ti);
float redTmp = Lerp(iRedA, iRedB, ti) / 100;
float greenTmp = Lerp(iGreenA, iGreenB, ti) / 100;
float blueTmp = Lerp(iBlueA, iBlueB, ti) / 100;
if (i < 10000)
{
for (int xi = (int)ceil(leftEndPoint); xi <= (int)ceil(rightEndPoint); xi++)
{
float ti = (float)ci / (float)xLength;
float UCoordTmp = Lerp(UCoordA, UCoordB, ti);
float VCoordTmp = Lerp(VCoordA, VCoordB, ti);
float redTmp = Lerp(iRedA, iRedB, ti) / 100;
float greenTmp = Lerp(iGreenA, iGreenB, ti) / 100;
float blueTmp = Lerp(iBlueA, iBlueB, ti) / 100;
COLORREF textureColor = model.GetTexture().GetTextureValue((int)UCoordTmp, (int)tempUVA.GetV());
COLORREF currentColor = RGB(BoundsCheck(0, 255, (int)(GetRValue(textureColor) * redTmp)), BoundsCheck(0, 255, (int)(GetGValue(textureColor) * greenTmp)), BoundsCheck(0, 255, (int)(GetBValue(textureColor) * blueTmp)));
COLORREF textureColor = model.GetTexture().GetTextureValue((int)UCoordTmp, (int)VCoordTmp);
COLORREF currentColor = RGB(BoundsCheck(0, 255, (int)(GetRValue(textureColor) * redTmp)), BoundsCheck(0, 255, (int)(GetGValue(textureColor) * greenTmp)), BoundsCheck(0, 255, (int)(GetBValue(textureColor) * blueTmp)));
SetPixel(hDc, xi, tempA.GetYInt(), currentColor);
ci++;
SetPixel(hDc, xi, tempA.GetYInt(), currentColor);
ci++;
}
}

View File

@ -11,6 +11,11 @@ Vertex::Vertex()
_r = 0;
_g = 0;
_b = 0;
_uvIndex = -1;
_zOriginal = 0;
_uOverZ = 0;
_vOverZ = 0;
_zRecip = 0;
}
Vertex::Vertex(const float x, const float y, const float z)
@ -24,6 +29,11 @@ Vertex::Vertex(const float x, const float y, const float z)
_r = 0;
_g = 0;
_b = 0;
_uvIndex = -1;
_zOriginal = 0;
_uOverZ = 0;
_vOverZ = 0;
_zRecip = 0;
}
Vertex::Vertex(const float x, const float y, const float z, const float w)
@ -37,6 +47,11 @@ Vertex::Vertex(const float x, const float y, const float z, const float w)
_r = 0;
_g = 0;
_b = 0;
_uvIndex = -1;
_zOriginal = 0;
_uOverZ = 0;
_vOverZ = 0;
_zRecip = 0;
}
Vertex::Vertex(const Vertex & other)
@ -187,6 +202,44 @@ void Vertex::SetUVIndex(const int index)
_uvIndex = index;
}
float Vertex::GetZOriginal() const
{
return _zOriginal;
}
float Vertex::GetUOverZ() const
{
return _uOverZ;
}
void Vertex::SetUOverZ(const float value)
{
_uOverZ = value / _zOriginal;
}
float Vertex::GetVOverZ() const
{
return _vOverZ;
}
void Vertex::SetVOverZ(const float value)
{
_vOverZ = value / _zOriginal;
}
float Vertex::GetZRecip() const
{
return _zRecip;
}
void Vertex::UVCorrect(float u, float v)
{
_zOriginal = _w;
_zRecip = 1 / _zOriginal;
SetUOverZ(u);
SetVOverZ(v);
}
int Vertex::GetXInt(bool forceRoundUp) const
{
if (forceRoundUp)
@ -236,7 +289,7 @@ int Vertex::GetWInt(bool forceRoundUp) const
}
void Vertex::Dehomogenize()
{
{
_x = _x / _w;
_y = _y / _w;
_z = _z / _w;
@ -293,4 +346,9 @@ void Vertex::Copy(const Vertex& other)
_b = other.GetB();
_uvIndex = other.GetUVIndex();
_zOriginal = other.GetZOriginal();
_uOverZ = other.GetUOverZ();
_vOverZ = other.GetVOverZ();
_zRecip = other.GetZRecip();
}

View File

@ -44,6 +44,14 @@ public:
int GetUVIndex() const;
void SetUVIndex(const int index);
float GetZOriginal() const;
float GetUOverZ() const;
void SetUOverZ(const float value);
float GetVOverZ() const;
void SetVOverZ(const float value);
float GetZRecip() const;
void UVCorrect(float u, float v);
// Accessors for returning the private x, y, z and w values as integeres instead of floats
// the ceil function to round the number up by defaults but using providing a false param will
// use the floor function instead to round the number down
@ -79,6 +87,10 @@ private:
int _uvIndex;
float _uOverZ;
float _vOverZ;
float _zRecip;
void Copy(const Vertex& other);
};

BIN
model_data/uvcheck.pcx Normal file

Binary file not shown.