
Added active Variable to the Lights Classes Added updated MD2Loader Class Added Model Filename and Texture File Name to the Model Class Added Active Flag to the Model Class Added DrawMode to the Model Class Added Texture and UV Variables to the Model Class Added UV Coordinates to the Polygon3D Class Added DrawString method to the Rasterizer to write text to the screen space Added Interpolate and Lerp Methods to the Rasterizer Added Select statement for drawing a current models draw mode Added DrawTextured Method to the Rasterizer Class Added UVCoord Class Added Texture Class Added = operator to the Vector3D Class Added UVCoord to the Vertex Class Moved Models and Texture Files into a subfolder Fixed issue with textures not loading properly because of the vector address problem
363 lines
7.1 KiB
C++
363 lines
7.1 KiB
C++
#include "Model.h"
|
|
|
|
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<Polygon3D>& Model::GetPolygons()
|
|
{
|
|
return _polygons;
|
|
}
|
|
|
|
vector<Vertex>& Model::GetVertices()
|
|
{
|
|
return _vertices;
|
|
}
|
|
|
|
vector<UVCoord>& Model::GetUVCoords()
|
|
{
|
|
return _uvCoords;
|
|
}
|
|
|
|
const vector<Matrix>& Model::GetPendingTransforms()
|
|
{
|
|
return _pendingTransforms;
|
|
}
|
|
|
|
size_t Model::GetPolygonCount()
|
|
{
|
|
return _polygons.size();
|
|
}
|
|
|
|
size_t Model::GetVerticesCount()
|
|
{
|
|
return _vertices.size();
|
|
}
|
|
|
|
size_t Model::GetUVCoordCount()
|
|
{
|
|
return _uvCoords.size();
|
|
}
|
|
|
|
size_t Model::GetPendingTransformCount()
|
|
{
|
|
return _pendingTransforms.size();
|
|
}
|
|
|
|
void Model::AddVertex(float x, float y, float z)
|
|
{
|
|
_vertices.push_back(Vertex(x, y, z));
|
|
_transformedVertices.push_back(Vertex(x, y, z));
|
|
}
|
|
|
|
void Model::AddPolygon(int index0, int index1, int index2, int uvIndex0, int uvIndex1, int uvIndex2)
|
|
{
|
|
_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)
|
|
{
|
|
_pendingTransforms.push_back(transform);
|
|
}
|
|
|
|
void Model::ClearPendingTransforms()
|
|
{
|
|
_pendingTransforms.clear();
|
|
}
|
|
|
|
Texture& Model::GetTexture()
|
|
{
|
|
return _texture;
|
|
}
|
|
|
|
const Polygon3D& Model::GetPolygon(int index) const
|
|
{
|
|
return _polygons[index];
|
|
}
|
|
|
|
const Vertex& Model::GetVertex(int polygonIndex, int vertexPolygonIndex) const
|
|
{
|
|
return GetVertex(GetPolygon(polygonIndex).GetIndex(vertexPolygonIndex));
|
|
}
|
|
|
|
const Vertex& Model::GetVertex(int index) const
|
|
{
|
|
return _transformedVertices[index];
|
|
}
|
|
|
|
const UVCoord& Model::GetUVCoord(int index) const
|
|
{
|
|
return _uvCoords[index];
|
|
}
|
|
|
|
vector<Vertex> Model::GetPolygonVertexArray(int index) const
|
|
{
|
|
vector<Vertex> polygonVerticies = {};
|
|
|
|
for (int i = 0; i < GetPolygon(index).GetPolygonVertexCount(); i++)
|
|
{
|
|
polygonVerticies.push_back(GetVertex(index, i));
|
|
}
|
|
return polygonVerticies;
|
|
}
|
|
|
|
void Model::SetPolygonColor(int index, COLORREF color)
|
|
{
|
|
_polygons[index].SetColor(color);
|
|
}
|
|
|
|
void Model::SetVertexColor(int polyIndex, int vertIndex, COLORREF color)
|
|
{
|
|
_transformedVertices[GetPolygon(polyIndex).GetIndex(vertIndex)].SetColor(color);
|
|
}
|
|
|
|
void Model::SetReflectionCoefficient(float red, float green, float blue)
|
|
{
|
|
_kdRed = BoundsCheck(0.0f, 1.0f, red);
|
|
_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++)
|
|
{
|
|
_transformedVertices[i] = transform * _vertices[i];
|
|
}
|
|
}
|
|
|
|
void Model::ApplyTransformToTransformedVertices(const Matrix& transform)
|
|
{
|
|
for (int i = 0; i < GetVerticesCount(); i++)
|
|
{
|
|
_transformedVertices[i] = transform * _transformedVertices[i];
|
|
}
|
|
}
|
|
|
|
void Model::DehomogenizeAllVertices()
|
|
{
|
|
for (Vertex& currentVertex : _transformedVertices)
|
|
{
|
|
currentVertex.Dehomogenize();
|
|
}
|
|
}
|
|
|
|
void Model::CalculateBackfaces(Camera& currentCamera)
|
|
{
|
|
for (Polygon3D& currentPolygon : _polygons)
|
|
{
|
|
Vector3D vectorA = _transformedVertices[currentPolygon.GetIndex(1)] - _transformedVertices[currentPolygon.GetIndex(0)];
|
|
Vector3D vectorB = _transformedVertices[currentPolygon.GetIndex(2)] - _transformedVertices[currentPolygon.GetIndex(0)];
|
|
currentPolygon.SetNormal(Vector3D::CrossProduct(vectorA, vectorB));
|
|
currentPolygon.NormalizeNormal();
|
|
Vector3D eyeVector = _transformedVertices[currentPolygon.GetIndex(0)] - currentCamera.GetCameraPosition();
|
|
eyeVector.Normalize();
|
|
|
|
float dotProduct = Vector3D::DotProduct(currentPolygon.GetNormal(), eyeVector);
|
|
if (dotProduct < 0)
|
|
{
|
|
currentPolygon.SetCulled(true);
|
|
}
|
|
else
|
|
{
|
|
currentPolygon.SetCulled(false);
|
|
}
|
|
}
|
|
}
|
|
|
|
void Model::CalculateVertexNormals()
|
|
{
|
|
for (Vertex& currentVertex : _transformedVertices)
|
|
{
|
|
currentVertex.ResetNormal(true);
|
|
}
|
|
|
|
for (int pi = 0; pi < GetPolygonCount(); pi++)
|
|
{
|
|
for (int i = 0; i < _polygons[pi].GetPolygonVertexCount(); i++)
|
|
{
|
|
_transformedVertices[_polygons[pi].GetIndex(i)].SetNormal(_transformedVertices[_polygons[pi].GetIndex(i)].GetNormal() + _polygons[pi].GetNormal());
|
|
_transformedVertices[_polygons[pi].GetIndex(i)].IncrementContributeCount();
|
|
_transformedVertices[_polygons[pi].GetIndex(i)].SetUVIndex(_polygons[pi].GetUVIndex(i));
|
|
}
|
|
}
|
|
|
|
for (Vertex& currentVertex : _transformedVertices)
|
|
{
|
|
|
|
currentVertex.SetNormal(currentVertex.GetNormal() / currentVertex.GetContributeCount());
|
|
currentVertex.NormalizeNormal();
|
|
|
|
}
|
|
}
|
|
|
|
bool DepthCompare(Polygon3D& a, Polygon3D& b)
|
|
{
|
|
return a.GetDepth() > b.GetDepth();
|
|
}
|
|
|
|
void Model::Sort()
|
|
{
|
|
for (Polygon3D& currentPolygon : _polygons)
|
|
{
|
|
float zTotal = 0.0f;
|
|
for (int i = 0; i < currentPolygon.GetPolygonVertexCount(); i++)
|
|
{
|
|
zTotal += _transformedVertices[currentPolygon.GetIndex(i)].GetZ();
|
|
}
|
|
currentPolygon.SetDepth(zTotal / currentPolygon.GetPolygonVertexCount());
|
|
}
|
|
|
|
sort(_polygons.begin(), _polygons.end(), DepthCompare);
|
|
} |