Week10 [30/11] - [06/12]

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
This commit is contained in:
IDunnoDev
2021-12-11 20:31:39 +00:00
committed by iDunnoDev
parent df3c9fac81
commit cdb940f6aa
32 changed files with 1136 additions and 243 deletions

View File

@ -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<char*>(&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<char*>(&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<char*>(&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<char*>(&processByte), 1);
if (processByte == 12)
{
BYTE rawPalette[768];
file.read(reinterpret_cast<char*>(&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<Md2Frame*>(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<char*>(frame), header.frameSize);
// Read texture coordinate data
file.seekg(header.offsetTexCoords, std::ios::beg);
file.read(reinterpret_cast<char*>(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<float>((frame->verts[i].v[2] * frame->scale[2]) + frame->translate[2]),
static_cast<float>((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;
}