public void Render() { if ( indices == null ) return; // use a GlList for performance if (glListNo >= 0) { Gl.glCallList(glListNo); return; } // first run we create the glList and manually render our entity glListNo = Gl.glGenLists(1); Gl.glNewList(glListNo, Gl.GL_COMPILE); // some 3ds files have no material faces, so we just draw all the faces bool noMaterials = materialFaces.Count == 0; if (noMaterials) { MaterialFaces m = new MaterialFaces(); m.Material = new Material(); materialFaces.Add(m); } foreach (MaterialFaces m in materialFaces) { Material material = m.Material; // set up light properties Gl.glMaterialfv (Gl.GL_FRONT_AND_BACK, Gl.GL_AMBIENT, material.Ambient); Gl.glMaterialfv (Gl.GL_FRONT_AND_BACK, Gl.GL_DIFFUSE, material.Diffuse); Gl.glMaterialfv (Gl.GL_FRONT_AND_BACK, Gl.GL_SPECULAR, material.Specular); Gl.glMaterialf (Gl.GL_FRONT_AND_BACK, Gl.GL_SHININESS, material.Shininess); // if we have a texture, bind it if (material.TextureId >= 0 ) { Gl.glBindTexture ( Gl.GL_TEXTURE_2D, material.TextureId ); Gl.glEnable( Gl.GL_TEXTURE_2D ); } // Draw every triangle in the entity, it's normal, and it's material (if exists) Gl.glBegin ( Gl.GL_TRIANGLES); //foreach ( Triangle tri in indices ) for (int ii = 0; ii < (noMaterials ? indices.Length : m.Faces.Length); ii++) { Triangle tri = noMaterials ? indices[ii] : indices[m.Faces[ii]]; // Vertex 1 if (normalized) Gl.glNormal3d ( normals[tri.Vertex1].X, normals[tri.Vertex1].Y, normals[tri.Vertex1].Z ); if ( material.TextureId >= 0 ) Gl.glTexCoord2f ( texcoords [ tri.Vertex1 ].U, texcoords [ tri.Vertex1 ].V); Gl.glVertex3d ( vertices[tri.Vertex1].X, vertices[tri.Vertex1].Y, vertices[tri.Vertex1].Z ); // Vertex 2 if (normalized) Gl.glNormal3d ( normals[tri.Vertex2].X, normals[tri.Vertex2].Y, normals[tri.Vertex2].Z ); if ( material.TextureId >= 0 ) Gl.glTexCoord2f ( texcoords [ tri.Vertex2 ].U, texcoords [ tri.Vertex2 ].V); Gl.glVertex3d ( vertices[tri.Vertex2].X, vertices[tri.Vertex2].Y, vertices[tri.Vertex2].Z ); // Vertex 3 if (normalized) Gl.glNormal3d ( normals[tri.Vertex3].X, normals[tri.Vertex3].Y, normals[tri.Vertex3].Z ); if ( material.TextureId >= 0 ) Gl.glTexCoord2f( texcoords [ tri.Vertex3 ].U, texcoords [ tri.Vertex3 ].V); Gl.glVertex3d ( vertices[tri.Vertex3].X, vertices[tri.Vertex3].Y, vertices[tri.Vertex3].Z ); } Gl.glEnd(); } Gl.glDisable( Gl.GL_TEXTURE_2D ); Gl.glEndList(); }
Entity ProcessObjectChunk(ThreeDSChunk chunk, Entity e) { while (chunk.BytesRead < chunk.Length) { ThreeDSChunk child = new ThreeDSChunk(reader); switch ((Groups)child.ID) { case Groups.C_OBJECT_MESH: ProcessObjectChunk(child, e); break; case Groups.C_OBJECT_VERTICES: e.vertices = ReadVertices(child); break; case Groups.C_OBJECT_FACES: e.indices = ReadIndices(child); if (child.BytesRead < child.Length) { ProcessObjectChunk(child, e); } break; case Groups.C_OBJECT_MATERIAL: string name2 = ProcessString(child); Console.WriteLine(" Uses Material: {0}", name2); Material mat; if (materials.TryGetValue(name2, out mat)) { //e.material = mat; MaterialFaces m = new MaterialFaces(); m.Material = mat; int nfaces = reader.ReadUInt16(); child.BytesRead += 2; //Console.WriteLine ( nfaces ); m.Faces = new UInt16[nfaces]; for (int ii = 0; ii < nfaces; ii++) { //Console.Write ( reader.ReadUInt16 () + " " ); m.Faces[ii] = reader.ReadUInt16(); child.BytesRead += 2; } e.MaterialFaces.Add(m); } else { Console.WriteLine(" Warning: Material '{0}' not found. ", name2); //throw new Exception ( "Material not found!" ); SkipChunk(child); } break; case Groups.C_OBJECT_UV: int cnt = reader.ReadUInt16(); child.BytesRead += 2; Console.WriteLine(" TexCoords: {0}", cnt); e.texcoords = new TexCoord [cnt]; for (int ii = 0; ii < cnt; ii++) { e.texcoords [ii] = new TexCoord(reader.ReadSingle(), reader.ReadSingle()); } child.BytesRead += (cnt * (4 * 2)); break; default: SkipChunk(child); break; } chunk.BytesRead += child.BytesRead; //Console.WriteLine ( " ID: {0} Length: {1} Read: {2}", chunk.ID.ToString("x"), chunk.Length , chunk.BytesRead ); } return(e); }
Entity ProcessObjectChunk( ThreeDSChunk chunk, Entity e ) { while ( chunk.BytesRead < chunk.Length ) { ThreeDSChunk child = new ThreeDSChunk ( reader ); switch ((Groups) child.ID) { case Groups.C_OBJECT_MESH: ProcessObjectChunk ( child , e ); break; case Groups.C_OBJECT_VERTICES: e.vertices = ReadVertices ( child ); break; case Groups.C_OBJECT_FACES: e.indices = ReadIndices ( child ); if ( child.BytesRead < child.Length ) ProcessObjectChunk ( child, e ); break; case Groups.C_OBJECT_MATERIAL: string name2 = ProcessString ( child ); Console.WriteLine ( " Uses Material: {0}", name2 ); Material mat; if ( materials.TryGetValue ( name2, out mat ) ) { //e.material = mat; MaterialFaces m = new MaterialFaces(); m.Material = mat; int nfaces = reader.ReadUInt16 (); child.BytesRead += 2; //Console.WriteLine ( nfaces ); m.Faces = new UInt16[nfaces]; for ( int ii=0; ii<nfaces; ii++) { //Console.Write ( reader.ReadUInt16 () + " " ); m.Faces[ii] = reader.ReadUInt16 (); child.BytesRead += 2; } e.MaterialFaces.Add(m); } else { Console.WriteLine ( " Warning: Material '{0}' not found. ", name2 ); //throw new Exception ( "Material not found!" ); SkipChunk ( child ); } break; case Groups.C_OBJECT_UV: int cnt = reader.ReadUInt16 (); child.BytesRead += 2; Console.WriteLine ( " TexCoords: {0}", cnt ); e.texcoords = new TexCoord [ cnt ]; for ( int ii=0; ii<cnt; ii++ ) e.texcoords [ii] = new TexCoord ( reader.ReadSingle (), reader.ReadSingle () ); child.BytesRead += ( cnt * ( 4 * 2 ) ); break; default: SkipChunk ( child ); break; } chunk.BytesRead += child.BytesRead; //Console.WriteLine ( " ID: {0} Length: {1} Read: {2}", chunk.ID.ToString("x"), chunk.Length , chunk.BytesRead ); } return e; }
public void Render() { if (indices == null) { return; } // use a GlList for performance if (glListNo >= 0) { Gl.glCallList(glListNo); return; } // first run we create the glList and manually render our entity glListNo = Gl.glGenLists(1); Gl.glNewList(glListNo, Gl.GL_COMPILE); // some 3ds files have no material faces, so we just draw all the faces bool noMaterials = materialFaces.Count == 0; if (noMaterials) { MaterialFaces m = new MaterialFaces(); m.Material = new Material(); materialFaces.Add(m); } foreach (MaterialFaces m in materialFaces) { Material material = m.Material; // set up light properties Gl.glMaterialfv(Gl.GL_FRONT_AND_BACK, Gl.GL_AMBIENT, material.Ambient); Gl.glMaterialfv(Gl.GL_FRONT_AND_BACK, Gl.GL_DIFFUSE, material.Diffuse); Gl.glMaterialfv(Gl.GL_FRONT_AND_BACK, Gl.GL_SPECULAR, material.Specular); Gl.glMaterialf(Gl.GL_FRONT_AND_BACK, Gl.GL_SHININESS, material.Shininess); // if we have a texture, bind it if (material.TextureId >= 0) { Gl.glBindTexture(Gl.GL_TEXTURE_2D, material.TextureId); Gl.glEnable(Gl.GL_TEXTURE_2D); } // Draw every triangle in the entity, it's normal, and it's material (if exists) Gl.glBegin(Gl.GL_TRIANGLES); //foreach ( Triangle tri in indices ) for (int ii = 0; ii < (noMaterials ? indices.Length : m.Faces.Length); ii++) { Triangle tri = noMaterials ? indices[ii] : indices[m.Faces[ii]]; // Vertex 1 if (normalized) { Gl.glNormal3d(normals[tri.Vertex1].X, normals[tri.Vertex1].Y, normals[tri.Vertex1].Z); } if (material.TextureId >= 0) { Gl.glTexCoord2f(texcoords [tri.Vertex1].U, texcoords [tri.Vertex1].V); } Gl.glVertex3d(vertices[tri.Vertex1].X, vertices[tri.Vertex1].Y, vertices[tri.Vertex1].Z); // Vertex 2 if (normalized) { Gl.glNormal3d(normals[tri.Vertex2].X, normals[tri.Vertex2].Y, normals[tri.Vertex2].Z); } if (material.TextureId >= 0) { Gl.glTexCoord2f(texcoords [tri.Vertex2].U, texcoords [tri.Vertex2].V); } Gl.glVertex3d(vertices[tri.Vertex2].X, vertices[tri.Vertex2].Y, vertices[tri.Vertex2].Z); // Vertex 3 if (normalized) { Gl.glNormal3d(normals[tri.Vertex3].X, normals[tri.Vertex3].Y, normals[tri.Vertex3].Z); } if (material.TextureId >= 0) { Gl.glTexCoord2f(texcoords [tri.Vertex3].U, texcoords [tri.Vertex3].V); } Gl.glVertex3d(vertices[tri.Vertex3].X, vertices[tri.Vertex3].Y, vertices[tri.Vertex3].Z); } Gl.glEnd(); } Gl.glDisable(Gl.GL_TEXTURE_2D); Gl.glEndList(); }