Week9 [23/11] - [29/11]
Added Lighting Changes for Vertex Normal Calculation Added Method to Get a Polygons Vertices as a Vector array Added Methods to Add the Color to a Polygon and Vertex Object Added Normalization to the Polygon normal vector Added Vector Normal Calculation to the Model Class Added Light Calculation method to the Rasterizer Class Added Flag to Rasterizer to stop processing when the screen is minimised Added Flat and Gouraud Drawing Methods to the Resterizer Added Standard and INT triangle drawing Methods Added Function to mimic sgn function from Java Added Length to Vector3D class Added / operator to Vector3D class Added Get(x,y,z,w)Int methods to Vertex class Changed Color Variables on the Vertex/Polygon classes to use r, g and b values rather than COLORREF Changed Camera translation functions to use normal Translation Functions Cleaned up Code Removed Unused code from the Camera Class
This commit is contained in:
@ -5,7 +5,7 @@ AmbientLight::AmbientLight(const AmbientLight& other) : Light(other)
|
||||
Copy(other);
|
||||
}
|
||||
|
||||
COLORREF AmbientLight::CalculateLight(const Model& currentModel, const Polygon3D& currentPolygon, COLORREF colorIn)
|
||||
COLORREF AmbientLight::CalculateLightShared(const Model& currentModel, COLORREF colorIn)
|
||||
{
|
||||
float workingRed = (float)GetRedLightIntensity();
|
||||
float workingGreen = (float)GetGreenLightIntensity();
|
||||
@ -27,6 +27,16 @@ COLORREF AmbientLight::CalculateLight(const Model& currentModel, const Polygon3D
|
||||
return outputColor;
|
||||
}
|
||||
|
||||
COLORREF AmbientLight::CalculateLight(const Model& currentModel, const Polygon3D& currentPolygon, COLORREF colorIn)
|
||||
{
|
||||
return CalculateLightShared(currentModel, colorIn);
|
||||
}
|
||||
|
||||
COLORREF AmbientLight::CalculateLight(const Model& currentModel, const Vertex& currentVertex, COLORREF colorIn)
|
||||
{
|
||||
return CalculateLightShared(currentModel, colorIn);
|
||||
}
|
||||
|
||||
AmbientLight& AmbientLight::operator= (const AmbientLight& rhs)
|
||||
{
|
||||
if (this != &rhs)
|
||||
|
@ -9,7 +9,10 @@ public:
|
||||
AmbientLight(int red, int green, int blue) : Light(red, green, blue) {};
|
||||
AmbientLight(const AmbientLight& other);
|
||||
|
||||
COLORREF CalculateLightShared(const Model& currentModel, COLORREF colorIn);
|
||||
|
||||
COLORREF CalculateLight(const Model& currentModel, const Polygon3D& currentPolygon, COLORREF colorIn);
|
||||
COLORREF CalculateLight(const Model& currentModel, const Vertex& currentVertex, COLORREF colorIn);
|
||||
|
||||
AmbientLight& operator= (const AmbientLight& rhs);
|
||||
|
||||
|
90
Camera.cpp
90
Camera.cpp
@ -1,19 +1,11 @@
|
||||
#include "Camera.h"
|
||||
|
||||
Camera::Camera()
|
||||
{
|
||||
}
|
||||
|
||||
Camera::Camera(float xRot, float yRot, float zRot, const Vertex& pos)
|
||||
{
|
||||
_initialRotation[0] = xRot;
|
||||
_currentRotation[0] = xRot;
|
||||
_initialRotation[1] = yRot;
|
||||
_currentRotation[1] = yRot;
|
||||
_initialRotation[2] = zRot;
|
||||
_currentRotation[2] = zRot;
|
||||
_initialPosition = pos;
|
||||
_currentPosition = pos;
|
||||
_xRot = xRot;
|
||||
_yRot = yRot;
|
||||
_zRot = zRot;
|
||||
_cameraPosition = pos;
|
||||
}
|
||||
|
||||
Camera::Camera(const Camera& other)
|
||||
@ -27,61 +19,56 @@ Camera::~Camera()
|
||||
|
||||
Matrix Camera::UpdateCameraPosition(const Vertex& newPos)
|
||||
{
|
||||
_currentPosition = newPos;
|
||||
_cameraPosition = newPos;
|
||||
return GetCurrentCameraTransformMatrix();
|
||||
}
|
||||
|
||||
Matrix Camera::RotateCamera(float xRot, float yRot, float zRot)
|
||||
{
|
||||
_currentRotation[0] = xRot;
|
||||
_currentRotation[1] = yRot;
|
||||
_currentRotation[2] = zRot;
|
||||
_xRot = xRot;
|
||||
_yRot = yRot;
|
||||
_zRot = zRot;
|
||||
return GetCurrentCameraTransformMatrix();
|
||||
}
|
||||
|
||||
Matrix Camera::GetCurrentCameraTransformMatrix()
|
||||
{
|
||||
return GetCameraRotationMatrix(Axis::X, _currentRotation[0]) * GetCameraRotationMatrix(Axis::Y, _currentRotation[1]) * GetCameraRotationMatrix(Axis::Z, _currentRotation[2]) * GetCameraTranslateMatrix(_currentPosition);
|
||||
return GetCameraRotationMatrix(Axis::X, _xRot) * GetCameraRotationMatrix(Axis::Y, _yRot) * GetCameraRotationMatrix(Axis::Z, _zRot) * GetCameraTranslateMatrix(_cameraPosition);
|
||||
}
|
||||
|
||||
float Camera::GetCurrentRotationValue(const Axis axis)
|
||||
void Camera::SetXRot(const float value)
|
||||
{
|
||||
switch (axis)
|
||||
{
|
||||
case (Axis::X):
|
||||
return _currentRotation[0];
|
||||
case (Axis::Y):
|
||||
return _currentRotation[1];
|
||||
case (Axis::Z):
|
||||
return _currentRotation[2];
|
||||
default:
|
||||
throw "No valid axis?";
|
||||
}
|
||||
_xRot = value;
|
||||
}
|
||||
|
||||
float Camera::GetInitialRotationValue(const Axis axis)
|
||||
float Camera::GetXRot() const
|
||||
{
|
||||
switch (axis)
|
||||
{
|
||||
case (Axis::X):
|
||||
return _initialRotation[0];
|
||||
case (Axis::Y):
|
||||
return _initialRotation[1];
|
||||
case (Axis::Z):
|
||||
return _initialRotation[2];
|
||||
default:
|
||||
throw "No valid axis?";
|
||||
}
|
||||
return _xRot;
|
||||
}
|
||||
|
||||
Vertex Camera::GetCurrentPosition()
|
||||
void Camera::SetYRot(const float value)
|
||||
{
|
||||
return _currentPosition;
|
||||
_yRot = value;
|
||||
}
|
||||
|
||||
Vertex Camera::GetInitialPosition()
|
||||
float Camera::GetYRot() const
|
||||
{
|
||||
return _initialPosition;
|
||||
return _yRot;
|
||||
}
|
||||
|
||||
void Camera::SetZRot(const float value)
|
||||
{
|
||||
_zRot = value;
|
||||
}
|
||||
|
||||
float Camera::GetZRot() const
|
||||
{
|
||||
return _zRot;
|
||||
}
|
||||
|
||||
Vertex Camera::GetCameraPosition() const
|
||||
{
|
||||
return _cameraPosition;
|
||||
}
|
||||
|
||||
Camera& Camera::operator=(const Camera& rhs)
|
||||
@ -95,12 +82,9 @@ Camera& Camera::operator=(const Camera& rhs)
|
||||
|
||||
void Camera::Copy(const Camera& other)
|
||||
{
|
||||
_initialRotation[0] = other._initialRotation[0];
|
||||
_currentRotation[0] = other._currentRotation[0];
|
||||
_initialRotation[1] = other._initialRotation[1];
|
||||
_currentRotation[1] = other._currentRotation[1];
|
||||
_initialRotation[2] = other._initialRotation[2];
|
||||
_currentRotation[2] = other._currentRotation[2];
|
||||
_initialPosition = other._initialPosition;
|
||||
_currentPosition = other._currentPosition;
|
||||
_xRot = other.GetXRot();
|
||||
_yRot = other.GetYRot();
|
||||
_zRot = other.GetZRot();
|
||||
|
||||
_cameraPosition = other.GetCameraPosition();
|
||||
}
|
26
Camera.h
26
Camera.h
@ -8,7 +8,7 @@ using namespace SharedTools;
|
||||
class Camera
|
||||
{
|
||||
public:
|
||||
Camera();
|
||||
Camera() : _xRot(0), _yRot(0), _zRot(0) {};
|
||||
Camera(float xRot, float yRot, float zRot, const Vertex& pos);
|
||||
Camera(const Camera& other);
|
||||
|
||||
@ -17,23 +17,23 @@ public:
|
||||
Matrix UpdateCameraPosition(const Vertex& newPos);
|
||||
Matrix RotateCamera(float xRot, float yRot, float zRot);
|
||||
|
||||
Matrix GetCurrentCameraTransformMatrix();
|
||||
void SetXRot(const float value);
|
||||
float GetXRot() const;
|
||||
void SetYRot(const float value);
|
||||
float GetYRot() const;
|
||||
void SetZRot(const float value);
|
||||
float GetZRot() const;
|
||||
|
||||
float GetCurrentRotationValue(const Axis axis);
|
||||
float GetInitialRotationValue(const Axis axis);
|
||||
Vertex GetCurrentPosition();
|
||||
Vertex GetInitialPosition();
|
||||
Matrix GetCurrentCameraTransformMatrix();
|
||||
Vertex GetCameraPosition() const;
|
||||
|
||||
Camera& operator= (const Camera& rhs);
|
||||
|
||||
private:
|
||||
float _initialRotation[3] = { 0 };
|
||||
Vertex _initialPosition;
|
||||
|
||||
float _currentRotation[3] = { 0 };
|
||||
Vertex _currentPosition;
|
||||
|
||||
Matrix _currentCameraTransform;
|
||||
float _xRot;
|
||||
float _yRot;
|
||||
float _zRot;
|
||||
Vertex _cameraPosition;
|
||||
|
||||
void Copy(const Camera& other);
|
||||
};
|
||||
|
@ -34,17 +34,17 @@ Vector3D DirectionalLight::GetLightDirection() const
|
||||
return _lightDirection;
|
||||
}
|
||||
|
||||
COLORREF DirectionalLight::CalculateLight(const Model& currentModel, const Polygon3D& currentPolygon, COLORREF colorIn)
|
||||
COLORREF DirectionalLight::CalculateLightShared(const Model& currentModel, const Vector3D& currentNormal, COLORREF colorIn)
|
||||
{
|
||||
float workingRed = (float) GetRedLightIntensity();
|
||||
float workingGreen = (float) GetGreenLightIntensity();
|
||||
float workingBlue = (float) GetBlueLightIntensity();
|
||||
float workingRed = (float)GetRedLightIntensity();
|
||||
float workingGreen = (float)GetGreenLightIntensity();
|
||||
float workingBlue = (float)GetBlueLightIntensity();
|
||||
|
||||
workingRed *= currentModel.GetRedReflectionCoefficient();
|
||||
workingGreen *= currentModel.GetGreenReflectionCoefficient();
|
||||
workingBlue *= currentModel.GetBlueReflectionCoefficient();
|
||||
|
||||
float lightDotProd = Vector3D::DotProduct(_normalizedLightDirection, currentPolygon.GetNormal());
|
||||
float lightDotProd = Vector3D::DotProduct(_normalizedLightDirection, currentNormal);
|
||||
|
||||
workingRed *= lightDotProd;
|
||||
workingGreen *= lightDotProd;
|
||||
@ -62,6 +62,16 @@ COLORREF DirectionalLight::CalculateLight(const Model& currentModel, const Polyg
|
||||
return outputColor;
|
||||
}
|
||||
|
||||
COLORREF DirectionalLight::CalculateLight(const Model& currentModel, const Polygon3D& currentPolygon, COLORREF colorIn)
|
||||
{
|
||||
return CalculateLightShared(currentModel, currentPolygon.GetNormal(), colorIn);
|
||||
}
|
||||
|
||||
COLORREF DirectionalLight::CalculateLight(const Model& currentModel, const Vertex& currentVertex, COLORREF colorIn)
|
||||
{
|
||||
return CalculateLightShared(currentModel, currentVertex.GetNormal(), colorIn);
|
||||
}
|
||||
|
||||
DirectionalLight& DirectionalLight::operator= (const DirectionalLight& rhs)
|
||||
{
|
||||
if (this != &rhs)
|
||||
|
@ -13,7 +13,10 @@ public:
|
||||
void SetLightDirection(Vector3D direction);
|
||||
Vector3D GetLightDirection() const;
|
||||
|
||||
COLORREF CalculateLightShared(const Model& currentModel, const Vector3D& currentNormal, COLORREF colorIn);
|
||||
|
||||
COLORREF CalculateLight(const Model& currentModel, const Polygon3D& currentPolygon, COLORREF colorIn);
|
||||
COLORREF CalculateLight(const Model& currentModel, const Vertex& currentVertex, COLORREF colorIn);
|
||||
|
||||
DirectionalLight& operator= (const DirectionalLight& rhs);
|
||||
|
||||
|
1
Light.h
1
Light.h
@ -27,6 +27,7 @@ public:
|
||||
int GetBlueLightIntensity() const;
|
||||
|
||||
virtual COLORREF CalculateLight(const Model& currentModel, const Polygon3D& currentPolygon, COLORREF colorIn) = 0;
|
||||
virtual COLORREF CalculateLight(const Model& currentModel, const Vertex& currentVertex, COLORREF colorIn) = 0;
|
||||
|
||||
Light& operator= (const Light& rhs);
|
||||
|
||||
|
58
Model.cpp
58
Model.cpp
@ -16,7 +16,7 @@ vector<Polygon3D>& Model::GetPolygons()
|
||||
return _polygons;
|
||||
}
|
||||
|
||||
const vector<Vertex>& Model::GetVertices()
|
||||
vector<Vertex>& Model::GetVertices()
|
||||
{
|
||||
return _vertices;
|
||||
}
|
||||
@ -77,6 +77,27 @@ const Vertex& Model::GetVertex(int index) const
|
||||
return _transformedVertices[index];
|
||||
}
|
||||
|
||||
vector<Vertex> Model::GetPolygonVertexArray(int index) const
|
||||
{
|
||||
vector<Vertex> polygonVerticies = {};
|
||||
|
||||
for (int i = 0; i < GetPolygon(index).GetPolygonVertexCount(); i++)
|
||||
{
|
||||
polygonVerticies.push_back(GetVertex(index, i));
|
||||
}
|
||||
return polygonVerticies;
|
||||
}
|
||||
|
||||
void Model::SetPolygonColor(int index, COLORREF color)
|
||||
{
|
||||
_polygons[index].SetColor(color);
|
||||
}
|
||||
|
||||
void Model::SetVertexColor(int polyIndex, int vertIndex, COLORREF color)
|
||||
{
|
||||
_transformedVertices[GetPolygon(polyIndex).GetIndex(vertIndex)].SetColor(color);
|
||||
}
|
||||
|
||||
void Model::SetReflectionCoefficient(float red, float green, float blue)
|
||||
{
|
||||
_kdRed = BoundsCheck(0.0f, 1.0f, red);
|
||||
@ -171,7 +192,7 @@ void Model::ApplyTransformToTransformedVertices(const Matrix& transform)
|
||||
|
||||
void Model::DehomogenizeAllVertices()
|
||||
{
|
||||
for (Vertex ¤tVertex : _transformedVertices)
|
||||
for (Vertex& currentVertex : _transformedVertices)
|
||||
{
|
||||
currentVertex.Dehomogenize();
|
||||
}
|
||||
@ -179,12 +200,14 @@ void Model::DehomogenizeAllVertices()
|
||||
|
||||
void Model::CalculateBackfaces(Camera& currentCamera)
|
||||
{
|
||||
for (Polygon3D ¤tPolygon : _polygons)
|
||||
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();
|
||||
currentPolygon.NormalizeNormal();
|
||||
Vector3D eyeVector = _transformedVertices[currentPolygon.GetIndex(0)] - currentCamera.GetCameraPosition();
|
||||
eyeVector.Normalize();
|
||||
|
||||
float dotProduct = Vector3D::DotProduct(currentPolygon.GetNormal(), eyeVector);
|
||||
if (dotProduct < 0)
|
||||
@ -198,6 +221,31 @@ void Model::CalculateBackfaces(Camera& currentCamera)
|
||||
}
|
||||
}
|
||||
|
||||
void Model::CalculateVertexNormals()
|
||||
{
|
||||
for (Vertex& currentVertex : _transformedVertices)
|
||||
{
|
||||
currentVertex.ResetNormal(true);
|
||||
}
|
||||
|
||||
for (int pi = 0; pi < GetPolygonCount(); pi++)
|
||||
{
|
||||
for (int i = 0; i < _polygons[pi].GetPolygonVertexCount(); i++)
|
||||
{
|
||||
_transformedVertices[_polygons[pi].GetIndex(i)].SetNormal(_transformedVertices[_polygons[pi].GetIndex(i)].GetNormal() + _polygons[pi].GetNormal());
|
||||
_transformedVertices[_polygons[pi].GetIndex(i)].IncrementContributeCount();
|
||||
}
|
||||
}
|
||||
|
||||
for (Vertex& currentVertex : _transformedVertices)
|
||||
{
|
||||
|
||||
currentVertex.SetNormal(currentVertex.GetNormal() / currentVertex.GetContributeCount());
|
||||
currentVertex.NormalizeNormal();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
bool DepthCompare(Polygon3D& a, Polygon3D& b)
|
||||
{
|
||||
return a.GetDepth() > b.GetDepth();
|
||||
@ -205,7 +253,7 @@ bool DepthCompare(Polygon3D& a, Polygon3D& b)
|
||||
|
||||
void Model::Sort()
|
||||
{
|
||||
for (Polygon3D ¤tPolygon : _polygons)
|
||||
for (Polygon3D& currentPolygon : _polygons)
|
||||
{
|
||||
float zTotal = 0.0f;
|
||||
for (int i = 0; i < currentPolygon.GetPolygonVertexCount(); i++)
|
||||
|
7
Model.h
7
Model.h
@ -16,7 +16,7 @@ public:
|
||||
~Model();
|
||||
|
||||
vector<Polygon3D>& GetPolygons(void);
|
||||
const vector<Vertex>& GetVertices(void);
|
||||
vector<Vertex>& GetVertices(void);
|
||||
const vector<Matrix>& GetPendingTransforms(void);
|
||||
|
||||
size_t GetPolygonCount(void);
|
||||
@ -32,6 +32,10 @@ public:
|
||||
const Vertex& GetVertex(int polygonIndex, int vertexPolygonIndex) const;
|
||||
const Vertex& GetVertex(int index) const;
|
||||
|
||||
vector<Vertex> GetPolygonVertexArray(int index) const;
|
||||
void SetPolygonColor(int index, COLORREF color);
|
||||
void SetVertexColor(int polyIndex, int vertIndex, COLORREF color);
|
||||
|
||||
void SetReflectionCoefficient(float red, float green, float blue);
|
||||
void SetReflectionCoefficient(ColRef color, float value);
|
||||
void SetRedReflectionCoefficient(float value);
|
||||
@ -48,6 +52,7 @@ public:
|
||||
void DehomogenizeAllVertices(void);
|
||||
|
||||
void CalculateBackfaces(Camera& currentCamera);
|
||||
void CalculateVertexNormals();
|
||||
void Sort(void);
|
||||
|
||||
private:
|
||||
|
@ -75,25 +75,25 @@ Vertex PointLight::GetLightPosition() const
|
||||
return _lightPosition;
|
||||
}
|
||||
|
||||
COLORREF PointLight::CalculateLight(const Model& currentModel, const Polygon3D& currentPolygon, COLORREF colorIn)
|
||||
COLORREF PointLight::CalculateLightShared(const Model& currentModel, const Vertex& currentVertex, const Vector3D& currentNormal, COLORREF colorIn)
|
||||
{
|
||||
float workingRed = (float)GetRedLightIntensity();
|
||||
float workingGreen = (float)GetGreenLightIntensity();
|
||||
float workingBlue = (float)GetBlueLightIntensity();
|
||||
|
||||
float fudge = 50;
|
||||
float fudge = 100;
|
||||
|
||||
workingRed *= currentModel.GetRedReflectionCoefficient();
|
||||
workingGreen *= currentModel.GetGreenReflectionCoefficient();
|
||||
workingBlue *= currentModel.GetBlueReflectionCoefficient();
|
||||
|
||||
Vector3D lightSource = currentModel.GetVertex(currentPolygon.GetIndex(0)) - _lightPosition;
|
||||
Vector3D lightSource = currentVertex - _lightPosition;
|
||||
Vector3D lightSourceNormalized = lightSource;
|
||||
lightSourceNormalized.Normalize();
|
||||
|
||||
float distance = Vector3D::DotProduct(lightSource, currentPolygon.GetNormal());
|
||||
float distance = Vector3D::Length(currentNormal, lightSource);
|
||||
|
||||
float lightDotProd = Vector3D::DotProduct(lightSourceNormalized, currentPolygon.GetNormal());
|
||||
float lightDotProd = Vector3D::DotProduct(lightSourceNormalized, currentNormal);
|
||||
float attenuation = 1 / (GetAttenuationA() + GetAttenuationB() * distance + GetAttenuationC() * (distance * distance));
|
||||
|
||||
workingRed *= lightDotProd;
|
||||
@ -120,6 +120,16 @@ COLORREF PointLight::CalculateLight(const Model& currentModel, const Polygon3D&
|
||||
return outputColor;
|
||||
}
|
||||
|
||||
COLORREF PointLight::CalculateLight(const Model& currentModel, const Polygon3D& currentPolygon, COLORREF colorIn)
|
||||
{
|
||||
return CalculateLightShared(currentModel, currentModel.GetVertex(currentPolygon.GetIndex(0)), currentPolygon.GetNormal(), colorIn);
|
||||
}
|
||||
|
||||
COLORREF PointLight::CalculateLight(const Model& currentModel, const Vertex& currentVertex, COLORREF colorIn)
|
||||
{
|
||||
return CalculateLightShared(currentModel, currentVertex, currentVertex.GetNormal(), colorIn);
|
||||
}
|
||||
|
||||
PointLight& PointLight::operator= (const PointLight& rhs)
|
||||
{
|
||||
if (this != &rhs)
|
||||
|
@ -21,8 +21,10 @@ public:
|
||||
float GetAttenuationB();
|
||||
float GetAttenuationC();
|
||||
|
||||
COLORREF CalculateLightShared(const Model& currentModel, const Vertex& currentVertex, const Vector3D& currentNormal, COLORREF colorIn);
|
||||
|
||||
COLORREF CalculateLight(const Model& currentModel, const Polygon3D& currentPolygon, COLORREF colorIn);
|
||||
COLORREF CalculateLight(const Model& currentModel, const Vertex& currentVertex, COLORREF colorIn);
|
||||
|
||||
PointLight& operator= (const PointLight& rhs);
|
||||
|
||||
|
@ -4,6 +4,7 @@ Polygon3D::Polygon3D() : _indices{ 0 }
|
||||
{
|
||||
_depth = 0.0f;
|
||||
_color = RGB(0, 0, 0);
|
||||
_culled = false;
|
||||
}
|
||||
|
||||
Polygon3D::Polygon3D(int index0, int index1, int index2)
|
||||
@ -13,6 +14,7 @@ Polygon3D::Polygon3D(int index0, int index1, int index2)
|
||||
_indices[2] = index2;
|
||||
_depth = 0.0f;
|
||||
_color = RGB(0, 0, 0);
|
||||
_culled = false;
|
||||
}
|
||||
|
||||
Polygon3D::Polygon3D(const Polygon3D& other)
|
||||
@ -39,11 +41,16 @@ void Polygon3D::SetNormal(const Vector3D& normal)
|
||||
_normal = normal;
|
||||
}
|
||||
|
||||
Vector3D Polygon3D::GetNormal() const
|
||||
const Vector3D& Polygon3D::GetNormal() const
|
||||
{
|
||||
return _normal;
|
||||
}
|
||||
|
||||
void Polygon3D::NormalizeNormal()
|
||||
{
|
||||
_normal.Normalize();
|
||||
}
|
||||
|
||||
void Polygon3D::SetColor(int red, int green, int blue)
|
||||
{
|
||||
int redChecked = BoundsCheck(0, 255, red);
|
||||
@ -97,9 +104,9 @@ 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();
|
||||
_color = other.GetColor();
|
||||
}
|
||||
}
|
@ -19,7 +19,8 @@ public:
|
||||
int GetIndex(int index) const;
|
||||
|
||||
void SetNormal(const Vector3D& normal);
|
||||
Vector3D GetNormal() const;
|
||||
const Vector3D& GetNormal() const;
|
||||
void NormalizeNormal();
|
||||
|
||||
void SetColor(int red, int green, int blue);
|
||||
void SetColor(const COLORREF color);
|
||||
@ -35,8 +36,8 @@ public:
|
||||
private:
|
||||
int _indices[3];
|
||||
Vector3D _normal;
|
||||
float _depth = 0.0f;
|
||||
bool _culled = false;
|
||||
float _depth;
|
||||
bool _culled;
|
||||
COLORREF _color;
|
||||
|
||||
void Copy(const Polygon3D& other);
|
||||
|
553
Rasteriser.cpp
553
Rasteriser.cpp
@ -5,8 +5,6 @@ Rasteriser app;
|
||||
bool Rasteriser::Initialise()
|
||||
{
|
||||
Model modelA;
|
||||
Model modelB;
|
||||
Model modelC;
|
||||
if (MD2Loader::LoadModel(".\\marvin.MD2", modelA, &Model::AddPolygon, &Model::AddVertex))
|
||||
{
|
||||
_sceneModels.push_back(modelA);
|
||||
@ -16,28 +14,14 @@ bool Rasteriser::Initialise()
|
||||
return false;
|
||||
}
|
||||
|
||||
if (MD2Loader::LoadModel(".\\megaman.MD2", modelB, &Model::AddPolygon, &Model::AddVertex))
|
||||
{
|
||||
_sceneModels.push_back(modelB);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (MD2Loader::LoadModel(".\\w_railgun.MD2", modelC, &Model::AddPolygon, &Model::AddVertex))
|
||||
{
|
||||
_sceneModels.push_back(modelC);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
_lights.push_back(new AmbientLight(150, 150, 150));
|
||||
//_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(-10, 0, 10), 0, 1, 0, 100, 0, 0));
|
||||
_cameras.push_back(Camera(0.0f, 0.0f, 0.0f, Vertex(0.0f, 0.0f, -50.0f)));
|
||||
|
||||
_lights.push_back(new AmbientLight(50, 50, 50));
|
||||
_lights.push_back(new DirectionalLight(Vector3D(1, 0, 1), 50, 0, 0));
|
||||
_lights.push_back(new PointLight(Vertex(0, 10, 0), 0, 1, 0, 100, 0, 0));
|
||||
_cameras.push_back(Camera(0.0f, 0.0f, 0.0f, Vertex(0.0f, 0.0f, -100.0f)));
|
||||
_screenMinimized = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -60,18 +44,62 @@ Camera& Rasteriser::GetCurrentCamera()
|
||||
return GetCamera(_currentCamera);
|
||||
}
|
||||
|
||||
void Rasteriser::CalculateLighting(Model& currentModel, bool fullLightRender)
|
||||
{
|
||||
{
|
||||
for (int pi = 0; pi < currentModel.GetPolygonCount(); pi++)
|
||||
{
|
||||
if (!currentModel.GetPolygon(pi).GetCulled())
|
||||
{
|
||||
if (fullLightRender)
|
||||
{
|
||||
for (int i = 0; i < currentModel.GetPolygon(pi).GetPolygonVertexCount(); i++)
|
||||
{
|
||||
COLORREF colorWorking = RGB(0, 0, 0);
|
||||
for (Light* currentLight : _lights)
|
||||
{
|
||||
colorWorking = currentLight->CalculateLight(currentModel, currentModel.GetVertex(pi, i), colorWorking);
|
||||
}
|
||||
currentModel.SetVertexColor(pi, i, colorWorking);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
COLORREF colorWorking = RGB(0, 0, 0);
|
||||
for (Light* currentLight : _lights)
|
||||
{
|
||||
colorWorking = currentLight->CalculateLight(currentModel, currentModel.GetPolygon(pi), colorWorking);
|
||||
}
|
||||
currentModel.SetPolygonColor(pi, colorWorking);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Rasteriser::Update(const Bitmap& bitmap)
|
||||
{
|
||||
if (bitmap.GetWidth() == 0 || bitmap.GetHeight() == 0)
|
||||
{
|
||||
_screenMinimized = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
_screenMinimized = false;
|
||||
}
|
||||
|
||||
if (!_screenMinimized)
|
||||
{
|
||||
int currentRot = (_rotation % 360);
|
||||
Vertex startPos = Vertex(-50, 0, 0);
|
||||
Vertex startPos = Vertex(0, 0, 20);
|
||||
int currentZOff = 0;
|
||||
int currentModelIndex = 0;
|
||||
|
||||
for (Model ¤tModel : _sceneModels)
|
||||
for (Model& currentModel : _sceneModels)
|
||||
{
|
||||
currentModel.EnqueueTransform(GetTranslateMatrix(startPos));
|
||||
currentModel.EnqueueTransform(GetRotationMatrix(Axis::Y, (float) currentRot));
|
||||
startPos.SetX(startPos.GetX() + 50);
|
||||
currentModel.EnqueueTransform(GetRotationMatrix(Axis::Y, (float)currentRot));
|
||||
//startPos.SetX(startPos.GetX() + 100);
|
||||
if ((currentModelIndex % 2) == 1)
|
||||
{
|
||||
currentZOff = 0;
|
||||
@ -80,11 +108,11 @@ void Rasteriser::Update(const Bitmap& bitmap)
|
||||
{
|
||||
currentZOff = 100;
|
||||
}
|
||||
startPos.SetZ((float)currentZOff);
|
||||
//startPos.SetZ((float)currentZOff);
|
||||
currentModelIndex++;
|
||||
}
|
||||
|
||||
_currentAspectRatio = (float)(bitmap.GetWidth() / bitmap.GetHeight());
|
||||
_currentAspectRatio = (float)(bitmap.GetWidth() / (float)bitmap.GetHeight());
|
||||
_currentPerspectiveMatrix = GetPerspectiveProjectionMatrix(1, _currentAspectRatio);
|
||||
_currentViewMatrix = GetViewMatrix(1, bitmap.GetWidth(), bitmap.GetHeight());
|
||||
|
||||
@ -96,15 +124,18 @@ void Rasteriser::Update(const Bitmap& bitmap)
|
||||
{
|
||||
_rotation += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Rasteriser::Render(const Bitmap& bitmap)
|
||||
{
|
||||
if (!_screenMinimized)
|
||||
{
|
||||
ClearViewport(bitmap);
|
||||
SelectObject(bitmap.GetDC(), GetStockObject(DC_BRUSH));
|
||||
SelectObject(bitmap.GetDC(), GetStockObject(DC_PEN));
|
||||
|
||||
for (Model ¤tModel : _sceneModels)
|
||||
for (Model& currentModel : _sceneModels)
|
||||
{
|
||||
currentModel.SetReflectionCoefficient(0.5f, 0.5f, 0.5f);
|
||||
Matrix workingMatrix = workingMatrix.IdentityMatrix();
|
||||
@ -113,27 +144,25 @@ void Rasteriser::Render(const Bitmap& bitmap)
|
||||
workingMatrix *= currentTransform;
|
||||
}
|
||||
currentModel.ApplyTransformToLocalVertices(workingMatrix);
|
||||
currentModel.CalculateBackfaces(GetCurrentCamera());
|
||||
for (Polygon3D ¤tPolygon : currentModel.GetPolygons())
|
||||
{
|
||||
if (!currentPolygon.GetCulled())
|
||||
{
|
||||
COLORREF colorWorking = RGB(0, 0, 0);
|
||||
for (Light* currentLight : _lights)
|
||||
{
|
||||
colorWorking = currentLight->CalculateLight(currentModel, currentPolygon, colorWorking);
|
||||
}
|
||||
currentPolygon.SetColor(colorWorking);
|
||||
}
|
||||
}
|
||||
currentModel.ApplyTransformToTransformedVertices(GetCurrentCamera().GetCurrentCameraTransformMatrix());
|
||||
|
||||
currentModel.CalculateBackfaces(GetCurrentCamera());
|
||||
currentModel.Sort();
|
||||
|
||||
currentModel.CalculateVertexNormals();
|
||||
CalculateLighting(currentModel, true);
|
||||
|
||||
currentModel.ApplyTransformToTransformedVertices(_currentPerspectiveMatrix);
|
||||
currentModel.DehomogenizeAllVertices();
|
||||
currentModel.ApplyTransformToTransformedVertices(_currentViewMatrix);
|
||||
DrawSolidFlat(bitmap.GetDC(), currentModel);
|
||||
|
||||
//DrawWireFrame(bitmap.GetDC(), currentModel);
|
||||
//DrawSolidFlat(bitmap.GetDC(), currentModel);
|
||||
//DrawRasterisedSolidFlat(bitmap.GetDC(), currentModel);
|
||||
DrawGouraud(bitmap.GetDC(), currentModel);
|
||||
currentModel.ClearPendingTransforms();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Rasteriser::ClearViewport(const Bitmap& bitmap)
|
||||
@ -222,3 +251,441 @@ void Rasteriser::DrawSolidFlat(HDC hDc, Model& model)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Rasteriser::DrawRasterisedSolidFlat(HDC hDc, Model& model)
|
||||
{
|
||||
int modelPolygonCount = (int)model.GetPolygonCount();
|
||||
for (int i = 0; i < modelPolygonCount; i++)
|
||||
{
|
||||
|
||||
if (!model.GetPolygon(i).GetCulled())
|
||||
{
|
||||
vector<Vertex> vertexArray = model.GetPolygonVertexArray(i);
|
||||
FillPolygonFlat(hDc, vertexArray, model.GetPolygon(i).GetColor());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Rasteriser::DrawGouraud(HDC hDc, Model& model)
|
||||
{
|
||||
int modelPolygonCount = (int)model.GetPolygonCount();
|
||||
for (int i = 0; i < modelPolygonCount; i++)
|
||||
{
|
||||
|
||||
if (!model.GetPolygon(i).GetCulled())
|
||||
{
|
||||
vector<Vertex> vertexArray = model.GetPolygonVertexArray(i);
|
||||
FillPolygonGouraud(hDc, vertexArray);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool VerticiesYCompareAsc(Vertex& v1, Vertex& v2)
|
||||
{
|
||||
return v1.GetY() < v2.GetY();
|
||||
}
|
||||
|
||||
void Rasteriser::FillPolygonFlat(HDC hDc, vector<Vertex>& verts, COLORREF colorIn)
|
||||
{
|
||||
sort(verts.begin(), verts.end(), VerticiesYCompareAsc);
|
||||
if (verts[1].GetY() == verts[2].GetY())
|
||||
{
|
||||
FillFlatSideTriangle(hDc, verts[0], verts[1], verts[2], colorIn);
|
||||
}
|
||||
else if (verts[0].GetY() == verts[1].GetY())
|
||||
{
|
||||
FillFlatSideTriangle(hDc, verts[2], verts[0], verts[1], colorIn);
|
||||
}
|
||||
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());
|
||||
if (verts[1].GetX() < temp.GetX())
|
||||
{
|
||||
FillFlatSideTriangle(hDc, verts[0], verts[1], temp, colorIn);
|
||||
FillFlatSideTriangle(hDc, verts[2], verts[1], temp, colorIn);
|
||||
}
|
||||
else
|
||||
{
|
||||
FillFlatSideTriangle(hDc, verts[0], temp, verts[1], colorIn);
|
||||
FillFlatSideTriangle(hDc, verts[2], temp, verts[1], colorIn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Rasteriser::FillFlatSideTriangle(HDC hDc, const Vertex& v1, const Vertex& v2, const Vertex& v3, COLORREF colorIn)
|
||||
{
|
||||
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 dx2 = (int)ceil(abs(v3.GetX() - v1.GetX()));
|
||||
int dy2 = (int)ceil(abs(v3.GetY() - v1.GetY()));
|
||||
|
||||
int signx1 = (int)sgn(v2.GetX() - v1.GetX());
|
||||
int signx2 = (int)sgn(v3.GetX() - v1.GetX());
|
||||
|
||||
int signy1 = (int)sgn(v2.GetY() - v1.GetY());
|
||||
int signy2 = (int)sgn(v3.GetY() - v1.GetY());
|
||||
|
||||
if (dy1 > dx1)
|
||||
{
|
||||
int tempInt = dx1;
|
||||
dx1 = dy1;
|
||||
dy1 = tempInt;
|
||||
changed1 = true;
|
||||
}
|
||||
|
||||
if (dy2 > dx2)
|
||||
{
|
||||
int tempInt = dx2;
|
||||
dx2 = dy2;
|
||||
dy2 = tempInt;
|
||||
changed2 = true;
|
||||
}
|
||||
|
||||
int e1 = 2 * dy1 - dx1;
|
||||
int e2 = 2 * dy2 - dx2;
|
||||
|
||||
for (int i = 0; i <= dx1; i++)
|
||||
{
|
||||
int startPoint;
|
||||
int endPoint;
|
||||
|
||||
if (tempA.GetXInt() < tempB.GetXInt())
|
||||
{
|
||||
startPoint = tempA.GetXInt();
|
||||
endPoint = tempB.GetXInt();
|
||||
}
|
||||
else
|
||||
{
|
||||
startPoint = tempB.GetXInt();
|
||||
endPoint = tempA.GetXInt();
|
||||
}
|
||||
|
||||
for (int xi = (int)ceil(startPoint); xi <= endPoint; xi++)
|
||||
{
|
||||
SetPixel(hDc, xi, tempA.GetYInt(), colorIn);
|
||||
}
|
||||
|
||||
|
||||
while (e1 >= 0)
|
||||
{
|
||||
if (changed1)
|
||||
{
|
||||
tempA.SetX(tempA.GetX() + signx1);
|
||||
}
|
||||
else
|
||||
{
|
||||
tempA.SetY(tempA.GetY() + signy1);
|
||||
}
|
||||
e1 = e1 - 2 * dx1;
|
||||
}
|
||||
|
||||
if (changed1)
|
||||
{
|
||||
tempA.SetY(tempA.GetY() + signy1);
|
||||
}
|
||||
else
|
||||
{
|
||||
tempA.SetX(tempA.GetX() + signx1);
|
||||
}
|
||||
|
||||
e1 = e1 + 2 * dy1;
|
||||
|
||||
while (tempB.GetY() != tempA.GetY())
|
||||
{
|
||||
while (e2 >= 0)
|
||||
{
|
||||
if (changed2)
|
||||
{
|
||||
tempB.SetX(tempB.GetX() + signx2);
|
||||
}
|
||||
else
|
||||
{
|
||||
tempB.SetY(tempB.GetY() + signy2);
|
||||
}
|
||||
e2 = e2 - 2 * dx2;
|
||||
}
|
||||
|
||||
if (changed2)
|
||||
{
|
||||
tempB.SetY(tempB.GetY() + signy2);
|
||||
}
|
||||
else
|
||||
{
|
||||
tempB.SetX(tempB.GetX() + signx2);
|
||||
}
|
||||
e2 = e2 + 2 * dy2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Rasteriser::FillPolygonGouraud(HDC hDc, vector<Vertex>& verts)
|
||||
{
|
||||
sort(verts.begin(), verts.end(), VerticiesYCompareAsc);
|
||||
if (verts[1].GetY() == verts[2].GetY())
|
||||
{
|
||||
FillGouraudBottomFlatTriangle(hDc, verts[0], verts[1], verts[2]);
|
||||
}
|
||||
else if (verts[0].GetY() == verts[1].GetY())
|
||||
{
|
||||
FillGouraudTopFlatTriangle(hDc, verts[0], verts[1], verts[2]);
|
||||
}
|
||||
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());
|
||||
|
||||
float cRed = GetRValue(verts[0].GetColor()) + ((verts[1].GetY() - verts[0].GetY()) / (verts[2].GetY() - verts[0].GetY())) * (GetRValue(verts[2].GetColor()) - GetRValue(verts[0].GetColor()));
|
||||
float cGreen = GetGValue(verts[0].GetColor()) + ((verts[1].GetY() - verts[0].GetY()) / (verts[2].GetY() - verts[0].GetY())) * (GetGValue(verts[2].GetColor()) - GetGValue(verts[0].GetColor()));
|
||||
float cBlue = GetBValue(verts[0].GetColor()) + ((verts[1].GetY() - verts[0].GetY()) / (verts[2].GetY() - verts[0].GetY())) * (GetBValue(verts[2].GetColor()) - GetBValue(verts[0].GetColor()));
|
||||
temp.SetColor(RGB((int)cRed, (int)cGreen, (int)cBlue));
|
||||
|
||||
temp.SetColor(verts[1].GetColor());
|
||||
|
||||
FillGouraudBottomFlatTriangle(hDc, verts[0], verts[1], temp);
|
||||
FillGouraudTopFlatTriangle(hDc, verts[1], temp, verts[2]);
|
||||
}
|
||||
}
|
||||
|
||||
void Rasteriser::FillGouraudBottomFlatTriangle(HDC hDc, const Vertex& v1, const Vertex& v2, const Vertex& v3)
|
||||
{
|
||||
float slope1 = (float)(v2.GetX() - v1.GetX()) / (float)(v2.GetY() - v1.GetY());
|
||||
float slope2 = (float)(v3.GetX() - v1.GetX()) / (float)(v3.GetY() - v1.GetY());
|
||||
|
||||
float x1 = (float)v1.GetX();
|
||||
float x2 = (float)v1.GetX() + 0.5f;
|
||||
|
||||
if (slope2 < slope1)
|
||||
{
|
||||
float slopeTmp = slope1;
|
||||
slope1 = slope2;
|
||||
slope2 = slopeTmp;
|
||||
}
|
||||
|
||||
for (int scanlineY = (int)v1.GetY(); scanlineY <= (int)v2.GetY(); scanlineY++)
|
||||
{
|
||||
float iRedA = (scanlineY - v2.GetY()) / (v1.GetY() - v2.GetY()) * v1.GetR() + (v1.GetY() - scanlineY) / (v1.GetY() - v2.GetY()) * v2.GetR();
|
||||
float iRedB = (scanlineY - v3.GetY()) / (v1.GetY() - v3.GetY()) * v1.GetR() + (v1.GetY() - scanlineY) / (v1.GetY() - v3.GetY()) * v3.GetR();
|
||||
float iGreenA = (scanlineY - v2.GetY()) / (v1.GetY() - v2.GetY()) * v1.GetG() + (v1.GetY() - scanlineY) / (v1.GetY() - v2.GetY()) * v2.GetG();
|
||||
float iGreenB = (scanlineY - v3.GetY()) / (v1.GetY() - v3.GetY()) * v1.GetG() + (v1.GetY() - scanlineY) / (v1.GetY() - v3.GetY()) * v3.GetG();
|
||||
float iBlueA = (scanlineY - v2.GetY()) / (v1.GetY() - v2.GetY()) * v1.GetB() + (v1.GetY() - scanlineY) / (v1.GetY() - v2.GetY()) * v2.GetB();
|
||||
float iBlueB = (scanlineY - v3.GetY()) / (v1.GetY() - v3.GetY()) * v1.GetB() + (v1.GetY() - scanlineY) / (v1.GetY() - v3.GetY()) * v3.GetB();
|
||||
|
||||
for (int xi = (int)ceil(x1); xi < (int)x2; xi++)
|
||||
{
|
||||
float redTmp = (x2 - xi) / (x2 - x1) * iRedA + (xi - x1) / (x2 - x1) * iRedB;
|
||||
float greenTmp = (x2 - xi) / (x2 - x1) * iGreenA + (xi - x1) / (x2 - x1) * iGreenB;
|
||||
float blueTmp = (x2 - xi) / (x2 - x1) * iBlueA + (xi - x1) / (x2 - x1) * iBlueB;
|
||||
|
||||
COLORREF currentColor = RGB(BoundsCheck(0, 255, (int)redTmp), BoundsCheck(0, 255, (int)greenTmp), BoundsCheck(0, 255, (int)blueTmp));
|
||||
SetPixel(hDc, xi, scanlineY, currentColor);
|
||||
}
|
||||
|
||||
x1 += slope1;
|
||||
x2 += slope2;
|
||||
}
|
||||
}
|
||||
|
||||
void Rasteriser::FillGouraudTopFlatTriangle(HDC hDc, const Vertex& v1, const Vertex& v2, const Vertex& v3)
|
||||
{
|
||||
float slope1 = (float)(v3.GetX() - v1.GetX()) / (float)(v3.GetY() - v1.GetY());
|
||||
float slope2 = (float)(v3.GetX() - v2.GetX()) / (float)(v3.GetY() - v2.GetY());
|
||||
|
||||
float x1 = (float)v3.GetX();
|
||||
float x2 = (float)v3.GetX() + 0.5f;
|
||||
|
||||
if (slope1 < slope2)
|
||||
{
|
||||
float slopeTmp = slope1;
|
||||
slope1 = slope2;
|
||||
slope2 = slopeTmp;
|
||||
}
|
||||
|
||||
for (int scanlineY = (int)v3.GetY(); scanlineY > (int)v1.GetY(); scanlineY--)
|
||||
{
|
||||
float iRedA = (scanlineY - v2.GetY()) / (v1.GetY() - v2.GetY()) * v1.GetR() + (v1.GetY() - scanlineY) / (v1.GetY() - v2.GetY()) * v2.GetR();
|
||||
float iRedB = (scanlineY - v3.GetY()) / (v1.GetY() - v3.GetY()) * v1.GetR() + (v1.GetY() - scanlineY) / (v1.GetY() - v3.GetY()) * v3.GetR();
|
||||
float iGreenA = (scanlineY - v2.GetY()) / (v1.GetY() - v2.GetY()) * v1.GetG() + (v1.GetY() - scanlineY) / (v1.GetY() - v2.GetY()) * v2.GetG();
|
||||
float iGreenB = (scanlineY - v3.GetY()) / (v1.GetY() - v3.GetY()) * v1.GetG() + (v1.GetY() - scanlineY) / (v1.GetY() - v3.GetY()) * v3.GetG();
|
||||
float iBlueA = (scanlineY - v2.GetY()) / (v1.GetY() - v2.GetY()) * v1.GetB() + (v1.GetY() - scanlineY) / (v1.GetY() - v2.GetY()) * v2.GetB();
|
||||
float iBlueB = (scanlineY - v3.GetY()) / (v1.GetY() - v3.GetY()) * v1.GetB() + (v1.GetY() - scanlineY) / (v1.GetY() - v3.GetY()) * v3.GetB();
|
||||
|
||||
for (int xi = (int)ceil(x1); xi < (int)x2; xi++)
|
||||
{
|
||||
float redTmp = (x2 - xi) / (x2 - x1) * iRedA - (xi - x1) / (x2 - x1) * iRedB;
|
||||
float greenTmp = (x2 - xi) / (x2 - x1) * iGreenA - (xi - x1) / (x2 - x1) * iGreenB;
|
||||
float blueTmp = (x2 - xi) / (x2 - x1) * iBlueA - (xi - x1) / (x2 - x1) * iBlueB;
|
||||
|
||||
COLORREF currentColor = RGB(BoundsCheck(0, 255, (int)redTmp), BoundsCheck(0, 255, (int)greenTmp), BoundsCheck(0, 255, (int)blueTmp));
|
||||
SetPixel(hDc, xi, scanlineY, currentColor);
|
||||
}
|
||||
|
||||
x1 -= slope1;
|
||||
x2 -= slope2;
|
||||
}
|
||||
}
|
||||
|
||||
void Rasteriser::FillPolygonGouraudInt(HDC hDc, vector<Vertex>& verts)
|
||||
{
|
||||
sort(verts.begin(), verts.end(), VerticiesYCompareAsc);
|
||||
if (verts[1].GetY() == verts[2].GetY())
|
||||
{
|
||||
FillGouraudSideTriangle(hDc, verts[0], verts[1], verts[2]);
|
||||
}
|
||||
else if (verts[0].GetY() == verts[1].GetY())
|
||||
{
|
||||
FillGouraudSideTriangle(hDc, verts[2], verts[0], verts[1]);
|
||||
}
|
||||
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());
|
||||
|
||||
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())
|
||||
{
|
||||
FillGouraudSideTriangle(hDc, verts[0], verts[1], temp);
|
||||
FillGouraudSideTriangle(hDc, verts[2], verts[1], temp);
|
||||
}
|
||||
else
|
||||
{
|
||||
FillGouraudSideTriangle(hDc, verts[0], temp, verts[1]);
|
||||
FillGouraudSideTriangle(hDc, verts[2], temp, verts[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Rasteriser::FillGouraudSideTriangle(HDC hDc, const Vertex& v1, const Vertex& v2, const Vertex& v3)
|
||||
{
|
||||
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 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()));
|
||||
|
||||
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;
|
||||
|
||||
if (tempA.GetX() < tempB.GetX())
|
||||
{
|
||||
leftEndPoint = tempA.GetX();
|
||||
rightEndPoint = tempB.GetX();
|
||||
}
|
||||
else
|
||||
{
|
||||
leftEndPoint = tempB.GetX();
|
||||
rightEndPoint = tempA.GetX();
|
||||
}
|
||||
|
||||
float iRedA = (tempA.GetY() - v2.GetY()) / (v1.GetY() - v2.GetY()) * v1.GetR() + (v1.GetY() - tempA.GetY()) / (v1.GetY() - v2.GetY()) * v2.GetR();
|
||||
float iRedB = (tempA.GetY() - v3.GetY()) / (v1.GetY() - v3.GetY()) * v1.GetR() + (v1.GetY() - tempA.GetY()) / (v1.GetY() - v3.GetY()) * v3.GetR();
|
||||
float iGreenA = (tempA.GetY() - v2.GetY()) / (v1.GetY() - v2.GetY()) * v1.GetG() + (v1.GetY() - tempA.GetY()) / (v1.GetY() - v2.GetY()) * v2.GetG();
|
||||
float iGreenB = (tempA.GetY() - v3.GetY()) / (v1.GetY() - v3.GetY()) * v1.GetG() + (v1.GetY() - tempA.GetY()) / (v1.GetY() - v3.GetY()) * v3.GetG();
|
||||
float iBlueA = (tempA.GetY() - v2.GetY()) / (v1.GetY() - v2.GetY()) * v1.GetB() + (v1.GetY() - tempA.GetY()) / (v1.GetY() - v2.GetY()) * v2.GetB();
|
||||
float iBlueB = (tempA.GetY() - v3.GetY()) / (v1.GetY() - v3.GetY()) * v1.GetB() + (v1.GetY() - tempA.GetY()) / (v1.GetY() - v3.GetY()) * v3.GetB();
|
||||
|
||||
for (int xi = (int)ceil(leftEndPoint); xi <= (int)rightEndPoint; xi++)
|
||||
{
|
||||
float redTmp = (rightEndPoint - xi) / (rightEndPoint - leftEndPoint) * iRedA + (xi - leftEndPoint) / (rightEndPoint - leftEndPoint) * iRedB;
|
||||
float greenTmp = (rightEndPoint - xi) / (rightEndPoint - leftEndPoint) * iGreenA + (xi - leftEndPoint) / (rightEndPoint - leftEndPoint) * iGreenB;
|
||||
float blueTmp = (rightEndPoint - xi) / (rightEndPoint - leftEndPoint) * iBlueA + (xi - leftEndPoint) / (rightEndPoint - leftEndPoint) * iBlueB;
|
||||
|
||||
COLORREF currentColor = RGB(BoundsCheck(0, 255, (int)redTmp), BoundsCheck(0, 255, (int)greenTmp), BoundsCheck(0, 255, (int)blueTmp));
|
||||
SetPixel(hDc, xi, tempA.GetYInt(), currentColor);
|
||||
}
|
||||
|
||||
|
||||
while (e1 >= 0)
|
||||
{
|
||||
if (changed1)
|
||||
{
|
||||
tempA.SetX((float)tempA.GetXInt() + (float)signx1);
|
||||
}
|
||||
else
|
||||
{
|
||||
tempA.SetY((float)tempA.GetYInt() + (float)signy1);
|
||||
}
|
||||
e1 = e1 - 2 * dx1;
|
||||
}
|
||||
|
||||
if (changed1)
|
||||
{
|
||||
tempA.SetY((float)tempA.GetYInt() + (float)signy1);
|
||||
}
|
||||
else
|
||||
{
|
||||
tempA.SetX((float)tempA.GetXInt() + (float)signx1);
|
||||
}
|
||||
|
||||
e1 = e1 + 2 * dy1;
|
||||
|
||||
while (tempB.GetY() < tempA.GetY() && tempB.GetY() > tempA.GetY())
|
||||
{
|
||||
while (e2 >= 0)
|
||||
{
|
||||
if (changed2)
|
||||
{
|
||||
tempB.SetX((float)tempB.GetXInt() + (float)signx2);
|
||||
}
|
||||
else
|
||||
{
|
||||
tempB.SetY((float)tempB.GetYInt() + (float)signy2);
|
||||
}
|
||||
e2 = e2 - 2 * dx2;
|
||||
}
|
||||
|
||||
if (changed2)
|
||||
{
|
||||
tempB.SetY((float)tempB.GetYInt() + (float)signy2);
|
||||
}
|
||||
else
|
||||
{
|
||||
tempB.SetX((float)tempB.GetXInt() + (float)signx2);
|
||||
}
|
||||
e2 = e2 + 2 * dy2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
16
Rasteriser.h
16
Rasteriser.h
@ -28,11 +28,25 @@ public:
|
||||
Camera& GetCamera(int index);
|
||||
Camera& GetCurrentCamera();
|
||||
|
||||
void CalculateLighting(Model& currentModel, bool fullLightRender);
|
||||
|
||||
void DrawSquare(HDC hDc, const vector<Vertex> verticies);
|
||||
void DrawShape(HDC hDc, const vector<Vertex> verticies);
|
||||
|
||||
void DrawWireFrame(HDC hDc, Model& model);
|
||||
void DrawSolidFlat(HDC hDc, Model& model);
|
||||
void DrawRasterisedSolidFlat(HDC hDc, Model& model);
|
||||
void DrawGouraud(HDC hDc, Model& model);
|
||||
|
||||
void FillPolygonFlat(HDC hDc, vector<Vertex>& verticies, COLORREF colorIn);
|
||||
void FillFlatSideTriangle(HDC hDc, const Vertex& v1, const Vertex& v2, const Vertex& v3, COLORREF colorIn);
|
||||
|
||||
void FillPolygonGouraud(HDC hDc, vector<Vertex>& verticies);
|
||||
void FillGouraudTopFlatTriangle(HDC hDc, const Vertex& v1, const Vertex& v2, const Vertex& v3);
|
||||
void FillGouraudBottomFlatTriangle(HDC hDc, const Vertex& v1, const Vertex& v2, const Vertex& v3);
|
||||
|
||||
void FillPolygonGouraudInt(HDC hDc, vector<Vertex>& verticies);
|
||||
void FillGouraudSideTriangle(HDC hDc, const Vertex& v1, const Vertex& v2, const Vertex& v3);
|
||||
|
||||
private:
|
||||
vector<Model> _sceneModels;
|
||||
@ -45,5 +59,7 @@ private:
|
||||
Matrix _currentViewMatrix;
|
||||
float _currentAspectRatio = 0.0f;
|
||||
int _rotation = 0;
|
||||
|
||||
bool _screenMinimized = false;
|
||||
};
|
||||
|
||||
|
@ -92,12 +92,12 @@ Matrix SharedTools::GetViewMatrix(float d, int width, int height)
|
||||
|
||||
Matrix SharedTools::GetCameraTranslateMatrix(const float x, const float y, const float z)
|
||||
{
|
||||
return Matrix({ 1, 0, 0, -x, 0, 1, 0, -y, 0, 0, 1, -z, 0, 0, 0, 1 });
|
||||
return GetTranslateMatrix(-x, -y, -z);
|
||||
}
|
||||
|
||||
Matrix SharedTools::GetCameraTranslateMatrix(const Vertex& position)
|
||||
{
|
||||
return GetCameraTranslateMatrix(position.GetX(), position.GetY(), position.GetZ());
|
||||
return GetTranslateMatrix(-position.GetX(), -position.GetY(), -position.GetZ());
|
||||
}
|
||||
|
||||
|
||||
|
@ -5,6 +5,10 @@
|
||||
enum class Axis { X, Y, Z };
|
||||
enum class ColRef { Red, Green, Blue };
|
||||
|
||||
template <typename T> int sgn(T val) {
|
||||
return (T(0) < val) - (val < T(0));
|
||||
}
|
||||
|
||||
namespace SharedTools
|
||||
{
|
||||
const float PI = (float)acos(-1);
|
||||
|
33
Vector3D.cpp
33
Vector3D.cpp
@ -2,16 +2,16 @@
|
||||
|
||||
Vector3D::Vector3D()
|
||||
{
|
||||
SetX(1);
|
||||
SetY(1);
|
||||
SetZ(1);
|
||||
_x = 1;
|
||||
_y = 1;
|
||||
_z = 1;
|
||||
}
|
||||
|
||||
Vector3D::Vector3D(float x, float y, float z)
|
||||
{
|
||||
SetX(x);
|
||||
SetY(y);
|
||||
SetZ(z);
|
||||
_x = x;
|
||||
_y = y;
|
||||
_z = z;
|
||||
}
|
||||
|
||||
Vector3D::Vector3D(const Vector3D& other)
|
||||
@ -54,7 +54,7 @@ void Vector3D::SetZ(const float z)
|
||||
_z = z;
|
||||
}
|
||||
|
||||
void Vector3D::Normalize()
|
||||
const void Vector3D::Normalize()
|
||||
{
|
||||
float length = sqrt(_x * _x + _y * _y + _z * _z);
|
||||
|
||||
@ -68,12 +68,17 @@ void Vector3D::Normalize()
|
||||
|
||||
float Vector3D::DotProduct(const Vector3D v1, const Vector3D v2)
|
||||
{
|
||||
return ((v1.GetX() * v2.GetX()) + (v1.GetY() * v2.GetY()) + (v1.GetZ() * v2.GetZ()));
|
||||
return v1.GetX() * v2.GetX() + v1.GetY() * v2.GetY() + v1.GetZ() * v2.GetZ();
|
||||
}
|
||||
|
||||
float Vector3D::Length(const Vector3D v1, const Vector3D v2)
|
||||
{
|
||||
return (float)sqrt(pow((v1.GetX() - v2.GetX()), 2) + pow((v1.GetY() - v2.GetY()), 2) + pow((v1.GetZ() - v2.GetZ()), 2));
|
||||
}
|
||||
|
||||
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()));
|
||||
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());
|
||||
}
|
||||
|
||||
|
||||
@ -82,6 +87,16 @@ const Vector3D Vector3D::operator+ (const Vector3D& rhs) const
|
||||
return Vector3D(_x + rhs.GetX(), _y + rhs.GetY(), _z + rhs.GetZ());
|
||||
}
|
||||
|
||||
const Vector3D Vector3D::operator/ (const float rhs) const
|
||||
{
|
||||
return Vector3D(_x / rhs, _y / rhs, _z / rhs);
|
||||
}
|
||||
|
||||
const Vector3D Vector3D::operator/ (const int rhs) const
|
||||
{
|
||||
return Vector3D(_x / rhs, _y / rhs, _z / rhs);
|
||||
}
|
||||
|
||||
void Vector3D::Copy(const Vector3D& other)
|
||||
{
|
||||
_x = other.GetX();
|
||||
|
@ -18,12 +18,15 @@ public:
|
||||
float GetZ() const;
|
||||
void SetZ(const float z);
|
||||
|
||||
void Normalize();
|
||||
const void Normalize();
|
||||
|
||||
static float DotProduct(const Vector3D v1, const Vector3D v2);
|
||||
static float Length(const Vector3D v1, const Vector3D v2);
|
||||
static Vector3D CrossProduct(const Vector3D v1, const Vector3D v2);
|
||||
|
||||
const Vector3D operator+ (const Vector3D& rhs) const;
|
||||
const Vector3D operator/ (const int rhs) const;
|
||||
const Vector3D operator/ (const float rhs) const;
|
||||
|
||||
private:
|
||||
float _x;
|
||||
|
148
Vertex.cpp
148
Vertex.cpp
@ -6,6 +6,11 @@ Vertex::Vertex()
|
||||
_y = 0.0f;
|
||||
_z = 0.0f;
|
||||
_w = 0.0f;
|
||||
_contributeCount = 0;
|
||||
_normal = Vector3D(0, 0, 0);
|
||||
_r = 0;
|
||||
_g = 0;
|
||||
_b = 0;
|
||||
}
|
||||
|
||||
Vertex::Vertex(const float x, const float y, const float z)
|
||||
@ -14,6 +19,11 @@ Vertex::Vertex(const float x, const float y, const float z)
|
||||
_y = y;
|
||||
_z = z;
|
||||
_w = 1.0f;
|
||||
_contributeCount = 0;
|
||||
_normal = Vector3D(0, 0, 0);
|
||||
_r = 0;
|
||||
_g = 0;
|
||||
_b = 0;
|
||||
}
|
||||
|
||||
Vertex::Vertex(const float x, const float y, const float z, const float w)
|
||||
@ -22,6 +32,11 @@ Vertex::Vertex(const float x, const float y, const float z, const float w)
|
||||
_y = y;
|
||||
_z = z;
|
||||
_w = w;
|
||||
_contributeCount = 0;
|
||||
_normal = Vector3D(0, 0, 0);
|
||||
_r = 0;
|
||||
_g = 0;
|
||||
_b = 0;
|
||||
}
|
||||
|
||||
Vertex::Vertex(const Vertex & other)
|
||||
@ -69,6 +84,132 @@ void Vertex::SetW(const float w)
|
||||
_w = w;
|
||||
}
|
||||
|
||||
const int Vertex::GetContributeCount() const
|
||||
{
|
||||
return _contributeCount;
|
||||
}
|
||||
|
||||
void Vertex::IncrementContributeCount()
|
||||
{
|
||||
_contributeCount++;
|
||||
}
|
||||
|
||||
void Vertex::ResetContributeCount()
|
||||
{
|
||||
_contributeCount = 0;
|
||||
}
|
||||
|
||||
const Vector3D& Vertex::GetNormal() const
|
||||
{
|
||||
return _normal;
|
||||
}
|
||||
|
||||
void Vertex::SetNormal(float x, float y, float z)
|
||||
{
|
||||
_normal.SetX(x);
|
||||
_normal.SetY(y);
|
||||
_normal.SetZ(z);
|
||||
}
|
||||
|
||||
void Vertex::SetNormal(const Vector3D& normal)
|
||||
{
|
||||
SetNormal(normal.GetX(), normal.GetY(), normal.GetZ());
|
||||
}
|
||||
|
||||
void Vertex::NormalizeNormal()
|
||||
{
|
||||
_normal.Normalize();
|
||||
}
|
||||
|
||||
void Vertex::ResetNormal(bool resetCount)
|
||||
{
|
||||
SetNormal(0, 0, 0);
|
||||
if (resetCount)
|
||||
{
|
||||
ResetContributeCount();
|
||||
}
|
||||
}
|
||||
|
||||
const COLORREF Vertex::GetColor() const
|
||||
{
|
||||
return RGB(_r, _g, _b);
|
||||
}
|
||||
|
||||
int Vertex::GetR() const
|
||||
{
|
||||
return _r;
|
||||
}
|
||||
|
||||
int Vertex::GetG() const
|
||||
{
|
||||
return _g;
|
||||
}
|
||||
|
||||
int Vertex::GetB() const
|
||||
{
|
||||
return _b;
|
||||
}
|
||||
|
||||
void Vertex::SetColor(int r, int g, int b)
|
||||
{
|
||||
_r = r;
|
||||
_g = g;
|
||||
_b = b;
|
||||
}
|
||||
|
||||
void Vertex::SetColor(const COLORREF colorIn)
|
||||
{
|
||||
SetColor((int)GetRValue(colorIn), (int)GetGValue(colorIn), (int)GetBValue(colorIn));
|
||||
}
|
||||
|
||||
int Vertex::GetXInt(bool forceRoundUp) const
|
||||
{
|
||||
if (forceRoundUp)
|
||||
{
|
||||
return (int)ceil(GetX());
|
||||
}
|
||||
else
|
||||
{
|
||||
return (int)floor(GetX());
|
||||
}
|
||||
;}
|
||||
|
||||
int Vertex::GetYInt(bool forceRoundUp) const
|
||||
{
|
||||
if (forceRoundUp)
|
||||
{
|
||||
return (int)ceil(GetY());
|
||||
}
|
||||
else
|
||||
{
|
||||
return (int)floor(GetY());
|
||||
}
|
||||
}
|
||||
|
||||
int Vertex::GetZInt(bool forceRoundUp) const
|
||||
{
|
||||
if (forceRoundUp)
|
||||
{
|
||||
return (int)ceil(GetZ());
|
||||
}
|
||||
else
|
||||
{
|
||||
return (int)floor(GetZ());
|
||||
}
|
||||
}
|
||||
|
||||
int Vertex::GetWInt(bool forceRoundUp) const
|
||||
{
|
||||
if (forceRoundUp)
|
||||
{
|
||||
return (int)ceil(GetW());
|
||||
}
|
||||
else
|
||||
{
|
||||
return (int)floor(GetW());
|
||||
}
|
||||
}
|
||||
|
||||
void Vertex::Dehomogenize()
|
||||
{
|
||||
_x = _x / _w;
|
||||
@ -90,7 +231,7 @@ Vertex& Vertex::operator=(const Vertex& rhs)
|
||||
|
||||
const Vector3D Vertex::operator-(const Vertex& rhs) const
|
||||
{
|
||||
return Vector3D(rhs.GetX() - GetX(), rhs.GetY() - GetY(), rhs.GetZ() - GetZ());
|
||||
return Vector3D(rhs.GetX() - _x, rhs.GetY() - _y, rhs.GetZ() - _z);
|
||||
}
|
||||
|
||||
// The const at the end of the declaraion for '==" indicates that this operation does not change
|
||||
@ -118,4 +259,9 @@ void Vertex::Copy(const Vertex& other)
|
||||
_y = other.GetY();
|
||||
_z = other.GetZ();
|
||||
_w = other.GetW();
|
||||
|
||||
_contributeCount = other.GetContributeCount();
|
||||
SetNormal(other.GetNormal());
|
||||
|
||||
SetColor(other.GetR(), other.GetG(), other.GetB());
|
||||
}
|
||||
|
33
Vertex.h
33
Vertex.h
@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#include "Vector3D.h"
|
||||
#include "windows.h"
|
||||
|
||||
class Vertex
|
||||
{
|
||||
@ -19,6 +20,31 @@ public:
|
||||
float GetW() const;
|
||||
void SetW(const float w);
|
||||
|
||||
const int GetContributeCount() const;
|
||||
void IncrementContributeCount();
|
||||
void ResetContributeCount();
|
||||
|
||||
const Vector3D& GetNormal() const;
|
||||
void SetNormal(float x, float y, float z);
|
||||
void SetNormal(const Vector3D& normal);
|
||||
void NormalizeNormal();
|
||||
void ResetNormal(bool resetCount = false);
|
||||
|
||||
const COLORREF GetColor() const;
|
||||
int GetR() const;
|
||||
int GetG() const;
|
||||
int GetB() const;
|
||||
void SetColor(const int r, const int g, const int b);
|
||||
void SetColor(const COLORREF colorIn);
|
||||
|
||||
// Accessor Methods 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
|
||||
int GetXInt(bool forceRoundUp = false) const;
|
||||
int GetYInt(bool forceRoundUp = false) const;
|
||||
int GetZInt(bool forceRoundUp = false) const;
|
||||
int GetWInt(bool forceRoundUp = false) const;
|
||||
|
||||
void Dehomogenize();
|
||||
|
||||
// Assignment operator
|
||||
@ -35,6 +61,13 @@ private:
|
||||
float _z;
|
||||
float _w;
|
||||
|
||||
int _contributeCount;
|
||||
Vector3D _normal;
|
||||
|
||||
int _r;
|
||||
int _g;
|
||||
int _b;
|
||||
|
||||
void Copy(const Vertex& other);
|
||||
};
|
||||
|
||||
|
BIN
teapot.md2
Normal file
BIN
teapot.md2
Normal file
Binary file not shown.
Reference in New Issue
Block a user