From 773507b4ab486503e3f5cca013d10b790d662e5e Mon Sep 17 00:00:00 2001 From: IDunnoDev Date: Sat, 11 Dec 2021 14:48:46 +0000 Subject: [PATCH] Week7 [09/11] - [11/11] Added Backface Culling Methods to the Model Class Added Depth, Normal and Culled Flag Variables to the Polygon3D Class Added Vector3D Class Added - operator to the Vertex Class Cleaned up Code, Adding Void to Params etc --- BaseFramework.vcxproj | 2 + BaseFramework.vcxproj.filters | 6 +++ Model.cpp | 47 +++++++++++++++++++-- Model.h | 29 +++++++------ Polygon3D.cpp | 36 +++++++++++++++- Polygon3D.h | 15 ++++++- Rasteriser.cpp | 26 ++++++++---- Rasteriser.h | 6 +-- Vector3D.cpp | 78 +++++++++++++++++++++++++++++++++++ Vector3D.h | 32 ++++++++++++++ Vertex.cpp | 5 +++ Vertex.h | 7 +++- 12 files changed, 257 insertions(+), 32 deletions(-) create mode 100644 Vector3D.cpp create mode 100644 Vector3D.h 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;