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
This commit is contained in:
IDunnoDev
2021-12-11 14:48:46 +00:00
committed by iDunnoDev
parent 19639d70d1
commit 773507b4ab
12 changed files with 257 additions and 32 deletions

View File

@ -154,6 +154,7 @@
<ClCompile Include="Polygon3D.cpp" /> <ClCompile Include="Polygon3D.cpp" />
<ClCompile Include="Rasteriser.cpp" /> <ClCompile Include="Rasteriser.cpp" />
<ClCompile Include="TransformTools.cpp" /> <ClCompile Include="TransformTools.cpp" />
<ClCompile Include="Vector3D.cpp" />
<ClCompile Include="Vertex.cpp" /> <ClCompile Include="Vertex.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@ -168,6 +169,7 @@
<ClInclude Include="Resource.h" /> <ClInclude Include="Resource.h" />
<ClInclude Include="targetver.h" /> <ClInclude Include="targetver.h" />
<ClInclude Include="TransformTools.h" /> <ClInclude Include="TransformTools.h" />
<ClInclude Include="Vector3D.h" />
<ClInclude Include="Vertex.h" /> <ClInclude Include="Vertex.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -45,6 +45,9 @@
<ClCompile Include="TransformTools.cpp"> <ClCompile Include="TransformTools.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="Vector3D.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="Framework.h"> <ClInclude Include="Framework.h">
@ -83,6 +86,9 @@
<ClInclude Include="TransformTools.h"> <ClInclude Include="TransformTools.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Vector3D.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Image Include="Rasteriser.ico"> <Image Include="Rasteriser.ico">

View File

@ -59,17 +59,17 @@ void Model::ClearPendingTransforms()
_pendingTransforms.clear(); _pendingTransforms.clear();
} }
Polygon3D Model::GetPolygon(int index) const Polygon3D& Model::GetPolygon(int index)
{ {
return _polygons[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)); return GetVertex(GetPolygon(polygonIndex).GetIndex(vertexPolygonIndex));
} }
Vertex Model::GetVertex(int index) const Vertex& Model::GetVertex(int index)
{ {
return _transformedVertices[index]; return _transformedVertices[index];
} }
@ -96,4 +96,45 @@ void Model::DehomogenizeAllVertices()
{ {
currentVertex.Dehomogenize(); currentVertex.Dehomogenize();
} }
}
void Model::CalculateBackfaces(Camera& currentCamera)
{
for (Polygon3D &currentPolygon : _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 &currentPolygon : _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);
} }

29
Model.h
View File

@ -1,8 +1,11 @@
#pragma once #pragma once
#include "Polygon3D.h" #include "Vector3D.h"
#include "Vertex.h" #include "Vertex.h"
#include "Polygon3D.h"
#include "Matrix.h" #include "Matrix.h"
#include "Camera.h"
#include <vector> #include <vector>
#include <algorithm>
using namespace std; using namespace std;
@ -10,29 +13,31 @@ class Model
{ {
public: public:
Model(); Model();
~Model(); ~Model();
const vector<Polygon3D>& GetPolygons(); const vector<Polygon3D>& GetPolygons(void);
const vector<Vertex>& GetVertices(); const vector<Vertex>& GetVertices(void);
const vector<Matrix>& GetPendingTransforms(); const vector<Matrix>& GetPendingTransforms(void);
size_t GetPolygonCount(); size_t GetPolygonCount(void);
size_t GetVerticesCount(); size_t GetVerticesCount(void);
size_t GetPendingTransformCount(); size_t GetPendingTransformCount(void);
void AddVertex(float x, float y, float z); void AddVertex(float x, float y, float z);
void AddPolygon(int index0, int index1, int index2); void AddPolygon(int index0, int index1, int index2);
void EnqueueTransform(Matrix transform); void EnqueueTransform(Matrix transform);
void ClearPendingTransforms(); void ClearPendingTransforms();
Polygon3D GetPolygon(int index); const Polygon3D& GetPolygon(int index);
Vertex GetVertex(int polygonIndex, int vertexPolygonIndex); const Vertex& GetVertex(int polygonIndex, int vertexPolygonIndex);
Vertex GetVertex(int index); const Vertex& GetVertex(int index);
void ApplyTransformToLocalVertices(const Matrix& transform); void ApplyTransformToLocalVertices(const Matrix& transform);
void ApplyTransformToTransformedVertices(const Matrix& transform); void ApplyTransformToTransformedVertices(const Matrix& transform);
void DehomogenizeAllVertices(); void DehomogenizeAllVertices(void);
void CalculateBackfaces(Camera& currentCamera);
void Sort(void);
private: private:
vector<Polygon3D> _polygons; vector<Polygon3D> _polygons;

View File

@ -9,6 +9,7 @@ Polygon3D::Polygon3D(int index0, int index1, int index2)
_indices[0] = index0; _indices[0] = index0;
_indices[1] = index1; _indices[1] = index1;
_indices[2] = index2; _indices[2] = index2;
_depth = 0.0f;
} }
Polygon3D::Polygon3D(const Polygon3D& other) 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]); return sizeof(_indices) / sizeof(_indices[0]);
} }
@ -30,6 +31,36 @@ int Polygon3D::GetIndex(const int index) const
return _indices[index]; 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) Polygon3D& Polygon3D::operator= (const Polygon3D& rhs)
{ {
if (this != &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++) for (int i = 0; i < sizeof(_indices)/sizeof(_indices[0]); i++)
{ {
_indices[i] = other.GetIndex(i); _indices[i] = other.GetIndex(i);
_normal = other.GetNormal();
_culled = other.GetCulled();
_depth = other.GetDepth();
} }
} }

