diff --git a/BaseFramework.vcxproj b/BaseFramework.vcxproj
index c1b3ee3..0f521ae 100644
--- a/BaseFramework.vcxproj
+++ b/BaseFramework.vcxproj
@@ -154,6 +154,7 @@
+
@@ -168,6 +169,7 @@
+
diff --git a/BaseFramework.vcxproj.filters b/BaseFramework.vcxproj.filters
index a13257d..ee53882 100644
--- a/BaseFramework.vcxproj.filters
+++ b/BaseFramework.vcxproj.filters
@@ -45,6 +45,9 @@
Source Files
+
+ Source Files
+
@@ -83,6 +86,9 @@
Header Files
+
+ Header Files
+
diff --git a/Model.cpp b/Model.cpp
index 3b9d659..c8291d3 100644
--- a/Model.cpp
+++ b/Model.cpp
@@ -59,17 +59,17 @@ void Model::ClearPendingTransforms()
_pendingTransforms.clear();
}
-Polygon3D Model::GetPolygon(int index)
+const Polygon3D& Model::GetPolygon(int index)
{
return _polygons[index];
}
-Vertex Model::GetVertex(int polygonIndex, int vertexPolygonIndex)
+const Vertex& Model::GetVertex(int polygonIndex, int vertexPolygonIndex)
{
return GetVertex(GetPolygon(polygonIndex).GetIndex(vertexPolygonIndex));
}
-Vertex Model::GetVertex(int index)
+const Vertex& Model::GetVertex(int index)
{
return _transformedVertices[index];
}
@@ -96,4 +96,45 @@ void Model::DehomogenizeAllVertices()
{
currentVertex.Dehomogenize();
}
+}
+
+void Model::CalculateBackfaces(Camera& currentCamera)
+{
+ for (Polygon3D ¤tPolygon : _polygons)
+ {
+ Vector3D vectorA = _transformedVertices[currentPolygon.GetIndex(1)] - _transformedVertices[currentPolygon.GetIndex(0)];
+ Vector3D vectorB = _transformedVertices[currentPolygon.GetIndex(2)] - _transformedVertices[currentPolygon.GetIndex(0)];
+ currentPolygon.SetNormal(Vector3D::CrossProduct(vectorA, vectorB));
+ Vector3D eyeVector = _transformedVertices[currentPolygon.GetIndex(0)] - currentCamera.GetCurrentPosition();
+
+ float dotProduct = Vector3D::DotProduct(currentPolygon.GetNormal(), eyeVector);
+ if (dotProduct < 0)
+ {
+ currentPolygon.SetCulled(true);
+ }
+ else
+ {
+ currentPolygon.SetCulled(false);
+ }
+ }
+}
+
+bool DepthCompare(Polygon3D& a, Polygon3D& b)
+{
+ return a.GetDepth() > b.GetDepth();
+}
+
+void Model::Sort()
+{
+ for (Polygon3D ¤tPolygon : _polygons)
+ {
+ float zTotal = 0.0f;
+ for (int i = 0; i < currentPolygon.GetPolygonVertexCount(); i++)
+ {
+ zTotal += _transformedVertices[currentPolygon.GetIndex(i)].GetZ();
+ }
+ currentPolygon.SetDepth(zTotal / currentPolygon.GetPolygonVertexCount());
+ }
+
+ sort(_polygons.begin(), _polygons.end(), DepthCompare);
}
\ No newline at end of file
diff --git a/Model.h b/Model.h
index 56f4b3c..178e767 100644
--- a/Model.h
+++ b/Model.h
@@ -1,8 +1,11 @@
#pragma once
-#include "Polygon3D.h"
+#include "Vector3D.h"
#include "Vertex.h"
+#include "Polygon3D.h"
#include "Matrix.h"
+#include "Camera.h"
#include
+#include
using namespace std;
@@ -10,29 +13,31 @@ class Model
{
public:
Model();
-
~Model();
- const vector& GetPolygons();
- const vector& GetVertices();
- const vector& GetPendingTransforms();
+ const vector& GetPolygons(void);
+ const vector& GetVertices(void);
+ const vector& GetPendingTransforms(void);
- size_t GetPolygonCount();
- size_t GetVerticesCount();
- size_t GetPendingTransformCount();
+ size_t GetPolygonCount(void);
+ size_t GetVerticesCount(void);
+ size_t GetPendingTransformCount(void);
void AddVertex(float x, float y, float z);
void AddPolygon(int index0, int index1, int index2);
void EnqueueTransform(Matrix transform);
void ClearPendingTransforms();
- Polygon3D GetPolygon(int index);
- Vertex GetVertex(int polygonIndex, int vertexPolygonIndex);
- Vertex GetVertex(int index);
+ const Polygon3D& GetPolygon(int index);
+ const Vertex& GetVertex(int polygonIndex, int vertexPolygonIndex);
+ const Vertex& GetVertex(int index);
void ApplyTransformToLocalVertices(const Matrix& transform);
void ApplyTransformToTransformedVertices(const Matrix& transform);
- void DehomogenizeAllVertices();
+ void DehomogenizeAllVertices(void);
+
+ void CalculateBackfaces(Camera& currentCamera);
+ void Sort(void);
private:
vector _polygons;
diff --git a/Polygon3D.cpp b/Polygon3D.cpp
index 2db1c3e..2bc2a12 100644
--- a/Polygon3D.cpp
+++ b/Polygon3D.cpp
@@ -9,6 +9,7 @@ Polygon3D::Polygon3D(int index0, int index1, int index2)
_indices[0] = index0;
_indices[1] = index1;
_indices[2] = index2;
+ _depth = 0.0f;
}
Polygon3D::Polygon3D(const Polygon3D& other)
@@ -20,7 +21,7 @@ Polygon3D::~Polygon3D()
{
}
-size_t Polygon3D::GetPolygonVertexCount()
+size_t Polygon3D::GetPolygonVertexCount() const
{
return sizeof(_indices) / sizeof(_indices[0]);
}
@@ -30,6 +31,36 @@ int Polygon3D::GetIndex(const int index) const
return _indices[index];
}
+void Polygon3D::SetNormal(const Vector3D& normal)
+{
+ _normal = normal;
+}
+
+Vector3D Polygon3D::GetNormal() const
+{
+ return _normal;
+}
+
+void Polygon3D::SetDepth(float depth)
+{
+ _depth = depth;
+}
+
+float Polygon3D::GetDepth() const
+{
+ return _depth;
+}
+
+void Polygon3D::SetCulled(bool culled)
+{
+ _culled = culled;
+}
+
+bool Polygon3D::GetCulled() const
+{
+ return _culled;
+}
+
Polygon3D& Polygon3D::operator= (const Polygon3D& rhs)
{
if (this != &rhs)
@@ -44,5 +75,8 @@ void Polygon3D::Copy(const Polygon3D& other)
for (int i = 0; i < sizeof(_indices)/sizeof(_indices[0]); i++)
{
_indices[i] = other.GetIndex(i);
+ _normal = other.GetNormal();
+ _culled = other.GetCulled();
+ _depth = other.GetDepth();
}
}
\ No newline at end of file
diff --git a/Polygon3D.h b/Polygon3D.h
index d34456a..01b151c 100644
--- a/Polygon3D.h
+++ b/Polygon3D.h
@@ -1,4 +1,6 @@
#pragma once
+#include "Vector3D.h"
+
class Polygon3D
{
public:
@@ -8,14 +10,25 @@ public:
~Polygon3D();
- size_t GetPolygonVertexCount();
+ size_t GetPolygonVertexCount() const;
int GetIndex(int index) const;
+
+ void SetNormal(const Vector3D& normal);
+ Vector3D GetNormal() const;
+
+ void SetDepth(float depth);
+ float GetDepth() const;
+ void SetCulled(bool culled);
+ bool GetCulled() const;
Polygon3D& operator= (const Polygon3D& rhs);
private:
int _indices[3];
+ Vector3D _normal;
+ float _depth = 0.0f;
+ bool _culled = false;
void Copy(const Polygon3D& other);
};
diff --git a/Rasteriser.cpp b/Rasteriser.cpp
index 19c5fc1..0783bee 100644
--- a/Rasteriser.cpp
+++ b/Rasteriser.cpp
@@ -90,7 +90,9 @@ void Rasteriser::Render(const Bitmap& bitmap)
workingMatrix *= currentTransform;
}
currentModel.ApplyTransformToLocalVertices(workingMatrix);
+ currentModel.CalculateBackfaces(mainCamera);
currentModel.ApplyTransformToTransformedVertices(mainCamera.GetCurrentCameraTransformMatrix());
+ currentModel.Sort();
currentModel.ApplyTransformToTransformedVertices(_currentPerspectiveMatrix);
currentModel.DehomogenizeAllVertices();
currentModel.ApplyTransformToTransformedVertices(_currentViewMatrix);
@@ -139,19 +141,25 @@ void Rasteriser::DrawWireFrame(HDC hDc, Model& model)
vector pointArray;
vector sizeArray;
+ int unculledPolyCount = 0;
int modelPolygonCount = (int) model.GetPolygonCount();
for (int i = 0; i < modelPolygonCount; i++)
- {
- int currentPolygonVertexCount = (int) model.GetPolygon(i).GetPolygonVertexCount();
- for (int j = 0; j < currentPolygonVertexCount; j++)
+ {
+
+ if (!model.GetPolygon(i).GetCulled())
{
- POINT newPoint;
- newPoint.x = (long) model.GetVertex(i, j).GetX();
- newPoint.y = (long) model.GetVertex(i, j).GetY();
- pointArray.push_back(newPoint);
+ int currentPolygonVertexCount = (int)model.GetPolygon(i).GetPolygonVertexCount();
+ for (int j = 0; j < currentPolygonVertexCount; j++)
+ {
+ POINT newPoint;
+ newPoint.x = (long)model.GetVertex(i, j).GetX();
+ newPoint.y = (long)model.GetVertex(i, j).GetY();
+ pointArray.push_back(newPoint);
+ }
+ sizeArray.push_back(currentPolygonVertexCount);
+ unculledPolyCount++;
}
- sizeArray.push_back(currentPolygonVertexCount);
}
- PolyPolygon(hDc, pointArray.data(), sizeArray.data(), modelPolygonCount);
+ PolyPolygon(hDc, pointArray.data(), sizeArray.data(), unculledPolyCount);
}
\ No newline at end of file
diff --git a/Rasteriser.h b/Rasteriser.h
index 23c8be3..e1e05c1 100644
--- a/Rasteriser.h
+++ b/Rasteriser.h
@@ -29,9 +29,7 @@ private:
Matrix _currentPerspectiveMatrix;
Matrix _currentViewMatrix;
- float _currentAspectRatio;
-
- int _rotation;
-
+ float _currentAspectRatio = 0.0f;
+ int _rotation = 0;
};
diff --git a/Vector3D.cpp b/Vector3D.cpp
new file mode 100644
index 0000000..05969f7
--- /dev/null
+++ b/Vector3D.cpp
@@ -0,0 +1,78 @@
+#include "Vector3D.h"
+
+Vector3D::Vector3D()
+{
+ SetX(1);
+ SetY(1);
+ SetZ(1);
+}
+
+Vector3D::Vector3D(float x, float y, float z)
+{
+ SetX(x);
+ SetY(y);
+ SetZ(z);
+}
+
+Vector3D::Vector3D(const Vector3D& other)
+{
+ Copy(other);
+}
+
+Vector3D::~Vector3D()
+{
+}
+
+// Accessors
+float Vector3D::GetX() const
+{
+ return _x;
+}
+
+void Vector3D::SetX(const float x)
+{
+ _x = x;
+}
+
+float Vector3D::GetY() const
+{
+ return _y;
+}
+
+void Vector3D::SetY(const float y)
+{
+ _y = y;
+}
+
+float Vector3D::GetZ() const
+{
+ return _z;
+}
+
+void Vector3D::SetZ(const float z)
+{
+ _z = z;
+}
+
+float Vector3D::DotProduct(const Vector3D v1, const Vector3D v2)
+{
+ return ((v1.GetX() * v2.GetX()) + (v1.GetY() * v2.GetY()) + (v1.GetZ() * v2.GetZ()));
+
+}
+
+Vector3D Vector3D::CrossProduct(const Vector3D v1, const Vector3D v2)
+{
+ return Vector3D((v1.GetY() * v2.GetZ()) - (v1.GetZ() * v2.GetY()), (v1.GetZ() * v2.GetX()) - (v1.GetX() * v2.GetZ()), (v1.GetX() * v2.GetY()) - (v1.GetY() * v2.GetX()));
+}
+
+const Vector3D Vector3D::operator+ (const Vector3D& rhs) const
+{
+ return Vector3D(_x + rhs.GetX(), _y + rhs.GetY(), _z + rhs.GetZ());
+}
+
+void Vector3D::Copy(const Vector3D& other)
+{
+ _x = other.GetX();
+ _y = other.GetY();
+ _z = other.GetZ();
+}
\ No newline at end of file
diff --git a/Vector3D.h b/Vector3D.h
new file mode 100644
index 0000000..03763c4
--- /dev/null
+++ b/Vector3D.h
@@ -0,0 +1,32 @@
+#pragma once
+
+class Vector3D
+{
+public:
+ Vector3D();
+ Vector3D(float x, float y, float z);
+ Vector3D(const Vector3D& other);
+
+ ~Vector3D();
+
+ // Accessors
+ float GetX() const;
+ void SetX(const float x);
+ float GetY() const;
+ void SetY(const float y);
+ float GetZ() const;
+ void SetZ(const float z);
+
+ static float DotProduct(const Vector3D v1, const Vector3D v2);
+ static Vector3D CrossProduct(const Vector3D v1, const Vector3D v2);
+
+ const Vector3D operator+ (const Vector3D& rhs) const;
+
+private:
+ float _x;
+ float _y;
+ float _z;
+
+ void Copy(const Vector3D& other);
+};
+
diff --git a/Vertex.cpp b/Vertex.cpp
index 2a5d694..caab4d8 100644
--- a/Vertex.cpp
+++ b/Vertex.cpp
@@ -88,6 +88,11 @@ Vertex& Vertex::operator=(const Vertex& rhs)
return *this;
}
+const Vector3D Vertex::operator-(const Vertex& rhs) const
+{
+ return Vector3D(rhs.GetX() - GetX(), rhs.GetY() - GetY(), rhs.GetZ() - GetZ());
+}
+
// The const at the end of the declaraion for '==" indicates that this operation does not change
// any of the member variables in this class.
diff --git a/Vertex.h b/Vertex.h
index 2923b0d..71cc658 100644
--- a/Vertex.h
+++ b/Vertex.h
@@ -1,10 +1,12 @@
#pragma once
+#include "Vector3D.h"
+
class Vertex
{
public:
Vertex();
- Vertex(const float x, const float y, const float z);
- Vertex(const float x, const float y, const float z, const float w);
+ Vertex(float x, float y, float z);
+ Vertex(float x, float y, float z, float w);
Vertex(const Vertex& other);
// Accessors
@@ -25,6 +27,7 @@ public:
bool operator== (const Vertex& rhs) const;
const Vertex operator+ (const Vertex& rhs) const;
+ const Vector3D operator- (const Vertex& rhs) const;
private:
float _x;