diff --git a/BaseFramework.vcxproj b/BaseFramework.vcxproj
index 88e0270..a7510ed 100644
--- a/BaseFramework.vcxproj
+++ b/BaseFramework.vcxproj
@@ -158,6 +158,8 @@
+
+
@@ -177,6 +179,8 @@
+
+
diff --git a/BaseFramework.vcxproj.filters b/BaseFramework.vcxproj.filters
index c0189fb..9108e2c 100644
--- a/BaseFramework.vcxproj.filters
+++ b/BaseFramework.vcxproj.filters
@@ -60,6 +60,12 @@
Source Files
+
+ Source Files
+
+
+ Source Files
+
@@ -113,6 +119,12 @@
Header Files
+
+ Header Files
+
+
+ Header Files
+
diff --git a/Light.cpp b/Light.cpp
index 82ff655..a0319e8 100644
--- a/Light.cpp
+++ b/Light.cpp
@@ -3,11 +3,13 @@
Light::Light()
{
SetLightIntensity(255, 255, 255);
+ _active = true;
}
Light::Light(int red, int green, int blue)
{
SetLightIntensity(red, green, blue);
+ _active = true;
}
Light::Light(const Light& other)
@@ -95,6 +97,21 @@ int Light::GetBlueLightIntensity() const
return GetLightIntensity(ColRef::Blue);
}
+bool Light::GetLightActive() const
+{
+ return _active;
+}
+
+void Light::SetLightActive(bool active)
+{
+ _active = active;
+}
+
+void Light::ToggleLightActive()
+{
+ _active = !_active;
+}
+
Light& Light::operator= (const Light& rhs)
{
if (this != &rhs)
@@ -109,4 +126,5 @@ void Light::Copy(const Light& other)
_liRed = other.GetRedLightIntensity();
_liGreen = other.GetGreenLightIntensity();
_liBlue = other.GetBlueLightIntensity();
+ _active = other.GetLightActive();
}
\ No newline at end of file
diff --git a/Light.h b/Light.h
index 07b39e8..2976491 100644
--- a/Light.h
+++ b/Light.h
@@ -26,6 +26,10 @@ public:
int GetGreenLightIntensity() const;
int GetBlueLightIntensity() const;
+ bool GetLightActive() const;
+ void SetLightActive(bool active);
+ void ToggleLightActive();
+
virtual COLORREF CalculateLight(const Model& currentModel, const Polygon3D& currentPolygon, COLORREF colorIn) = 0;
virtual COLORREF CalculateLight(const Model& currentModel, const Vertex& currentVertex, COLORREF colorIn) = 0;
@@ -36,6 +40,8 @@ protected:
int _liGreen;
int _liBlue;
+ bool _active;
+
void Copy(const Light& other);
};
diff --git a/MD2Loader.cpp b/MD2Loader.cpp
index 3aac28c..34262c0 100644
--- a/MD2Loader.cpp
+++ b/MD2Loader.cpp
@@ -48,6 +48,13 @@ struct Md2Vertex
BYTE lightNormalIndex; // Index to a normal vector for the lighting
};
+// Texture co-ordinates
+struct Md2TextureCoord
+{
+ short textureCoord[2];
+};
+
+
struct Md2Frame
{
float scale[3]; // Scale values
@@ -56,14 +63,139 @@ struct Md2Frame
Md2Vertex verts[1]; // First vertex of this frame
};
-// ----------------------------------------------
-// LoadModel() - load model from file.
-// ----------------------------------------------
+struct PcxHeader
+{
+ BYTE ID;
+ BYTE Version;
+ BYTE Encoding;
+ BYTE BitsPerPixel;
+ short XMin;
+ short YMin;
+ short XMax;
+ short YMax;
+ short HRes;
+ short VRes;
+ BYTE ClrMap[16 * 3];
+ BYTE Reserved;
+ BYTE NumPlanes;
+ short BytesPerLine;
+ short Pal;
+ BYTE Filler[58];
+};
-bool MD2Loader::LoadModel(const char* md2Filename, Model& model, AddPolygon addPolygon, AddVertex addVertex)
+
+MD2Loader::MD2Loader()
+{
+}
+
+MD2Loader::~MD2Loader()
+{
+}
+
+bool LoadPCX(const char* textureFilename, Texture& texture, const Md2Header* md2Header)
+{
+ std::ifstream file;
+
+ BYTE * paletteIndices = texture.GetPaletteIndices();
+ COLORREF * palette = texture.GetPalette();
+
+ // Try to open file
+ file.open(textureFilename, std::ios::in | std::ios::binary);
+ if (file.fail())
+ {
+ return false;
+ }
+ // Read PCX header
+ PcxHeader header;
+ file.read(reinterpret_cast(&header), sizeof(PcxHeader));
+
+ // Verify that this is a valid PCX file
+
+ // We only handle those with 256 colour palette
+ if ((header.Version != 5) || (header.BitsPerPixel != 8) ||
+ (header.Encoding != 1) || (header.NumPlanes != 1) ||
+ (md2Header && (header.BytesPerLine != md2Header->skinWidth)))
+ {
+ // This is not valid supported PCX
+ file.close();
+ return false;
+ }
+
+ // Check dimensions
+
+ int xSize = header.XMax - header.XMin + 1;
+ int ySize = header.YMax - header.YMin + 1;
+ int size = xSize * ySize;
+
+ // Check that this matches our MD2 expected texture
+ // Note. valid size is <= because uses RLE (so potentially smaller)
+ if (md2Header && (size > (md2Header->skinHeight * md2Header->skinWidth)))
+ {
+ // Doesn't match expected MD2 skin size
+ file.close();
+ return false;
+ }
+
+ // Reading file data
+
+ BYTE processByte, colourByte;
+ int count = 0;
+ while (count < size)
+ {
+ file.read(reinterpret_cast(&processByte), 1);
+
+ // Run length encoding - test if byte is an RLE byte
+ if ((processByte & 192) == 192)
+ {
+ // Extract number of times repeated byte
+ processByte &= 63;
+ file.read(reinterpret_cast(&colourByte), 1);
+ for (int index = 0; index < processByte; ++index)
+ {
+ // repeatedly write colour
+ paletteIndices[count] = colourByte;
+ ++count;
+ }
+ }
+ else
+ {
+ // Byte is the colour
+ paletteIndices[count] = processByte;
+ ++count;
+ }
+ }
+
+ bool returnValue = false;
+
+ // read palette data...
+ file.seekg(-769, std::ios::end); // This offset from end of file
+ file.read(reinterpret_cast(&processByte), 1);
+ if (processByte == 12)
+ {
+ BYTE rawPalette[768];
+ file.read(reinterpret_cast(&rawPalette), 768);
+
+ // Build palette
+ for (int palIndex = 0; palIndex < 256; ++palIndex)
+ {
+ palette[palIndex] = RGB(rawPalette[palIndex * 3],
+ rawPalette[(palIndex * 3) + 1],
+ rawPalette[(palIndex * 3) + 2]);
+ }
+ returnValue = true;
+ }
+
+ file.close();
+ return returnValue;
+}
+
+// Load model from file.
+
+bool MD2Loader::LoadModel(const char* md2Filename, const char * textureFilename, Model& model, AddPolygon addPolygon, AddVertex addVertex, AddTextureUV addTextureUV)
{
ifstream file;
Md2Header header;
+ bool bHasTexture = false;
// Try to open MD2 file
file.open(md2Filename, ios::in | ios::binary);
@@ -87,6 +219,7 @@ bool MD2Loader::LoadModel(const char* md2Filename, Model& model, AddPolygon addP
// We are only interested in the first frame
BYTE* frameBuffer = new BYTE[header.frameSize];
Md2Frame* frame = reinterpret_cast(frameBuffer);
+ Md2TextureCoord * textureCoords = new Md2TextureCoord[header.numTexCoords];
// Read polygon data...
file.seekg(header.offsetTriangles, ios::beg);
@@ -95,17 +228,28 @@ bool MD2Loader::LoadModel(const char* md2Filename, Model& model, AddPolygon addP
// Read frame data...
file.seekg(header.offsetFrames, ios::beg);
file.read(reinterpret_cast(frame), header.frameSize);
+
+ // Read texture coordinate data
+ file.seekg(header.offsetTexCoords, std::ios::beg);
+ file.read(reinterpret_cast(textureCoords), sizeof(Md2TextureCoord) * header.numTexCoords);
// Close the file
file.close();
- //----------------------------------------------------------------------------------------------
+ // Attempt to load any texture
+ if (textureFilename)
+ {
+ model.GetTexture().SetTextureSize(header.skinWidth, header.skinHeight);
+ bHasTexture = LoadPCX(textureFilename, model.GetTexture(), &header);
+ }
// Polygon array initialization
for ( int i = 0; i < header.numTriangles; ++i )
{
// Call supplied member function to add a new polygon to the list
- std::invoke(addPolygon, model, triangles[i].vertexIndex[0], triangles[i].vertexIndex[1], triangles[i].vertexIndex[2]);
+ std::invoke(addPolygon, model,
+ triangles[i].vertexIndex[0], triangles[i].vertexIndex[1], triangles[i].vertexIndex[2],
+ triangles[i].uvIndex[0], triangles[i].uvIndex[1], triangles[i].uvIndex[2]);
}
// Vertex array initialization
@@ -123,7 +267,14 @@ bool MD2Loader::LoadModel(const char* md2Filename, Model& model, AddPolygon addP
static_cast((frame->verts[i].v[2] * frame->scale[2]) + frame->translate[2]),
static_cast((frame->verts[i].v[1] * frame->scale[1]) + frame->translate[1]));
}
-
+ // Texture coordinates initialisation
+ if (bHasTexture)
+ {
+ for (int i = 0; i < header.numTexCoords; i++)
+ {
+ std::invoke(addTextureUV, model, textureCoords[i].textureCoord[0], textureCoords[i].textureCoord[1]);
+ }
+ }
// Free dynamically allocated memory
delete [] triangles; // NOTE: this is 'array' delete. Must be sure to use this
triangles = 0;
@@ -132,5 +283,8 @@ bool MD2Loader::LoadModel(const char* md2Filename, Model& model, AddPolygon addP
frameBuffer = 0;
frame = 0;
+ delete[] textureCoords;
+ textureCoords = 0;
+
return true;
}
diff --git a/MD2Loader.h b/MD2Loader.h
index 3d9ada9..f469e01 100644
--- a/MD2Loader.h
+++ b/MD2Loader.h
@@ -1,14 +1,17 @@
#pragma once
#include "Model.h"
-// Declare typedefs used by the MD2Loader to call the methods to add a vertex and
-// add a polygon to the lists
+// Declare typedefs used by the MD2Loader to call the methods to add a vertex,
+// add a polygon and add a texture UV to the lists
typedef void (Model::*AddVertex)(float x, float y, float z);
-typedef void (Model::*AddPolygon)(int i0, int i1, int i2);
+typedef void (Model::*AddPolygon)(int i0, int i1, int i2, int uvIndex0, int uvIndex1, int uvIndex2);
+typedef void (Model::*AddTextureUV)(float u, float v);
class MD2Loader
{
public:
- static bool LoadModel(const char* md2Filename, Model& model, AddPolygon addPolygon, AddVertex addVertex);
+ MD2Loader();
+ ~MD2Loader();
+ static bool LoadModel(const char* md2Filename, const char * textureFilename, Model& model, AddPolygon addPolygon, AddVertex addVertex, AddTextureUV addTextureUV);
};
diff --git a/Matrix.h b/Matrix.h
index a14733d..b7ab9d4 100644
--- a/Matrix.h
+++ b/Matrix.h
@@ -1,5 +1,4 @@
#pragma once
-
#include "Vertex.h"
#include
diff --git a/Model.cpp b/Model.cpp
index fdb026c..5c0a4b5 100644
--- a/Model.cpp
+++ b/Model.cpp
@@ -5,10 +5,80 @@ Model::Model()
_kdRed = 1.0f;
_kdGreen = 1.0f;
_kdBlue = 1.0f;
+
+ _active = false;
+ _drawMethod = DrawMethod::Wireframe;
+
+ _modelMD2Filename = "";
+ _modelTextureFilename = "";
+}
+
+
+Model::Model(string MD2Filename, string textureFilename)
+{
+ _kdRed = 1.0f;
+ _kdGreen = 1.0f;
+ _kdBlue = 1.0f;
+
+ _active = false;
+ _drawMethod = DrawMethod::Wireframe;
+
+ _modelMD2Filename = MD2Filename;
+ _modelTextureFilename = textureFilename;
}
Model::~Model()
{
+ _vertices.~vector();
+ _transformedVertices.~vector();
+ _polygons.~vector();
+ _pendingTransforms.~vector();
+ _uvCoords.~vector();
+}
+
+string Model::GetModelFilename() const
+{
+ return _modelMD2Filename;
+}
+
+const char* Model::CGetModelFilename() const
+{
+ return _modelMD2Filename.c_str();
+}
+
+string Model::GetTextureFilename() const
+{
+ return _modelTextureFilename;
+}
+
+const char* Model::CGetTextureFilename() const
+{
+ return _modelTextureFilename.c_str();
+}
+
+void Model::SetActive(bool value)
+{
+ _active = value;
+}
+
+void Model::ToggleActive()
+{
+ _active = !_active;
+}
+
+bool Model::GetActive() const
+{
+ return _active;
+}
+
+void Model::SetDrawMethod(DrawMethod method)
+{
+ _drawMethod = method;
+}
+
+DrawMethod Model::GetDrawMethod() const
+{
+ return _drawMethod;
}
vector& Model::GetPolygons()
@@ -21,6 +91,11 @@ vector& Model::GetVertices()
return _vertices;
}
+vector& Model::GetUVCoords()
+{
+ return _uvCoords;
+}
+
const vector& Model::GetPendingTransforms()
{
return _pendingTransforms;
@@ -36,6 +111,11 @@ size_t Model::GetVerticesCount()
return _vertices.size();
}
+size_t Model::GetUVCoordCount()
+{
+ return _uvCoords.size();
+}
+
size_t Model::GetPendingTransformCount()
{
return _pendingTransforms.size();
@@ -47,9 +127,14 @@ void Model::AddVertex(float x, float y, float z)
_transformedVertices.push_back(Vertex(x, y, z));
}
-void Model::AddPolygon(int index0, int index1, int index2)
+void Model::AddPolygon(int index0, int index1, int index2, int uvIndex0, int uvIndex1, int uvIndex2)
{
- _polygons.push_back(Polygon3D(index0, index1, index2));
+ _polygons.push_back(Polygon3D(index0, index1, index2, uvIndex0, uvIndex1, uvIndex2));
+}
+
+void Model::AddTextureUV(float u, float v)
+{
+ _uvCoords.push_back(UVCoord(u, v));
}
void Model::EnqueueTransform(Matrix transform)
@@ -62,6 +147,11 @@ void Model::ClearPendingTransforms()
_pendingTransforms.clear();
}
+Texture& Model::GetTexture()
+{
+ return _texture;
+}
+
const Polygon3D& Model::GetPolygon(int index) const
{
return _polygons[index];
@@ -77,6 +167,11 @@ const Vertex& Model::GetVertex(int index) const
return _transformedVertices[index];
}
+const UVCoord& Model::GetUVCoord(int index) const
+{
+ return _uvCoords[index];
+}
+
vector Model::GetPolygonVertexArray(int index) const
{
vector polygonVerticies = {};
@@ -234,6 +329,7 @@ void Model::CalculateVertexNormals()
{
_transformedVertices[_polygons[pi].GetIndex(i)].SetNormal(_transformedVertices[_polygons[pi].GetIndex(i)].GetNormal() + _polygons[pi].GetNormal());
_transformedVertices[_polygons[pi].GetIndex(i)].IncrementContributeCount();
+ _transformedVertices[_polygons[pi].GetIndex(i)].SetUVIndex(_polygons[pi].GetUVIndex(i));
}
}
diff --git a/Model.h b/Model.h
index 1742d03..a959115 100644
--- a/Model.h
+++ b/Model.h
@@ -4,33 +4,56 @@
#include "Polygon3D.h"
#include "Matrix.h"
#include "Camera.h"
+#include "Texture.h"
+#include "UVCoord.h"
#include
#include
+#include
using namespace std;
+enum class DrawMethod { Wireframe, Flat, FlatRaster, Smooth, Textured };
+
class Model
{
public:
Model();
+ Model(string MD2Filename, string textureFilename);
~Model();
+ string GetModelFilename() const;
+ const char* CGetModelFilename() const;
+ string GetTextureFilename() const;
+ const char* CGetTextureFilename() const;
+
+ void SetActive(bool value);
+ void ToggleActive();
+ bool GetActive() const;
+
+ void SetDrawMethod(DrawMethod method);
+ DrawMethod GetDrawMethod() const;
+
vector& GetPolygons(void);
vector& GetVertices(void);
+ vector& GetUVCoords(void);
const vector& GetPendingTransforms(void);
size_t GetPolygonCount(void);
size_t GetVerticesCount(void);
+ size_t GetUVCoordCount(void);
size_t GetPendingTransformCount(void);
void AddVertex(float x, float y, float z);
- void AddPolygon(int index0, int index1, int index2);
+ void AddPolygon(int index0, int index1, int index2, int uvIndex0, int uvIndex1, int uvIndex2);
+ void AddTextureUV(float u, float v);
void EnqueueTransform(Matrix transform);
void ClearPendingTransforms();
+ Texture& GetTexture();
const Polygon3D& GetPolygon(int index) const;
const Vertex& GetVertex(int polygonIndex, int vertexPolygonIndex) const;
- const Vertex& GetVertex(int index) const;
+ const Vertex& GetVertex(int index) const;
+ const UVCoord& GetUVCoord(int index) const;
vector GetPolygonVertexArray(int index) const;
void SetPolygonColor(int index, COLORREF color);
@@ -60,9 +83,19 @@ private:
vector _vertices;
vector _transformedVertices;
vector _pendingTransforms;
+
+ vector _uvCoords;
+ Texture _texture;
+
float _kdRed;
float _kdGreen;
float _kdBlue;
+
+ bool _active;
+ DrawMethod _drawMethod;
+
+ string _modelMD2Filename;
+ string _modelTextureFilename;
};
diff --git a/Polygon3D.cpp b/Polygon3D.cpp
index 1b37b9f..04add6a 100644
--- a/Polygon3D.cpp
+++ b/Polygon3D.cpp
@@ -1,19 +1,30 @@
#include "Polygon3D.h"
-Polygon3D::Polygon3D() : _indices{ 0 }
+Polygon3D::Polygon3D() : _indices{ 0 }, _uvIndices { 0 }
{
_depth = 0.0f;
- _color = RGB(0, 0, 0);
+ _r = 0;
+ _g = 0;
+ _b = 0;
_culled = false;
}
-Polygon3D::Polygon3D(int index0, int index1, int index2)
+Polygon3D::Polygon3D(int index0, int index1, int index2, int uvIndex0, int uvIndex1, int uvIndex2)
{
_indices[0] = index0;
_indices[1] = index1;
_indices[2] = index2;
+
+ _uvIndices[0] = uvIndex0;
+ _uvIndices[1] = uvIndex1;
+ _uvIndices[2] = uvIndex2;
+
_depth = 0.0f;
- _color = RGB(0, 0, 0);
+
+ _r = 0;
+ _g = 0;
+ _b = 0;
+
_culled = false;
}
@@ -24,6 +35,7 @@ Polygon3D::Polygon3D(const Polygon3D& other)
Polygon3D::~Polygon3D()
{
+
}
size_t Polygon3D::GetPolygonVertexCount() const
@@ -31,11 +43,21 @@ size_t Polygon3D::GetPolygonVertexCount() const
return sizeof(_indices) / sizeof(_indices[0]);
}
+size_t Polygon3D::GetPolygonUVCount() const
+{
+ return sizeof(_uvIndices) / sizeof(_uvIndices[0]);
+}
+
int Polygon3D::GetIndex(const int index) const
{
return _indices[index];
}
+int Polygon3D::GetUVIndex(const int index) const
+{
+ return _uvIndices[index];
+}
+
void Polygon3D::SetNormal(const Vector3D& normal)
{
_normal = normal;
@@ -52,22 +74,52 @@ void Polygon3D::NormalizeNormal()
}
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);
+{
+ _r = red;
+ _g = green;
+ _b = blue;
}
void Polygon3D::SetColor(const COLORREF color)
{
- _color = color;
+ _r = GetRValue(color);
+ _g = GetGValue(color);
+ _b = GetBValue(color);
+}
+
+int Polygon3D::GetR() const
+{
+ return _r;
+}
+
+void Polygon3D::SetR(const int r)
+{
+ _r = r;
+}
+
+int Polygon3D::GetG() const
+{
+ return _g;
+}
+
+void Polygon3D::SetG(const int g)
+{
+ _g = g;
+}
+
+int Polygon3D::GetB() const
+{
+ return _b;
+}
+
+void Polygon3D::SetB(const int b)
+{
+ _b = b;
}
COLORREF Polygon3D::GetColor() const
{
- return _color;
+ return RGB(_r, _g, _b);
}
void Polygon3D::SetDepth(float depth)
@@ -105,8 +157,17 @@ void Polygon3D::Copy(const Polygon3D& other)
{
_indices[i] = other.GetIndex(i);
}
+
+ for (int i = 0; i < sizeof(_uvIndices) / sizeof(_uvIndices[0]); i++)
+ {
+ _uvIndices[i] = other.GetUVIndex(i);
+ }
+
_normal = other.GetNormal();
_culled = other.GetCulled();
_depth = other.GetDepth();
- _color = other.GetColor();
+
+ _r = other.GetR();
+ _g = other.GetG();
+ _b = other.GetB();
}
\ No newline at end of file
diff --git a/Polygon3D.h b/Polygon3D.h
index 5307a87..b352e02 100644
--- a/Polygon3D.h
+++ b/Polygon3D.h
@@ -1,29 +1,36 @@
#pragma once
#include "Vector3D.h"
-#include "SharedTools.h"
#include "windows.h"
-using namespace SharedTools;
-
class Polygon3D
{
public:
Polygon3D();
- Polygon3D(int index0, int index1, int index2);
+ Polygon3D(int index0, int index1, int index2, int uvIndex0, int uvIndex1, int uvIndex2);
Polygon3D(const Polygon3D& other);
~Polygon3D();
size_t GetPolygonVertexCount() const;
+ size_t GetPolygonUVCount() const;
int GetIndex(int index) const;
+ int GetUVIndex(int index) const;
void SetNormal(const Vector3D& normal);
const Vector3D& GetNormal() const;
void NormalizeNormal();
-
+
void SetColor(int red, int green, int blue);
void SetColor(const COLORREF color);
+
+ int GetR() const;
+ void SetR(const int r);
+ int GetG() const;
+ void SetG(const int g);
+ int GetB() const;
+ void SetB(const int b);
+
COLORREF GetColor() const;
void SetDepth(float depth);
@@ -35,10 +42,15 @@ public:
private:
int _indices[3];
+ int _uvIndices[3];
+
Vector3D _normal;
float _depth;
bool _culled;
- COLORREF _color;
+
+ int _r;
+ int _g;
+ int _b;
void Copy(const Polygon3D& other);
};
diff --git a/Rasteriser.cpp b/Rasteriser.cpp
index 39ba2d8..5e4bd32 100644
--- a/Rasteriser.cpp
+++ b/Rasteriser.cpp
@@ -2,23 +2,60 @@
Rasteriser app;
+Rasteriser::~Rasteriser()
+{
+ _lights.~vector();
+ _sceneModels.~vector();
+}
+
+void Rasteriser::DrawString(HDC hDc, int x, int y, LPCTSTR text, COLORREF textColor, COLORREF backgroundColor)
+{
+ HFONT hFont, hOldFont;
+
+ // Retrieve a handle to the variable stock font.
+ hFont = hFont = CreateFont(48, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_OUTLINE_PRECIS,
+ CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY, VARIABLE_PITCH, TEXT("Myfont"));
+
+ // Select the variable stock font into the specified device context.
+ if (hOldFont = (HFONT)SelectObject(hDc, hFont))
+ {
+ SetTextColor(hDc, textColor);
+ SetBkColor(hDc, backgroundColor);
+
+ // Display the text string.
+ TextOut(hDc, x, y, text, lstrlen(text));
+
+ // Restore the original font.
+ SelectObject(hDc, hOldFont);
+ }
+ DeleteObject(hFont);
+}
+
bool Rasteriser::Initialise()
{
- Model modelA;
- if (MD2Loader::LoadModel(".\\marvin.MD2", modelA, &Model::AddPolygon, &Model::AddVertex))
+ Model modelA = Model(_modelDataLocation + "cube.MD2", _modelDataLocation + "lines.pcx");
+ // Changed to adding the model to the vector first because doing it once the model has been loaded
+ // caused the texture pointers to be at incorrect addresses.............
+ _sceneModels.push_back(modelA);
+
+ for (Model& currentModel : _sceneModels)
{
- _sceneModels.push_back(modelA);
- }
- else
- {
- return false;
- }
-
+ if (MD2Loader::LoadModel(currentModel.CGetModelFilename(), currentModel.CGetTextureFilename(), currentModel, &Model::AddPolygon, &Model::AddVertex, &Model::AddTextureUV))
+ {
+ currentModel.SetDrawMethod(DrawMethod::Textured);
+ currentModel.SetActive(true);
+
+ }
+ else
+ {
+ return false;
+ }
+ }
- _lights.push_back(new AmbientLight(150, 150, 150));
- //_lights.push_back(new AmbientLight(255, 255, 255));
- _lights.push_back(new DirectionalLight(Vector3D(-1, 0, -1), 150, 150, 150));
- //_lights.push_back(new PointLight(Vertex(-10, 0, 10), 0, 1, 0, 100, 0, 0));
+ //_lights.push_back(new AmbientLight(50, 50, 50));
+ _lights.push_back(new AmbientLight(255, 255, 255));
+ //_lights.push_back(new DirectionalLight(Vector3D(-1, 0, 0), 150, 150, 150));
+ _lights.push_back(new PointLight(Vertex(0, 0, -10), 0, 1, 0.01f, 150, 0, 0));
_cameras.push_back(Camera(0.0f, 0.0f, 0.0f, Vertex(0.0f, 0.0f, -50.0f)));
_screenMinimized = false;
@@ -58,7 +95,10 @@ void Rasteriser::CalculateLighting(Model& currentModel, bool fullLightRender)
COLORREF colorWorking = RGB(0, 0, 0);
for (Light* currentLight : _lights)
{
- colorWorking = currentLight->CalculateLight(currentModel, currentModel.GetVertex(pi, i), colorWorking);
+ if (currentLight->GetLightActive())
+ {
+ colorWorking = currentLight->CalculateLight(currentModel, currentModel.GetVertex(pi, i), colorWorking);
+ }
}
currentModel.SetVertexColor(pi, i, colorWorking);
}
@@ -68,7 +108,10 @@ void Rasteriser::CalculateLighting(Model& currentModel, bool fullLightRender)
COLORREF colorWorking = RGB(0, 0, 0);
for (Light* currentLight : _lights)
{
- colorWorking = currentLight->CalculateLight(currentModel, currentModel.GetPolygon(pi), colorWorking);
+ if (currentLight->GetLightActive())
+ {
+ colorWorking = currentLight->CalculateLight(currentModel, currentModel.GetPolygon(pi), colorWorking);
+ }
}
currentModel.SetPolygonColor(pi, colorWorking);
}
@@ -77,6 +120,26 @@ void Rasteriser::CalculateLighting(Model& currentModel, bool fullLightRender)
}
}
+float Rasteriser::Interpolate(float y, float x0, float x1, float y0, float y1)
+{
+ return x0 + (y - y0) * ((x1 - x0) / (y1 - y0));
+}
+
+float Rasteriser::Interpolate(int y, int x0, int x1, int y0, int y1)
+{
+ return Interpolate((float)y, (float)x0, (float)x1, (float)y0, (float)y1);
+}
+
+float Rasteriser::Lerp(float a, float b, float t)
+{
+ return a + (b - a) * t;
+}
+
+float Rasteriser::Lerp(int a, int b, float t)
+{
+ return Lerp((float)a, (float)b, t);
+}
+
void Rasteriser::Update(const Bitmap& bitmap)
{
if (bitmap.GetWidth() == 0 || bitmap.GetHeight() == 0)
@@ -97,19 +160,22 @@ void Rasteriser::Update(const Bitmap& bitmap)
for (Model& currentModel : _sceneModels)
{
- currentModel.EnqueueTransform(GetTranslateMatrix(startPos));
- currentModel.EnqueueTransform(GetRotationMatrix(Axis::Y, (float)currentRot));
- //startPos.SetX(startPos.GetX() + 100);
- if ((currentModelIndex % 2) == 1)
+ if (currentModel.GetActive())
{
- 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++;
}
- else
- {
- currentZOff = 100;
- }
- //startPos.SetZ((float)currentZOff);
- currentModelIndex++;
}
_currentAspectRatio = (float)(bitmap.GetWidth() / (float)bitmap.GetHeight());
@@ -137,31 +203,70 @@ void Rasteriser::Render(const Bitmap& bitmap)
for (Model& currentModel : _sceneModels)
{
- currentModel.SetReflectionCoefficient(0.5f, 0.5f, 0.5f);
- Matrix workingMatrix = workingMatrix.IdentityMatrix();
- for (Matrix currentTransform : currentModel.GetPendingTransforms())
+ if (currentModel.GetActive())
{
- workingMatrix *= currentTransform;
+ currentModel.SetReflectionCoefficient(0.5f, 0.5f, 0.5f);
+ Matrix workingMatrix = workingMatrix.IdentityMatrix();
+ for (Matrix currentTransform : currentModel.GetPendingTransforms())
+ {
+ workingMatrix *= currentTransform;
+ }
+ currentModel.ApplyTransformToLocalVertices(workingMatrix);
+ currentModel.ApplyTransformToTransformedVertices(GetCurrentCamera().GetCurrentCameraTransformMatrix());
+
+ currentModel.CalculateBackfaces(GetCurrentCamera());
+ currentModel.Sort();
+
+ switch (currentModel.GetDrawMethod())
+ {
+ case (DrawMethod::Wireframe):
+ currentModel.ApplyTransformToTransformedVertices(_currentPerspectiveMatrix);
+ currentModel.DehomogenizeAllVertices();
+ currentModel.ApplyTransformToTransformedVertices(_currentViewMatrix);
+ DrawWireFrame(bitmap.GetDC(), currentModel);
+ break;
+ case (DrawMethod::Flat):
+ currentModel.CalculateVertexNormals();
+ CalculateLighting(currentModel, false);
+
+ currentModel.ApplyTransformToTransformedVertices(_currentPerspectiveMatrix);
+ currentModel.DehomogenizeAllVertices();
+ currentModel.ApplyTransformToTransformedVertices(_currentViewMatrix);
+ DrawSolidFlat(bitmap.GetDC(), currentModel);
+ break;
+ case (DrawMethod::FlatRaster):
+ currentModel.CalculateVertexNormals();
+ CalculateLighting(currentModel, false);
+
+ currentModel.ApplyTransformToTransformedVertices(_currentPerspectiveMatrix);
+ currentModel.DehomogenizeAllVertices();
+ currentModel.ApplyTransformToTransformedVertices(_currentViewMatrix);
+ DrawRasterisedSolidFlat(bitmap.GetDC(), currentModel);
+ break;
+ case (DrawMethod::Smooth):
+ currentModel.CalculateVertexNormals();
+ CalculateLighting(currentModel, true);
+
+ currentModel.ApplyTransformToTransformedVertices(_currentPerspectiveMatrix);
+ currentModel.DehomogenizeAllVertices();
+ currentModel.ApplyTransformToTransformedVertices(_currentViewMatrix);
+ DrawGouraud(bitmap.GetDC(), currentModel);
+ break;
+ case (DrawMethod::Textured):
+ currentModel.CalculateVertexNormals();
+ CalculateLighting(currentModel, true);
+
+ currentModel.ApplyTransformToTransformedVertices(_currentPerspectiveMatrix);
+ currentModel.DehomogenizeAllVertices();
+ currentModel.ApplyTransformToTransformedVertices(_currentViewMatrix);
+ DrawSolidTextured(bitmap.GetDC(), currentModel);
+ break;
+ }
+ currentModel.ClearPendingTransforms();
}
- 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();
}
+
+ DrawString(bitmap.GetDC(), 10, 10, _T("Hello World"));
}
}
@@ -179,8 +284,8 @@ void Rasteriser::DrawSquare(HDC hDc, const vector verticies)
pointArray[i].y = (long) verticies[i].GetY();
}
- SetDCBrushColor(hDc, RGB(255, 0, 255));
- SetDCPenColor(hDc, RGB(0, 0, 255));
+ SetDCBrushColor(hDc, RGB(rand() % 256, rand() % 256, rand() % 256));
+ SetDCPenColor(hDc, RGB(rand() % 256, rand() % 256, rand() % 256));
Polygon(hDc, pointArray, 4);
}
@@ -225,6 +330,8 @@ void Rasteriser::DrawWireFrame(HDC hDc, Model& model)
}
}
+ SetDCBrushColor(hDc, RGB(1,1,1));
+ SetDCPenColor(hDc, RGB(255,255,255));
PolyPolygon(hDc, pointArray.data(), sizeArray.data(), unculledPolyCount);
}
@@ -280,6 +387,20 @@ void Rasteriser::DrawGouraud(HDC hDc, Model& model)
}
}
+void Rasteriser::DrawSolidTextured(HDC hDc, Model& model)
+{
+ int modelPolygonCount = (int)model.GetPolygonCount();
+ for (int i = 0; i < modelPolygonCount; i++)
+ {
+
+ if (!model.GetPolygon(i).GetCulled())
+ {
+ vector vertexArray = model.GetPolygonVertexArray(i);
+ FillPolygonTextured(hDc, model, vertexArray);
+ }
+ }
+}
+
bool VerticiesYCompareAsc(Vertex& v1, Vertex& v2)
{
return v1.GetY() < v2.GetY();
@@ -326,11 +447,11 @@ void Rasteriser::FillFlatSideTriangle(HDC hDc, const Vertex& v1, const Vertex& v
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 signx1 = (int)ceil(sgn(v2.GetX() - v1.GetX()));
+ int signx2 = (int)ceil(sgn(v3.GetX() - v1.GetX()));
- int signy1 = (int)sgn(v2.GetY() - v1.GetY());
- int signy2 = (int)sgn(v3.GetY() - v1.GetY());
+ int signy1 = (int)ceil(sgn(v2.GetY() - v1.GetY()));
+ int signy2 = (int)ceil(sgn(v3.GetY() - v1.GetY()));
if (dy1 > dx1)
{
@@ -353,72 +474,73 @@ void Rasteriser::FillFlatSideTriangle(HDC hDc, const Vertex& v1, const Vertex& v
for (int i = 0; i <= dx1; i++)
{
- int startPoint;
- int endPoint;
+ float leftEndPoint;
+ float rightEndPoint;
- if (tempA.GetXInt() < tempB.GetXInt())
+ if (tempA.GetX() < tempB.GetX())
{
- startPoint = tempA.GetXInt();
- endPoint = tempB.GetXInt();
+ leftEndPoint = tempA.GetX() - 1.0f;
+ rightEndPoint = tempB.GetX() + 1.0f;
}
else
{
- startPoint = tempB.GetXInt();
- endPoint = tempA.GetXInt();
+ leftEndPoint = tempB.GetX() - 1.0f;
+ rightEndPoint = tempA.GetX() + 1.0f;
}
- for (int xi = (int)ceil(startPoint); xi <= endPoint; xi++)
+ for (int xi = (int)ceil(leftEndPoint); xi <= (int)ceil(rightEndPoint); xi++)
{
SetPixel(hDc, xi, tempA.GetYInt(), colorIn);
}
+
while (e1 >= 0)
{
if (changed1)
{
- tempA.SetX(tempA.GetX() + signx1);
+ tempA.SetX((float)tempA.GetX() + (float)signx1);
}
else
{
- tempA.SetY(tempA.GetY() + signy1);
+ tempA.SetY((float)tempA.GetY() + (float)signy1);
}
e1 = e1 - 2 * dx1;
}
if (changed1)
{
- tempA.SetY(tempA.GetY() + signy1);
+ tempA.SetY((float)tempA.GetY() + (float)signy1);
}
else
{
- tempA.SetX(tempA.GetX() + signx1);
+ tempA.SetX((float)tempA.GetX() + (float)signx1);
}
e1 = e1 + 2 * dy1;
- while (tempB.GetY() != tempA.GetY())
+ while (tempB.GetYInt() != tempA.GetYInt())
{
while (e2 >= 0)
{
if (changed2)
{
- tempB.SetX(tempB.GetX() + signx2);
+ tempB.SetX((float)tempB.GetXInt() + (float)signx2);
}
else
{
- tempB.SetY(tempB.GetY() + signy2);
+ tempB.SetY((float)tempB.GetYInt() + (float)signy2);
}
e2 = e2 - 2 * dx2;
}
if (changed2)
{
- tempB.SetY(tempB.GetY() + signy2);
+ tempB.SetY((float)tempB.GetYInt() + (float)signy2);
}
else
{
- tempB.SetX(tempB.GetX() + signx2);
+ tempB.SetX((float)tempB.GetXInt() + (float)signx2);
}
e2 = e2 + 2 * dy2;
}
@@ -426,112 +548,6 @@ void Rasteriser::FillFlatSideTriangle(HDC hDc, const Vertex& v1, const Vertex& v
}
void Rasteriser::FillPolygonGouraud(HDC hDc, vector& 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& verts)
{
sort(verts.begin(), verts.end(), VerticiesYCompareAsc);
if (verts[1].GetY() == verts[2].GetY())
@@ -547,12 +563,13 @@ void Rasteriser::FillPolygonGouraudInt(HDC hDc, vector& verts)
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());
+ float vDiff = ((verts[1].GetY() - verts[0].GetY()) / (verts[2].GetY() - verts[0].GetY()));
+ float cRed = Lerp(verts[0].GetR(), verts[2].GetR(), vDiff);
+ float cGreen = Lerp(verts[0].GetG(), verts[2].GetG(), vDiff);
+ float cBlue = Lerp(verts[0].GetB(), verts[2].GetB(), vDiff);
temp.SetColor(BoundsCheck(0, 255, (int)cRed), BoundsCheck(0, 255, (int)cGreen), BoundsCheck(0, 255, (int)cBlue));
- if (verts[1].GetX() < temp.GetX())
+ if (verts[1].GetX() <= temp.GetX())
{
FillGouraudSideTriangle(hDc, verts[0], verts[1], temp);
FillGouraudSideTriangle(hDc, verts[2], verts[1], temp);
@@ -611,30 +628,35 @@ void Rasteriser::FillGouraudSideTriangle(HDC hDc, const Vertex& v1, const Vertex
if (tempA.GetX() < tempB.GetX())
{
- leftEndPoint = tempA.GetX();
- rightEndPoint = tempB.GetX();
+ leftEndPoint = tempA.GetX() - 1.0f;
+ rightEndPoint = tempB.GetX() + 1.0f;
}
else
{
- leftEndPoint = tempB.GetX();
- rightEndPoint = tempA.GetX();
+ leftEndPoint = tempB.GetX() - 1.0f;
+ rightEndPoint = tempA.GetX() + 1.0f;
}
- 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();
+ float iRedA = Lerp(v1.GetR(), v2.GetR(), (float)i / (float)dx1);
+ float iRedB = Lerp(v1.GetR(), v3.GetR(), (float)i / (float)dx1);
+ float iGreenA = Lerp(v1.GetG(), v2.GetG(), (float)i / (float)dx1);
+ float iGreenB = Lerp(v1.GetG(), v3.GetG(), (float)i / (float)dx1);
+ float iBlueA = Lerp(v1.GetB(), v2.GetB(), (float)i / (float)dx1);
+ float iBlueB = Lerp(v1.GetB(), v3.GetB(), (float)i / (float)dx1);
- 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;
+ int xLength = (int)ceil(rightEndPoint) - (int)ceil(leftEndPoint);
+ int ci = 0;
+
+ for (int xi = (int)ceil(leftEndPoint); xi <= (int)ceil(rightEndPoint); xi++)
+ {
+ float ti = (float)ci / (float)xLength;
+ float redTmp = Lerp(iRedA, iRedB, ti);
+ float greenTmp = Lerp(iGreenA, iGreenB, ti);
+ float blueTmp = Lerp(iBlueA, iBlueB, ti);
COLORREF currentColor = RGB(BoundsCheck(0, 255, (int)redTmp), BoundsCheck(0, 255, (int)greenTmp), BoundsCheck(0, 255, (int)blueTmp));
SetPixel(hDc, xi, tempA.GetYInt(), currentColor);
+ ci++;
}
@@ -642,27 +664,27 @@ void Rasteriser::FillGouraudSideTriangle(HDC hDc, const Vertex& v1, const Vertex
{
if (changed1)
{
- tempA.SetX((float)tempA.GetXInt() + (float)signx1);
+ tempA.SetX((float)tempA.GetX() + (float)signx1);
}
else
{
- tempA.SetY((float)tempA.GetYInt() + (float)signy1);
+ tempA.SetY((float)tempA.GetY() + (float)signy1);
}
e1 = e1 - 2 * dx1;
}
if (changed1)
{
- tempA.SetY((float)tempA.GetYInt() + (float)signy1);
+ tempA.SetY((float)tempA.GetY() + (float)signy1);
}
else
{
- tempA.SetX((float)tempA.GetXInt() + (float)signx1);
+ tempA.SetX((float)tempA.GetX() + (float)signx1);
}
e1 = e1 + 2 * dy1;
- while (tempB.GetY() < tempA.GetY() && tempB.GetY() > tempA.GetY())
+ while (tempB.GetYInt() != tempA.GetYInt())
{
while (e2 >= 0)
{
@@ -689,3 +711,224 @@ void Rasteriser::FillGouraudSideTriangle(HDC hDc, const Vertex& v1, const Vertex
}
}
}
+
+void Rasteriser::FillPolygonTextured(HDC hDc, Model& model, vector& verts)
+{
+ sort(verts.begin(), verts.end(), VerticiesYCompareAsc);
+ if (verts[1].GetY() == verts[2].GetY())
+ {
+ FillTexturedSideTriangle(hDc, model, verts[0], verts[1], verts[2], model.GetUVCoord(verts[0].GetUVIndex()), model.GetUVCoord(verts[1].GetUVIndex()), model.GetUVCoord(verts[2].GetUVIndex()));
+ }
+ else if (verts[0].GetY() == verts[1].GetY())
+ {
+ FillTexturedSideTriangle(hDc, model, verts[2], verts[0], verts[1], model.GetUVCoord(verts[2].GetUVIndex()), model.GetUVCoord(verts[0].GetUVIndex()), model.GetUVCoord(verts[1].GetUVIndex()));
+ }
+ 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 tempU = model.GetUVCoord(verts[0].GetUVIndex()).GetU() + ((verts[1].GetY() - verts[0].GetY()) / (verts[2].GetY() - verts[0].GetY())) * (model.GetUVCoord(verts[2].GetUVIndex()).GetU() - model.GetUVCoord(verts[0].GetUVIndex()).GetU());
+ float tempV = model.GetUVCoord(verts[0].GetUVIndex()).GetV() + ((verts[1].GetY() - verts[0].GetY()) / (verts[2].GetY() - verts[0].GetY())) * (model.GetUVCoord(verts[2].GetUVIndex()).GetV() - model.GetUVCoord(verts[0].GetUVIndex()).GetV());
+
+ UVCoord tempCoords = UVCoord(tempU, tempV);
+
+ 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())
+ {
+ temp.SetUVIndex(verts[2].GetUVIndex());
+ FillTexturedSideTriangle(hDc, model, verts[0], verts[1], temp, model.GetUVCoord(verts[0].GetUVIndex()), model.GetUVCoord(verts[1].GetUVIndex()), tempCoords);
+ temp.SetUVIndex(verts[0].GetUVIndex());
+ FillTexturedSideTriangle(hDc, model, verts[2], verts[1], temp, model.GetUVCoord(verts[2].GetUVIndex()), model.GetUVCoord(verts[1].GetUVIndex()), tempCoords);
+ }
+ else
+ {
+ temp.SetUVIndex(verts[2].GetUVIndex());
+ FillTexturedSideTriangle(hDc, model, verts[0], temp, verts[1], model.GetUVCoord(verts[0].GetUVIndex()), tempCoords, model.GetUVCoord(verts[1].GetUVIndex()));
+ temp.SetUVIndex(verts[0].GetUVIndex());
+ FillTexturedSideTriangle(hDc, model, verts[2], temp, verts[1], model.GetUVCoord(verts[2].GetUVIndex()), tempCoords, model.GetUVCoord(verts[1].GetUVIndex()));
+ }
+ }
+}
+
+void Rasteriser::FillTexturedSideTriangle(HDC hDc, Model& model, const Vertex& v1, const Vertex& v2, const Vertex& v3, const UVCoord& uv1, const UVCoord& uv2, const UVCoord& uv3)
+{
+ Vertex tempA = Vertex(v1);
+ Vertex tempB = Vertex(v1);
+ UVCoord tempUVA = UVCoord(uv1);
+ UVCoord tempUVB = UVCoord(uv1);
+
+ bool changed1 = false;
+ bool changed2 = false;
+
+ float uc0 = uv1.GetU();
+ float vc0 = uv1.GetV();
+ float uc1 = uv2.GetU();
+ float vc1 = uv2.GetV();
+ float uc2 = uv3.GetU();
+ float vc2 = uv3.GetV();
+
+ int dx1 = (int)ceil(abs(v2.GetX() - v1.GetX()));
+ int dy1 = (int)ceil(abs(v2.GetY() - v1.GetY()));
+ int du1 = (int)ceil(abs(uc1 - uc0));
+ int dv1 = (int)ceil(abs(vc1 - vc0));
+
+ int dx2 = (int)ceil(abs(v3.GetX() - v1.GetX()));
+ int dy2 = (int)ceil(abs(v3.GetY() - v1.GetY()));
+ int du2 = (int)ceil(abs(uc2 - uc0));
+ int dv2 = (int)ceil(abs(vc2 - vc0));
+
+ int signx1 = (int)ceil(sgn(v2.GetX() - v1.GetX()));
+ int signx2 = (int)ceil(sgn(v3.GetX() - v1.GetX()));
+ int signu1 = (int)ceil(sgn(uc1 - uc0));
+ int signu2 = (int)ceil(sgn(uc2 - uc0));
+
+ int signy1 = (int)ceil(sgn(v2.GetY() - v1.GetY()));
+ int signy2 = (int)ceil(sgn(v3.GetY() - v1.GetY()));
+ int signv1 = (int)ceil(sgn(vc1 - vc0));
+ int signv2 = (int)ceil(sgn(vc2 - vc0));
+
+ if (dy1 > dx1)
+ {
+ int tempDx = dx1;
+ dx1 = dy1;
+ dy1 = tempDx;
+
+ int tempDu = du1;
+ du1 = dv1;
+ dv1 = tempDu;
+
+ changed1 = true;
+ }
+
+ if (dy2 > dx2)
+ {
+ int tempDx = dx2;
+ dx2 = dy2;
+ dy2 = tempDx;
+
+ int tempDu = du2;
+ du2 = dv2;
+ dv2 = tempDu;
+
+ 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;
+ float leftUV;
+ float rightUV;
+
+ if (tempA.GetX() < tempB.GetX())
+ {
+ leftEndPoint = tempA.GetX() - 1.0f;
+ rightEndPoint = tempB.GetX() + 1.0f;
+ leftUV = tempUVA.GetU();
+ rightUV = tempUVB.GetU();
+ }
+ else
+ {
+ leftEndPoint = tempB.GetX() - 1.0f;
+ rightEndPoint = tempA.GetX() + 1.0f;
+ leftUV = tempUVB.GetU();
+ rightUV = tempUVA.GetU();
+ }
+
+
+ float UCoordA = Interpolate(uv1.GetV() + i, uv1.GetU(), uv2.GetU(), uv1.GetV(), uv2.GetV());
+ float UCoordB = Interpolate(uv1.GetV() + i, uv1.GetU(), uv3.GetU(), uv1.GetV(), uv3.GetV());
+
+ float iRedA = Lerp(v1.GetR(), v2.GetR(), (float)i / (float)dx1);
+ float iRedB = Lerp(v1.GetR(), v3.GetR(), (float)i / (float)dx1);
+ float iGreenA = Lerp(v1.GetG(), v2.GetG(), (float)i / (float)dx1);
+ float iGreenB = Lerp(v1.GetG(), v3.GetG(), (float)i / (float)dx1);
+ float iBlueA = Lerp(v1.GetB(), v2.GetB(), (float)i / (float)dx1);
+ float iBlueB = Lerp(v1.GetB(), v3.GetB(), (float)i / (float)dx1);
+
+ int xLength = (int)ceil(rightEndPoint) - (int)ceil(leftEndPoint);
+ int ci = 0;
+
+ for (int xi = (int)ceil(leftEndPoint); xi <= (int)ceil(rightEndPoint); xi++)
+ {
+ float ti = (float)ci / (float)xLength;
+ float UCoordTmp = Lerp(leftUV, rightUV, ti);
+ float redTmp = Lerp(iRedA, iRedB, ti) / 100;
+ float greenTmp = Lerp(iGreenA, iGreenB, ti) / 100;
+ float blueTmp = Lerp(iBlueA, iBlueB, ti) / 100;
+
+ COLORREF textureColor = model.GetTexture().GetTextureValue((int)UCoordTmp, (int)tempUVA.GetV());
+ COLORREF currentColor = RGB(BoundsCheck(0, 255, (int)(GetRValue(textureColor) * redTmp)), BoundsCheck(0, 255, (int)(GetGValue(textureColor) * greenTmp)), BoundsCheck(0, 255, (int)(GetBValue(textureColor) * blueTmp)));
+
+ SetPixel(hDc, xi, tempA.GetYInt(), currentColor);
+ ci++;
+ }
+
+
+ while (e1 >= 0)
+ {
+ if (changed1)
+ {
+ tempA.SetX((float)tempA.GetXInt() + (float)signx1);
+ tempUVA.SetU((float)tempUVA.GetU() + (float)signu1);
+ }
+ else
+ {
+ tempA.SetY((float)tempA.GetYInt() + (float)signy1);
+ tempUVA.SetV((float)tempUVA.GetV() + (float)signv1);
+ }
+ e1 = e1 - 2 * dx1;
+ }
+
+ if (changed1)
+ {
+ tempA.SetY((float)tempA.GetYInt() + (float)signy1);
+ tempUVA.SetV((float)tempUVA.GetV() + (float)signv1);
+ }
+ else
+ {
+ tempA.SetX((float)tempA.GetXInt() + (float)signx1);
+ tempUVA.SetU((float)tempUVA.GetU() + (float)signu1);
+ }
+
+ e1 = e1 + 2 * dy1;
+
+ while (tempB.GetYInt(true) != tempA.GetYInt(true))
+ {
+ while (e2 >= 0)
+ {
+ if (changed2)
+ {
+ tempB.SetX((float)tempB.GetXInt() + (float)signx2);
+ tempUVB.SetU((float)tempUVB.GetU() + (float)signu2);
+ }
+ else
+ {
+ tempB.SetY((float)tempB.GetYInt() + (float)signy2);
+ tempUVB.SetV((float)tempUVB.GetV() + (float)signv2);
+ }
+ e2 = e2 - 2 * dx2;
+ }
+
+ if (changed2)
+ {
+ tempB.SetY((float)tempB.GetYInt() + (float)signy2);
+ tempUVB.SetV((float)tempUVB.GetV() + (float)signv2);
+ }
+ else
+ {
+ tempB.SetX((float)tempB.GetXInt() + (float)signx2);
+ tempUVB.SetU((float)tempUVB.GetU() + (float)signu2);
+ }
+ e2 = e2 + 2 * dy2;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Rasteriser.h b/Rasteriser.h
index 7ea264b..c948ce2 100644
--- a/Rasteriser.h
+++ b/Rasteriser.h
@@ -1,5 +1,7 @@
#pragma once
#include
+#include
+#include
#include "Framework.h"
#include "Vector3D.h"
#include "Vertex.h"
@@ -23,13 +25,23 @@ public:
void Update(const Bitmap& bitmap);
void Render(const Bitmap& bitmap);
void ClearViewport(const Bitmap& bitmap);
+ void DrawString(HDC hDc, int x, int y, LPCTSTR text, COLORREF textColor = 0x00FFFFFF, COLORREF backgroundColor = 0x00000000);
+
+ ~Rasteriser();
void SetCurrentCamera(int index);
Camera& GetCamera(int index);
Camera& GetCurrentCamera();
+ // Calculate the Lighting for the scene, fullLightRender sets the method to calculate the
+ // light values of all verticies otherwise light values are calculated at the polygon level
void CalculateLighting(Model& currentModel, bool fullLightRender);
+ float Interpolate(float y, float x0, float x1, float y0, float y1);
+ float Interpolate(int y, int x0, int x1, int y0, int y1);
+ float Lerp(float a, float b, float t);
+ float Lerp(int a, int b, float t);
+
void DrawSquare(HDC hDc, const vector verticies);
void DrawShape(HDC hDc, const vector verticies);
@@ -37,17 +49,17 @@ public:
void DrawSolidFlat(HDC hDc, Model& model);
void DrawRasterisedSolidFlat(HDC hDc, Model& model);
void DrawGouraud(HDC hDc, Model& model);
+ void DrawSolidTextured(HDC hDc, Model& model);
void FillPolygonFlat(HDC hDc, vector& verticies, COLORREF colorIn);
void FillFlatSideTriangle(HDC hDc, const Vertex& v1, const Vertex& v2, const Vertex& v3, COLORREF colorIn);
void FillPolygonGouraud(HDC hDc, vector& 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& verticies);
void FillGouraudSideTriangle(HDC hDc, const Vertex& v1, const Vertex& v2, const Vertex& v3);
+ void FillPolygonTextured(HDC hDc, Model& model, vector& verticies);
+ void FillTexturedSideTriangle(HDC hDc, Model& model, const Vertex& v1, const Vertex& v2, const Vertex& v3, const UVCoord& uv1, const UVCoord& uv2, const UVCoord& uv3);
+
private:
vector _sceneModels;
vector _lights;
@@ -60,6 +72,9 @@ private:
float _currentAspectRatio = 0.0f;
int _rotation = 0;
+ int _currentDrawMode = 0;
+
bool _screenMinimized = false;
+ string _modelDataLocation = ".//model_data/";
};
diff --git a/SharedTools.h b/SharedTools.h
index d99ccd2..adf1bf0 100644
--- a/SharedTools.h
+++ b/SharedTools.h
@@ -1,4 +1,5 @@
#pragma once
+#include "Vertex.h"
#include "Matrix.h"
#include
@@ -9,6 +10,7 @@ template int sgn(T val) {
return (T(0) < val) - (val < T(0));
}
+
namespace SharedTools
{
const float PI = (float)acos(-1);
diff --git a/Texture.cpp b/Texture.cpp
new file mode 100644
index 0000000..9017a32
--- /dev/null
+++ b/Texture.cpp
@@ -0,0 +1,80 @@
+#include "Texture.h"
+
+Texture::Texture()
+{
+ _width = 0;
+ _height = 0;
+ _paletteIndices = nullptr;
+ _palette = nullptr;
+}
+
+Texture::~Texture()
+{
+ if (_paletteIndices != nullptr)
+ {
+ delete[] _paletteIndices;
+ _paletteIndices = nullptr;
+ }
+ if (_palette != nullptr)
+ {
+ delete[] _palette;
+ _palette = nullptr;
+ }
+}
+
+void Texture::SetTextureSize(int width, int height)
+{
+ _width = width;
+ _height = height;
+ if (_paletteIndices != nullptr)
+ {
+ delete[] _paletteIndices;
+ }
+ _paletteIndices = new BYTE[_width * _height];
+ if (_palette != nullptr)
+ {
+ delete[] _palette;
+ }
+ _palette = new COLORREF[256];
+}
+
+COLORREF Texture::GetTextureValue(int u, int v) const
+{
+ if (v < 0)
+ {
+ v = 0;
+ }
+ if (v >= _height)
+ {
+ v = _height - 1;
+ }
+ if (u < 0)
+ {
+ u = 0;
+ }
+ if (u >= _width)
+ {
+ u = _width - 1;
+ }
+ return _palette[_paletteIndices[v * _width + u]];
+}
+
+BYTE * Texture::GetPaletteIndices()
+{
+ return _paletteIndices;
+}
+
+COLORREF * Texture::GetPalette()
+{
+ return _palette;
+}
+
+int Texture::GetWidth() const
+{
+ return _width;
+}
+
+int Texture::GetHeight() const
+{
+ return _height;
+}
diff --git a/Texture.h b/Texture.h
new file mode 100644
index 0000000..5b1c206
--- /dev/null
+++ b/Texture.h
@@ -0,0 +1,22 @@
+#pragma once
+#include "windows.h"
+
+class Texture
+{
+public:
+ Texture();
+ ~Texture();
+
+ void SetTextureSize(int width, int height);
+ COLORREF GetTextureValue(int u, int v) const;
+ BYTE * GetPaletteIndices();
+ COLORREF * GetPalette();
+ int GetWidth() const;
+ int GetHeight() const;
+
+private:
+ BYTE * _paletteIndices;
+ COLORREF * _palette;
+ int _width;
+ int _height;
+};
\ No newline at end of file
diff --git a/UVCoord.cpp b/UVCoord.cpp
new file mode 100644
index 0000000..8e8222f
--- /dev/null
+++ b/UVCoord.cpp
@@ -0,0 +1,57 @@
+#include "UVCoord.h"
+
+UVCoord::UVCoord()
+{
+ _u = 0.0f;
+ _v = 0.0f;
+}
+
+UVCoord::UVCoord(float u, float v)
+{
+ _u = u;
+ _v = v;
+}
+
+UVCoord::UVCoord(const UVCoord& other)
+{
+ Copy(other);
+}
+
+UVCoord::~UVCoord()
+{
+}
+
+float UVCoord::GetU() const
+{
+ return _u;
+}
+
+void UVCoord::SetU(const float u)
+{
+ _u = u;
+}
+
+float UVCoord::GetV() const
+{
+ return _v;
+}
+
+void UVCoord::SetV(const float v)
+{
+ _v = v;
+}
+
+UVCoord& UVCoord::operator= (const UVCoord& rhs)
+{
+ if (this != &rhs)
+ {
+ Copy(rhs);
+ }
+ return *this;
+}
+
+void UVCoord::Copy(const UVCoord& other)
+{
+ _u = other.GetU();
+ _v = other.GetV();
+}
diff --git a/UVCoord.h b/UVCoord.h
new file mode 100644
index 0000000..8f26d53
--- /dev/null
+++ b/UVCoord.h
@@ -0,0 +1,26 @@
+#pragma once
+
+class UVCoord
+{
+public:
+ UVCoord();
+ UVCoord(float u, float v);
+ UVCoord(const UVCoord& other);
+
+ ~UVCoord();
+
+ float GetU() const;
+ void SetU(const float u);
+ float GetV() const;
+ void SetV(const float v);
+
+ UVCoord& operator= (const UVCoord& rhs);
+
+private:
+ float _u;
+ float _v;
+
+ void Copy(const UVCoord& other);
+
+};
+
diff --git a/Vector3D.cpp b/Vector3D.cpp
index 96dba3f..0af3c0d 100644
--- a/Vector3D.cpp
+++ b/Vector3D.cpp
@@ -81,6 +81,14 @@ 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());
}
+Vector3D& Vector3D::operator= (const Vector3D& rhs)
+{
+ if (this != &rhs)
+ {
+ Copy(rhs);
+ }
+ return *this;
+}
const Vector3D Vector3D::operator+ (const Vector3D& rhs) const
{
diff --git a/Vector3D.h b/Vector3D.h
index f4bc9c5..42395d2 100644
--- a/Vector3D.h
+++ b/Vector3D.h
@@ -24,6 +24,8 @@ public:
static float Length(const Vector3D v1, const Vector3D v2);
static Vector3D CrossProduct(const Vector3D v1, const Vector3D v2);
+ Vector3D& operator= (const Vector3D& rhs);
+
const Vector3D operator+ (const Vector3D& rhs) const;
const Vector3D operator/ (const int rhs) const;
const Vector3D operator/ (const float rhs) const;
diff --git a/Vertex.cpp b/Vertex.cpp
index f878424..2c6fd37 100644
--- a/Vertex.cpp
+++ b/Vertex.cpp
@@ -140,16 +140,31 @@ int Vertex::GetR() const
return _r;
}
+void Vertex::SetR(const int r)
+{
+ _r = r;
+}
+
int Vertex::GetG() const
{
return _g;
}
+void Vertex::SetG(const int g)
+{
+ _g = g;
+}
+
int Vertex::GetB() const
{
return _b;
}
+void Vertex::SetB(const int b)
+{
+ _b = b;
+}
+
void Vertex::SetColor(int r, int g, int b)
{
_r = r;
@@ -162,6 +177,16 @@ void Vertex::SetColor(const COLORREF colorIn)
SetColor((int)GetRValue(colorIn), (int)GetGValue(colorIn), (int)GetBValue(colorIn));
}
+int Vertex::GetUVIndex() const
+{
+ return _uvIndex;
+}
+
+void Vertex::SetUVIndex(const int index)
+{
+ _uvIndex = index;
+}
+
int Vertex::GetXInt(bool forceRoundUp) const
{
if (forceRoundUp)
@@ -261,7 +286,11 @@ void Vertex::Copy(const Vertex& other)
_w = other.GetW();
_contributeCount = other.GetContributeCount();
- SetNormal(other.GetNormal());
+ _normal = other.GetNormal();
- SetColor(other.GetR(), other.GetG(), other.GetB());
+ _r = other.GetR();
+ _g = other.GetG();
+ _b = other.GetB();
+
+ _uvIndex = other.GetUVIndex();
}
diff --git a/Vertex.h b/Vertex.h
index 86e3f13..026ba5e 100644
--- a/Vertex.h
+++ b/Vertex.h
@@ -1,5 +1,6 @@
#pragma once
#include "Vector3D.h"
+#include "UVCoord.h"
#include "windows.h"
class Vertex
@@ -32,12 +33,18 @@ public:
const COLORREF GetColor() const;
int GetR() const;
+ void SetR(const int r);
int GetG() const;
+ void SetG(const int g);
int GetB() const;
+ void SetB(const int b);
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
+ int GetUVIndex() const;
+ void SetUVIndex(const int index);
+
+ // Accessors 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;
@@ -61,6 +68,8 @@ private:
float _z;
float _w;
+ float _zOriginal;
+
int _contributeCount;
Vector3D _normal;
@@ -68,6 +77,8 @@ private:
int _g;
int _b;
+ int _uvIndex;
+
void Copy(const Vertex& other);
};
diff --git a/cheff.md2 b/model_data/cheff.md2
similarity index 100%
rename from cheff.md2
rename to model_data/cheff.md2
diff --git a/cow.md2 b/model_data/cow.md2
similarity index 100%
rename from cow.md2
rename to model_data/cow.md2
diff --git a/cube.md2 b/model_data/cube.md2
similarity index 100%
rename from cube.md2
rename to model_data/cube.md2
diff --git a/fire.md2 b/model_data/fire.md2
similarity index 100%
rename from fire.md2
rename to model_data/fire.md2
diff --git a/model_data/lines.pcx b/model_data/lines.pcx
new file mode 100644
index 0000000..5f94e71
Binary files /dev/null and b/model_data/lines.pcx differ
diff --git a/marvin.md2 b/model_data/marvin.md2
similarity index 100%
rename from marvin.md2
rename to model_data/marvin.md2
diff --git a/model_data/marvin.pcx b/model_data/marvin.pcx
new file mode 100644
index 0000000..c0ad227
Binary files /dev/null and b/model_data/marvin.pcx differ
diff --git a/megaman.MD2 b/model_data/megaman.MD2
similarity index 100%
rename from megaman.MD2
rename to model_data/megaman.MD2
diff --git a/teapot.md2 b/model_data/teapot.md2
similarity index 100%
rename from teapot.md2
rename to model_data/teapot.md2
diff --git a/w_railgun.md2 b/model_data/w_railgun.md2
similarity index 100%
rename from w_railgun.md2
rename to model_data/w_railgun.md2