void Viewer::renderModel() { // get the renderer of the model CalRenderer *pCalRenderer; pCalRenderer = m_calModel->getRenderer(); // begin the rendering loop if(!pCalRenderer->beginRendering()) return; m_VBCursor=0; m_IBCursor=0; m_TBCursor=0; m_TCBCursor=0; DWORD dwVBLockFlags=D3DLOCK_NOOVERWRITE; DWORD dwIBLockFlags=D3DLOCK_NOOVERWRITE; DWORD dwTBLockFlags=D3DLOCK_NOOVERWRITE; DWORD dwTCBLockFlags=D3DLOCK_NOOVERWRITE; g_pD3DDevice->SetStreamSource( 0, m_pVB, 0, sizeof(VERTEX) ); g_pD3DDevice->SetStreamSource( 1, NULL , 0, 0 ); g_pD3DDevice->SetStreamSource( 2, NULL , 0, 0 ); g_pD3DDevice->SetFVF(D3DFVF_VERTEX); // get the number of meshes int meshCount; meshCount = pCalRenderer->getMeshCount(); // render all meshes of the model int meshId; for(meshId = 0; meshId < meshCount; meshId++) { // get the number of submeshes int submeshCount; submeshCount = pCalRenderer->getSubmeshCount(meshId); // render all submeshes of the mesh int submeshId; for(submeshId = 0; submeshId < submeshCount; submeshId++) { // select mesh and submesh for further data access if(pCalRenderer->selectMeshSubmesh(meshId, submeshId)) { D3DMATERIAL9 mat; unsigned char meshColor[4]; pCalRenderer->getAmbientColor(&meshColor[0]); mat.Ambient.r=meshColor[0]/255.0f;mat.Ambient.g=meshColor[1]/255.0f; mat.Ambient.b=meshColor[2]/255.0f;mat.Ambient.a=meshColor[3]/255.0f; pCalRenderer->getDiffuseColor(&meshColor[0]); mat.Diffuse.r=meshColor[0]/255.0f;mat.Diffuse.g=meshColor[1]/255.0f; mat.Diffuse.b=meshColor[2]/255.0f;mat.Diffuse.a=meshColor[3]/255.0f; pCalRenderer->getSpecularColor(&meshColor[0]); mat.Specular.r=meshColor[0]/255.0f;mat.Specular.g=meshColor[1]/255.0f; mat.Specular.b=meshColor[2]/255.0f;mat.Specular.a=meshColor[3]/255.0f; mat.Power=0.0f; mat.Emissive.r=0.0f;mat.Emissive.g=0.0f;mat.Emissive.b=0.0f;mat.Emissive.a=0.0f; g_pD3DDevice->SetMaterial(&mat); if(m_VBCursor+ pCalRenderer->getVertexCount()>=30000) { m_VBCursor=0; dwVBLockFlags=D3DLOCK_DISCARD; } if(m_TBCursor+ pCalRenderer->getVertexCount()>=30000) { m_TBCursor=0; dwTBLockFlags=D3DLOCK_DISCARD; } if(m_TCBCursor+ pCalRenderer->getVertexCount()>=30000) { m_TCBCursor=0; dwTCBLockFlags=D3DLOCK_DISCARD; } if(m_IBCursor + pCalRenderer->getFaceCount()>=50000) { m_IBCursor=0; dwIBLockFlags=D3DLOCK_DISCARD; } // Get vertexbuffer from the model VERTEX *pVertices; m_pVB->Lock(m_VBCursor*sizeof(VERTEX), pCalRenderer->getVertexCount()*sizeof(VERTEX), (void**)&pVertices, dwVBLockFlags); int vertexCount = pCalRenderer->getVerticesNormalsAndTexCoords(&pVertices->pos.x); m_pVB->Unlock(); CalIndex *meshFaces; m_pIB->Lock(m_IBCursor* 3*sizeof(CalIndex), pCalRenderer->getFaceCount()*3* sizeof(CalIndex), (void**)&meshFaces,dwIBLockFlags); int faceCount = pCalRenderer->getFaces(meshFaces); m_pIB->Unlock(); if(pCalRenderer->getMapCount()==2 && m_bBump && pCalRenderer->isTangentsEnabled(1)) { D3DXVECTOR4 *pTangents; m_pTB->Lock(m_TBCursor*sizeof(D3DXVECTOR4), pCalRenderer->getVertexCount()*sizeof(D3DXVECTOR4), (void**)&pTangents, dwTBLockFlags); pCalRenderer->getTangentSpaces(1,(float*)pTangents); m_pTB->Unlock(); D3DXVECTOR2 *pTexCoords; m_pTCB->Lock(m_TCBCursor*sizeof(D3DXVECTOR2), pCalRenderer->getVertexCount()*sizeof(D3DXVECTOR2), (void**)&pTexCoords, dwTCBLockFlags); pCalRenderer->getTextureCoordinates(1,(float*)pTexCoords); m_pTCB->Unlock(); // Rem: // We need to swap the map, texture coord are also swapped in the vertex shader g_pD3DDevice->SetTexture(0,(LPDIRECT3DTEXTURE9)pCalRenderer->getMapUserData(1)); g_pD3DDevice->SetTexture(1,(LPDIRECT3DTEXTURE9)pCalRenderer->getMapUserData(0)); g_pD3DDevice->SetTextureStageState(0,D3DTSS_COLORARG1 ,D3DTA_TEXTURE); g_pD3DDevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_DOTPRODUCT3); g_pD3DDevice->SetTextureStageState(0,D3DTSS_COLORARG2 ,D3DTA_DIFFUSE); g_pD3DDevice->SetTextureStageState(1,D3DTSS_COLORARG1 ,D3DTA_TEXTURE); g_pD3DDevice->SetTextureStageState(1,D3DTSS_COLOROP,D3DTOP_MODULATE); g_pD3DDevice->SetTextureStageState(1,D3DTSS_COLORARG2 ,D3DTA_CURRENT); // Uncomment this if you want to use the diffuse color of // The material, but I will not work on a geforce-class hardware /* g_pD3DDevice->SetTextureStageState(2,D3DTSS_COLORARG1 ,D3DTA_CURRENT); g_pD3DDevice->SetTextureStageState(2,D3DTSS_COLOROP,D3DTOP_MODULATE); g_pD3DDevice->SetTextureStageState(2,D3DTSS_COLORARG2 ,D3DTA_SPECULAR); */ g_pD3DDevice->SetStreamSource( 0, m_pVB, 0, sizeof(VERTEX) ); g_pD3DDevice->SetStreamSource( 1, m_pTB,0, sizeof(D3DXVECTOR4) ); g_pD3DDevice->SetStreamSource( 2, m_pTCB,0, sizeof(D3DXVECTOR2) ); g_pD3DDevice->SetVertexShader(m_pVS); g_pD3DDevice->SetVertexDeclaration(m_pVertexDeclaration); g_pD3DDevice->SetRenderState( D3DRS_LIGHTING, FALSE ); g_pD3DDevice->SetVertexShaderConstantF(9, (float*)&mat.Diffuse, 1 ); g_pD3DDevice->SetVertexShaderConstantF(10, (float*)&mat.Specular, 1 ); g_pD3DDevice->SetVertexShaderConstantF(11, (float*)&mat.Ambient, 1 ); } if(pCalRenderer->getMapCount()==1 || ( (!m_bBump || !pCalRenderer->isTangentsEnabled(1)) && pCalRenderer->getMapCount()==2)) { g_pD3DDevice->SetTexture(0,(LPDIRECT3DTEXTURE9)pCalRenderer->getMapUserData(0)); g_pD3DDevice->SetTexture(1,NULL); g_pD3DDevice->SetTextureStageState(0,D3DTSS_COLORARG1 ,D3DTA_CURRENT); g_pD3DDevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_MODULATE); g_pD3DDevice->SetTextureStageState(0,D3DTSS_COLORARG2 ,D3DTA_TEXTURE); g_pD3DDevice->SetTextureStageState(1,D3DTSS_COLOROP,D3DTOP_DISABLE); g_pD3DDevice->SetStreamSource( 0, m_pVB, 0, sizeof(VERTEX) ); g_pD3DDevice->SetStreamSource( 1, NULL,0, 0 ); g_pD3DDevice->SetStreamSource( 2, NULL,0, 0 ); g_pD3DDevice->SetVertexShader(NULL); g_pD3DDevice->SetVertexDeclaration(NULL); g_pD3DDevice->SetFVF(D3DFVF_VERTEX); g_pD3DDevice->SetRenderState( D3DRS_LIGHTING, TRUE ); } if(pCalRenderer->getMapCount()==0) { g_pD3DDevice->SetTexture(0,NULL); g_pD3DDevice->SetTexture(1,NULL); g_pD3DDevice->SetTextureStageState(0,D3DTSS_COLORARG1 ,D3DTA_CURRENT); g_pD3DDevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_SELECTARG1); g_pD3DDevice->SetTextureStageState(1,D3DTSS_COLOROP,D3DTOP_DISABLE); g_pD3DDevice->SetStreamSource( 1, NULL,0, 0 ); g_pD3DDevice->SetStreamSource( 2, NULL,0, 0 ); g_pD3DDevice->SetStreamSource( 0, m_pVB, 0, sizeof(VERTEX) ); g_pD3DDevice->SetVertexShader(NULL); g_pD3DDevice->SetVertexDeclaration(NULL); g_pD3DDevice->SetFVF(D3DFVF_VERTEX); g_pD3DDevice->SetRenderState( D3DRS_LIGHTING, TRUE ); } g_pD3DDevice->SetIndices(m_pIB); g_pD3DDevice->SetRenderState(D3DRS_CULLMODE,D3DCULL_NONE); g_pD3DDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, m_VBCursor, 0, vertexCount, m_IBCursor*3, faceCount ); m_VBCursor+=vertexCount; m_TBCursor+=vertexCount; m_TCBCursor+=vertexCount; m_IBCursor+=faceCount; dwIBLockFlags=D3DLOCK_NOOVERWRITE; dwTBLockFlags=D3DLOCK_NOOVERWRITE; dwTCBLockFlags=D3DLOCK_NOOVERWRITE; dwVBLockFlags=D3DLOCK_NOOVERWRITE; } } } // end the rendering pCalRenderer->endRendering(); }
void Viewer::renderModel() { // get the renderer of the model CalRenderer *pCalRenderer; pCalRenderer = m_calModel->getRenderer(); // begin the rendering loop if(!pCalRenderer->beginRendering()) return; m_VBCursor=0; m_IBCursor=0; DWORD dwVBLockFlags=D3DLOCK_NOOVERWRITE; DWORD dwIBLockFlags=D3DLOCK_NOOVERWRITE; g_pD3DDevice->SetStreamSource( 0, m_pVB, 0, sizeof(VERTEX) ); g_pD3DDevice->SetFVF(D3DFVF_VERTEX); g_pD3DDevice->SetIndices(m_pIB); // get the number of meshes int meshCount; meshCount = pCalRenderer->getMeshCount(); // render all meshes of the model int meshId; for(meshId = 0; meshId < meshCount; meshId++) { // get the number of submeshes int submeshCount; submeshCount = pCalRenderer->getSubmeshCount(meshId); // render all submeshes of the mesh int submeshId; for(submeshId = 0; submeshId < submeshCount; submeshId++) { // select mesh and submesh for further data access if(pCalRenderer->selectMeshSubmesh(meshId, submeshId)) { D3DMATERIAL9 mat; unsigned char meshColor[4]; pCalRenderer->getAmbientColor(&meshColor[0]); mat.Ambient.r=meshColor[0]/255.0f;mat.Ambient.g=meshColor[1]/255.0f; mat.Ambient.b=meshColor[2]/255.0f;mat.Ambient.a=meshColor[3]/255.0f; pCalRenderer->getDiffuseColor(&meshColor[0]); mat.Diffuse.r=meshColor[0]/255.0f;mat.Diffuse.g=meshColor[1]/255.0f; mat.Diffuse.b=meshColor[2]/255.0f;mat.Diffuse.a=meshColor[3]/255.0f; pCalRenderer->getSpecularColor(&meshColor[0]); mat.Specular.r=meshColor[0]/255.0f;mat.Specular.g=meshColor[1]/255.0f; mat.Specular.b=meshColor[2]/255.0f;mat.Specular.a=meshColor[3]/255.0f; mat.Power=0.0f; mat.Emissive.r=0.0f;mat.Emissive.g=0.0f;mat.Emissive.b=0.0f;mat.Emissive.a=0.0f; g_pD3DDevice->SetMaterial(&mat); if(m_VBCursor+ pCalRenderer->getVertexCount()>=30000) { m_VBCursor=0; dwVBLockFlags=D3DLOCK_DISCARD; } if(m_IBCursor + pCalRenderer->getFaceCount()>=50000) { m_IBCursor=0; dwIBLockFlags=D3DLOCK_DISCARD; } // Get vertexbuffer from the model VERTEX *pVertices; m_pVB->Lock(m_VBCursor*sizeof(VERTEX), pCalRenderer->getVertexCount()*sizeof(VERTEX), (void**)&pVertices, dwVBLockFlags); int vertexCount = pCalRenderer->getVerticesNormalsAndTexCoords(&pVertices->pos.x); m_pVB->Unlock(); CalIndex *meshFaces; int faceCount; m_pIB->Lock(m_IBCursor* 3*sizeof(CalIndex), pCalRenderer->getFaceCount()*3* sizeof(CalIndex), (void**)&meshFaces,dwIBLockFlags); faceCount = pCalRenderer->getFaces(meshFaces); m_pIB->Unlock(); g_pD3DDevice->SetRenderState(D3DRS_CULLMODE,D3DCULL_NONE); g_pD3DDevice->SetTexture(0,(LPDIRECT3DTEXTURE9)pCalRenderer->getMapUserData(0)); g_pD3DDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, m_VBCursor, 0, vertexCount, m_IBCursor*3, faceCount ); m_VBCursor+=vertexCount; m_IBCursor+=faceCount; dwIBLockFlags=D3DLOCK_NOOVERWRITE; dwVBLockFlags=D3DLOCK_NOOVERWRITE; } } } // end the rendering pCalRenderer->endRendering(); }
void Model::renderMesh(bool bWireframe, bool bLight) { // get the renderer of the model CalRenderer *pCalRenderer; pCalRenderer = m_calModel->getRenderer(); // begin the rendering loop if(!pCalRenderer->beginRendering()) return; // set wireframe mode if necessary if(bWireframe) { glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); } // set the global OpenGL states glEnable(GL_DEPTH_TEST); glShadeModel(GL_SMOOTH); // set the lighting mode if necessary if(bLight) { glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); } // we will use vertex arrays, so enable them glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); // get the number of meshes int meshCount; meshCount = pCalRenderer->getMeshCount(); // render all meshes of the model int meshId; for(meshId = 0; meshId < meshCount; meshId++) { // get the number of submeshes int submeshCount; submeshCount = pCalRenderer->getSubmeshCount(meshId); // render all submeshes of the mesh int submeshId; for(submeshId = 0; submeshId < submeshCount; submeshId++) { // select mesh and submesh for further data access if(pCalRenderer->selectMeshSubmesh(meshId, submeshId)) { unsigned char meshColor[4]; GLfloat materialColor[4]; // set the material ambient color pCalRenderer->getAmbientColor(&meshColor[0]); materialColor[0] = meshColor[0] / 255.0f; materialColor[1] = meshColor[1] / 255.0f; materialColor[2] = meshColor[2] / 255.0f; materialColor[3] = meshColor[3] / 255.0f; glMaterialfv(GL_FRONT, GL_AMBIENT, materialColor); // set the material diffuse color pCalRenderer->getDiffuseColor(&meshColor[0]); materialColor[0] = meshColor[0] / 255.0f; materialColor[1] = meshColor[1] / 255.0f; materialColor[2] = meshColor[2] / 255.0f; materialColor[3] = meshColor[3] / 255.0f; glMaterialfv(GL_FRONT, GL_DIFFUSE, materialColor); // set the vertex color if we have no lights if(!bLight) { glColor4fv(materialColor); } // set the material specular color pCalRenderer->getSpecularColor(&meshColor[0]); materialColor[0] = meshColor[0] / 255.0f; materialColor[1] = meshColor[1] / 255.0f; materialColor[2] = meshColor[2] / 255.0f; materialColor[3] = meshColor[3] / 255.0f; glMaterialfv(GL_FRONT, GL_SPECULAR, materialColor); // set the material shininess factor float shininess; shininess = 50.0f; //TODO: pCalRenderer->getShininess(); glMaterialfv(GL_FRONT, GL_SHININESS, &shininess); // get the transformed vertices of the submesh static float meshVertices[30000][3]; int vertexCount; vertexCount = pCalRenderer->getVertices(&meshVertices[0][0]); // get the transformed normals of the submesh static float meshNormals[30000][3]; pCalRenderer->getNormals(&meshNormals[0][0]); // get the texture coordinates of the submesh static float meshTextureCoordinates[30000][2]; int textureCoordinateCount; textureCoordinateCount = pCalRenderer->getTextureCoordinates(0, &meshTextureCoordinates[0][0]); // get the faces of the submesh static CalIndex meshFaces[50000][3]; int faceCount; faceCount = pCalRenderer->getFaces(&meshFaces[0][0]); // set the vertex and normal buffers glVertexPointer(3, GL_FLOAT, 0, &meshVertices[0][0]); glNormalPointer(GL_FLOAT, 0, &meshNormals[0][0]); // set the texture coordinate buffer and state if necessary if((pCalRenderer->getMapCount() > 0) && (textureCoordinateCount > 0)) { glEnable(GL_TEXTURE_2D); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnable(GL_COLOR_MATERIAL); // set the texture id we stored in the map user data glBindTexture(GL_TEXTURE_2D, (GLuint)pCalRenderer->getMapUserData(0)); // set the texture coordinate buffer glTexCoordPointer(2, GL_FLOAT, 0, &meshTextureCoordinates[0][0]); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); } // draw the submesh if(sizeof(CalIndex)==2) glDrawElements(GL_TRIANGLES, faceCount * 3, GL_UNSIGNED_SHORT, &meshFaces[0][0]); else glDrawElements(GL_TRIANGLES, faceCount * 3, GL_UNSIGNED_INT, &meshFaces[0][0]); // disable the texture coordinate state if necessary if((pCalRenderer->getMapCount() > 0) && (textureCoordinateCount > 0)) { glDisable(GL_COLOR_MATERIAL); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisable(GL_TEXTURE_2D); } // DEBUG-CODE ////////////////////////////////////////////////////////////////// /* glBegin(GL_LINES); glColor3f(1.0f, 1.0f, 1.0f); int vertexId; for(vertexId = 0; vertexId < vertexCount; vertexId++) { const float scale = 0.3f; glVertex3f(meshVertices[vertexId][0], meshVertices[vertexId][1], meshVertices[vertexId][2]); glVertex3f(meshVertices[vertexId][0] + meshNormals[vertexId][0] * scale, meshVertices[vertexId][1] + meshNormals[vertexId][1] * scale, meshVertices[vertexId][2] + meshNormals[vertexId][2] * scale); } glEnd(); */ //////////////////////////////////////////////////////////////////////////////// } } } // clear vertex array state glDisableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_VERTEX_ARRAY); // reset the lighting mode if(bLight) { glDisable(GL_LIGHTING); glDisable(GL_LIGHT0); } // reset the global OpenGL states glDisable(GL_DEPTH_TEST); // reset wireframe mode if necessary if(bWireframe) { glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } // end the rendering pCalRenderer->endRendering(); }
void CCal3DSceneNode::render() { //----------------------------------------------------------// if ( calModel == 0 ) return; // Make sure there is a model to render //----------------------------------------------------------// video::IVideoDriver* driver = SceneManager->getVideoDriver(); // Get the video driver CalRenderer* renderer = calModel->getRenderer(); // Get the CalRenderer //----------------------------------------------------------// // All we're doing here is form a bridge between the CalRenderer and the IVideoDriver // The CalRenderer gives us data (doesn't draw anything) and IVideoDriver needs that data // Only problem is that we need to convert it to Irrlicht Compatible data // To explain what's going on, this simple diagram should help: // CalRenderer >--GET--> Data >--CONVERT--> Irrlicht Format >--SEND--> IVideoDriver >--DRAW--> .. //----------------------------------------------------------// calModel->getSkeleton()->calculateBoundingBoxes(); // Calculate the bounding box of the skeleton //----------------------------------------------------------// if ( renderer == 0 ) return; // Bail out if no renderer was received if ( !renderer->beginRendering() ) return; // Bail out if renderer encountered an error //----------------------------------------------------------// Move to our position (and rotate/scale) driver->setTransform( video::ETS_WORLD, AbsoluteTransformation ); //----------------------------------------------------------// s32 numMeshes = renderer->getMeshCount(); // Get the number of meshes we need to draw for ( s32 meshId = 0; meshId < numMeshes; meshId++ ) // Loop for every mesh { //--------------------------------------------------------// s32 numSubMeshes = renderer->getSubmeshCount(meshId); // Get the number of submeshes for ( s32 subId = 0; subId < numSubMeshes; subId++ ) // Loop for every submesh { if ( !renderer->selectMeshSubmesh(meshId, subId) ) // Select the current mesh and submesh { continue; // Skip this submesh if it failed } //------------------------------------------------------// if ( !OverrideMaterial ) // Should we use Cal3D's material? { u8 meshColor [4]; // Color stored in RGBA format // Irrlicht wants it in ARGB format renderer->getAmbientColor( meshColor ); // Get the ambient color Material.AmbientColor.setRed( meshColor[0] ); // Set the red component Material.AmbientColor.setGreen( meshColor[1] ); // Set the green component Material.AmbientColor.setBlue( meshColor[2] ); // Set the blue component Material.AmbientColor.setAlpha( meshColor[3] ); // Set the alpha component renderer->getDiffuseColor( meshColor ); // Get the diffuse color Material.DiffuseColor.setRed( meshColor[0] ); // Set the red component Material.DiffuseColor.setGreen( meshColor[1] ); // Set the green component Material.DiffuseColor.setBlue( meshColor[2] ); // Set the blue component Material.DiffuseColor.setAlpha( meshColor[3] ); // Set the alpha component renderer->getSpecularColor( meshColor ); // Get the specular color Material.SpecularColor.setRed( meshColor[0] ); // Set the red component Material.SpecularColor.setGreen( meshColor[1] ); // Set the green component Material.SpecularColor.setBlue( meshColor[2] ); // Set the blue component Material.SpecularColor.setAlpha( meshColor[3] ); // Set the alpha component Material.Shininess = renderer->getShininess(); // Set the shininess factor if ( renderer->getMapCount() >= 1 ) { // Get the irrlicht texture from user data Material.setTexture(0, (video::ITexture*)renderer->getMapUserData(0)); } } //------------------------------------------------------// s32 vertexCount = renderer->getVertexCount(); // Get the number of vertices if (vertexCount == 0) continue; // Skip if the mesh is empty static core::array<core::vector3df> vertexBuffer; // Use a core::array to support msvc vertexBuffer.set_used( vertexCount ); // Make room for the vertex coordinates renderer->getVertices( &vertexBuffer[0].X ); // Copy the vertices into the buffer //------------------------------------------------------// static core::array<core::vector3df> normalBuffer; normalBuffer.set_used( vertexCount ); // Buffer for the vertex normals renderer->getNormals( &normalBuffer[0].X ); // Copy the normals to the buffer //------------------------------------------------------// static core::array<core::vector2df> texCoordBuffer; texCoordBuffer.set_used( vertexCount ); // Buffer for the vertex texture coordinates renderer->getTextureCoordinates( 0, &texCoordBuffer[0].X );// Copy the texture coordinates to the buffer //------------------------------------------------------// s32 faceCount = renderer->getFaceCount(); // Get the number of faces static CalIndex cal_indices[30000000]; renderer->getFaces( cal_indices ); // Copy the face indices to the buffer static core::array<u16> faceBuffer; faceBuffer.set_used( faceCount * 3 ); // Buffer for the face v1,v2,v3 indices for(int i = 0; i < faceCount * 3; ++i) { faceBuffer[i] = cal_indices[i]; } //------------------------------------------------------// static core::array<video::S3DVertex> irrVertexBuffer; irrVertexBuffer.set_used( vertexCount ); // Buffer for the irrlicht vertices for (s32 vert=0; vert<vertexCount; vert++) // Convert all vertices to irrlicht format { // Irrlicht and Cal3D uses different coordinates. Irrlicht's Y points up, where Cal3D's Z points up irrVertexBuffer[vert].Pos.X = vertexBuffer[vert].X; // Set the X coordinate irrVertexBuffer[vert].Pos.Y = vertexBuffer[vert].Y; // Set the Y coordinate (Cal3D's Z coord) irrVertexBuffer[vert].Pos.Z = vertexBuffer[vert].Z; // Set the Z coordinate (Cal3D's Y coord) irrVertexBuffer[vert].Color.set(255,128,128,128); // Vertex colors aren't supported by Cal3D irrVertexBuffer[vert].Normal.X = normalBuffer[vert].X;// Set the X coordinate irrVertexBuffer[vert].Normal.Y = normalBuffer[vert].Y;// Set the Y coordinate (Cal3D's Z coord) irrVertexBuffer[vert].Normal.Z = normalBuffer[vert].Z;// Set the Z coordinate (Cal3D's Y coord) irrVertexBuffer[vert].TCoords.X = texCoordBuffer[vert].X;// Set the X texture coordinate (U) irrVertexBuffer[vert].TCoords.Y = texCoordBuffer[vert].Y;// Set the Y texture coordinate (V) } //------------------------------------------------------// Invert triangle direction for (s32 face=0; face<faceCount; face++) // Irrlicht wants indices in the opposite order { u16 faceA = faceBuffer[face*3]; // Swap first and last vertex index faceBuffer[face*3] = faceBuffer[face*3+2]; // Set the first to the last faceBuffer[face*3+2] = faceA; // And the last to the first } //------------------------------------------------------// Finally! Time to draw everthing Material.BackfaceCulling = false; float k; if(draw_mode != DM_DEFAULT) { video::SMaterial debug_material; debug_material.Wireframe = true; debug_material.BackfaceCulling = false; debug_material.Lighting = false; driver->setMaterial(debug_material); /* so that debug looks good for all sizes of models*/ k = EXTENT_K * BoundingBox.getExtent().getLength(); } else { driver->setMaterial( Material ); } if(draw_mode == DM_DEFAULT) { driver->drawIndexedTriangleList(irrVertexBuffer.const_pointer(), vertexCount, faceBuffer.const_pointer(), faceCount); } else if(draw_mode == DM_WIREFRAME || draw_mode == DM_WIREFRAME_AND_SKELETON) { /* draw faces */ for (s32 face=0; face<faceCount; ++face) { u16 i1, i2, i3; i1 = faceBuffer[face*3+0]; i2 = faceBuffer[face*3+1]; i3 = faceBuffer[face*3+2]; driver->draw3DLine(core::vector3df(vertexBuffer[i1].X, vertexBuffer[i1].Y, vertexBuffer[i1].Z), core::vector3df(vertexBuffer[i2].X, vertexBuffer[i2].Y, vertexBuffer[i2].Z), video::SColor(255,0,0,255)); driver->draw3DLine(core::vector3df(vertexBuffer[i2].X, vertexBuffer[i2].Y, vertexBuffer[i2].Z), core::vector3df(vertexBuffer[i3].X, vertexBuffer[i3].Y, vertexBuffer[i3].Z), video::SColor(255,0,0,255)); driver->draw3DLine(core::vector3df(vertexBuffer[i3].X, vertexBuffer[i3].Y, vertexBuffer[i3].Z), core::vector3df(vertexBuffer[i1].X, vertexBuffer[i1].Y, vertexBuffer[i1].Z), video::SColor(255,0,0,255)); } } if(draw_mode == DM_SKELETON || draw_mode == DM_WIREFRAME_AND_SKELETON) { float lines[1024][2][3]; int num_lines; num_lines = calModel->getSkeleton()->getBoneLines(&lines[0][0][0]); video::S3DVertex vertex; for(int line = 0; line < num_lines; ++line) { driver->draw3DLine(core::vector3df(lines[line][0][0], lines[line][0][1], lines[line][0][2]), core::vector3df(lines[line][1][0], lines[line][1][1], lines[line][1][2]), video::SColor(255,255,0,0)); core::aabbox3df box1(lines[line][0][0]-SKELETON_K*k, lines[line][0][1]-SKELETON_K*k, lines[line][0][2]-SKELETON_K*k, lines[line][0][0]+SKELETON_K*k, lines[line][0][1]+SKELETON_K*k, lines[line][0][2]+SKELETON_K*k); core::aabbox3df box2(lines[line][1][0]-SKELETON_K*k, lines[line][1][1]-SKELETON_K*k, lines[line][1][2]-SKELETON_K*k, lines[line][1][0]+SKELETON_K*k, lines[line][1][1]+SKELETON_K*k, lines[line][1][2]+SKELETON_K*k); driver->draw3DBox(box1, video::SColor(255,0,255,0)); driver->draw3DBox(box2, video::SColor(255,0,255,0)); } } if(draw_bbox) { video::SMaterial debug_material; debug_material.Wireframe = true; debug_material.BackfaceCulling = false; debug_material.Lighting = false; driver->setMaterial(debug_material); driver->draw3DBox(BoundingBox, video::SColor(255,255,0,255)); } if(draw_normals) { k = EXTENT_K * BoundingBox.getExtent().getLength(); video::SMaterial debug_material; debug_material.Wireframe = true; debug_material.BackfaceCulling = false; debug_material.Lighting = false; driver->setMaterial(debug_material); /* draw normals */ for (s32 vert=0; vert<vertexCount; ++vert) { driver->draw3DLine(core::vector3df(vertexBuffer[vert].X, vertexBuffer[vert].Y, vertexBuffer[vert].Z), core::vector3df(vertexBuffer[vert].X + NORMAL_K*k*normalBuffer[vert].X, vertexBuffer[vert].Y + NORMAL_K*k*normalBuffer[vert].Y, vertexBuffer[vert].Z + NORMAL_K*k*normalBuffer[vert].Z), video::SColor(255,0,255,0)); } } } // for subId } // for meshId //----------------------------------------------------------// renderer->endRendering(); // Tell the renderer we are finished now }
void Cal3dModel::renderMesh(bool useTextures, bool useLighting, bool select_mode) { // get the renderer of the model CalRenderer *pCalRenderer = m_calModel->getRenderer(); assert(pCalRenderer != NULL); // We let open gl do this, so no need to do it twice pCalRenderer->setNormalization(false); // begin the rendering loop if (!pCalRenderer->beginRendering()) { // Some kind of error here! return; } // get the number of meshes int meshCount = pCalRenderer->getMeshCount(); int numSubMeshes = 0; for (int i = 0; i < meshCount; ++i) { numSubMeshes += pCalRenderer->getSubmeshCount(i); } m_dos.resize(numSubMeshes); int counter = -1; // render all meshes of the model for(int meshId = 0; meshId < meshCount; ++meshId) { // get the number of submeshes int submeshCount = pCalRenderer->getSubmeshCount(meshId); // render all submeshes of the mesh for(int submeshId = 0; submeshId < submeshCount; ++submeshId) { // select mesh and submesh for further data access if(pCalRenderer->selectMeshSubmesh(meshId, submeshId)) { DynamicObject* dyno = m_dos[++counter]; if (!dyno) { dyno = new DynamicObject(); dyno->init(); dyno->contextCreated(); m_dos[counter] = dyno; // Lets assume this doesn't change static unsigned char meshColor[4]; static float ambient[4]; static float diffuse[4]; static float specular[4]; static float shininess; pCalRenderer->getAmbientColor(&meshColor[0]); ambient[0] = meshColor[0] / 255.0f; ambient[1] = meshColor[1] / 255.0f; ambient[2] = meshColor[2] / 255.0f; ambient[3] = meshColor[3] / 255.0f; dyno->setAmbient(ambient); // set the material diffuse color pCalRenderer->getDiffuseColor(&meshColor[0]); diffuse[0] = meshColor[0] / 255.0f; diffuse[1] = meshColor[1] / 255.0f; diffuse[2] = meshColor[2] / 255.0f; diffuse[3] = 1.0f;//meshColor[3] / 255.0f; dyno->setDiffuse(diffuse); // set the material specular color pCalRenderer->getSpecularColor(&meshColor[0]); specular[0] = meshColor[0] / 255.0f; specular[1] = meshColor[1] / 255.0f; specular[2] = meshColor[2] / 255.0f; specular[3] = meshColor[3] / 255.0f; dyno->setSpecular(specular); dyno->setEmission(0.0f, 0.0f, 0.0f,0.0f); shininess = pCalRenderer->getShininess(); dyno->setShininess(shininess); dyno->getMatrix().rotateZ(-m_rotate / 180.0 * WFMath::Pi); dyno->setState(m_state); dyno->setSelectState(m_select_state); dyno->setUseStencil(m_use_stencil); } // get the transformed vertices of the submesh int vertexCount = pCalRenderer->getVertexCount(); bool realloc = false; float *vertex_ptr, *normal_ptr, *texture_ptr; int textureCoordinateCount = 0; if (vertexCount > dyno->getNumPoints()) { realloc = true; vertex_ptr = dyno->createVertexData(vertexCount * 3); pCalRenderer->getVertices(vertex_ptr); dyno->releaseVertexDataPtr(); normal_ptr = dyno->createNormalData(vertexCount * 3); pCalRenderer->getNormals(normal_ptr); dyno->releaseNormalDataPtr(); } else { vertex_ptr = dyno->getVertexDataPtr(); pCalRenderer->getVertices(vertex_ptr); dyno->releaseVertexDataPtr(); normal_ptr = dyno->getNormalDataPtr(); pCalRenderer->getNormals(normal_ptr); dyno->releaseNormalDataPtr(); } int faceCount = pCalRenderer->getFaceCount(); if (faceCount > 0) { int *face_ptr; if (faceCount > dyno->getNumFaces()) { face_ptr = dyno->createIndices(faceCount * 3); } else { face_ptr = dyno->getIndicesPtr(); } pCalRenderer->getFaces(face_ptr); dyno->releaseIndicesPtr(); dyno->setNumFaces(faceCount); } dyno->setNumPoints(vertexCount); // There are several situations that can happen here. // Model with/without texture coordinates // Model with/without texture maps // Model with/without texture mas name defined // Each model can be a mixture of the above. We want objects with // textures and texture coords. bool mapDataFound = false; std::vector<std::vector<CalCoreSubmesh::TextureCoordinate> > & vectorvectorTextureCoordinate = m_calModel->getVectorMesh()[meshId]->getSubmesh(submeshId)->getCoreSubmesh()->getVectorVectorTextureCoordinate(); // check if the map id is valid if ( vectorvectorTextureCoordinate.size() > 0) { textureCoordinateCount = vectorvectorTextureCoordinate[0].size(); } if((pCalRenderer->getMapCount() > 0) && (textureCoordinateCount > 0)) { for (int i = 0; i < pCalRenderer->getMapCount(); ++i) { MapData *md = reinterpret_cast<MapData*> (pCalRenderer->getMapUserData(i)); if (md) { dyno->setTexture(i, md->textureID, md->textureMaskID); mapDataFound = true; } else { // Can't have a missing texture map between units. break; } } } if (mapDataFound){ if (realloc) { texture_ptr = dyno->createTextureData(vertexCount * 2); textureCoordinateCount = pCalRenderer->getTextureCoordinates(0, texture_ptr); dyno->releaseTextureDataPtr(); } else { texture_ptr = dyno->getTextureDataPtr(); textureCoordinateCount = pCalRenderer->getTextureCoordinates(0, texture_ptr); dyno->releaseTextureDataPtr(); } if (textureCoordinateCount == -1) { // Need to ignore the texture buffer } // assert(textureCoordinateCount == vertexCount); } } } } pCalRenderer->endRendering(); }
void RenderFacesModelSkinned(CModelSkinned* pModelSkinned, int meshId) { CalModel* pCalModel = (CalModel*)pModelSkinned->GetCalModel(); CalRenderer *pCalRenderer = pCalModel->getRenderer(); int submeshCount = pCalRenderer->getSubmeshCount(meshId); for(int submeshId = 0; submeshId < submeshCount; submeshId++) { // select mesh and submesh for further data access if(pCalRenderer->selectMeshSubmesh(meshId, submeshId)) { // get the material colors unsigned char meshColor[4]; GLfloat materialColor[4]; pCalRenderer->getAmbientColor(&meshColor[0]); materialColor[0] = meshColor[0] / 255.0f; materialColor[1] = meshColor[1] / 255.0f; materialColor[2] = meshColor[2] / 255.0f; materialColor[3] = meshColor[3] / 255.0f; // glMaterialfv(GL_FRONT, GL_AMBIENT, &materialColor[0]); pCalRenderer->getDiffuseColor(&meshColor[0]); materialColor[0] = meshColor[0] / 255.0f; materialColor[1] = meshColor[1] / 255.0f; materialColor[2] = meshColor[2] / 255.0f; materialColor[3] = meshColor[3] / 255.0f; // glMaterialfv(GL_FRONT, GL_DIFFUSE, &materialColor[0]); pCalRenderer->getSpecularColor(&meshColor[0]); materialColor[0] = meshColor[0] / 255.0f; materialColor[1] = meshColor[1] / 255.0f; materialColor[2] = meshColor[2] / 255.0f; materialColor[3] = meshColor[3] / 255.0f; // glMaterialfv(GL_FRONT, GL_SPECULAR, &materialColor[0]); // get the material shininess factor float shininess; shininess = pCalRenderer->getShininess(); // glMaterialfv(GL_FRONT, GL_SHININESS, &shininess); // get the transformed vertices of the submesh static float meshVertices[30000][3]; int vertexCount; vertexCount = pCalRenderer->getVertices(&meshVertices[0][0]); // get the transformed normals of the submesh static float meshNormals[30000][3]; pCalRenderer->getNormals(&meshNormals[0][0]); // get the texture coordinates of the submesh // (only for the first map as example, others can be accessed in the same way though) static float meshTextureCoordinates[30000][2]; int textureCoordinateCount; textureCoordinateCount = pCalRenderer->getTextureCoordinates(0, &meshTextureCoordinates[0][0]); // get the stored texture identifier // (only for the first map as example, others can be accessed in the same way though) Cal::UserData textureId; textureId = pCalRenderer->getMapUserData(0); /* set the material, vertex, normal and texture states in the graphic-API here */ // get the faces of the submesh static int meshFaces[50000][3]; int faceCount; faceCount = pCalRenderer->getFaces(&meshFaces[0][0]); /* render the faces with the graphic-API here */ glVertexPointer(3, GL_FLOAT, 0, &meshVertices[0][0]); glNormalPointer(GL_FLOAT, 0, &meshNormals[0][0]); if ( textureCoordinateCount > 0 ) { glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnable(GL_COLOR_MATERIAL); glTexCoordPointer(2, GL_FLOAT, 0, &meshTextureCoordinates[0][0]); } else { _ASSERT(false); pCalRenderer->getDiffuseColor(&meshColor[0]); materialColor[0] = meshColor[0] / 255.0f; materialColor[1] = meshColor[1] / 255.0f; materialColor[2] = meshColor[2] / 255.0f; materialColor[3] = meshColor[3] / 255.0f; glColor3fv(materialColor); } if(sizeof(CalIndex)==2) glDrawElements(GL_TRIANGLES, faceCount * 3, GL_UNSIGNED_SHORT, &meshFaces[0][0]); else glDrawElements(GL_TRIANGLES, faceCount * 3, GL_UNSIGNED_INT, &meshFaces[0][0]); if ( textureCoordinateCount > 0 ) { glDisableClientState(GL_TEXTURE_COORD_ARRAY); // glDisable(GL_TEXTURE_2D); glDisable(GL_COLOR_MATERIAL); } } } }
void CCal3DSceneNode::render() { if ( bInitialized ) { irr::video::IVideoDriver* driver = SceneManager->getVideoDriver(); driver->setTransform( irr::video::ETS_WORLD, AbsoluteTransformation ); irr::video::S3DVertex tmp; irr::scene::SMeshBuffer mb; unsigned char meshColor[4]; // r g b a // get the renderer of the model CalRenderer* pCalRenderer; pCalRenderer = m_calModel->getRenderer(); pCalRenderer->setNormalization( true ); if ( this->DebugDataVisible ) { irr::video::SMaterial mat; mat.Wireframe = false; mat.Lighting = false; driver->setMaterial( mat ); driver->draw3DBox( Box ); CalSkeleton* pCalSkeleton = m_calModel->getSkeleton(); pCalSkeleton->calculateBoundingBoxes(); std::vector<CalBone*>& vectorCoreBone = pCalSkeleton->getVectorBone(); irr::core::aabbox3df b; CalVector p[8]; Vector3 v[8]; for ( size_t boneId = 0; boneId < vectorCoreBone.size(); ++boneId ) { CalBone* bone = vectorCoreBone[boneId]; CalBoundingBox& calBoundingBox = bone->getBoundingBox(); calBoundingBox.computePoints( p ); for ( int i = 0; i < 8; ++i ) { v[i].set( p[i].x, p[i].y, p[i].z ); } driver->setMaterial( mat ); // draw the box driver->draw3DLine( v[0], v[1], irr::video::SColor( 255, 0, 0, 255 ) ); driver->draw3DLine( v[0], v[2], irr::video::SColor( 255, 0, 0, 255 ) ); driver->draw3DLine( v[1], v[3], irr::video::SColor( 255, 0, 0, 255 ) ); driver->draw3DLine( v[2], v[3], irr::video::SColor( 255, 0, 0, 255 ) ); driver->draw3DLine( v[4], v[5], irr::video::SColor( 255, 0, 0, 255 ) ); driver->draw3DLine( v[4], v[6], irr::video::SColor( 255, 0, 0, 255 ) ); driver->draw3DLine( v[5], v[7], irr::video::SColor( 255, 0, 0, 255 ) ); driver->draw3DLine( v[6], v[7], irr::video::SColor( 255, 0, 0, 255 ) ); driver->draw3DLine( v[0], v[4], irr::video::SColor( 255, 0, 0, 255 ) ); driver->draw3DLine( v[1], v[5], irr::video::SColor( 255, 0, 0, 255 ) ); driver->draw3DLine( v[2], v[6], irr::video::SColor( 255, 0, 0, 255 ) ); driver->draw3DLine( v[3], v[7], irr::video::SColor( 255, 0, 0, 255 ) ); //printf("F: %f\n", v[0].X); } } // begin the rendering loop if ( pCalRenderer->beginRendering() ) { // get the number of meshes int meshCount; meshCount = pCalRenderer->getMeshCount(); // render all meshes of the model int meshId; for ( meshId = 0; meshId < meshCount; meshId++ ) { // get the number of submeshes int submeshCount; submeshCount = pCalRenderer->getSubmeshCount( meshId ); // render all submeshes of the mesh int submeshId; for ( submeshId = 0; submeshId < submeshCount; submeshId++ ) { // select mesh and submesh for further data access if ( pCalRenderer->selectMeshSubmesh( meshId, submeshId ) ) { // set the material ambient color pCalRenderer->getAmbientColor( &meshColor[0] ); material.AmbientColor.set( meshColor[3], meshColor[0], meshColor[1], meshColor[2] ); // set the material diffuse color pCalRenderer->getDiffuseColor( &meshColor[0] ); material.DiffuseColor.set( meshColor[3], meshColor[0], meshColor[1], meshColor[2] ); // set the material specular color pCalRenderer->getSpecularColor( &meshColor[0] ); material.SpecularColor.set( meshColor[3], meshColor[0], meshColor[1], meshColor[2] ); // set the material shininess factor material.Shininess = pCalRenderer->getShininess(); // get the transformed vertices of the submesh static float meshVertices[3000][3]; int vertexCount = 0; // TODO: //if (KERNEL.GetTicks() % 3 == 0) //- make lod dependent? vertexCount = pCalRenderer->getVertices( &meshVertices[0][0] ); // get the transformed normals of the submesh static float meshNormals[3000][3]; int normalsCount = 0; // if (KERNEL.GetTicks() % 3 == 0) normalsCount = pCalRenderer->getNormals( &meshNormals[0][0] ); // get the texture coordinates of the submesh static float meshTextureCoordinates[3000][2]; int textureCoordinateCount = 0; textureCoordinateCount = pCalRenderer->getTextureCoordinates( 0, &meshTextureCoordinates[0][0] ); // get the faces of the submesh static CalIndex meshFaces[5000][3]; int faceCount = 0; //if (KERNEL.GetTicks() % 12 == 0) faceCount = pCalRenderer->getFaces( &meshFaces[0][0] ); if ( ( pCalRenderer->getMapCount() > 0 ) && ( textureCoordinateCount > 0 ) ) { irr::video::ITexture* t = static_cast<irr::video::ITexture*>( pCalRenderer->getMapUserData( 0 ) ); material.Texture1 = t; } static S3DVertex vs[5000]; for ( int i = 0; i < vertexCount; i++ ) { vs[i].Pos.set( meshVertices[i][0], meshVertices[i][1], meshVertices[i][2] ); vs[i].Normal.set( meshNormals[i][0], meshNormals[i][1], meshNormals[i][2] ); vs[i].TCoords.set( meshTextureCoordinates[i][0], meshTextureCoordinates[i][1] ); vs[i].Color = irr::video::SColor( 255, 255, 255, 255 ); } static u16 is[5000]; for ( int i = 0; i < faceCount; i += 1 ) { is[i * 3 + 0] = meshFaces[i][0]; is[i * 3 + 1] = meshFaces[i][1]; is[i * 3 + 2] = meshFaces[i][2]; } //mb.Vertices.clear(); //mb.Vertices.reallocate(vertexCount); //for(int i=0;i<vertexCount;i++) //{ // tmp.Pos.set(meshVertices[i][0],meshVertices[i][1],meshVertices[i][2]); // tmp.Normal.set(meshNormals[i][0],meshNormals[i][1],meshNormals[i][2]); // tmp.TCoords.set(meshTextureCoordinates[i][0],meshTextureCoordinates[i][1]); // tmp.Color=irr::video::SColor(255,255,255,255); // mb.Vertices.push_back(tmp); //} //mb.Indices.clear(); //mb.Indices.reallocate(faceCount); //for(int i=0; i<faceCount; ++i) //{ // mb.Indices.push_back(meshFaces[i][0]); // mb.Indices.push_back(meshFaces[i][1]); // mb.Indices.push_back(meshFaces[i][2]); //} // draw driver->setMaterial( material ); //driver->drawIndexedTriangleList(mb.Vertices.const_pointer(),mb.Vertices.size(),mb.Indices.const_pointer(),faceCount); driver->drawIndexedTriangleList( vs, vertexCount, is, faceCount ); //driver->drawMeshBuffer(&mb); //CONSOLE.addx("#Verts %d #Norm %d #Tex %d #Faces %d #Map %d", // vertexCount,normalsCount,textureCoordinateCount,faceCount, pCalRenderer->getMapCount()); } } } // end the rendering pCalRenderer->endRendering(); } } }