View File

@ -1,4 +1,6 @@
#pragma once #pragma once
#include "Vector3D.h"
class Polygon3D class Polygon3D
{ {
public: public:
@ -8,14 +10,25 @@ public:
~Polygon3D(); ~Polygon3D();
size_t GetPolygonVertexCount(); size_t GetPolygonVertexCount() const;
int GetIndex(int index) 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); Polygon3D& operator= (const Polygon3D& rhs);
private: private:
int _indices[3]; int _indices[3];
Vector3D _normal;
float _depth = 0.0f;
bool _culled = false;
void Copy(const Polygon3D& other); void Copy(const Polygon3D& other);
}; };

View File

@ -90,7 +90,9 @@ void Rasteriser::Render(const Bitmap& bitmap)
workingMatrix *= currentTransform; workingMatrix *= currentTransform;
} }
currentModel.ApplyTransformToLocalVertices(workingMatrix); currentModel.ApplyTransformToLocalVertices(workingMatrix);
currentModel.CalculateBackfaces(mainCamera);
currentModel.ApplyTransformToTransformedVertices(mainCamera.GetCurrentCameraTransformMatrix()); currentModel.ApplyTransformToTransformedVertices(mainCamera.GetCurrentCameraTransformMatrix());
currentModel.Sort();
currentModel.ApplyTransformToTransformedVertices(_currentPerspectiveMatrix); currentModel.ApplyTransformToTransformedVertices(_currentPerspectiveMatrix);
currentModel.DehomogenizeAllVertices(); currentModel.DehomogenizeAllVertices();
currentModel.ApplyTransformToTransformedVertices(_currentViewMatrix); currentModel.ApplyTransformToTransformedVertices(_currentViewMatrix);
@ -139,19 +141,25 @@ void Rasteriser::DrawWireFrame(HDC hDc, Model& model)
vector<POINT> pointArray; vector<POINT> pointArray;
vector<int> sizeArray; vector<int> sizeArray;
int unculledPolyCount = 0;
int modelPolygonCount = (int) model.GetPolygonCount(); int modelPolygonCount = (int) model.GetPolygonCount();
for (int i = 0; i < modelPolygonCount; i++) 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; int currentPolygonVertexCount = (int)model.GetPolygon(i).GetPolygonVertexCount();
newPoint.x = (long) model.GetVertex(i, j).GetX(); for (int j = 0; j < currentPolygonVertexCount; j++)
newPoint.y = (long) model.GetVertex(i, j).GetY(); {
pointArray.push_back(newPoint); 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);
} }

View File

@ -29,9 +29,7 @@ private:
Matrix _currentPerspectiveMatrix; Matrix _currentPerspectiveMatrix;
Matrix _currentViewMatrix; Matrix _currentViewMatrix;
float _currentAspectRatio; float _currentAspectRatio = 0.0f;
int _rotation = 0;
int _rotation;
}; };

78
Vector3D.cpp Normal file
View File

@ -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();
}

32
Vector3D.h Normal file
View File

@ -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);
};

View File

@ -88,6 +88,11 @@ Vertex& Vertex::operator=(const Vertex& rhs)
return *this; 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 // The const at the end of the declaraion for '==" indicates that this operation does not change
// any of the member variables in this class. // any of the member variables in this class.

View File

@ -1,10 +1,12 @@
#pragma once #pragma once
#include "Vector3D.h"
class Vertex class Vertex
{ {
public: public:
Vertex(); Vertex();
Vertex(const float x, const float y, const float z); Vertex(float x, float y, float z);
Vertex(const float x, const float y, const float z, const float w); Vertex(float x, float y, float z, float w);
Vertex(const Vertex& other); Vertex(const Vertex& other);
// Accessors // Accessors
@ -25,6 +27,7 @@ public:
bool operator== (const Vertex& rhs) const; bool operator== (const Vertex& rhs) const;
const Vertex operator+ (const Vertex& rhs) const; const Vertex operator+ (const Vertex& rhs) const;
const Vector3D operator- (const Vertex& rhs) const;
private: private:
float _x; float _x;