diff --git a/BaseFramework.vcxproj b/BaseFramework.vcxproj
index a7510ed..0c59717 100644
--- a/BaseFramework.vcxproj
+++ b/BaseFramework.vcxproj
@@ -29,26 +29,26 @@
Application
true
- v142
+ v143
Unicode
Application
false
- v142
+ v143
true
Unicode
Application
true
- v142
+ v143
Unicode
Application
false
- v142
+ v143
true
Unicode
diff --git a/Model.cpp b/Model.cpp
index 5c0a4b5..16ed899 100644
--- a/Model.cpp
+++ b/Model.cpp
@@ -334,11 +334,9 @@ void Model::CalculateVertexNormals()
}
for (Vertex& currentVertex : _transformedVertices)
- {
-
- currentVertex.SetNormal(currentVertex.GetNormal() / currentVertex.GetContributeCount());
- currentVertex.NormalizeNormal();
-
+ {
+ currentVertex.SetNormal(currentVertex.GetNormal() / currentVertex.GetContributeCount());
+ currentVertex.NormalizeNormal();
}
}
@@ -360,4 +358,17 @@ void Model::Sort()
}
sort(_polygons.begin(), _polygons.end(), DepthCompare);
+}
+
+void Model::CalculateUVPerspective()
+{
+ for (Polygon3D& currentPolygon : _polygons)
+ {
+
+ for (int cpi = 0; cpi < currentPolygon.GetPolygonVertexCount(); cpi++)
+ {
+ _transformedVertices[currentPolygon.GetIndex(cpi)].UVCorrect(_uvCoords[currentPolygon.GetUVIndex(cpi)].GetU(), _uvCoords[currentPolygon.GetUVIndex(cpi)].GetV());
+ }
+
+ }
}
\ No newline at end of file
diff --git a/Model.h b/Model.h
index a959115..efc7d97 100644
--- a/Model.h
+++ b/Model.h
@@ -78,6 +78,8 @@ public:
void CalculateVertexNormals();
void Sort(void);
+ void CalculateUVPerspective(void);
+
private:
vector _polygons;
vector _vertices;
diff --git a/Rasteriser.cpp b/Rasteriser.cpp
index b4ceeea..2208877 100644
--- a/Rasteriser.cpp
+++ b/Rasteriser.cpp
@@ -8,12 +8,12 @@ Rasteriser::~Rasteriser()
_sceneModels.~vector();
}
-void Rasteriser::DrawString(HDC hDc, int x, int y, LPCTSTR text, COLORREF textColor, COLORREF backgroundColor)
+void Rasteriser::DrawString(HDC hDc, int x, int y, LPCTSTR text, int fontSize, COLORREF textColor, COLORREF backgroundColor)
{
HFONT hFont, hOldFont;
// Retrieve a handle to the variable stock font.
- hFont = hFont = CreateFont(48, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_OUTLINE_PRECIS,
+ hFont = hFont = CreateFont(fontSize, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_OUTLINE_PRECIS,
CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY, VARIABLE_PITCH, TEXT("Myfont"));
// Select the variable stock font into the specified device context.
@@ -60,6 +60,16 @@ bool Rasteriser::Initialise()
_screenMinimized = false;
+ //Set the current Time for the automation
+ time(&_startTime);
+ time(&_currentTime);
+ _currentState = 0;
+ _maxStates = 5;
+ for (int i = 0; i < (sizeof _counters / sizeof _counters[0]); i++)
+ {
+ _counters[i] = 0;
+ }
+
return true;
}
@@ -140,12 +150,8 @@ 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;
@@ -155,19 +161,58 @@ void Rasteriser::Update(const Bitmap& bitmap)
_screenMinimized = false;
}
- if (!_screenMinimized)
+ int duration = 0;
+ switch (_currentState)
{
- int currentRot = 0;// 45; // (_rotation % 360);
- Vertex startPos = Vertex(0, 0, 20);
- int currentZOff = 0;
- int currentModelIndex = 0;
+ case -1:
+ duration = -1;
+ case 0:
+ duration = 10;
+ break;
+ case 1:
+ duration = 10;
+ break;
+ case 2:
+ duration = 10;
+ break;
+ case 3:
+ duration = 10;
+ break;
+ case 4:
+ duration = 10;
+ break;
+ }
+ if (!_screenMinimized)
+ {
for (Model& currentModel : _sceneModels)
{
if (currentModel.GetActive())
{
- currentModel.EnqueueTransform(GetTranslateMatrix(startPos));
- currentModel.EnqueueTransform(GetRotationMatrix(Axis::Y, (float)currentRot));
+ switch (_currentState)
+ {
+ case -1:
+
+ break;
+ case 0:
+ currentModel.SetDrawMethod(DrawMethod::Wireframe);
+ break;
+ case 1:
+ currentModel.SetDrawMethod(DrawMethod::Flat);
+ break;
+ case 2:
+ currentModel.SetDrawMethod(DrawMethod::FlatRaster);
+ break;
+ case 3:
+ currentModel.SetDrawMethod(DrawMethod::Smooth);
+ break;
+ case 4:
+ currentModel.SetDrawMethod(DrawMethod::Textured);
+ break;
+ }
+
+ //currentModel.EnqueueTransform(GetTranslateMatrix(startPos));
+ //currentModel.EnqueueTransform(GetRotationMatrix(Axis::Y, (float)currentRot));
/*startPos.SetX(startPos.GetX() + 100);
if ((currentModelIndex % 2) == 1)
{
@@ -178,7 +223,7 @@ void Rasteriser::Update(const Bitmap& bitmap)
currentZOff = 100;
}
startPos.SetZ((float)currentZOff);*/
- currentModelIndex++;
+
}
}
@@ -186,19 +231,26 @@ void Rasteriser::Update(const Bitmap& bitmap)
_currentPerspectiveMatrix = GetPerspectiveProjectionMatrix(1, _currentAspectRatio);
_currentViewMatrix = GetViewMatrix(1, bitmap.GetWidth(), bitmap.GetHeight());
- if (_rotation == 360)
+ }
+
+ if (((int)_currentTime > (int)_startTime + duration) && (duration != -1))
+ {
+ if (_currentState == _maxStates)
{
- _rotation = 0;
+ _currentState = 0;
}
else
{
- _rotation += 1;
- }
- }
+ _currentState++;
+ }
+ time(&_startTime);
+ }
+ time(&_currentTime);
}
void Rasteriser::Render(const Bitmap& bitmap)
{
+ bool titleDrawn = false;
if (!_screenMinimized)
{
ClearViewport(bitmap);
@@ -224,12 +276,22 @@ void Rasteriser::Render(const Bitmap& bitmap)
switch (currentModel.GetDrawMethod())
{
case (DrawMethod::Wireframe):
+ if (!titleDrawn)
+ {
+ DrawString(bitmap.GetDC(), 10, 10, _T("Wireframe"));
+ titleDrawn = true;
+ }
currentModel.ApplyTransformToTransformedVertices(_currentPerspectiveMatrix);
currentModel.DehomogenizeAllVertices();
currentModel.ApplyTransformToTransformedVertices(_currentViewMatrix);
DrawWireFrame(bitmap.GetDC(), currentModel);
break;
case (DrawMethod::Flat):
+ if (!titleDrawn)
+ {
+ DrawString(bitmap.GetDC(), 10, 10, TEXT("Flat Polygon"));
+ titleDrawn = true;
+ }
currentModel.CalculateVertexNormals();
CalculateLighting(currentModel, false);
@@ -239,6 +301,11 @@ void Rasteriser::Render(const Bitmap& bitmap)
DrawSolidFlat(bitmap.GetDC(), currentModel);
break;
case (DrawMethod::FlatRaster):
+ if (!titleDrawn)
+ {
+ DrawString(bitmap.GetDC(), 10, 10, _T("Flat Raster"));
+ titleDrawn = true;
+ }
currentModel.CalculateVertexNormals();
CalculateLighting(currentModel, false);
@@ -248,6 +315,11 @@ void Rasteriser::Render(const Bitmap& bitmap)
DrawRasterisedSolidFlat(bitmap.GetDC(), currentModel);
break;
case (DrawMethod::Smooth):
+ if (!titleDrawn)
+ {
+ DrawString(bitmap.GetDC(), 10, 10, _T("Gouraud Shading"));
+ titleDrawn = true;
+ }
currentModel.CalculateVertexNormals();
CalculateLighting(currentModel, true);
@@ -257,6 +329,11 @@ void Rasteriser::Render(const Bitmap& bitmap)
DrawGouraud(bitmap.GetDC(), currentModel);
break;
case (DrawMethod::Textured):
+ if (!titleDrawn)
+ {
+ DrawString(bitmap.GetDC(), 10, 10, _T("Textured"));
+ titleDrawn = true;
+ }
currentModel.CalculateVertexNormals();
CalculateLighting(currentModel, true);
@@ -269,8 +346,6 @@ void Rasteriser::Render(const Bitmap& bitmap)
currentModel.ClearPendingTransforms();
}
}
-
- DrawString(bitmap.GetDC(), 10, 10, _T("Hello World"));
}
}
@@ -393,6 +468,8 @@ void Rasteriser::DrawGouraud(HDC hDc, Model& model)
void Rasteriser::DrawSolidTextured(HDC hDc, Model& model)
{
+ model.CalculateUVPerspective();
+
int modelPolygonCount = (int)model.GetPolygonCount();
for (int i = 0; i < modelPolygonCount; i++)
{
@@ -439,112 +516,110 @@ void Rasteriser::FillPolygonFlat(HDC hDc, vector& verts, COLORREF colorI
void Rasteriser::FillFlatSideTriangle(HDC hDc, const Vertex& v1, const Vertex& v2, const Vertex& v3, COLORREF colorIn)
{
+ // Check if any of the vertices match and dont draw the triangle if they do, this should stop the infinite loop that can happen with small vertex float numbers
+ if ((v1.GetXInt() == v2.GetXInt() && v1.GetYInt() == v2.GetYInt()) || (v1.GetXInt() == v3.GetXInt() && v1.GetYInt() == v3.GetYInt()) || (v2.GetXInt() == v3.GetXInt() && v3.GetYInt() == v2.GetYInt()))
+ {
+ return;
+ }
+
Vertex tempA = Vertex(v1);
Vertex tempB = Vertex(v1);
bool changed1 = false;
bool changed2 = false;
- int dx1 = (int)ceil(abs(v2.GetX() - v1.GetX()));
- int dy1 = (int)ceil(abs(v2.GetY() - v1.GetY()));
+ int dx1 = (int)abs(v2.GetXInt() - v1.GetXInt());
+ int dy1 = (int)abs(v2.GetYInt() - v1.GetYInt());
+ int dx2 = (int)abs(v3.GetXInt() - v1.GetXInt());
+ int dy2 = (int)abs(v3.GetYInt() - v1.GetYInt());
- int dx2 = (int)ceil(abs(v3.GetX() - v1.GetX()));
- int dy2 = (int)ceil(abs(v3.GetY() - v1.GetY()));
-
- int signx1 = (int)ceil(sgn(v2.GetX() - v1.GetX()));
- int signx2 = (int)ceil(sgn(v3.GetX() - v1.GetX()));
-
- int signy1 = (int)ceil(sgn(v2.GetY() - v1.GetY()));
- int signy2 = (int)ceil(sgn(v3.GetY() - v1.GetY()));
+ int signx1 = (int)sgn(v2.GetXInt() - v1.GetXInt());
+ int signx2 = (int)sgn(v3.GetXInt() - v1.GetXInt());
+ int signy1 = (int)sgn(v2.GetYInt() - v1.GetYInt());
+ int signy2 = (int)sgn(v3.GetYInt() - v1.GetYInt());
if (dy1 > dx1)
{
- int tempInt = dx1;
- dx1 = dy1;
- dy1 = tempInt;
+ swap(dx1, dy1);
changed1 = true;
}
if (dy2 > dx2)
{
- int tempInt = dx2;
- dx2 = dy2;
- dy2 = tempInt;
+ swap(dx2, dy2);
changed2 = true;
}
int e1 = 2 * dy1 - dx1;
- int e2 = 2 * dy2 - dx2;
+ int e2 = 2 * dy2 - dx2;
for (int i = 0; i <= dx1; i++)
{
- float leftEndPoint;
- float rightEndPoint;
-
- if (tempA.GetX() < tempB.GetX())
+ int leftEndPoint;
+ int rightEndPoint;
+
+ if (tempA.GetXInt() < tempB.GetXInt())
{
- leftEndPoint = tempA.GetX() - 1.0f;
- rightEndPoint = tempB.GetX() + 1.0f;
+ leftEndPoint = tempA.GetXInt();
+ rightEndPoint = tempB.GetXInt();
}
else
{
- leftEndPoint = tempB.GetX() - 1.0f;
- rightEndPoint = tempA.GetX() + 1.0f;
+ leftEndPoint = tempB.GetXInt();
+ rightEndPoint = tempA.GetXInt();
}
- for (int xi = (int)ceil(leftEndPoint); xi <= (int)ceil(rightEndPoint); xi++)
+ for (int xi = leftEndPoint; xi < rightEndPoint; xi++)
{
SetPixel(hDc, xi, tempA.GetYInt(), colorIn);
}
-
-
while (e1 >= 0)
{
if (changed1)
{
- tempA.SetX((float)tempA.GetX() + (float)signx1);
+ tempA.SetX((float)(tempA.GetXInt() + signx1));
}
else
{
- tempA.SetY((float)tempA.GetY() + (float)signy1);
+ tempA.SetY((float)(tempA.GetYInt() + signy1));
}
e1 = e1 - 2 * dx1;
}
if (changed1)
{
- tempA.SetY((float)tempA.GetY() + (float)signy1);
+ tempA.SetY((float)(tempA.GetYInt() + signy1));
}
else
{
- tempA.SetX((float)tempA.GetX() + (float)signx1);
+ tempA.SetX((float)(tempA.GetXInt() + signx1));
}
e1 = e1 + 2 * dy1;
- while (tempB.GetYInt() != tempA.GetYInt())
+ while (tempB.GetYInt(true) != tempA.GetYInt(true))
{
while (e2 >= 0)
{
if (changed2)
{
- tempB.SetX((float)tempB.GetXInt() + (float)signx2);
+ tempB.SetX((float)(tempB.GetXInt() + signx2));
}
else
{
- tempB.SetY((float)tempB.GetYInt() + (float)signy2);
+ tempB.SetY((float)(tempB.GetYInt() + signy2));
}
e2 = e2 - 2 * dx2;
}
if (changed2)
{
- tempB.SetY((float)tempB.GetYInt() + (float)signy2);
+ tempB.SetY((float)(tempB.GetYInt() + signy2));
}
else
{
- tempB.SetX((float)tempB.GetXInt() + (float)signx2);
+ tempB.SetX((float)(tempB.GetXInt() + signx2));
}
e2 = e2 + 2 * dy2;
}
@@ -588,66 +663,62 @@ void Rasteriser::FillPolygonGouraud(HDC hDc, vector& verts)
void Rasteriser::FillGouraudSideTriangle(HDC hDc, const Vertex& v1, const Vertex& v2, const Vertex& v3)
{
+ // Check if any of the vertices match and dont draw the triangle if they do, this should stop the infinite loop that can happen with small vertex float numbers
+ if ((v1.GetXInt() == v2.GetXInt() && v1.GetYInt() == v2.GetYInt()) || (v1.GetXInt() == v3.GetXInt() && v1.GetYInt() == v3.GetYInt()) || (v2.GetXInt() == v3.GetXInt() && v3.GetYInt() == v2.GetYInt()))
+ {
+ return;
+ }
+
Vertex tempA = Vertex(v1);
Vertex tempB = Vertex(v1);
bool changed1 = false;
bool changed2 = false;
- int dx1 = (int)ceil(abs(v2.GetX() - v1.GetX()));
- int dy1 = (int)ceil(abs(v2.GetY() - v1.GetY()));
+ int dx1 = (int)abs(v2.GetXInt() - v1.GetXInt());
+ int dy1 = (int)abs(v2.GetYInt() - v1.GetYInt());
+ int dx2 = (int)abs(v3.GetXInt() - v1.GetXInt());
+ int dy2 = (int)abs(v3.GetYInt() - v1.GetYInt());
- int dx2 = (int)ceil(abs(v3.GetX() - v1.GetX()));
- int dy2 = (int)ceil(abs(v3.GetY() - v1.GetY()));
-
- int signx1 = (int)ceil(sgn(v2.GetX() - v1.GetX()));
- int signx2 = (int)ceil(sgn(v3.GetX() - v1.GetX()));
-
- int signy1 = (int)ceil(sgn(v2.GetY() - v1.GetY()));
- int signy2 = (int)ceil(sgn(v3.GetY() - v1.GetY()));
+ int signx1 = (int)sgn(v2.GetXInt() - v1.GetXInt());
+ int signx2 = (int)sgn(v3.GetXInt() - v1.GetXInt());
+ int signy1 = (int)sgn(v2.GetYInt() - v1.GetYInt());
+ int signy2 = (int)sgn(v3.GetYInt() - v1.GetYInt());
if (dy1 > dx1)
{
- int tempDx = dx1;
- dx1 = dy1;
- dy1 = tempDx;
+ swap(dx1, dy1);
changed1 = true;
}
if (dy2 > dx2)
{
- int tempDx = dx2;
- dx2 = dy2;
- dy2 = tempDx;
+ swap(dx2, dy2);
changed2 = true;
}
- int e1 = 2 * (int)dy1 - (int)dx1;
- int e2 = 2 * (int)dy2 - (int)dx2;
+ int e1 = 2 * dy1 - dx1;
+ int e2 = 2 * dy2 - dx2;
- for (int i = 0; i <= (int)dx1; i++)
+ for (int i = 0; i <= dx1; i++)
{
- float leftEndPoint;
- float rightEndPoint;
+ int leftEndPoint;
+ int rightEndPoint;
+ int sideFix;
- if (tempA.GetX() < tempB.GetX())
+ if (tempA.GetXInt() < tempB.GetXInt())
{
- leftEndPoint = tempA.GetX();
- rightEndPoint = tempB.GetX() + 1.0f;
+ leftEndPoint = tempA.GetXInt();
+ rightEndPoint = tempB.GetXInt();
+ sideFix = 0;
}
else
{
- leftEndPoint = tempB.GetX();
- rightEndPoint = tempA.GetX() + 1.0f;
+ leftEndPoint = tempB.GetXInt();
+ rightEndPoint = tempA.GetXInt();
+ sideFix = 1;
}
- //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
@@ -659,279 +730,49 @@ void Rasteriser::FillGouraudSideTriangle(HDC hDc, const Vertex& v1, const Vertex
float iBlueA = Lerp(v1.GetB(), v2.GetB(), (float)i / (float)dx1);
float iBlueB = Lerp(v1.GetB(), v3.GetB(), (float)i / (float)dx1);
- int xLength = (int)ceil(rightEndPoint) - (int)ceil(leftEndPoint);
- int ci = 0;
+ int xLength = rightEndPoint - leftEndPoint;
+ int ci = xLength * sideFix;
+
+ for (int xi = leftEndPoint; xi < rightEndPoint; xi++)
+ {
+ float ti = ((float)ci / (float)xLength);
- for (int xi = (int)leftEndPoint; xi <= (int)rightEndPoint; xi++)
- {
- float ti = (float)ci / (float)xLength;
float redTmp = Lerp(iRedA, iRedB, ti);
float greenTmp = Lerp(iGreenA, iGreenB, ti);
float blueTmp = Lerp(iBlueA, iBlueB, ti);
COLORREF currentColor = RGB(BoundsCheck(0, 255, (int)redTmp), BoundsCheck(0, 255, (int)greenTmp), BoundsCheck(0, 255, (int)blueTmp));
SetPixel(hDc, xi, tempA.GetYInt(), currentColor);
- ci++;
- }
-
-
- while (e1 >= 0)
- {
- if (changed1)
+ if (sideFix == 1)
{
- tempA.SetX((float)tempA.GetX() + (float)signx1);
+ ci--;
}
else
{
- tempA.SetY((float)tempA.GetY() + (float)signy1);
- }
- e1 = e1 - 2 * dx1;
- }
-
- if (changed1)
- {
- tempA.SetY((float)tempA.GetY() + (float)signy1);
- }
- else
- {
- tempA.SetX((float)tempA.GetX() + (float)signx1);
- }
-
- e1 = e1 + 2 * dy1;
-
- while (tempB.GetYInt() != tempA.GetYInt())
- {
- while (e2 >= 0)
- {
- if (changed2)
- {
- tempB.SetX((float)tempB.GetX() + (float)signx2);
- }
- else
- {
- tempB.SetY((float)tempB.GetY() + (float)signy2);
- }
- e2 = e2 - 2 * dx2;
- }
-
- if (changed2)
- {
- tempB.SetY((float)tempB.GetY() + (float)signy2);
- }
- else
- {
- tempB.SetX((float)tempB.GetX() + (float)signx2);
- }
- e2 = e2 + 2 * dy2;
- }
- }
-}
-
-void Rasteriser::FillPolygonTextured(HDC hDc, Model& model, vector& verts)
-{
- sort(verts.begin(), verts.end(), VerticiesYCompareAsc);
- if (verts[1].GetY() == verts[2].GetY())
- {
- FillTexturedSideTriangle(hDc, model, verts[0], verts[1], verts[2], model.GetUVCoord(verts[0].GetUVIndex()), model.GetUVCoord(verts[1].GetUVIndex()), model.GetUVCoord(verts[2].GetUVIndex()));
- }
- else if (verts[0].GetY() == verts[1].GetY())
- {
- FillTexturedSideTriangle(hDc, model, verts[2], verts[0], verts[1], model.GetUVCoord(verts[2].GetUVIndex()), model.GetUVCoord(verts[0].GetUVIndex()), model.GetUVCoord(verts[1].GetUVIndex()));
- }
- else
- {
- 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 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());
- float cGreen = verts[0].GetG() + ((verts[1].GetY() - verts[0].GetY()) / (verts[2].GetY() - verts[0].GetY())) * (verts[2].GetG() - verts[0].GetG());
- 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 (drawn < toDraw + 100)
- {
- 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++;
- }
- }
- }
-}
-
-void Rasteriser::FillTexturedSideTriangle(HDC hDc, Model& model, const Vertex& v1, const Vertex& v2, const Vertex& v3, const UVCoord& uv1, const UVCoord& uv2, const UVCoord& uv3)
-{
- Vertex tempA = Vertex(v1);
- Vertex tempB = Vertex(v1);
- UVCoord tempUVA = UVCoord(uv1);
- UVCoord tempUVB = UVCoord(uv1);
-
- bool changed1 = false;
- bool changed2 = false;
-
- float uc0 = uv1.GetU();
- float vc0 = uv1.GetV();
- float uc1 = uv2.GetU();
- float vc1 = uv2.GetV();
- float uc2 = uv3.GetU();
- float vc2 = uv3.GetV();
-
- int dx1 = (int)ceil(abs(v2.GetX() - v1.GetX()));
- int dy1 = (int)ceil(abs(v2.GetY() - v1.GetY()));
- int du1 = (int)ceil(abs(uc1 - uc0));
- int dv1 = (int)ceil(abs(vc1 - vc0));
-
- int dx2 = (int)ceil(abs(v3.GetX() - v1.GetX()));
- int dy2 = (int)ceil(abs(v3.GetY() - v1.GetY()));
- int du2 = (int)ceil(abs(uc2 - uc0));
- int dv2 = (int)ceil(abs(vc2 - vc0));
-
- int signx1 = (int)ceil(sgn(v2.GetX() - v1.GetX()));
- int signx2 = (int)ceil(sgn(v3.GetX() - v1.GetX()));
- int signu1 = (int)ceil(sgn(uc1 - uc0));
- int signu2 = (int)ceil(sgn(uc2 - uc0));
-
- int signy1 = (int)ceil(sgn(v2.GetY() - v1.GetY()));
- int signy2 = (int)ceil(sgn(v3.GetY() - v1.GetY()));
- int signv1 = (int)ceil(sgn(vc1 - vc0));
- int signv2 = (int)ceil(sgn(vc2 - vc0));
-
- if (dy1 > dx1)
- {
- int tempDx = dx1;
- dx1 = dy1;
- dy1 = tempDx;
-
- changed1 = true;
- }
-
- if (dy2 > dx2)
- {
- int tempDx = dx2;
- dx2 = dy2;
- dy2 = tempDx;
-
- changed2 = true;
- }
-
- int e1 = 2 * (int)dy1 - (int)dx1;
- int e2 = 2 * (int)dy2 - (int)dx2;
-
- for (int i = 0; i <= (int)dx1; i++)
- {
- float leftEndPoint;
- float rightEndPoint;
- float leftU;
- float rightU;
- float leftV;
- float rightV;
-
- if (tempA.GetX() < tempB.GetX())
- {
- leftEndPoint = tempA.GetX() - 1.0f;
- rightEndPoint = tempB.GetX() + 1.0f;
- leftU = tempUVA.GetU();
- rightU = tempUVB.GetU();
- leftV = tempUVA.GetV();
- rightV = tempUVB.GetV();
- }
- else
- {
- leftEndPoint = tempB.GetX() - 1.0f;
- rightEndPoint = tempA.GetX() + 1.0f;
- 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);
-
- //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);
- float iGreenA = Lerp(v1.GetG(), v2.GetG(), (float)i / (float)dx1);
- float iGreenB = Lerp(v1.GetG(), v3.GetG(), (float)i / (float)dx1);
- float iBlueA = Lerp(v1.GetB(), v2.GetB(), (float)i / (float)dx1);
- float iBlueB = Lerp(v1.GetB(), v3.GetB(), (float)i / (float)dx1);
-
- int xLength = (int)ceil(rightEndPoint) - (int)ceil(leftEndPoint);
- int ci = 0;
-
- 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)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++;
}
}
-
while (e1 >= 0)
{
if (changed1)
{
- tempA.SetX((float)tempA.GetXInt() + (float)signx1);
- tempUVA.SetU((float)tempUVA.GetU() + (float)signu1);
+ tempA.SetX((float)(tempA.GetXInt() + signx1));
}
else
{
- tempA.SetY((float)tempA.GetYInt() + (float)signy1);
- tempUVA.SetV((float)tempUVA.GetV() + (float)signv1);
+ tempA.SetY((float)(tempA.GetYInt() + signy1));
}
e1 = e1 - 2 * dx1;
}
if (changed1)
{
- tempA.SetY((float)tempA.GetYInt() + (float)signy1);
- tempUVA.SetV((float)tempUVA.GetV() + (float)signv1);
+ tempA.SetY((float)(tempA.GetYInt() + signy1));
}
else
{
- tempA.SetX((float)tempA.GetXInt() + (float)signx1);
- tempUVA.SetU((float)tempUVA.GetU() + (float)signu1);
+ tempA.SetX((float)(tempA.GetXInt() + signx1));
}
e1 = e1 + 2 * dy1;
@@ -942,28 +783,491 @@ void Rasteriser::FillTexturedSideTriangle(HDC hDc, Model& model, const Vertex& v
{
if (changed2)
{
- tempB.SetX((float)tempB.GetXInt() + (float)signx2);
- tempUVB.SetU((float)tempUVB.GetU() + (float)signu2);
+ tempB.SetX((float)(tempB.GetXInt() + signx2));
}
else
{
- tempB.SetY((float)tempB.GetYInt() + (float)signy2);
- tempUVB.SetV((float)tempUVB.GetV() + (float)signv2);
+ tempB.SetY((float)(tempB.GetYInt() + signy2));
}
e2 = e2 - 2 * dx2;
}
if (changed2)
{
- tempB.SetY((float)tempB.GetYInt() + (float)signy2);
- tempUVB.SetV((float)tempUVB.GetV() + (float)signv2);
+ tempB.SetY((float)(tempB.GetYInt() + signy2));
}
else
{
- tempB.SetX((float)tempB.GetXInt() + (float)signx2);
- tempUVB.SetU((float)tempUVB.GetU() + (float)signu2);
+ tempB.SetX((float)(tempB.GetXInt() + signx2));
}
e2 = e2 + 2 * dy2;
}
}
-}
\ No newline at end of file
+}
+
+void Rasteriser::FillPolygonTextured(HDC hDc, Model& model, vector& verts)
+{
+ sort(verts.begin(), verts.end(), VerticiesYCompareAsc);
+
+ if (verts[1].GetY() == verts[2].GetY())
+ {
+ FillTexturedSideTriangle(hDc, model, verts[0], verts[1], verts[2]);
+ }
+ else if (verts[0].GetY() == verts[1].GetY())
+ {
+ FillTexturedSideTriangle(hDc, model, verts[2], verts[0], verts[1]);
+ }
+ else
+ {
+ Vertex temp = verts[1];
+ temp.SetX(verts[0].GetX() + ((verts[1].GetY() - verts[0].GetY()) / (verts[2].GetY() - verts[0].GetY())) * (verts[2].GetX() - verts[0].GetX()));
+
+ float tempZr = verts[0].GetZRecip() + ((verts[1].GetY() - verts[0].GetY()) / (verts[2].GetY() - verts[0].GetY())) * (verts[2].GetZRecip() - verts[0].GetZRecip());
+ temp.SetZRecip(tempZr);
+
+ float tempU = verts[0].GetUOverZ() + ((verts[1].GetY() - verts[0].GetY()) / (verts[2].GetY() - verts[0].GetY())) * (verts[2].GetUOverZ() - verts[0].GetUOverZ());
+ float tempV = verts[0].GetVOverZ() + ((verts[1].GetY() - verts[0].GetY()) / (verts[2].GetY() - verts[0].GetY())) * (verts[2].GetVOverZ() - verts[0].GetVOverZ());
+ temp.SetUOverZ(tempU);
+ temp.SetVOverZ(tempV);
+
+ // Get the RGB value at the new vertex point
+ float cRed = verts[0].GetR() + ((verts[1].GetY() - verts[0].GetY()) / (verts[2].GetY() - verts[0].GetY())) * (verts[2].GetR() - verts[0].GetR());
+ float cGreen = verts[0].GetG() + ((verts[1].GetY() - verts[0].GetY()) / (verts[2].GetY() - verts[0].GetY())) * (verts[2].GetG() - verts[0].GetG());
+ 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())
+ {
+ FillTexturedSideTriangle(hDc, model, verts[0], verts[1], temp);
+ FillTexturedSideTriangle(hDc, model, verts[2], verts[1], temp);
+ }
+ else
+ {
+ FillTexturedSideTriangle(hDc, model, verts[0], temp, verts[1]);
+ FillTexturedSideTriangle(hDc, model, verts[2], temp, verts[1]);
+ }
+ }
+}
+
+void Rasteriser::FillTexturedSideTriangle(HDC hDc, Model& model, const Vertex& v1, const Vertex& v2, const Vertex& v3)
+{
+ // Check if any of the vertices match and dont draw the triangle if they do, this should stop the infinite loop that can happen with small vertex float numbers
+ if ((v1.GetXInt() == v2.GetXInt() && v1.GetYInt() == v2.GetYInt()) || (v1.GetXInt() == v3.GetXInt() && v1.GetYInt() == v3.GetYInt()) || (v2.GetXInt() == v3.GetXInt() && v3.GetYInt() == v2.GetYInt()))
+ {
+ return;
+ }
+
+ Vertex tempA = Vertex(v1);
+ Vertex tempB = Vertex(v1);
+
+ bool changed1 = false;
+ bool changed2 = false;
+
+ int dx1 = (int)abs(v2.GetXInt() - v1.GetXInt());
+ int dy1 = (int)abs(v2.GetYInt() - v1.GetYInt());
+ int dx2 = (int)abs(v3.GetXInt() - v1.GetXInt());
+ int dy2 = (int)abs(v3.GetYInt() - v1.GetYInt());
+
+ int signx1 = (int)sgn(v2.GetXInt() - v1.GetXInt());
+ int signx2 = (int)sgn(v3.GetXInt() - v1.GetXInt());
+ int signy1 = (int)sgn(v2.GetYInt() - v1.GetYInt());
+ int signy2 = (int)sgn(v3.GetYInt() - v1.GetYInt());
+
+ if (dy1 > dx1)
+ {
+ swap(dx1, dy1);
+ changed1 = true;
+ }
+
+ if (dy2 > dx2)
+ {
+ swap(dx2, dy2);
+ changed2 = true;
+ }
+
+ int e1 = 2 * dy1 - dx1;
+ int e2 = 2 * dy2 - dx2;
+
+ for (int i = 0; i <= dx1; i++)
+ {
+ int leftEndPoint;
+ int rightEndPoint;
+ int sideFix;
+
+ if (tempA.GetXInt() < tempB.GetXInt())
+ {
+ leftEndPoint = tempA.GetXInt();
+ rightEndPoint = tempB.GetXInt();
+ sideFix = 0;
+ }
+ else
+ {
+ leftEndPoint = tempB.GetXInt();
+ rightEndPoint = tempA.GetXInt();
+ sideFix = 1;
+ }
+
+ float currentPoint = (float)i / (float)dx1;
+ float UCoordA = Interpolate(tempA.GetY(), v1.GetUOverZ(), v2.GetUOverZ(), v1.GetY(), v2.GetY());
+ float UCoordB = Interpolate(tempA.GetY(), v1.GetUOverZ(), v3.GetUOverZ(), v1.GetY(), v3.GetY());
+ float VCoordA = Interpolate(tempA.GetY(), v1.GetVOverZ(), v2.GetVOverZ(), v1.GetY(), v2.GetY());
+ float VCoordB = Interpolate(tempA.GetY(), v1.GetVOverZ(), v3.GetVOverZ(), v1.GetY(), v3.GetY());
+ float ZRecipA = Interpolate(tempA.GetY(), v1.GetZRecip(), v2.GetZRecip(), v1.GetY(), v2.GetY());
+ float ZRecipB = Interpolate(tempA.GetY(), v1.GetZRecip(), v3.GetZRecip(), v1.GetY(), v3.GetY());
+
+ float iRedA = Lerp(v1.GetR(), v2.GetR(), currentPoint);
+ float iRedB = Lerp(v1.GetR(), v3.GetR(), currentPoint);
+ float iGreenA = Lerp(v1.GetG(), v2.GetG(), currentPoint);
+ float iGreenB = Lerp(v1.GetG(), v3.GetG(), currentPoint);
+ float iBlueA = Lerp(v1.GetB(), v2.GetB(), currentPoint);
+ float iBlueB = Lerp(v1.GetB(), v3.GetB(), currentPoint);
+
+ int xLength = rightEndPoint - leftEndPoint;
+ int ci = xLength * sideFix;
+
+ for (int xi = leftEndPoint; xi < rightEndPoint; xi++)
+ {
+ float ti = ((float)ci / (float)xLength);
+
+ float UCoordTmp = Lerp(UCoordA, UCoordB, ti);
+ float VCoordTmp = Lerp(VCoordA, VCoordB, ti);
+ float ZRecipTmp = Lerp(ZRecipA, ZRecipB, ti);
+ float redTmp = Lerp(iRedA, iRedB, ti) / 100;
+ float greenTmp = Lerp(iGreenA, iGreenB, ti) / 100;
+ float blueTmp = Lerp(iBlueA, iBlueB, ti) / 100;
+
+ float uFinal = UCoordTmp / ZRecipTmp;
+ float vFinal = VCoordTmp / ZRecipTmp;
+
+ COLORREF textureColor = model.GetTexture().GetTextureValue((int)uFinal, (int)vFinal);
+ 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);
+ if (sideFix == 1)
+ {
+ ci--;
+ }
+ else
+ {
+ ci++;
+ }
+ }
+
+ while (e1 >= 0)
+ {
+ if (changed1)
+ {
+ tempA.SetX((float)(tempA.GetXInt() + signx1));
+ }
+ else
+ {
+ tempA.SetY((float)(tempA.GetYInt() + signy1));
+ }
+ e1 = e1 - 2 * dx1;
+ }
+
+ if (changed1)
+ {
+ tempA.SetY((float)(tempA.GetYInt() + signy1));
+ }
+ else
+ {
+ tempA.SetX((float)(tempA.GetXInt() + signx1));
+ }
+
+ e1 = e1 + 2 * dy1;
+
+ while (tempB.GetYInt(true) != tempA.GetYInt(true))
+ {
+ while (e2 >= 0)
+ {
+ if (changed2)
+ {
+ tempB.SetX((float)(tempB.GetXInt() + signx2));
+ }
+ else
+ {
+ tempB.SetY((float)(tempB.GetYInt() + signy2));
+ }
+ e2 = e2 - 2 * dx2;
+ }
+
+ if (changed2)
+ {
+ tempB.SetY((float)(tempB.GetYInt() + signy2));
+ }
+ else
+ {
+ tempB.SetX((float)(tempB.GetXInt() + signx2));
+ }
+ e2 = e2 + 2 * dy2;
+ }
+
+ }
+}
+
+void Rasteriser::FillPolygonTexturedA(HDC hDc, Model& model, vector& verts)
+{
+ sort(verts.begin(), verts.end(), VerticiesYCompareAsc);
+
+ if (verts[1].GetY() == verts[2].GetY())
+ {
+ FillTexturedBottomFlatTriangle(hDc, model, verts[0], verts[1], verts[2]);
+ }
+ else if (verts[0].GetY() == verts[1].GetY())
+ {
+ FillTexturedTopFlatTriangle(hDc, model, verts[0], verts[1], verts[2]);
+ }
+ else
+ {
+ Vertex temp = verts[1];
+ temp.SetX(verts[0].GetX() + ((verts[1].GetY() - verts[0].GetY()) / (verts[2].GetY() - verts[0].GetY())) * (verts[2].GetX() - verts[0].GetX()));
+
+ float tempZr = verts[1].GetZOriginal() + ((verts[1].GetY() - verts[0].GetY()) / (verts[2].GetY() - verts[0].GetY())) * (verts[2].GetZOriginal() - verts[0].GetZOriginal());
+ temp.SetZOriginal(tempZr);
+
+ float uc1 = model.GetUVCoord(verts[0].GetUVIndex()).GetU();
+ float vc1 = model.GetUVCoord(verts[0].GetUVIndex()).GetV();
+ float uc2 = model.GetUVCoord(verts[1].GetUVIndex()).GetU();
+ float vc2 = model.GetUVCoord(verts[1].GetUVIndex()).GetV();
+ float uc3 = model.GetUVCoord(verts[2].GetUVIndex()).GetU();
+ float vc3 = model.GetUVCoord(verts[2].GetUVIndex()).GetV();
+
+ float tempU = Interpolate(verts[1].GetY(), uc1, uc3, verts[0].GetY(), verts[2].GetY()); // uc1 + ((verts[1].GetY() - verts[0].GetY()) / (verts[2].GetY() - verts[0].GetY())) * (uc3 - uc1);
+ float tempV = Interpolate(verts[1].GetY(), vc1, vc3, verts[0].GetY(), verts[2].GetY()); // vc2 + ((verts[1].GetY() - verts[0].GetY()) / (verts[2].GetY() - verts[0].GetY())) * (vc3 - vc2);
+ temp.UVCorrect(tempU, tempV);
+ //temp.SetUOverZ(tempU);
+ //temp.SetVOverZ(tempV);
+
+ //x0 + (y - y0) * ((x1 - x0) / (y1 - y0));
+
+ float cRed = verts[0].GetR() + ((verts[1].GetY() - verts[0].GetY()) / (verts[2].GetY() - verts[0].GetY())) * (verts[2].GetR() - verts[0].GetR());
+ float cGreen = verts[0].GetG() + ((verts[1].GetY() - verts[0].GetY()) / (verts[2].GetY() - verts[0].GetY())) * (verts[2].GetG() - verts[0].GetG());
+ 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));
+
+ FillTexturedBottomFlatTriangle(hDc, model, verts[0], verts[1], temp);
+ FillTexturedTopFlatTriangle(hDc, model, verts[1], temp, verts[2]);
+
+ }
+}
+
+void Rasteriser::FillTexturedBottomFlatTriangle(HDC hDc, Model& model, const Vertex& v1, const Vertex& v2, const Vertex& v3)
+{
+ float slope1 = (v2.GetX() - v1.GetX()) / (v2.GetY() - v1.GetY());
+ float slope2 = (v3.GetX() - v1.GetX()) / (v3.GetY() - v1.GetY());
+
+ float x1 = v1.GetX() - 1.0f;
+ float x2 = v1.GetX() + 1.0f;
+
+ float v2v1Diff = (v2.GetY() - v1.GetY());
+ float colorSlopeBlue1 = (v2.GetB() - v1.GetB()) / v2v1Diff;
+ float colorSlopeRed1 = (v2.GetR() - v1.GetR()) / v2v1Diff;
+ float colorSlopeGreen1 = (v2.GetG() - v1.GetG()) / v2v1Diff;
+ float uSlope1 = (v2.GetUOverZ() - v1.GetUOverZ()) / v2v1Diff;
+ float vSlope1 = (v2.GetVOverZ() - v1.GetVOverZ()) / v2v1Diff;
+ float zrSlope1 = (v2.GetZRecip() - v1.GetZRecip()) / v2v1Diff;
+
+ float v3v1Diff = (v3.GetY() - v1.GetY());
+ float colorSlopeBlue2 = (v3.GetB() - v1.GetB()) / v3v1Diff;
+ float colorSlopeRed2 = (v3.GetR() - v1.GetR()) / v3v1Diff;
+ float colorSlopeGreen2 = (v3.GetG() - v1.GetG()) / v3v1Diff;
+ float uSlope2 = (v3.GetUOverZ() - v1.GetUOverZ()) / v3v1Diff;
+ float vSlope2 = (v3.GetVOverZ() - v1.GetVOverZ()) / v3v1Diff;
+ float zrSlope2 = (v3.GetZRecip() - v1.GetZRecip()) / v3v1Diff;
+
+ float cBlue1 = (float)v1.GetB();
+ float cRed1 = (float)v1.GetR();
+ float cGreen1 = (float)v1.GetG();
+ float uc1 = v1.GetUOverZ();
+ float vc1 = v1.GetVOverZ();
+ float zr1 = v1.GetZRecip();
+ float cBlue2 = (float)v1.GetB();
+ float cRed2 = (float)v1.GetR();
+ float cGreen2 = (float)v1.GetG();
+ float uc2 = v1.GetUOverZ();
+ float vc2 = v1.GetVOverZ();
+ float zr2 = v1.GetZRecip();
+
+ if (slope2 < slope1)
+ {
+ float slopeTmp = slope1;
+ slope1 = slope2;
+ slope2 = slopeTmp;
+
+ slopeTmp = colorSlopeRed1;
+ colorSlopeRed1 = colorSlopeRed2;
+ colorSlopeRed2 = slopeTmp;
+
+ slopeTmp = colorSlopeGreen1;
+ colorSlopeGreen1 = colorSlopeGreen2;
+ colorSlopeGreen2 = slopeTmp;
+
+ slopeTmp = colorSlopeBlue1;
+ colorSlopeBlue1 = colorSlopeBlue2;
+ colorSlopeBlue2 = slopeTmp;
+
+ slopeTmp = uSlope1;
+ uSlope1 = uSlope2;
+ uSlope2 = slopeTmp;
+
+ slopeTmp = vSlope1;
+ vSlope1 = vSlope2;
+ vSlope2 = slopeTmp;
+
+ slopeTmp = zrSlope1;
+ zrSlope1 = zrSlope2;
+ zrSlope2 = slopeTmp;
+ }
+
+ for (float scanlineY = v1.GetY(); scanlineY < v2.GetY() + 0.5f; scanlineY++)
+ {
+ for (int xPos = (int)ceil(x1); xPos < (int)x2; xPos++)
+ {
+ float t = (xPos - x1) / (x2 - x1);
+
+ float redTmp = Lerp(cRed1, cRed2, t) / 100;
+ float greenTmp = Lerp(cGreen1, cGreen2, t) / 100;
+ float blueTmp = Lerp(cBlue1, cBlue2, t) / 100;
+
+ float UCoordTmp = Lerp(uc1, uc2, t);
+ float VCoordTmp = Lerp(vc1, vc2, t);
+ float ZRecipTmp = Lerp(zr1, zr2, t);
+
+ float uFinal = UCoordTmp / ZRecipTmp;
+ float vFinal = VCoordTmp / ZRecipTmp;
+
+ COLORREF textureColor = model.GetTexture().GetTextureValue((int)uFinal, (int)vFinal);
+ 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, xPos, (int)scanlineY, currentColor);
+ }
+
+ x1 += slope1;
+ x2 += slope2;
+
+ cRed1 += colorSlopeRed1;
+ cGreen1 += colorSlopeGreen1;
+ cBlue1 += colorSlopeBlue1;
+ uc1 += uSlope1;
+ vc1 += vSlope1;
+ zr1 += zrSlope1;
+
+ cRed2 += colorSlopeRed2;
+ cGreen2 += colorSlopeGreen2;
+ cBlue2 += colorSlopeBlue2;
+ uc2 += uSlope2;
+ vc2 += vSlope2;
+ zr2 += zrSlope2;
+ }
+}
+
+void Rasteriser::FillTexturedTopFlatTriangle(HDC hDc, Model& model, const Vertex& v1, const Vertex& v2, const Vertex& v3)
+{
+ float slope1 = (v3.GetX() - v1.GetX()) / (v3.GetY() - v1.GetY());
+ float slope2 = (v3.GetX() - v2.GetX()) / (v3.GetY() - v2.GetY());
+
+ float x1 = v3.GetX() - 1.0f;
+ float x2 = v3.GetX() + 1.0f;
+
+ float v3v1Diff = (v3.GetY() - v1.GetY());
+ float colorSlopeBlue1 = (v3.GetB() - v1.GetB()) / v3v1Diff;
+ float colorSlopeRed1 = (v3.GetR() - v1.GetR()) / v3v1Diff;
+ float colorSlopeGreen1 = (v3.GetG() - v1.GetG()) / v3v1Diff;
+ float uSlope1 = (v3.GetUOverZ() - v1.GetUOverZ()) / v3v1Diff;
+ float vSlope1 = (v3.GetVOverZ() - v1.GetVOverZ()) / v3v1Diff;
+ float zrSlope1 = (v3.GetZRecip() - v1.GetZRecip()) / v3v1Diff;
+
+ float v3v2Diff = (v3.GetY() - v2.GetY());
+ float colorSlopeBlue2 = (v3.GetB() - v2.GetB()) / v3v2Diff;
+ float colorSlopeRed2 = (v3.GetR() - v2.GetR()) / v3v2Diff;
+ float colorSlopeGreen2 = (v3.GetG() - v2.GetG()) / v3v2Diff;
+ float uSlope2 = (v3.GetUOverZ() - v2.GetUOverZ()) / v3v2Diff;
+ float vSlope2 = (v3.GetVOverZ() - v2.GetVOverZ()) / v3v2Diff;
+ float zrSlope2 = (v3.GetZRecip() - v2.GetZRecip()) / v3v2Diff;
+
+ float cBlue1 = (float)v3.GetB();
+ float cRed1 = (float)v3.GetR();
+ float cGreen1 = (float)v3.GetG();
+ float uc1 = v3.GetUOverZ();
+ float vc1 = v3.GetVOverZ();
+ float zr1 = v3.GetZRecip();
+ float cBlue2 = (float)v3.GetB();
+ float cRed2 = (float)v3.GetR();
+ float cGreen2 = (float)v3.GetG();
+ float uc2 = v3.GetUOverZ();
+ float vc2 = v3.GetVOverZ();
+ float zr2 = v3.GetZRecip();
+
+ if (slope1 < slope2)
+ {
+ float slopeTmp = slope1;
+ slope1 = slope2;
+ slope2 = slopeTmp;
+
+ slopeTmp = colorSlopeRed1;
+ colorSlopeRed1 = colorSlopeRed2;
+ colorSlopeRed2 = slopeTmp;
+
+ slopeTmp = colorSlopeGreen1;
+ colorSlopeGreen1 = colorSlopeGreen2;
+ colorSlopeGreen2 = slopeTmp;
+
+ slopeTmp = colorSlopeBlue1;
+ colorSlopeBlue1 = colorSlopeBlue2;
+ colorSlopeBlue2 = slopeTmp;
+
+ slopeTmp = uSlope1;
+ uSlope1 = uSlope2;
+ uSlope2 = slopeTmp;
+
+ slopeTmp = vSlope1;
+ vSlope1 = vSlope2;
+ vSlope2 = slopeTmp;
+
+ slopeTmp = zrSlope1;
+ zrSlope1 = zrSlope2;
+ zrSlope2 = slopeTmp;
+ }
+
+ for (float scanlineY = v3.GetY(); scanlineY > v1.GetY(); scanlineY--)
+ {
+ for (int xPos = (int)ceil(x1); xPos < (int)x2; xPos++)
+ {
+ float t = (xPos - x1) / (x2 - x1);
+
+ float redTmp = Lerp(cRed1, cRed2, t) / 100;
+ float greenTmp = Lerp(cGreen1, cGreen2, t) / 100;
+ float blueTmp = Lerp(cBlue1, cBlue2, t) / 100;
+
+ float UCoordTmp = Lerp(uc1, uc2, t);
+ float VCoordTmp = Lerp(vc1, vc2, t);
+ float ZRecipTmp = Lerp(zr1, zr2, t);
+
+ float uFinal = UCoordTmp / ZRecipTmp;
+ float vFinal = VCoordTmp / ZRecipTmp;
+
+ COLORREF textureColor = model.GetTexture().GetTextureValue((int)uFinal, (int)vFinal);
+ 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, xPos, (int)scanlineY, currentColor);
+ }
+
+ x1 -= slope1;
+ x2 -= slope2;
+
+ cRed1 -= colorSlopeRed1;
+ cGreen1 -= colorSlopeGreen1;
+ cBlue1 -= colorSlopeBlue1;
+ uc1 -= uSlope1;
+ vc1 -= vSlope1;
+ zr1 -= zrSlope1;
+
+ cRed2 -= colorSlopeRed2;
+ cGreen2 -= colorSlopeGreen2;
+ cBlue2 -= colorSlopeBlue2;
+ uc2 -= uSlope2;
+ vc2 -= vSlope2;
+ zr2 -= zrSlope2;
+ }
+}
diff --git a/Rasteriser.h b/Rasteriser.h
index c948ce2..162b21b 100644
--- a/Rasteriser.h
+++ b/Rasteriser.h
@@ -2,6 +2,7 @@
#include
#include
#include
+#include
#include "Framework.h"
#include "Vector3D.h"
#include "Vertex.h"
@@ -25,7 +26,7 @@ public:
void Update(const Bitmap& bitmap);
void Render(const Bitmap& bitmap);
void ClearViewport(const Bitmap& bitmap);
- void DrawString(HDC hDc, int x, int y, LPCTSTR text, COLORREF textColor = 0x00FFFFFF, COLORREF backgroundColor = 0x00000000);
+ void DrawString(HDC hDc, int x, int y, LPCTSTR text, int fontSize = 48, COLORREF textColor = 0x00FFFFFF, COLORREF backgroundColor = 0x00000000);
~Rasteriser();
@@ -58,23 +59,40 @@ public:
void FillGouraudSideTriangle(HDC hDc, const Vertex& v1, const Vertex& v2, const Vertex& v3);
void FillPolygonTextured(HDC hDc, Model& model, vector& verticies);
- void FillTexturedSideTriangle(HDC hDc, Model& model, const Vertex& v1, const Vertex& v2, const Vertex& v3, const UVCoord& uv1, const UVCoord& uv2, const UVCoord& uv3);
+ void FillTexturedSideTriangle(HDC hDc, Model& model, const Vertex& v1, const Vertex& v2, const Vertex& v3);
+
+ void FillPolygonTexturedA(HDC hDc, Model& model, vector& verticies);
+ void FillTexturedBottomFlatTriangle(HDC hDc, Model& model, const Vertex& v1, const Vertex& v2, const Vertex& v3);
+ void FillTexturedTopFlatTriangle(HDC hDc, Model& model, const Vertex& v1, const Vertex& v2, const Vertex& v3);
private:
+ // Vector arrays to hold the scene models, the lights and the cameras.
vector _sceneModels;
vector _lights;
vector _cameras;
+ // Index of the currently viewing camera.
int _currentCamera = 0;
+ // Matrices and Aspect ration for the viewing and perspective transformations.
Matrix _currentPerspectiveMatrix;
Matrix _currentViewMatrix;
float _currentAspectRatio = 0.0f;
- int _rotation = 0;
-
- int _currentDrawMode = 0;
+ // bool to check if the screen is minimized to stop processing
bool _screenMinimized = false;
string _modelDataLocation = ".//model_data/";
+
+ // timer variables to hold the start time of the showcase, and the current time for
+ // calculation of where in the showcase we are.
+ time_t _startTime;
+ time_t _currentTime;
+
+ // an int to store the current state of the showcase.
+ int _currentState;
+ int _maxStates;
+
+ // An array to store counters for use in.
+ int _counters[10];
};
diff --git a/Vertex.cpp b/Vertex.cpp
index 23fc46a..f306dc0 100644
--- a/Vertex.cpp
+++ b/Vertex.cpp
@@ -207,14 +207,19 @@ float Vertex::GetZOriginal() const
return _zOriginal;
}
-float Vertex::GetUOverZ() const
+void Vertex::SetZOriginal(const float value)
{
- return _uOverZ;
+ _zOriginal = value;
+}
+
+float Vertex::GetUOverZ() const
+{
+ return _uOverZ;
}
void Vertex::SetUOverZ(const float value)
{
- _uOverZ = value / _zOriginal;
+ _uOverZ = value;
}
float Vertex::GetVOverZ() const
@@ -224,20 +229,27 @@ float Vertex::GetVOverZ() const
void Vertex::SetVOverZ(const float value)
{
- _vOverZ = value / _zOriginal;
+ _vOverZ = value;
}
float Vertex::GetZRecip() const
{
- return _zRecip;
+ return _zRecip;
}
-void Vertex::UVCorrect(float u, float v)
+void Vertex::SetZRecip(const float value)
{
- _zOriginal = _w;
- _zRecip = 1 / _zOriginal;
- SetUOverZ(u);
- SetVOverZ(v);
+ _zRecip = value;
+}
+
+void Vertex::UVCorrect(float u, float v, bool calcZRecip)
+{
+ SetUOverZ(u / _zOriginal);
+ SetVOverZ(v / _zOriginal);
+ if (calcZRecip)
+ {
+ SetZRecip(1 / _zOriginal);
+ }
}
int Vertex::GetXInt(bool forceRoundUp) const
@@ -289,7 +301,8 @@ int Vertex::GetWInt(bool forceRoundUp) const
}
void Vertex::Dehomogenize()
-{
+{
+ _zOriginal = _w;
_x = _x / _w;
_y = _y / _w;
_z = _z / _w;
diff --git a/Vertex.h b/Vertex.h
index 1ca154a..e38537b 100644
--- a/Vertex.h
+++ b/Vertex.h
@@ -45,12 +45,14 @@ public:
void SetUVIndex(const int index);
float GetZOriginal() const;
+ void SetZOriginal(const float value);
float GetUOverZ() const;
void SetUOverZ(const float value);
- float GetVOverZ() const;
+ float GetVOverZ() const;
void SetVOverZ(const float value);
float GetZRecip() const;
- void UVCorrect(float u, float v);
+ void SetZRecip(const float value);
+ void UVCorrect(float u, float v, bool calcZRecip = true);
// 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
@@ -76,6 +78,7 @@ private:
float _z;
float _w;
+ float _zOriginalSet = 0;
float _zOriginal;
int _contributeCount;