From f5fd5b6756f2a04a7d8099b044a1838955e1b043 Mon Sep 17 00:00:00 2001 From: IDunnoDev Date: Sat, 11 Dec 2021 17:05:43 +0000 Subject: [PATCH] Week8 [16/11] - [19/11] Added Light Base Class Added AmbientLight, DirectionalLight and PointLight Classes Added Constructor to the Camera Class Added Light CoEff's to the Model Class Added Color Variables to Polygon3D Class Added Light Vector to hold the lights in the Rasteriser Added Camera Vector to hold multiple Cameras and Methods to set which is the current Added Lighting to the Rasterizer Added DrawSolidFlat method to the Rastorizer Added Bounds Check to the SharedTools for Int and Float values Added Color Enum Class Added Normalize Method to the Vector3D Class Renamed the TransformTools to SharedTools since adding more non transform methods to it --- AmbientLight.cpp | 42 ++++++++ AmbientLight.h | 20 ++++ BaseFramework.vcxproj | 12 ++- BaseFramework.vcxproj.filters | 28 +++++- Camera.cpp | 4 + Camera.h | 5 +- DirectionalLight.cpp | 78 +++++++++++++++ DirectionalLight.h | 26 +++++ Light.cpp | 112 +++++++++++++++++++++ Light.h | 40 ++++++++ Model.cpp | 87 +++++++++++++++- Model.h | 22 ++++- PointLight.cpp | 136 ++++++++++++++++++++++++++ PointLight.h | 38 +++++++ Polygon3D.cpp | 23 +++++ Polygon3D.h | 9 ++ Rasteriser.cpp | 75 ++++++++++++-- Rasteriser.h | 20 +++- TransformTools.cpp => SharedTools.cpp | 54 +++++++--- TransformTools.h => SharedTools.h | 6 +- Vector3D.cpp | 16 ++- Vector3D.h | 3 + fire.md2 | Bin 0 -> 23960 bytes w_railgun.md2 | Bin 0 -> 92173 bytes 24 files changed, 815 insertions(+), 41 deletions(-) create mode 100644 AmbientLight.cpp create mode 100644 AmbientLight.h create mode 100644 DirectionalLight.cpp create mode 100644 DirectionalLight.h create mode 100644 Light.cpp create mode 100644 Light.h create mode 100644 PointLight.cpp create mode 100644 PointLight.h rename TransformTools.cpp => SharedTools.cpp (62%) rename TransformTools.h => SharedTools.h (85%) create mode 100644 fire.md2 create mode 100644 w_railgun.md2 diff --git a/AmbientLight.cpp b/AmbientLight.cpp new file mode 100644 index 0000000..c1dda3d --- /dev/null +++ b/AmbientLight.cpp @@ -0,0 +1,42 @@ +#include "AmbientLight.h" + +AmbientLight::AmbientLight(const AmbientLight& other) : Light(other) +{ + Copy(other); +} + +COLORREF AmbientLight::CalculateLight(const Model& currentModel, const Polygon3D& currentPolygon, COLORREF colorIn) +{ + float workingRed = (float)GetRedLightIntensity(); + float workingGreen = (float)GetGreenLightIntensity(); + float workingBlue = (float)GetBlueLightIntensity(); + + workingRed *= currentModel.GetRedReflectionCoefficient(); + workingGreen *= currentModel.GetGreenReflectionCoefficient(); + workingBlue *= currentModel.GetBlueReflectionCoefficient(); + + workingRed += (float)GetRValue(colorIn); + workingGreen += (float)GetGValue(colorIn); + workingBlue += (float)GetBValue(colorIn); + + int finalRed = BoundsCheck(0, 255, (int)workingRed); + int finalGreen = BoundsCheck(0, 255, (int)workingGreen); + int finalBlue = BoundsCheck(0, 255, (int)workingBlue); + COLORREF outputColor = RGB(finalRed, finalGreen, finalBlue); + + return outputColor; +} + +AmbientLight& AmbientLight::operator= (const AmbientLight& rhs) +{ + if (this != &rhs) + { + Copy(rhs); + } + return *this; +} + +void AmbientLight::Copy(const AmbientLight& other) +{ + Light::Copy(other); +} diff --git a/AmbientLight.h b/AmbientLight.h new file mode 100644 index 0000000..91b45df --- /dev/null +++ b/AmbientLight.h @@ -0,0 +1,20 @@ +#pragma once +#include "Light.h" + +class AmbientLight : + public Light +{ +public: + AmbientLight() : Light() {}; + AmbientLight(int red, int green, int blue) : Light(red, green, blue) {}; + AmbientLight(const AmbientLight& other); + + COLORREF CalculateLight(const Model& currentModel, const Polygon3D& currentPolygon, COLORREF colorIn); + + AmbientLight& operator= (const AmbientLight& rhs); + +private: + void Copy(const AmbientLight& other); + +}; + diff --git a/BaseFramework.vcxproj b/BaseFramework.vcxproj index 0f521ae..88e0270 100644 --- a/BaseFramework.vcxproj +++ b/BaseFramework.vcxproj @@ -145,30 +145,38 @@ + + + + - + + + + + - + diff --git a/BaseFramework.vcxproj.filters b/BaseFramework.vcxproj.filters index ee53882..c0189fb 100644 --- a/BaseFramework.vcxproj.filters +++ b/BaseFramework.vcxproj.filters @@ -42,12 +42,24 @@ Source Files - + Source Files Source Files + + Source Files + + + Source Files + + + Source Files + + + Source Files + @@ -83,12 +95,24 @@ Header Files - + Header Files Header Files + + Header Files + + + Header Files + + + Header Files + + + Header Files + diff --git a/Camera.cpp b/Camera.cpp index 4576a2c..dd5ccdf 100644 --- a/Camera.cpp +++ b/Camera.cpp @@ -1,5 +1,9 @@ #include "Camera.h" +Camera::Camera() +{ +} + Camera::Camera(float xRot, float yRot, float zRot, const Vertex& pos) { _initialRotation[0] = xRot; diff --git a/Camera.h b/Camera.h index bab2b43..a19322d 100644 --- a/Camera.h +++ b/Camera.h @@ -1,13 +1,14 @@ #pragma once #include "Vertex.h" #include "Matrix.h" -#include "TransformTools.h" +#include "SharedTools.h" -using namespace TransformTools; +using namespace SharedTools; class Camera { public: + Camera(); Camera(float xRot, float yRot, float zRot, const Vertex& pos); Camera(const Camera& other); diff --git a/DirectionalLight.cpp b/DirectionalLight.cpp new file mode 100644 index 0000000..a7ad8d0 --- /dev/null +++ b/DirectionalLight.cpp @@ -0,0 +1,78 @@ +#include "DirectionalLight.h" + +DirectionalLight::DirectionalLight(Vector3D lightDirection) : Light() +{ + _lightDirection = lightDirection; + _normalizedLightDirection = lightDirection; + _normalizedLightDirection.Normalize(); +} + +DirectionalLight::DirectionalLight(Vector3D lightDirection, int red, int green, int blue) : Light(red, green, blue) +{ + _lightDirection = lightDirection; + _normalizedLightDirection = lightDirection; + _normalizedLightDirection.Normalize(); +} + +DirectionalLight::DirectionalLight(const DirectionalLight& other) : Light(other) +{ + Copy(other); +} + +void DirectionalLight::SetLightDirection(float x, float y, float z) +{ + SetLightDirection(Vector3D(x, y, z)); +} + +void DirectionalLight::SetLightDirection(Vector3D direction) +{ + _lightDirection = direction; +} + +Vector3D DirectionalLight::GetLightDirection() const +{ + return _lightDirection; +} + +COLORREF DirectionalLight::CalculateLight(const Model& currentModel, const Polygon3D& currentPolygon, COLORREF colorIn) +{ + 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()); + + workingRed *= lightDotProd; + workingGreen *= lightDotProd; + workingBlue *= lightDotProd; + + workingRed += (float)GetRValue(colorIn); + workingGreen += (float)GetGValue(colorIn); + workingBlue += (float)GetBValue(colorIn); + + int finalRed = BoundsCheck(0, 255, (int)workingRed); + int finalGreen = BoundsCheck(0, 255, (int)workingGreen); + int finalBlue = BoundsCheck(0, 255, (int)workingBlue); + COLORREF outputColor = RGB(finalRed, finalGreen, finalBlue); + + return outputColor; +} + +DirectionalLight& DirectionalLight::operator= (const DirectionalLight& rhs) +{ + if (this != &rhs) + { + Copy(rhs); + } + return *this; +} + +void DirectionalLight::Copy(const DirectionalLight& other) +{ + _lightDirection = other.GetLightDirection(); + Light::Copy(other); +} \ No newline at end of file diff --git a/DirectionalLight.h b/DirectionalLight.h new file mode 100644 index 0000000..dec5def --- /dev/null +++ b/DirectionalLight.h @@ -0,0 +1,26 @@ +#pragma once +#include "Light.h" + +class DirectionalLight : + public Light +{ +public: + DirectionalLight(Vector3D lightDirection); + DirectionalLight(Vector3D lightDirection, int red, int green, int blue); + DirectionalLight(const DirectionalLight& other); + + void SetLightDirection(float x, float y, float z); + void SetLightDirection(Vector3D direction); + Vector3D GetLightDirection() const; + + COLORREF CalculateLight(const Model& currentModel, const Polygon3D& currentPolygon, COLORREF colorIn); + + DirectionalLight& operator= (const DirectionalLight& rhs); + +private: + Vector3D _lightDirection; + Vector3D _normalizedLightDirection; + + void Copy(const DirectionalLight& other); +}; + diff --git a/Light.cpp b/Light.cpp new file mode 100644 index 0000000..82ff655 --- /dev/null +++ b/Light.cpp @@ -0,0 +1,112 @@ +#include "Light.h" + +Light::Light() +{ + SetLightIntensity(255, 255, 255); +} + +Light::Light(int red, int green, int blue) +{ + SetLightIntensity(red, green, blue); +} + +Light::Light(const Light& other) +{ + Copy(other); +} + +Light::~Light() +{ +} + +void Light::SetLightIntensity(int red, int green, int blue) +{ + _liRed = BoundsCheck(0, 255, red); + _liGreen = BoundsCheck(0, 255, green); + _liBlue = BoundsCheck(0, 255, blue); +} + +void Light::SetLightIntensity(ColRef color, int value) +{ + int valueChecked = BoundsCheck(0, 255, value); + + switch (color) + { + default: + case ColRef::Red: + _liRed = valueChecked; + break; + case ColRef::Green: + _liGreen = valueChecked; + break; + case ColRef::Blue: + _liBlue = valueChecked; + break; + } +} + +void Light::SetRedLightIntensity(int value) +{ + SetLightIntensity(ColRef::Red, value); +} + +void Light::SetGreenLightIntensity(int value) +{ + SetLightIntensity(ColRef::Green, value); +} + +void Light::SetBlueLightIntensity(int value) +{ + SetLightIntensity(ColRef::Blue, value); +} + +int Light::GetLightIntensity(ColRef color) const +{ + int result; + switch (color) + { + default: + case ColRef::Red: + result = _liRed; + break; + case ColRef::Green: + result = _liGreen; + break; + case ColRef::Blue: + result = _liBlue; + break; + } + + return result; +} + +int Light::GetRedLightIntensity() const +{ + return GetLightIntensity(ColRef::Red); +} + +int Light::GetGreenLightIntensity() const +{ + return GetLightIntensity(ColRef::Green); +} + +int Light::GetBlueLightIntensity() const +{ + return GetLightIntensity(ColRef::Blue); +} + +Light& Light::operator= (const Light& rhs) +{ + if (this != &rhs) + { + Copy(rhs); + } + return *this; +} + +void Light::Copy(const Light& other) +{ + _liRed = other.GetRedLightIntensity(); + _liGreen = other.GetGreenLightIntensity(); + _liBlue = other.GetBlueLightIntensity(); +} \ No newline at end of file diff --git a/Light.h b/Light.h new file mode 100644 index 0000000..05e1b51 --- /dev/null +++ b/Light.h @@ -0,0 +1,40 @@ +#pragma once +#include "Vector3D.h" +#include "Vertex.h" +#include "SharedTools.h" +#include "Model.h" +#include "Polygon3D.h" +#include "windows.h" + +class Light +{ +public: + Light(); + Light(int red, int green, int blue); + Light(const Light& other); + + ~Light(); + + void SetLightIntensity(int red, int green, int blue); + void SetLightIntensity(ColRef color, int value); + void SetRedLightIntensity(int value); + void SetGreenLightIntensity(int value); + void SetBlueLightIntensity(int value); + + int GetLightIntensity(ColRef color) const; + int GetRedLightIntensity() const; + int GetGreenLightIntensity() const; + int GetBlueLightIntensity() const; + + virtual COLORREF CalculateLight(const Model& currentModel, const Polygon3D& currentPolygon, COLORREF colorIn) = 0; + + Light& operator= (const Light& rhs); + +protected: + int _liRed; + int _liGreen; + int _liBlue; + + void Copy(const Light& other); +}; + diff --git a/Model.cpp b/Model.cpp index c8291d3..65d1e23 100644 --- a/Model.cpp +++ b/Model.cpp @@ -2,13 +2,16 @@ Model::Model() { + _kdRed = 1.0f; + _kdGreen = 1.0f; + _kdBlue = 1.0f; } Model::~Model() { } -const vector& Model::GetPolygons() +vector& Model::GetPolygons() { return _polygons; } @@ -59,21 +62,97 @@ void Model::ClearPendingTransforms() _pendingTransforms.clear(); } -const Polygon3D& Model::GetPolygon(int index) +const Polygon3D& Model::GetPolygon(int index) const { return _polygons[index]; } -const Vertex& Model::GetVertex(int polygonIndex, int vertexPolygonIndex) +const Vertex& Model::GetVertex(int polygonIndex, int vertexPolygonIndex) const { return GetVertex(GetPolygon(polygonIndex).GetIndex(vertexPolygonIndex)); } -const Vertex& Model::GetVertex(int index) +const Vertex& Model::GetVertex(int index) const { return _transformedVertices[index]; } +void Model::SetReflectionCoefficient(float red, float green, float blue) +{ + _kdRed = BoundsCheck(0.0f, 1.0f, red); + _kdGreen = BoundsCheck(0.0f, 1.0f, green); + _kdBlue = BoundsCheck(0.0f, 1.0f, blue); +} + +void Model::SetReflectionCoefficient(ColRef color, float value) +{ + float valueChecked = BoundsCheck(0.0f, 1.0f, value); + + switch (color) + { + default: + case ColRef::Red: + _kdRed = valueChecked; + break; + case ColRef::Green: + _kdGreen = valueChecked; + break; + case ColRef::Blue: + _kdBlue = valueChecked; + break; + } +} + +void Model::SetRedReflectionCoefficient(float value) +{ + SetReflectionCoefficient(ColRef::Red, value); +} + +void Model::SetGreenReflectionCoefficient(float value) +{ + SetReflectionCoefficient(ColRef::Green, value); +} + +void Model::SetBlueReflectionCoefficient(float value) +{ + SetReflectionCoefficient(ColRef::Blue, value); +} + +float Model::GetReflectionCoefficient(ColRef color) const +{ + float result; + switch (color) + { + default: + case ColRef::Red: + result = _kdRed; + break; + case ColRef::Green: + result = _kdGreen; + break; + case ColRef::Blue: + result = _kdBlue; + break; + } + + return result; +} + +float Model::GetRedReflectionCoefficient() const +{ + return GetReflectionCoefficient(ColRef::Red); +} + +float Model::GetGreenReflectionCoefficient() const +{ + return GetReflectionCoefficient(ColRef::Green); +} + +float Model::GetBlueReflectionCoefficient() const +{ + return GetReflectionCoefficient(ColRef::Blue); +} + void Model::ApplyTransformToLocalVertices(const Matrix& transform) { for (int i = 0; i < GetVerticesCount(); i++) diff --git a/Model.h b/Model.h index 178e767..a0ccca7 100644 --- a/Model.h +++ b/Model.h @@ -15,7 +15,7 @@ public: Model(); ~Model(); - const vector& GetPolygons(void); + vector& GetPolygons(void); const vector& GetVertices(void); const vector& GetPendingTransforms(void); @@ -28,9 +28,20 @@ public: void EnqueueTransform(Matrix transform); void ClearPendingTransforms(); - const Polygon3D& GetPolygon(int index); - const Vertex& GetVertex(int polygonIndex, int vertexPolygonIndex); - const Vertex& GetVertex(int index); + const Polygon3D& GetPolygon(int index) const; + const Vertex& GetVertex(int polygonIndex, int vertexPolygonIndex) const; + const Vertex& GetVertex(int index) const; + + void SetReflectionCoefficient(float red, float green, float blue); + void SetReflectionCoefficient(ColRef color, float value); + void SetRedReflectionCoefficient(float value); + void SetGreenReflectionCoefficient(float value); + void SetBlueReflectionCoefficient(float value); + + float GetReflectionCoefficient(ColRef color) const; + float GetRedReflectionCoefficient() const; + float GetGreenReflectionCoefficient() const; + float GetBlueReflectionCoefficient() const; void ApplyTransformToLocalVertices(const Matrix& transform); void ApplyTransformToTransformedVertices(const Matrix& transform); @@ -45,5 +56,8 @@ private: vector _transformedVertices; vector _pendingTransforms; + float _kdRed; + float _kdGreen; + float _kdBlue; }; diff --git a/PointLight.cpp b/PointLight.cpp new file mode 100644 index 0000000..e479289 --- /dev/null +++ b/PointLight.cpp @@ -0,0 +1,136 @@ +#include "PointLight.h" + +PointLight::PointLight(Vertex lightPosition) : Light() +{ + _lightPosition = lightPosition; + SetAttenuation(0, 0, 0); +} + +PointLight::PointLight(Vertex lightPosition, float a, float b, float c) : Light(255, 255, 255) +{ + _lightPosition = lightPosition; + SetAttenuation(a, b, c); +} + +PointLight::PointLight(Vertex lightPosition, float a, float b, float c, int red, int green, int blue) : Light(red, green, blue) +{ + _lightPosition = lightPosition; + SetAttenuation(a, b, c); +} + +PointLight::PointLight(const PointLight& other) : Light(other) +{ + Copy(other); +} + +void PointLight::SetAttenuation(float a, float b, float c) +{ + _attenuationA = a; + _attenuationB = b; + _attenuationC = c; +} + +void PointLight::SetAttenuationA(float value) +{ + _attenuationA = value; +} + +void PointLight::SetAttenuationB(float value) +{ + _attenuationB = value; +} + +void PointLight::SetAttenuationC(float value) +{ + _attenuationC = value; +} + +float PointLight::GetAttenuationA() +{ + return _attenuationA; +} + +float PointLight::GetAttenuationB() +{ + return _attenuationB; +} + +float PointLight::GetAttenuationC() +{ + return _attenuationC; +} + +void PointLight::SetLightPosition(float x, float y, float z) +{ + SetLightPosition(Vertex(x, y, z)); +} + +void PointLight::SetLightPosition(Vertex Position) +{ + _lightPosition = Position; +} + +Vertex PointLight::GetLightPosition() const +{ + return _lightPosition; +} + +COLORREF PointLight::CalculateLight(const Model& currentModel, const Polygon3D& currentPolygon, COLORREF colorIn) +{ + float workingRed = (float)GetRedLightIntensity(); + float workingGreen = (float)GetGreenLightIntensity(); + float workingBlue = (float)GetBlueLightIntensity(); + + float fudge = 50; + + workingRed *= currentModel.GetRedReflectionCoefficient(); + workingGreen *= currentModel.GetGreenReflectionCoefficient(); + workingBlue *= currentModel.GetBlueReflectionCoefficient(); + + Vector3D lightSource = currentModel.GetVertex(currentPolygon.GetIndex(0)) - _lightPosition; + Vector3D lightSourceNormalized = lightSource; + lightSourceNormalized.Normalize(); + + float distance = Vector3D::DotProduct(lightSource, currentPolygon.GetNormal()); + + float lightDotProd = Vector3D::DotProduct(lightSourceNormalized, currentPolygon.GetNormal()); + float attenuation = 1 / (GetAttenuationA() + GetAttenuationB() * distance + GetAttenuationC() * (distance * distance)); + + workingRed *= lightDotProd; + workingGreen *= lightDotProd; + workingBlue *= lightDotProd; + + workingRed *= attenuation; + workingGreen *= attenuation; + workingBlue *= attenuation; + + workingRed *= fudge; + workingGreen *= fudge; + workingBlue *= fudge; + + workingRed += (float)GetRValue(colorIn); + workingGreen += (float)GetGValue(colorIn); + workingBlue += (float)GetBValue(colorIn); + + int finalRed = BoundsCheck(0, 255, (int)workingRed); + int finalGreen = BoundsCheck(0, 255, (int)workingGreen); + int finalBlue = BoundsCheck(0, 255, (int)workingBlue); + COLORREF outputColor = RGB(finalRed, finalGreen, finalBlue); + + return outputColor; +} + +PointLight& PointLight::operator= (const PointLight& rhs) +{ + if (this != &rhs) + { + Copy(rhs); + } + return *this; +} + +void PointLight::Copy(const PointLight& other) +{ + _lightPosition = other.GetLightPosition(); + Light::Copy(other); +} diff --git a/PointLight.h b/PointLight.h new file mode 100644 index 0000000..69d1d76 --- /dev/null +++ b/PointLight.h @@ -0,0 +1,38 @@ +#pragma once +#include "Light.h" +class PointLight : + public Light +{ +public: + PointLight(Vertex lightPosition); + PointLight(Vertex lightPosition, float a, float b, float c); + PointLight(Vertex lightPosition, float a, float b, float c, int red, int green, int blue); + PointLight(const PointLight& other); + + void SetLightPosition(float x, float y, float z); + void SetLightPosition(Vertex Position); + Vertex GetLightPosition() const; + + void SetAttenuation(float a, float b, float c); + void SetAttenuationA(float value); + void SetAttenuationB(float value); + void SetAttenuationC(float value); + float GetAttenuationA(); + float GetAttenuationB(); + float GetAttenuationC(); + + + COLORREF CalculateLight(const Model& currentModel, const Polygon3D& currentPolygon, COLORREF colorIn); + + PointLight& operator= (const PointLight& rhs); + +private: + Vertex _lightPosition; + + float _attenuationA; + float _attenuationB; + float _attenuationC; + + void Copy(const PointLight& other); +}; + diff --git a/Polygon3D.cpp b/Polygon3D.cpp index 2bc2a12..3995aeb 100644 --- a/Polygon3D.cpp +++ b/Polygon3D.cpp @@ -2,6 +2,8 @@ Polygon3D::Polygon3D() : _indices{ 0 } { + _depth = 0.0f; + _color = RGB(0, 0, 0); } Polygon3D::Polygon3D(int index0, int index1, int index2) @@ -10,6 +12,7 @@ Polygon3D::Polygon3D(int index0, int index1, int index2) _indices[1] = index1; _indices[2] = index2; _depth = 0.0f; + _color = RGB(0, 0, 0); } Polygon3D::Polygon3D(const Polygon3D& other) @@ -41,6 +44,25 @@ Vector3D Polygon3D::GetNormal() const return _normal; } +void Polygon3D::SetColor(int red, int green, int blue) +{ + int redChecked = BoundsCheck(0, 255, red); + int greenChecked = BoundsCheck(0, 255, green); + int blueChecked = BoundsCheck(0, 255, blue); + + _color = RGB(redChecked, greenChecked, blueChecked); +} + +void Polygon3D::SetColor(const COLORREF color) +{ + _color = color; +} + +COLORREF Polygon3D::GetColor() const +{ + return _color; +} + void Polygon3D::SetDepth(float depth) { _depth = depth; @@ -78,5 +100,6 @@ void Polygon3D::Copy(const Polygon3D& other) _normal = other.GetNormal(); _culled = other.GetCulled(); _depth = other.GetDepth(); + _color = other.GetColor(); } } \ No newline at end of file diff --git a/Polygon3D.h b/Polygon3D.h index 01b151c..8de3a5a 100644 --- a/Polygon3D.h +++ b/Polygon3D.h @@ -1,5 +1,9 @@ #pragma once #include "Vector3D.h" +#include "SharedTools.h" +#include "windows.h" + +using namespace SharedTools; class Polygon3D { @@ -16,6 +20,10 @@ public: void SetNormal(const Vector3D& normal); Vector3D GetNormal() const; + + void SetColor(int red, int green, int blue); + void SetColor(const COLORREF color); + COLORREF GetColor() const; void SetDepth(float depth); float GetDepth() const; @@ -29,6 +37,7 @@ private: Vector3D _normal; float _depth = 0.0f; bool _culled = false; + COLORREF _color; void Copy(const Polygon3D& other); }; diff --git a/Rasteriser.cpp b/Rasteriser.cpp index 0783bee..ba9e4cd 100644 --- a/Rasteriser.cpp +++ b/Rasteriser.cpp @@ -25,7 +25,7 @@ bool Rasteriser::Initialise() return false; } - if (MD2Loader::LoadModel(".\\cheff.MD2", modelC, &Model::AddPolygon, &Model::AddVertex)) + if (MD2Loader::LoadModel(".\\w_railgun.MD2", modelC, &Model::AddPolygon, &Model::AddVertex)) { _sceneModels.push_back(modelC); } @@ -33,10 +33,33 @@ bool Rasteriser::Initialise() { 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; } +void Rasteriser::SetCurrentCamera(int index) +{ + if (index >= 0 && index < _cameras.size()) + { + _currentCamera = index; + } +} + +Camera& Rasteriser::GetCamera(int index) +{ + return _cameras[index]; +} + +Camera& Rasteriser::GetCurrentCamera() +{ + return GetCamera(_currentCamera); +} + void Rasteriser::Update(const Bitmap& bitmap) { int currentRot = (_rotation % 360); @@ -78,32 +101,44 @@ void Rasteriser::Update(const Bitmap& bitmap) void Rasteriser::Render(const Bitmap& bitmap) { ClearViewport(bitmap); - //SelectObject(bitmap.GetDC(), GetStockObject(DC_BRUSH)); + SelectObject(bitmap.GetDC(), GetStockObject(DC_BRUSH)); + SelectObject(bitmap.GetDC(), GetStockObject(DC_PEN)); - Camera mainCamera = Camera(0, 0, 0, Vertex(0, 0, -100)); - for (Model ¤tModel : _sceneModels) { + currentModel.SetReflectionCoefficient(0.5f, 0.5f, 0.5f); Matrix workingMatrix = workingMatrix.IdentityMatrix(); for (Matrix currentTransform : currentModel.GetPendingTransforms()) { workingMatrix *= currentTransform; } currentModel.ApplyTransformToLocalVertices(workingMatrix); - currentModel.CalculateBackfaces(mainCamera); - currentModel.ApplyTransformToTransformedVertices(mainCamera.GetCurrentCameraTransformMatrix()); + 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.Sort(); currentModel.ApplyTransformToTransformedVertices(_currentPerspectiveMatrix); currentModel.DehomogenizeAllVertices(); currentModel.ApplyTransformToTransformedVertices(_currentViewMatrix); - DrawWireFrame(bitmap.GetDC(), currentModel); + DrawSolidFlat(bitmap.GetDC(), currentModel); currentModel.ClearPendingTransforms(); } } void Rasteriser::ClearViewport(const Bitmap& bitmap) { - bitmap.Clear(RGB(255, 255, 255)); + bitmap.Clear(RGB(0, 0, 0)); } void Rasteriser::DrawSquare(HDC hDc, const vector verticies) @@ -162,4 +197,28 @@ void Rasteriser::DrawWireFrame(HDC hDc, Model& model) } PolyPolygon(hDc, pointArray.data(), sizeArray.data(), unculledPolyCount); +} + +void Rasteriser::DrawSolidFlat(HDC hDc, Model& model) +{ + int modelPolygonCount = (int)model.GetPolygonCount(); + for (int i = 0; i < modelPolygonCount; i++) + { + + if (!model.GetPolygon(i).GetCulled()) + { + vector pointArray; + int currentPolygonVertexCount = (int)model.GetPolygon(i).GetPolygonVertexCount(); + for (int j = 0; j < currentPolygonVertexCount; j++) + { + POINT newPoint; + newPoint.x = (long)model.GetVertex(i, j).GetX(); + newPoint.y = (long)model.GetVertex(i, j).GetY(); + pointArray.push_back(newPoint); + } + SetDCBrushColor(hDc, model.GetPolygon(i).GetColor()); + SetDCPenColor(hDc, model.GetPolygon(i).GetColor()); + Polygon(hDc, pointArray.data(), currentPolygonVertexCount); + } + } } \ No newline at end of file diff --git a/Rasteriser.h b/Rasteriser.h index e1e05c1..f7ae6a7 100644 --- a/Rasteriser.h +++ b/Rasteriser.h @@ -1,15 +1,20 @@ #pragma once +#include #include "Framework.h" +#include "Vector3D.h" #include "Vertex.h" #include "Matrix.h" -#include "TransformTools.h" +#include "SharedTools.h" #include "Camera.h" #include "Model.h" #include "MD2Loader.h" -#include +#include "Light.h" +#include "AmbientLight.h" +#include "DirectionalLight.h" +#include "PointLight.h" using namespace std; -using namespace TransformTools; +using namespace SharedTools; class Rasteriser : public Framework { @@ -19,13 +24,22 @@ public: void Render(const Bitmap& bitmap); void ClearViewport(const Bitmap& bitmap); + void SetCurrentCamera(int index); + Camera& GetCamera(int index); + Camera& GetCurrentCamera(); + void DrawSquare(HDC hDc, const vector verticies); void DrawShape(HDC hDc, const vector verticies); void DrawWireFrame(HDC hDc, Model& model); + void DrawSolidFlat(HDC hDc, Model& model); private: vector _sceneModels; + vector _lights; + vector _cameras; + + int _currentCamera = 0; Matrix _currentPerspectiveMatrix; Matrix _currentViewMatrix; diff --git a/TransformTools.cpp b/SharedTools.cpp similarity index 62% rename from TransformTools.cpp rename to SharedTools.cpp index ef27d44..f72c8d3 100644 --- a/TransformTools.cpp +++ b/SharedTools.cpp @@ -1,21 +1,49 @@ -#include "TransformTools.h" +#include "SharedTools.h" -Matrix TransformTools::GetTranslateMatrix(const float x, const float y, const float z) +int SharedTools::BoundsCheck(int min, int max, int value) +{ + int result = value; + if (value < min) + { + result = min; + } + else if (value > max) + { + result = max; + } + return result; +} + +float SharedTools::BoundsCheck(float min, float max, float value) +{ + float result = value; + if (value < min) + { + result = min; + } + else if (value > max) + { + result = max; + } + return result; +} + +Matrix SharedTools::GetTranslateMatrix(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 }); } -Matrix TransformTools::GetTranslateMatrix(const Vertex& position) +Matrix SharedTools::GetTranslateMatrix(const Vertex& position) { return GetTranslateMatrix(position.GetX(), position.GetY(), position.GetZ()); } -Matrix TransformTools::GetScaleMatrix(const float x, const float y, const float z) +Matrix SharedTools::GetScaleMatrix(const float x, const float y, const float z) { return Matrix({ x, 0, 0, 0, 0, y, 0, 0, 0, 0, z, 0, 0, 0, 0, 1 }); } -Matrix TransformTools::GetRotationMatrix(const Axis rotAxis, const float rotDegrees) +Matrix SharedTools::GetRotationMatrix(const Axis rotAxis, const float rotDegrees) { float rotationRadian = DegreesToRadians(rotDegrees); switch (rotAxis) @@ -31,29 +59,29 @@ Matrix TransformTools::GetRotationMatrix(const Axis rotAxis, const float rotDegr } } -Matrix TransformTools::GetRotationMatrixFromPoint(const Axis rotAxis, const float rotDegrees, const float x, const float y, const float z) +Matrix SharedTools::GetRotationMatrixFromPoint(const Axis rotAxis, const float rotDegrees, const float x, const float y, const float z) { return GetTranslateMatrix(x, y, z) * GetRotationMatrix(rotAxis, rotDegrees) * GetTranslateMatrix(-x, -y, -z); } -float TransformTools::DegreesToRadians(const float degrees) +float SharedTools::DegreesToRadians(const float degrees) { return (degrees * PI) / 180; } -Matrix TransformTools::GetOrthegraphicProjectionMatrix(float d) +Matrix SharedTools::GetOrthegraphicProjectionMatrix(float d) { return Matrix({ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, d, 0, 0, 0, 1 }); } -Matrix TransformTools::GetPerspectiveProjectionMatrix(float d, float aspectRatio) +Matrix SharedTools::GetPerspectiveProjectionMatrix(float d, float aspectRatio) { float distanceAspect = d / aspectRatio; return Matrix({ distanceAspect, 0, 0, 0, 0, d, 0, 0, 0, 0, d, 0, 0, 0, 1, 0 }); } -Matrix TransformTools::GetViewMatrix(float d, int width, int height) +Matrix SharedTools::GetViewMatrix(float d, int width, int height) { float widthCenter = (float) width / 2.0f; float heightCenter = (float) height / 2.0f; @@ -62,18 +90,18 @@ Matrix TransformTools::GetViewMatrix(float d, int width, int height) return Matrix({ widthCenter, 0, 0, widthCenter, 0, -heightCenter, 0, heightCenter, 0, 0, distanceCenter, distanceCenter, 0, 0, 0, 1 }); } -Matrix TransformTools::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 }); } -Matrix TransformTools::GetCameraTranslateMatrix(const Vertex& position) +Matrix SharedTools::GetCameraTranslateMatrix(const Vertex& position) { return GetCameraTranslateMatrix(position.GetX(), position.GetY(), position.GetZ()); } -Matrix TransformTools::GetCameraRotationMatrix(const Axis rotAxis, const float rotDegrees) +Matrix SharedTools::GetCameraRotationMatrix(const Axis rotAxis, const float rotDegrees) { float rotationRadian = DegreesToRadians(rotDegrees); switch (rotAxis) diff --git a/TransformTools.h b/SharedTools.h similarity index 85% rename from TransformTools.h rename to SharedTools.h index 9b15aa3..05b4731 100644 --- a/TransformTools.h +++ b/SharedTools.h @@ -3,11 +3,15 @@ #include enum class Axis { X, Y, Z }; +enum class ColRef { Red, Green, Blue }; -namespace TransformTools +namespace SharedTools { const float PI = (float)acos(-1); + int BoundsCheck(int min, int max, int value); + float BoundsCheck(float min, float max, float value); + Matrix GetTranslateMatrix(const float x, const float y, const float z); Matrix GetTranslateMatrix(const Vertex& position); diff --git a/Vector3D.cpp b/Vector3D.cpp index 05969f7..385eff0 100644 --- a/Vector3D.cpp +++ b/Vector3D.cpp @@ -54,10 +54,21 @@ void Vector3D::SetZ(const float z) _z = z; } -float Vector3D::DotProduct(const Vector3D v1, const Vector3D v2) +void Vector3D::Normalize() { - return ((v1.GetX() * v2.GetX()) + (v1.GetY() * v2.GetY()) + (v1.GetZ() * v2.GetZ())); + float length = sqrt(_x * _x + _y * _y + _z * _z); + if (length != 0) + { + _x /= length; + _y /= length; + _z /= length; + } +} + +float Vector3D::DotProduct(const Vector3D v1, const Vector3D v2) +{ + return ((v1.GetX() * v2.GetX()) + (v1.GetY() * v2.GetY()) + (v1.GetZ() * v2.GetZ())); } Vector3D Vector3D::CrossProduct(const Vector3D v1, const Vector3D v2) @@ -65,6 +76,7 @@ Vector3D Vector3D::CrossProduct(const Vector3D v1, const Vector3D v2) return Vector3D((v1.GetY() * v2.GetZ()) - (v1.GetZ() * v2.GetY()), (v1.GetZ() * v2.GetX()) - (v1.GetX() * v2.GetZ()), (v1.GetX() * v2.GetY()) - (v1.GetY() * v2.GetX())); } + const Vector3D Vector3D::operator+ (const Vector3D& rhs) const { return Vector3D(_x + rhs.GetX(), _y + rhs.GetY(), _z + rhs.GetZ()); diff --git a/Vector3D.h b/Vector3D.h index 03763c4..4f39ec9 100644 --- a/Vector3D.h +++ b/Vector3D.h @@ -1,4 +1,5 @@ #pragma once +#include class Vector3D { @@ -17,6 +18,8 @@ public: float GetZ() const; void SetZ(const float z); + void Normalize(); + static float DotProduct(const Vector3D v1, const Vector3D v2); static Vector3D CrossProduct(const Vector3D v1, const Vector3D v2); diff --git a/fire.md2 b/fire.md2 new file mode 100644 index 0000000000000000000000000000000000000000..78b69b9f6277469e03fb2aaed0a539b642fb4af9 GIT binary patch literal 23960 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 literal 0 HcmV?d00001 diff --git a/w_railgun.md2 b/w_railgun.md2 new file mode 100644 index 0000000000000000000000000000000000000000..04cc9b3dc8371c48a47cb222efa7532e5ef7762c GIT binary patch literal 92173 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%0ApQBU96YjGG92iL&SRMb4&D7*J!kb z^&;h_=@zLnvCxkDQ(PQGxar##CK7oi}7d*jb<`-@ir8*aAnc8g6y z0gT^`&Njx1@IH1hM$~tyT_eJvkLpvqh;iH^K?eOgAGt-%O9UKW+aE6^Pv+D(A^CBA zkaiJE{ie!S1@3vbfiCWo4^?j$QGM)St#xbXLO6&K|DHnC`iRS{g%X7pbz(>fMqjin8 zXnrtna%^eMQ5}sYOvw0Y&d~n?_s_V@H624bwwOa|kNP$zc%6{7NqNvVt-;3f^J;D5 L`ABWUp+@sx%;GTp literal 0 HcmV?d00001