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);
|
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 workingRed = (float)GetRedLightIntensity();
|
||||||
float workingGreen = (float)GetGreenLightIntensity();
|
float workingGreen = (float)GetGreenLightIntensity();
|
||||||
@ -27,6 +27,16 @@ COLORREF AmbientLight::CalculateLight(const Model& currentModel, const Polygon3D
|
|||||||
return outputColor;
|
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)
|
AmbientLight& AmbientLight::operator= (const AmbientLight& rhs)
|
||||||
{
|
{
|
||||||
if (this != &rhs)
|
if (this != &rhs)
|
||||||
|
@ -9,7 +9,10 @@ public:
|
|||||||
AmbientLight(int red, int green, int blue) : Light(red, green, blue) {};
|
AmbientLight(int red, int green, int blue) : Light(red, green, blue) {};
|
||||||
AmbientLight(const AmbientLight& other);
|
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 Polygon3D& currentPolygon, COLORREF colorIn);
|
||||||
|
COLORREF CalculateLight(const Model& currentModel, const Vertex& currentVertex, COLORREF colorIn);
|
||||||
|
|
||||||
AmbientLight& operator= (const AmbientLight& rhs);
|
AmbientLight& operator= (const AmbientLight& rhs);
|
||||||
|
|
||||||
|
90
Camera.cpp
90
Camera.cpp
@ -1,19 +1,11 @@
|
|||||||
#include "Camera.h"
|
#include "Camera.h"
|
||||||
|
|
||||||
Camera::Camera()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Camera::Camera(float xRot, float yRot, float zRot, const Vertex& pos)
|
Camera::Camera(float xRot, float yRot, float zRot, const Vertex& pos)
|
||||||
{
|
{
|
||||||
_initialRotation[0] = xRot;
|
_xRot = xRot;
|
||||||
_currentRotation[0] = xRot;
|
_yRot = yRot;
|
||||||
_initialRotation[1] = yRot;
|
_zRot = zRot;
|
||||||
_currentRotation[1] = yRot;
|
_cameraPosition = pos;
|
||||||
_initialRotation[2] = zRot;
|
|
||||||
_currentRotation[2] = zRot;
|
|
||||||
_initialPosition = pos;
|
|
||||||
_currentPosition = pos;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Camera::Camera(const Camera& other)
|
Camera::Camera(const Camera& other)
|
||||||
@ -27,61 +19,56 @@ Camera::~Camera()
|
|||||||
|
|
||||||
Matrix Camera::UpdateCameraPosition(const Vertex& newPos)
|
Matrix Camera::UpdateCameraPosition(const Vertex& newPos)
|
||||||
{
|
{
|
||||||
_currentPosition = newPos;
|
_cameraPosition = newPos;
|
||||||
return GetCurrentCameraTransformMatrix();
|
return GetCurrentCameraTransformMatrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
Matrix Camera::RotateCamera(float xRot, float yRot, float zRot)
|
Matrix Camera::RotateCamera(float xRot, float yRot, float zRot)
|
||||||
{
|
{
|
||||||
_currentRotation[0] = xRot;
|
_xRot = xRot;
|
||||||
_currentRotation[1] = yRot;
|
_yRot = yRot;
|
||||||
_currentRotation[2] = zRot;
|
_zRot = zRot;
|
||||||
return GetCurrentCameraTransformMatrix();
|
return GetCurrentCameraTransformMatrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
Matrix Camera::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)
|
_xRot = value;
|
||||||
{
|
|
||||||
case (Axis::X):
|
|
||||||
return _currentRotation[0];
|
|
||||||
case (Axis::Y):
|
|
||||||
return _currentRotation[1];
|
|
||||||
case (Axis::Z):
|
|
||||||
return _currentRotation[2];
|
|
||||||
default:
|
|
||||||
throw "No valid axis?";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float Camera::GetInitialRotationValue(const Axis axis)
|
float Camera::GetXRot() const
|
||||||
{
|
{
|
||||||
switch (axis)
|
return _xRot;
|
||||||
{
|
|
||||||
case (Axis::X):
|
|
||||||
return _initialRotation[0];
|
|
||||||
case (Axis::Y):
|
|
||||||
return _initialRotation[1];
|
|
||||||
case (Axis::Z):
|
|
||||||
return _initialRotation[2];
|
|
||||||
default:
|
|
||||||
throw "No valid axis?";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
Camera& Camera::operator=(const Camera& rhs)
|
||||||
@ -95,12 +82,9 @@ Camera& Camera::operator=(const Camera& rhs)
|
|||||||
|
|
||||||
void Camera::Copy(const Camera& other)
|
void Camera::Copy(const Camera& other)
|
||||||
{
|
{
|
||||||
_initialRotation[0] = other._initialRotation[0];
|
_xRot = other.GetXRot();
|
||||||
_currentRotation[0] = other._currentRotation[0];
|
_yRot = other.GetYRot();
|
||||||
_initialRotation[1] = other._initialRotation[1];
|
_zRot = other.GetZRot();
|
||||||
_currentRotation[1] = other._currentRotation[1];
|
|
||||||
_initialRotation[2] = other._initialRotation[2];
|
_cameraPosition = other.GetCameraPosition();
|
||||||
_currentRotation[2] = other._currentRotation[2];
|
|
||||||
_initialPosition = other._initialPosition;
|
|
||||||
_currentPosition = other._currentPosition;
|
|
||||||
}
|
}
|
26
Camera.h
26
Camera.h
@ -8,7 +8,7 @@ using namespace SharedTools;
|
|||||||
class Camera
|
class Camera
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Camera();
|
Camera() : _xRot(0), _yRot(0), _zRot(0) {};
|
||||||
Camera(float xRot, float yRot, float zRot, const Vertex& pos);
|
Camera(float xRot, float yRot, float zRot, const Vertex& pos);
|
||||||
Camera(const Camera& other);
|
Camera(const Camera& other);
|
||||||
|
|
||||||
@ -17,23 +17,23 @@ public:
|
|||||||
Matrix UpdateCameraPosition(const Vertex& newPos);
|
Matrix UpdateCameraPosition(const Vertex& newPos);
|
||||||
Matrix RotateCamera(float xRot, float yRot, float zRot);
|
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);
|
Matrix GetCurrentCameraTransformMatrix();
|
||||||
float GetInitialRotationValue(const Axis axis);
|
Vertex GetCameraPosition() const;
|
||||||
Vertex GetCurrentPosition();
|
|
||||||
Vertex GetInitialPosition();
|
|
||||||
|
|
||||||
Camera& operator= (const Camera& rhs);
|
Camera& operator= (const Camera& rhs);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
float _initialRotation[3] = { 0 };
|
float _xRot;
|
||||||
Vertex _initialPosition;
|
float _yRot;
|
||||||
|
float _zRot;
|
||||||
float _currentRotation[3] = { 0 };
|
Vertex _cameraPosition;
|
||||||
Vertex _currentPosition;
|
|
||||||
|
|
||||||
Matrix _currentCameraTransform;
|
|
||||||
|
|
||||||
void Copy(const Camera& other);
|
void Copy(const Camera& other);
|
||||||
};
|
};
|
||||||
|
@ -34,17 +34,17 @@ Vector3D DirectionalLight::GetLightDirection() const
|
|||||||
return _lightDirection;
|
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 workingRed = (float)GetRedLightIntensity();
|
||||||
float workingGreen = (float) GetGreenLightIntensity();
|
float workingGreen = (float)GetGreenLightIntensity();
|
||||||
float workingBlue = (float) GetBlueLightIntensity();
|
float workingBlue = (float)GetBlueLightIntensity();
|
||||||
|
|
||||||
workingRed *= currentModel.GetRedReflectionCoefficient();
|
workingRed *= currentModel.GetRedReflectionCoefficient();
|
||||||
workingGreen *= currentModel.GetGreenReflectionCoefficient();
|
workingGreen *= currentModel.GetGreenReflectionCoefficient();
|
||||||
workingBlue *= currentModel.GetBlueReflectionCoefficient();
|
workingBlue *= currentModel.GetBlueReflectionCoefficient();
|
||||||
|
|
||||||
float lightDotProd = Vector3D::DotProduct(_normalizedLightDirection, currentPolygon.GetNormal());
|
float lightDotProd = Vector3D::DotProduct(_normalizedLightDirection, currentNormal);
|
||||||
|
|
||||||
workingRed *= lightDotProd;
|
workingRed *= lightDotProd;
|
||||||
workingGreen *= lightDotProd;
|
workingGreen *= lightDotProd;
|
||||||
@ -62,6 +62,16 @@ COLORREF DirectionalLight::CalculateLight(const Model& currentModel, const Polyg
|
|||||||
return outputColor;
|
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)
|
DirectionalLight& DirectionalLight::operator= (const DirectionalLight& rhs)
|
||||||
{
|
{
|
||||||
if (this != &rhs)
|
if (this != &rhs)
|
||||||
|
@ -13,7 +13,10 @@ public:
|
|||||||
void SetLightDirection(Vector3D direction);
|
void SetLightDirection(Vector3D direction);
|
||||||
Vector3D GetLightDirection() const;
|
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 Polygon3D& currentPolygon, COLORREF colorIn);
|
||||||
|
COLORREF CalculateLight(const Model& currentModel, const Vertex& currentVertex, COLORREF colorIn);
|
||||||
|
|
||||||
DirectionalLight& operator= (const DirectionalLight& rhs);
|
DirectionalLight& operator= (const DirectionalLight& rhs);
|
||||||
|
|
||||||
|
1
Light.h
1
Light.h
@ -27,6 +27,7 @@ public:
|
|||||||
int GetBlueLightIntensity() const;
|
int GetBlueLightIntensity() const;
|
||||||
|
|
||||||
virtual COLORREF CalculateLight(const Model& currentModel, const Polygon3D& currentPolygon, COLORREF colorIn) = 0;
|
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);
|
Light& operator= (const Light& rhs);
|
||||||
|
|
||||||
|
60
Model.cpp
60
Model.cpp
@ -16,7 +16,7 @@ vector<Polygon3D>& Model::GetPolygons()
|
|||||||
return _polygons;
|
return _polygons;
|
||||||
}
|
}
|
||||||
|
|
||||||
const vector<Vertex>& Model::GetVertices()
|
vector<Vertex>& Model::GetVertices()
|
||||||
{
|
{
|
||||||
return _vertices;
|
return _vertices;
|
||||||
}
|
}
|
||||||
@ -77,6 +77,27 @@ const Vertex& Model::GetVertex(int index) const
|
|||||||
return _transformedVertices[index];
|
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)
|
void Model::SetReflectionCoefficient(float red, float green, float blue)
|
||||||
{
|
{
|
||||||
_kdRed = BoundsCheck(0.0f, 1.0f, red);
|
_kdRed = BoundsCheck(0.0f, 1.0f, red);
|
||||||
@ -171,7 +192,7 @@ void Model::ApplyTransformToTransformedVertices(const Matrix& transform)
|
|||||||
|
|
||||||
void Model::DehomogenizeAllVertices()
|
void Model::DehomogenizeAllVertices()
|
||||||
{
|
{
|
||||||
for (Vertex ¤tVertex : _transformedVertices)
|
for (Vertex& currentVertex : _transformedVertices)
|
||||||
{
|
{
|
||||||
currentVertex.Dehomogenize();
|
currentVertex.Dehomogenize();
|
||||||
}
|
}
|
||||||
@ -179,12 +200,14 @@ void Model::DehomogenizeAllVertices()
|
|||||||
|
|
||||||
void Model::CalculateBackfaces(Camera& currentCamera)
|
void Model::CalculateBackfaces(Camera& currentCamera)
|
||||||
{
|
{
|
||||||
for (Polygon3D ¤tPolygon : _polygons)
|
for (Polygon3D& currentPolygon : _polygons)
|
||||||
{
|
{
|
||||||
Vector3D vectorA = _transformedVertices[currentPolygon.GetIndex(1)] - _transformedVertices[currentPolygon.GetIndex(0)];
|
Vector3D vectorA = _transformedVertices[currentPolygon.GetIndex(1)] - _transformedVertices[currentPolygon.GetIndex(0)];
|
||||||
Vector3D vectorB = _transformedVertices[currentPolygon.GetIndex(2)] - _transformedVertices[currentPolygon.GetIndex(0)];
|
Vector3D vectorB = _transformedVertices[currentPolygon.GetIndex(2)] - _transformedVertices[currentPolygon.GetIndex(0)];
|
||||||
currentPolygon.SetNormal(Vector3D::CrossProduct(vectorA, vectorB));
|
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);
|
float dotProduct = Vector3D::DotProduct(currentPolygon.GetNormal(), eyeVector);
|
||||||
if (dotProduct < 0)
|
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)
|
bool DepthCompare(Polygon3D& a, Polygon3D& b)
|
||||||
{
|
{
|
||||||
return a.GetDepth() > b.GetDepth();
|
return a.GetDepth() > b.GetDepth();
|
||||||
@ -205,7 +253,7 @@ bool DepthCompare(Polygon3D& a, Polygon3D& b)
|
|||||||
|
|
||||||
void Model::Sort()
|
void Model::Sort()
|
||||||
{
|
{
|
||||||
for (Polygon3D ¤tPolygon : _polygons)
|
for (Polygon3D& currentPolygon : _polygons)
|
||||||
{
|
{
|
||||||
float zTotal = 0.0f;
|
float zTotal = 0.0f;
|
||||||
for (int i = 0; i < currentPolygon.GetPolygonVertexCount(); i++)
|
for (int i = 0; i < currentPolygon.GetPolygonVertexCount(); i++)
|
||||||
|
7
Model.h
7
Model.h
@ -16,7 +16,7 @@ public:
|
|||||||
~Model();
|
~Model();
|
||||||
|
|
||||||
vector<Polygon3D>& GetPolygons(void);
|
vector<Polygon3D>& GetPolygons(void);
|
||||||
const vector<Vertex>& GetVertices(void);
|
vector<Vertex>& GetVertices(void);
|
||||||
const vector<Matrix>& GetPendingTransforms(void);
|
const vector<Matrix>& GetPendingTransforms(void);
|
||||||
|
|
||||||
size_t GetPolygonCount(void);
|
size_t GetPolygonCount(void);
|
||||||
@ -32,6 +32,10 @@ public:
|
|||||||
const Vertex& GetVertex(int polygonIndex, int vertexPolygonIndex) const;
|
const Vertex& GetVertex(int polygonIndex, int vertexPolygonIndex) const;
|
||||||
const Vertex& GetVertex(int index) 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(float red, float green, float blue);
|
||||||
void SetReflectionCoefficient(ColRef color, float value);
|
void SetReflectionCoefficient(ColRef color, float value);
|
||||||
void SetRedReflectionCoefficient(float value);
|
void SetRedReflectionCoefficient(float value);
|
||||||
@ -48,6 +52,7 @@ public:
|
|||||||
void DehomogenizeAllVertices(void);
|
void DehomogenizeAllVertices(void);
|
||||||
|
|
||||||
void CalculateBackfaces(Camera& currentCamera);
|
void CalculateBackfaces(Camera& currentCamera);
|
||||||
|
void CalculateVertexNormals();
|
||||||
void Sort(void);
|
void Sort(void);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -75,25 +75,25 @@ Vertex PointLight::GetLightPosition() const
|
|||||||
return _lightPosition;
|
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 workingRed = (float)GetRedLightIntensity();
|
||||||
float workingGreen = (float)GetGreenLightIntensity();
|
float workingGreen = (float)GetGreenLightIntensity();
|
||||||
float workingBlue = (float)GetBlueLightIntensity();
|
float workingBlue = (float)GetBlueLightIntensity();
|
||||||
|
|
||||||
float fudge = 50;
|
float fudge = 100;
|
||||||
|
|
||||||
workingRed *= currentModel.GetRedReflectionCoefficient();
|
workingRed *= currentModel.GetRedReflectionCoefficient();
|
||||||
workingGreen *= currentModel.GetGreenReflectionCoefficient();
|
workingGreen *= currentModel.GetGreenReflectionCoefficient();
|
||||||
workingBlue *= currentModel.GetBlueReflectionCoefficient();
|
workingBlue *= currentModel.GetBlueReflectionCoefficient();
|
||||||
|
|
||||||
Vector3D lightSource = currentModel.GetVertex(currentPolygon.GetIndex(0)) - _lightPosition;
|
Vector3D lightSource = currentVertex - _lightPosition;
|
||||||
Vector3D lightSourceNormalized = lightSource;
|
Vector3D lightSourceNormalized = lightSource;
|
||||||
lightSourceNormalized.Normalize();
|
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));
|
float attenuation = 1 / (GetAttenuationA() + GetAttenuationB() * distance + GetAttenuationC() * (distance * distance));
|
||||||
|
|
||||||
workingRed *= lightDotProd;
|
workingRed *= lightDotProd;
|
||||||
@ -120,6 +120,16 @@ COLORREF PointLight::CalculateLight(const Model& currentModel, const Polygon3D&
|
|||||||
return outputColor;
|
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)
|
PointLight& PointLight::operator= (const PointLight& rhs)
|
||||||
{
|
{
|
||||||
if (this != &rhs)
|
if (this != &rhs)
|
||||||
|
@ -21,8 +21,10 @@ public:
|
|||||||
float GetAttenuationB();
|
float GetAttenuationB();
|
||||||
float GetAttenuationC();
|
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 Polygon3D& currentPolygon, COLORREF colorIn);
|
||||||
|
COLORREF CalculateLight(const Model& currentModel, const Vertex& currentVertex, COLORREF colorIn);
|
||||||
|
|
||||||
PointLight& operator= (const PointLight& rhs);
|
PointLight& operator= (const PointLight& rhs);
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ Polygon3D::Polygon3D() : _indices{ 0 }
|
|||||||
{
|
{
|
||||||
_depth = 0.0f;
|
_depth = 0.0f;
|
||||||
_color = RGB(0, 0, 0);
|
_color = RGB(0, 0, 0);
|
||||||
|
_culled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Polygon3D::Polygon3D(int index0, int index1, int index2)
|
Polygon3D::Polygon3D(int index0, int index1, int index2)
|
||||||
@ -13,6 +14,7 @@ Polygon3D::Polygon3D(int index0, int index1, int index2)
|
|||||||
_indices[2] = index2;
|
_indices[2] = index2;
|
||||||
_depth = 0.0f;
|
_depth = 0.0f;
|
||||||
_color = RGB(0, 0, 0);
|
_color = RGB(0, 0, 0);
|
||||||
|
_culled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Polygon3D::Polygon3D(const Polygon3D& other)
|
Polygon3D::Polygon3D(const Polygon3D& other)
|
||||||
@ -39,11 +41,16 @@ void Polygon3D::SetNormal(const Vector3D& normal)
|
|||||||
_normal = normal;
|
_normal = normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3D Polygon3D::GetNormal() const
|
const Vector3D& Polygon3D::GetNormal() const
|
||||||
{
|
{
|
||||||
return _normal;
|
return _normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Polygon3D::NormalizeNormal()
|
||||||
|
{
|
||||||
|
_normal.Normalize();
|
||||||
|
}
|
||||||
|
|
||||||
void Polygon3D::SetColor(int red, int green, int blue)
|
void Polygon3D::SetColor(int red, int green, int blue)
|
||||||
{
|
{
|
||||||
int redChecked = BoundsCheck(0, 255, red);
|
int redChecked = BoundsCheck(0, 255, red);
|
||||||
@ -96,10 +103,10 @@ 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();
|
|
||||||
_color = other.GetColor();
|
|
||||||
}
|
}
|
||||||
|
_normal = other.GetNormal();
|
||||||
|
_culled = other.GetCulled();
|
||||||
|
_depth = other.GetDepth();
|
||||||
|
_color = other.GetColor();
|
||||||
}
|
}
|
@ -19,7 +19,8 @@ public:
|
|||||||
int GetIndex(int index) const;
|
int GetIndex(int index) const;
|
||||||
|
|
||||||
void SetNormal(const Vector3D& normal);
|
void SetNormal(const Vector3D& normal);
|
||||||
Vector3D GetNormal() const;
|
const Vector3D& GetNormal() const;
|
||||||
|
void NormalizeNormal();
|
||||||
|
|
||||||
void SetColor(int red, int green, int blue);
|
void SetColor(int red, int green, int blue);
|
||||||
void SetColor(const COLORREF color);
|
void SetColor(const COLORREF color);
|
||||||
@ -35,8 +36,8 @@ public:
|
|||||||
private:
|
private:
|
||||||
int _indices[3];
|
int _indices[3];
|
||||||
Vector3D _normal;
|
Vector3D _normal;
|
||||||
float _depth = 0.0f;
|
float _depth;
|
||||||
bool _culled = false;
|
bool _culled;
|
||||||
COLORREF _color;
|
COLORREF _color;
|
||||||
|
|
||||||
void Copy(const Polygon3D& other);
|
void Copy(const Polygon3D& other);
|
||||||
|
627
Rasteriser.cpp
627
Rasteriser.cpp
@ -5,8 +5,6 @@ Rasteriser app;
|
|||||||
bool Rasteriser::Initialise()
|
bool Rasteriser::Initialise()
|
||||||
{
|
{
|
||||||
Model modelA;
|
Model modelA;
|
||||||
Model modelB;
|
|
||||||
Model modelC;
|
|
||||||
if (MD2Loader::LoadModel(".\\marvin.MD2", modelA, &Model::AddPolygon, &Model::AddVertex))
|
if (MD2Loader::LoadModel(".\\marvin.MD2", modelA, &Model::AddPolygon, &Model::AddVertex))
|
||||||
{
|
{
|
||||||
_sceneModels.push_back(modelA);
|
_sceneModels.push_back(modelA);
|
||||||
@ -15,29 +13,15 @@ bool Rasteriser::Initialise()
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (MD2Loader::LoadModel(".\\megaman.MD2", modelB, &Model::AddPolygon, &Model::AddVertex))
|
_lights.push_back(new AmbientLight(150, 150, 150));
|
||||||
{
|
//_lights.push_back(new AmbientLight(255, 255, 255));
|
||||||
_sceneModels.push_back(modelB);
|
_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));
|
||||||
else
|
_cameras.push_back(Camera(0.0f, 0.0f, 0.0f, Vertex(0.0f, 0.0f, -50.0f)));
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (MD2Loader::LoadModel(".\\w_railgun.MD2", modelC, &Model::AddPolygon, &Model::AddVertex))
|
_screenMinimized = false;
|
||||||
{
|
|
||||||
_sceneModels.push_back(modelC);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
_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)));
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -60,79 +44,124 @@ Camera& Rasteriser::GetCurrentCamera()
|
|||||||
return GetCamera(_currentCamera);
|
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)
|
void Rasteriser::Update(const Bitmap& bitmap)
|
||||||
{
|
{
|
||||||
int currentRot = (_rotation % 360);
|
if (bitmap.GetWidth() == 0 || bitmap.GetHeight() == 0)
|
||||||
Vertex startPos = Vertex(-50, 0, 0);
|
{
|
||||||
int currentZOff = 0;
|
_screenMinimized = true;
|
||||||
int currentModelIndex = 0;
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_screenMinimized = false;
|
||||||
|
}
|
||||||
|
|
||||||
for (Model ¤tModel : _sceneModels)
|
if (!_screenMinimized)
|
||||||
{
|
{
|
||||||
currentModel.EnqueueTransform(GetTranslateMatrix(startPos));
|
int currentRot = (_rotation % 360);
|
||||||
currentModel.EnqueueTransform(GetRotationMatrix(Axis::Y, (float) currentRot));
|
Vertex startPos = Vertex(0, 0, 20);
|
||||||
startPos.SetX(startPos.GetX() + 50);
|
int currentZOff = 0;
|
||||||
if ((currentModelIndex % 2) == 1)
|
int currentModelIndex = 0;
|
||||||
|
|
||||||
|
for (Model& currentModel : _sceneModels)
|
||||||
{
|
{
|
||||||
currentZOff = 0;
|
currentModel.EnqueueTransform(GetTranslateMatrix(startPos));
|
||||||
|
currentModel.EnqueueTransform(GetRotationMatrix(Axis::Y, (float)currentRot));
|
||||||
|
//startPos.SetX(startPos.GetX() + 100);
|
||||||
|
if ((currentModelIndex % 2) == 1)
|
||||||
|
{
|
||||||
|
currentZOff = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
currentZOff = 100;
|
||||||
|
}
|
||||||
|
//startPos.SetZ((float)currentZOff);
|
||||||
|
currentModelIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
_currentAspectRatio = (float)(bitmap.GetWidth() / (float)bitmap.GetHeight());
|
||||||
|
_currentPerspectiveMatrix = GetPerspectiveProjectionMatrix(1, _currentAspectRatio);
|
||||||
|
_currentViewMatrix = GetViewMatrix(1, bitmap.GetWidth(), bitmap.GetHeight());
|
||||||
|
|
||||||
|
if (_rotation == 360)
|
||||||
|
{
|
||||||
|
_rotation = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
currentZOff = 100;
|
_rotation += 1;
|
||||||
}
|
}
|
||||||
startPos.SetZ((float)currentZOff);
|
|
||||||
currentModelIndex++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_currentAspectRatio = (float)(bitmap.GetWidth() / bitmap.GetHeight());
|
|
||||||
_currentPerspectiveMatrix = GetPerspectiveProjectionMatrix(1, _currentAspectRatio);
|
|
||||||
_currentViewMatrix = GetViewMatrix(1, bitmap.GetWidth(), bitmap.GetHeight());
|
|
||||||
|
|
||||||
if (_rotation == 360)
|
|
||||||
{
|
|
||||||
_rotation = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_rotation += 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Rasteriser::Render(const Bitmap& bitmap)
|
void Rasteriser::Render(const Bitmap& bitmap)
|
||||||
{
|
{
|
||||||
ClearViewport(bitmap);
|
if (!_screenMinimized)
|
||||||
SelectObject(bitmap.GetDC(), GetStockObject(DC_BRUSH));
|
|
||||||
SelectObject(bitmap.GetDC(), GetStockObject(DC_PEN));
|
|
||||||
|
|
||||||
for (Model ¤tModel : _sceneModels)
|
|
||||||
{
|
{
|
||||||
currentModel.SetReflectionCoefficient(0.5f, 0.5f, 0.5f);
|
ClearViewport(bitmap);
|
||||||
Matrix workingMatrix = workingMatrix.IdentityMatrix();
|
SelectObject(bitmap.GetDC(), GetStockObject(DC_BRUSH));
|
||||||
for (Matrix currentTransform : currentModel.GetPendingTransforms())
|
SelectObject(bitmap.GetDC(), GetStockObject(DC_PEN));
|
||||||
|
|
||||||
|
for (Model& currentModel : _sceneModels)
|
||||||
{
|
{
|
||||||
workingMatrix *= currentTransform;
|
currentModel.SetReflectionCoefficient(0.5f, 0.5f, 0.5f);
|
||||||
}
|
Matrix workingMatrix = workingMatrix.IdentityMatrix();
|
||||||
currentModel.ApplyTransformToLocalVertices(workingMatrix);
|
for (Matrix currentTransform : currentModel.GetPendingTransforms())
|
||||||
currentModel.CalculateBackfaces(GetCurrentCamera());
|
|
||||||
for (Polygon3D ¤tPolygon : currentModel.GetPolygons())
|
|
||||||
{
|
|
||||||
if (!currentPolygon.GetCulled())
|
|
||||||
{
|
{
|
||||||
COLORREF colorWorking = RGB(0, 0, 0);
|
workingMatrix *= currentTransform;
|
||||||
for (Light* currentLight : _lights)
|
|
||||||
{
|
|
||||||
colorWorking = currentLight->CalculateLight(currentModel, currentPolygon, colorWorking);
|
|
||||||
}
|
|
||||||
currentPolygon.SetColor(colorWorking);
|
|
||||||
}
|
}
|
||||||
|
currentModel.ApplyTransformToLocalVertices(workingMatrix);
|
||||||
|
currentModel.ApplyTransformToTransformedVertices(GetCurrentCamera().GetCurrentCameraTransformMatrix());
|
||||||
|
|
||||||
|
currentModel.CalculateBackfaces(GetCurrentCamera());
|
||||||
|
currentModel.Sort();
|
||||||
|
|
||||||
|
currentModel.CalculateVertexNormals();
|
||||||
|
CalculateLighting(currentModel, true);
|
||||||
|
|
||||||
|
currentModel.ApplyTransformToTransformedVertices(_currentPerspectiveMatrix);
|
||||||
|
currentModel.DehomogenizeAllVertices();
|
||||||
|
currentModel.ApplyTransformToTransformedVertices(_currentViewMatrix);
|
||||||
|
|
||||||
|
//DrawWireFrame(bitmap.GetDC(), currentModel);
|
||||||
|
//DrawSolidFlat(bitmap.GetDC(), currentModel);
|
||||||
|
//DrawRasterisedSolidFlat(bitmap.GetDC(), currentModel);
|
||||||
|
DrawGouraud(bitmap.GetDC(), currentModel);
|
||||||
|
currentModel.ClearPendingTransforms();
|
||||||
}
|
}
|
||||||
currentModel.ApplyTransformToTransformedVertices(GetCurrentCamera().GetCurrentCameraTransformMatrix());
|
|
||||||
currentModel.Sort();
|
|
||||||
currentModel.ApplyTransformToTransformedVertices(_currentPerspectiveMatrix);
|
|
||||||
currentModel.DehomogenizeAllVertices();
|
|
||||||
currentModel.ApplyTransformToTransformedVertices(_currentViewMatrix);
|
|
||||||
DrawSolidFlat(bitmap.GetDC(), currentModel);
|
|
||||||
currentModel.ClearPendingTransforms();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -221,4 +250,442 @@ void Rasteriser::DrawSolidFlat(HDC hDc, Model& model)
|
|||||||
Polygon(hDc, pointArray.data(), currentPolygonVertexCount);
|
Polygon(hDc, pointArray.data(), currentPolygonVertexCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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& GetCamera(int index);
|
||||||
Camera& GetCurrentCamera();
|
Camera& GetCurrentCamera();
|
||||||
|
|
||||||
|
void CalculateLighting(Model& currentModel, bool fullLightRender);
|
||||||
|
|
||||||
void DrawSquare(HDC hDc, const vector<Vertex> verticies);
|
void DrawSquare(HDC hDc, const vector<Vertex> verticies);
|
||||||
void DrawShape(HDC hDc, const vector<Vertex> verticies);
|
void DrawShape(HDC hDc, const vector<Vertex> verticies);
|
||||||
|
|
||||||
void DrawWireFrame(HDC hDc, Model& model);
|
void DrawWireFrame(HDC hDc, Model& model);
|
||||||
void DrawSolidFlat(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:
|
private:
|
||||||
vector<Model> _sceneModels;
|
vector<Model> _sceneModels;
|
||||||
@ -45,5 +59,7 @@ private:
|
|||||||
Matrix _currentViewMatrix;
|
Matrix _currentViewMatrix;
|
||||||
float _currentAspectRatio = 0.0f;
|
float _currentAspectRatio = 0.0f;
|
||||||
int _rotation = 0;
|
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)
|
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)
|
Matrix SharedTools::GetCameraTranslateMatrix(const Vertex& position)
|
||||||
{
|
{
|
||||||
return GetCameraTranslateMatrix(position.GetX(), position.GetY(), position.GetZ());
|
return GetTranslateMatrix(-position.GetX(), -position.GetY(), -position.GetZ());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -115,4 +115,4 @@ Matrix SharedTools::GetCameraRotationMatrix(const Axis rotAxis, const float rotD
|
|||||||
default:
|
default:
|
||||||
throw "Invalid axis selected";
|
throw "Invalid axis selected";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,10 @@
|
|||||||
enum class Axis { X, Y, Z };
|
enum class Axis { X, Y, Z };
|
||||||
enum class ColRef { Red, Green, Blue };
|
enum class ColRef { Red, Green, Blue };
|
||||||
|
|
||||||
|
template <typename T> int sgn(T val) {
|
||||||
|
return (T(0) < val) - (val < T(0));
|
||||||
|
}
|
||||||
|
|
||||||
namespace SharedTools
|
namespace SharedTools
|
||||||
{
|
{
|
||||||
const float PI = (float)acos(-1);
|
const float PI = (float)acos(-1);
|
||||||
|
33
Vector3D.cpp
33
Vector3D.cpp
@ -2,16 +2,16 @@
|
|||||||
|
|
||||||
Vector3D::Vector3D()
|
Vector3D::Vector3D()
|
||||||
{
|
{
|
||||||
SetX(1);
|
_x = 1;
|
||||||
SetY(1);
|
_y = 1;
|
||||||
SetZ(1);
|
_z = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3D::Vector3D(float x, float y, float z)
|
Vector3D::Vector3D(float x, float y, float z)
|
||||||
{
|
{
|
||||||
SetX(x);
|
_x = x;
|
||||||
SetY(y);
|
_y = y;
|
||||||
SetZ(z);
|
_z = z;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3D::Vector3D(const Vector3D& other)
|
Vector3D::Vector3D(const Vector3D& other)
|
||||||
@ -54,7 +54,7 @@ void Vector3D::SetZ(const float z)
|
|||||||
_z = z;
|
_z = z;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Vector3D::Normalize()
|
const void Vector3D::Normalize()
|
||||||
{
|
{
|
||||||
float length = sqrt(_x * _x + _y * _y + _z * _z);
|
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)
|
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)
|
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());
|
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)
|
void Vector3D::Copy(const Vector3D& other)
|
||||||
{
|
{
|
||||||
_x = other.GetX();
|
_x = other.GetX();
|
||||||
|
@ -18,12 +18,15 @@ public:
|
|||||||
float GetZ() const;
|
float GetZ() const;
|
||||||
void SetZ(const float z);
|
void SetZ(const float z);
|
||||||
|
|
||||||
void Normalize();
|
const void Normalize();
|
||||||
|
|
||||||
static float DotProduct(const Vector3D v1, const Vector3D v2);
|
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);
|
static Vector3D CrossProduct(const Vector3D v1, const Vector3D v2);
|
||||||
|
|
||||||
const Vector3D operator+ (const Vector3D& rhs) const;
|
const Vector3D operator+ (const Vector3D& rhs) const;
|
||||||
|
const Vector3D operator/ (const int rhs) const;
|
||||||
|
const Vector3D operator/ (const float rhs) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
float _x;
|
float _x;
|
||||||
|
148
Vertex.cpp
148
Vertex.cpp
@ -6,6 +6,11 @@ Vertex::Vertex()
|
|||||||
_y = 0.0f;
|
_y = 0.0f;
|
||||||
_z = 0.0f;
|
_z = 0.0f;
|
||||||
_w = 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)
|
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;
|
_y = y;
|
||||||
_z = z;
|
_z = z;
|
||||||
_w = 1.0f;
|
_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)
|
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;
|
_y = y;
|
||||||
_z = z;
|
_z = z;
|
||||||
_w = w;
|
_w = w;
|
||||||
|
_contributeCount = 0;
|
||||||
|
_normal = Vector3D(0, 0, 0);
|
||||||
|
_r = 0;
|
||||||
|
_g = 0;
|
||||||
|
_b = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vertex::Vertex(const Vertex & other)
|
Vertex::Vertex(const Vertex & other)
|
||||||
@ -69,6 +84,132 @@ void Vertex::SetW(const float w)
|
|||||||
_w = 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()
|
void Vertex::Dehomogenize()
|
||||||
{
|
{
|
||||||
_x = _x / _w;
|
_x = _x / _w;
|
||||||
@ -90,7 +231,7 @@ Vertex& Vertex::operator=(const Vertex& rhs)
|
|||||||
|
|
||||||
const Vector3D Vertex::operator-(const Vertex& rhs) const
|
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
|
// 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();
|
_y = other.GetY();
|
||||||
_z = other.GetZ();
|
_z = other.GetZ();
|
||||||
_w = other.GetW();
|
_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
|
#pragma once
|
||||||
#include "Vector3D.h"
|
#include "Vector3D.h"
|
||||||
|
#include "windows.h"
|
||||||
|
|
||||||
class Vertex
|
class Vertex
|
||||||
{
|
{
|
||||||
@ -19,6 +20,31 @@ public:
|
|||||||
float GetW() const;
|
float GetW() const;
|
||||||
void SetW(const float w);
|
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();
|
void Dehomogenize();
|
||||||
|
|
||||||
// Assignment operator
|
// Assignment operator
|
||||||
@ -35,6 +61,13 @@ private:
|
|||||||
float _z;
|
float _z;
|
||||||
float _w;
|
float _w;
|
||||||
|
|
||||||
|
int _contributeCount;
|
||||||
|
Vector3D _normal;
|
||||||
|
|
||||||
|
int _r;
|
||||||
|
int _g;
|
||||||
|
int _b;
|
||||||
|
|
||||||
void Copy(const Vertex& other);
|
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