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:
168
MD2Loader.cpp
168
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<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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user