// Draws the given model with texturing, shading and a normal map. void Rasterizer::DrawSolidTexturedNormalMapped(Model3D& model, std::vector<DirectionalLight*> directionalLights, std::vector<AmbientLight*> ambientLights, std::vector<PointLight*> pointLights) { std::vector<Polygon3D> _polygonList = model.GetPolygonList(); std::vector<Vertex> _vertexList = model.GetTransformedVertexList(); std::vector<UVCoordinate> _uvCoordList = model.GetUVCoordinateList(); for (unsigned int i = 0; i < _polygonList.size(); i++) { Polygon3D poly = _polygonList[i]; if (poly.GetBackfacing() == true) continue; Vertex v1 = _vertexList[poly.GetVertexIndex(0)]; Vertex v2 = _vertexList[poly.GetVertexIndex(1)]; Vertex v3 = _vertexList[poly.GetVertexIndex(2)]; // Set the uv coordinates of each vertex temporarily to the coordinates in the // uv coordinate list. v1.SetUVCoordinate(_uvCoordList[poly.GetUVIndex(0)]); v2.SetUVCoordinate(_uvCoordList[poly.GetUVIndex(1)]); v3.SetUVCoordinate(_uvCoordList[poly.GetUVIndex(2)]); // Fill the polygon using the models texture. if (model.GetNormalMapOn() == true) FillPolygonTexturedNormalMapped(v1, v2, v3, v1.GetColor(), model, directionalLights, ambientLights, pointLights); else FillPolygonTextured(v1, v2, v3, v1.GetColor(), model); } }
// Draws the given model with gouraud shading. void Rasterizer::DrawSolidShaded(Model3D& model) { std::vector<Polygon3D> _polygonList = model.GetPolygonList(); std::vector<Vertex> _vertexList = model.GetTransformedVertexList(); // Iterate over and render each of the polygons in the list. for (unsigned int i = 0; i < _polygonList.size(); i++) { Polygon3D poly = _polygonList[i]; if (poly.GetBackfacing() == true) continue; Vertex v1 = _vertexList[poly.GetVertexIndex(0)]; Vertex v2 = _vertexList[poly.GetVertexIndex(1)]; Vertex v3 = _vertexList[poly.GetVertexIndex(2)]; // Fill the polygon using the polygons colour. FillPolygonShaded(v1, v2, v3, poly.GetColor()); } }
// Draws the given model in wireframe mode. void Rasterizer::DrawWireFrame(Model3D& model) { std::vector<Polygon3D> _polygonList = model.GetPolygonList(); std::vector<Vertex> _vertexList = model.GetTransformedVertexList(); // Iterate over and render each of the polygons in the list. for (unsigned int i = 0; i < _polygonList.size(); i++) { Polygon3D poly = _polygonList[i]; if (poly.GetBackfacing() == true) continue; Vertex v1 = _vertexList[poly.GetVertexIndex(0)]; Vertex v2 = _vertexList[poly.GetVertexIndex(1)]; Vertex v3 = _vertexList[poly.GetVertexIndex(2)]; // Draw a line between each of the vertexs in the polygon. DrawLine(v1.GetX(), v1.GetY(), v2.GetX(), v2.GetY()); DrawLine(v2.GetX(), v2.GetY(), v3.GetX(), v3.GetY()); DrawLine(v1.GetX(), v1.GetY(), v3.GetX(), v3.GetY()); _polygonsRendered++; } }
bool MD2Loader::LoadModel(const char* filename, Model3D& model, const char* textureFilename, const char* normalMapTextureFilename) { ifstream file; // Try to open MD2 file file.open( filename, ios::in | ios::binary ); if(file.fail()) { return false; } // Read file header Md2Header header; file.read( reinterpret_cast<char*>(&header), sizeof( Md2Header ) ); // Verify that this is a MD2 file (check for the magic number and version number) if( (header.indent != MD2_IDENT) && (header.version != MD2_VERSION) ) { // This is not a MD2 model file.close(); return false; } // Allocate the memory we need Md2Triangle* triangles = new Md2Triangle[header.numTriangles]; // We are only interested in the first frame BYTE* frameBuffer = new BYTE[ header.frameSize ]; Md2Frame* frame = reinterpret_cast<Md2Frame*>(frameBuffer); Md2TexCoord* texCoords = new Md2TexCoord[header.numTexCoords]; // Read polygon data... file.seekg( header.offsetTriangles, ios::beg ); file.read( reinterpret_cast<char*>(triangles), sizeof(Md2Triangle) * header.numTriangles ); // 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*>(texCoords), sizeof(Md2TexCoord) * header.numTexCoords ); // Close the file 2.0517745e-038 file.close(); //---------------------------------------------------------------------------------------------- // Initialize model textures. bool bHasTexture = false; // Attempt to load texture if ( textureFilename != 0 ) { BYTE* pTexture = new BYTE[header.skinWidth * header.skinHeight]; Gdiplus::Color* pPalette = new Gdiplus::Color[256]; bHasTexture = LoadPCX(textureFilename, pTexture, pPalette, &header); if ( !bHasTexture ) { delete(pTexture); delete(pPalette); } else { model.SetTexture(pTexture, pPalette, header.skinWidth); } } // Attempt to load normal map texture if ( normalMapTextureFilename != 0 ) { BYTE* pTexture = new BYTE[header.skinWidth * header.skinHeight]; Gdiplus::Color* pPalette = new Gdiplus::Color[256]; bool valid = LoadPCX(normalMapTextureFilename, pTexture, pPalette, &header); if (!valid) { delete(pTexture); delete(pPalette); } else { model.SetNormalMapTexture(pTexture, pPalette, header.skinWidth); } } // Polygon array initialization for ( int i = 0; i < header.numTriangles; ++i ) { // TODO - Put your own code here to create a new Polygon and store it in your list // // The following are the expressions you need to access each of the indexes into the list of vertices: // // Index 0: triangles[i].vertexIndex[0] // Index 1: triangles[i].vertexIndex[1] // Index 2: triangles[i].vertexIndex[2] Polygon3D newPoly = Polygon3D(triangles[i].vertexIndex[0], triangles[i].vertexIndex[1], triangles[i].vertexIndex[2]); newPoly.SetUVIndex(0, triangles[i].uvIndex[0]); newPoly.SetUVIndex(1, triangles[i].uvIndex[1]); newPoly.SetUVIndex(2, triangles[i].uvIndex[2]); model.GetPolygonList().push_back(newPoly); } // Vertex array initialization for( int i = 0; i < header.numVertices; ++i ) { // TODO - Put your own code here to create a new Vertex and store it in your list // // The following are the expressions you need to access each of the co-ordinates. // // X co-ordinate: frame->verts[i].v[0] * frame->scale[0]) + frame->translate[0] // Y co-ordinate: frame->verts[i].v[2] * frame->scale[2]) + frame->translate[2] // Z co-ordinate: frame->verts[i].v[1] * frame->scale[1]) + frame->translate[1] // // NOTE: We have to swap Y and Z over because Z is up in MD2 and we have Y as up-axis float x = (frame->verts[i].v[0] * frame->scale[0]) + frame->translate[0]; float y = (frame->verts[i].v[2] * frame->scale[2]) + frame->translate[2]; float z = (frame->verts[i].v[1] * frame->scale[1]) + frame->translate[1]; Vertex vert = Vertex(x, y, z, 1.0f, Gdiplus::Color::Black, Vector3D(0,0,0), 0); model.GetVertexList().push_back(vert); } // Load UV coordinates if (bHasTexture) { for (int i = 0; i < header.numTexCoords; i++) { short u = texCoords[i].texCoord[0]; short v = texCoords[i].texCoord[1]; UVCoordinate uvCoord; uvCoord.U = u; uvCoord.V = v; model.GetUVCoordinateList().push_back(uvCoord); } } // Rebuild model lists. model.RebuildTransformedVerticesList(); // Free dynamically allocated memory delete [] triangles; // NOTE: this is 'array' delete. Must be sure to use this triangles = 0; delete [] frameBuffer; frameBuffer = 0; frame = 0; delete [] texCoords; texCoords = 0; return true; }