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 0000000..78b69b9 Binary files /dev/null and b/fire.md2 differ diff --git a/w_railgun.md2 b/w_railgun.md2 new file mode 100644 index 0000000..04cc9b3 Binary files /dev/null and b/w_railgun.md2 differ