Mesh.cpp
上传用户:sz83729876
上传日期:2013-03-07
资源大小:4140k
文件大小:6k
源码类别:

OpenGL

开发平台:

Windows_Unix

  1. #include <math.h>
  2. #include "Log.h"
  3. #include "Mesh.h"
  4. #include "3dsloader.h"
  5. //****************************************
  6. //  CMesh
  7. //****************************************
  8. CMesh::CMesh()
  9. {
  10.     m_strName = "Unknown Mesh";
  11.     m_pVertices = NULL;
  12.     m_pIndices  = NULL;
  13.     m_dwIndexCount  = 0;
  14.     m_dwVertexCount = 0;
  15.     m_pMaterial = NULL;
  16. }
  17. CMesh::~CMesh()
  18. {
  19.     if (m_pVertices)
  20.     {
  21.         delete[] m_pVertices;
  22.         m_pVertices = NULL;
  23.     }
  24.     if (m_pIndices)
  25.     {
  26.         delete[] m_pIndices;
  27.         m_pIndices = NULL;
  28.     }
  29. }
  30. // standard hardcoded renderer
  31. void CMesh::Render()
  32. {
  33.     glEnable( GL_TEXTURE_2D );
  34.     glBindTexture( GL_TEXTURE_2D, m_pMaterial->m_iTextureID );
  35.     //glColor4f( 1, 1, 1, 1 );
  36.     glBegin( GL_TRIANGLES );
  37.     for( int i=0; i<m_dwIndexCount/3; i++ )
  38.     {
  39.         CVertex v1 = m_pVertices[ m_pIndices[i*3+0] ];
  40.         CVertex v2 = m_pVertices[ m_pIndices[i*3+1] ];
  41.         CVertex v3 = m_pVertices[ m_pIndices[i*3+2] ];
  42.         glNormal3f( v1.nx, v1.ny, v1.nz );
  43.         glTexCoord2f( v1.tu, v1.tv ); 
  44.         glVertex3f( v1.x, v1.y, v1.z );
  45.         glNormal3f( v2.nx, v2.ny, v2.nz );
  46.         glTexCoord2f( v2.tu, v2.tv );
  47.         glVertex3f( v2.x, v2.y, v2.z );
  48.         glNormal3f( v3.nx, v3.ny, v3.nz );
  49.         glTexCoord2f( v3.tu, v3.tv ); 
  50.         glVertex3f( v3.x, v3.y, v3.z );
  51.     }
  52.     glEnd();
  53.     /*glColor3f( 1, 1, 0 );
  54.     glBegin( GL_LINES );
  55.     for( i=0; i<m_dwVertexCount; i++ )
  56.     {
  57.         CVertex v1 = m_pVertices[ i ];
  58.         glVertex3f( v1.x, v1.y, v1.z );
  59.         glVertex3f( v1.x+(v1.nx*5), v1.y+(v1.ny*5), v1.z+(v1.nz*5) );
  60.     }
  61.     glEnd();
  62.     glColor3f( 1, 1, 1 );*/
  63. }
  64. void CMesh::CalculateNormals()
  65. {
  66.     // temporary normal buffer
  67.     float *pNormals = new float[ m_dwIndexCount ];
  68.     for( int i=0; i<m_dwIndexCount/3; i++ )
  69.     {
  70.         CVertex v1 = m_pVertices[ m_pIndices[i*3+0] ];
  71.         CVertex v2 = m_pVertices[ m_pIndices[i*3+1] ];
  72.         CVertex v3 = m_pVertices[ m_pIndices[i*3+2] ];
  73.         float x1, y1, z1;
  74.         float x2, y2, z2;
  75.         // two edges
  76.         x1 = v1.x - v2.x;
  77.         y1 = v1.y - v2.y;
  78.         z1 = v1.z - v2.z;
  79.         x2 = v1.x - v3.x;
  80.         y2 = v1.y - v3.y;
  81.         z2 = v1.z - v3.z;
  82.         // crossproduct
  83.         float nx = y1*z2 - z1*y2;
  84.         float ny = z1*x2 - x1*z2;
  85.         float nz = x1*y2 - y1*x2;
  86.         // normalize
  87.         float len = sqrtf( (nx*nx) + (ny*ny) + (nz*nz) );
  88.         nx /= len;
  89.         ny /= len;
  90.         nz /= len;
  91.         pNormals[ i*3 + 0 ] = nx;
  92.         pNormals[ i*3 + 1 ] = ny;
  93.         pNormals[ i*3 + 2 ] = nz;
  94.     }
  95.     for( int v=0; v<m_dwVertexCount; v++ )
  96.     {
  97.         float nx, ny, nz;
  98.         int count;
  99.         nx = ny = nz = 0.0f;
  100.         count = 0;
  101.         for( int i=0; i<m_dwIndexCount/3; i++ )
  102.         {
  103.             int idx = i * 3;
  104.             if ((m_pIndices[idx+0] == v) ||
  105.                 (m_pIndices[idx+1] == v) ||
  106.                 (m_pIndices[idx+2] == v) )
  107.             {
  108.                 nx += pNormals[ idx + 0 ];
  109.                 ny += pNormals[ idx + 1 ];
  110.                 nz += pNormals[ idx + 2 ];
  111.                 count++;
  112.             }
  113.         }
  114.         if (count>0)
  115.         {
  116.             nx /= count;
  117.             ny /= count;
  118.             nz /= count;
  119.         }
  120.         float len = sqrtf( (nx*nx) + (ny*ny) + (nz*nz) );
  121.         if (len<0.1f)
  122.         {
  123.             nx = 0;
  124.             ny = 0;
  125.             nz = 0;
  126.         }
  127.         m_pVertices[ v ].nx = nx;
  128.         m_pVertices[ v ].ny = ny;
  129.         m_pVertices[ v ].nz = nz;
  130.     }
  131.     delete[] pNormals;
  132. }
  133. //****************************************
  134. //  CObject
  135. //****************************************
  136. CObject::CObject()
  137. {
  138. }
  139. CObject::~CObject()
  140. {
  141.     // delete all meshes and materials
  142.     for( int i=0; i<m_vMesh.size(); i++  )
  143.         delete m_vMesh[i];
  144.     for( i=0; i<m_vMaterials.size(); i++  )
  145.         delete m_vMaterials[i];
  146. }
  147. bool CObject::LoadFrom3DS( std::string strFile )
  148. {
  149.     CLoader3DS* pLoad = new CLoader3DS();
  150.     // attempt loading..
  151.     if (!pLoad->Load( strFile.c_str(), this ))
  152.     {
  153.         // failed,... return error
  154.         delete pLoad;
  155.         return false;
  156.     }
  157.     delete pLoad;
  158.     if (!ParseMeshesAndMaterials())
  159.         return false;
  160.     Log::Print( "Mesh loaded "%s"...", strFile.c_str() );
  161.     return true;
  162. }
  163. bool CObject::Render()
  164. {
  165.     for( int i=0; i<m_vMesh.size(); i++ )
  166.         m_vMesh[i]->Render();
  167.     return true;
  168. }
  169. void CObject::AddMesh( CMesh* pMesh )
  170. {
  171.     if (pMesh)
  172.     {
  173.         m_vMesh.push_back( pMesh );
  174.     }
  175. }
  176. void CObject::AddMaterial( CMaterial* pMat )
  177. {
  178.     if (pMat)
  179.     {
  180.         m_vMaterials.push_back( pMat );
  181.     }
  182. }
  183. bool CObject::ParseMeshesAndMaterials()
  184. {
  185.     // set mesh material properties
  186.     for( int iMesh=0; iMesh<m_vMesh.size(); iMesh++ )
  187.     {
  188.         // find corresponding material
  189.         for( int iMat=0; iMat<m_vMaterials.size(); iMat++ )
  190.         {
  191.             if (m_vMaterials[iMat]->m_strName.compare(m_vMesh[iMesh]->m_strMaterialName)==0)
  192.             {
  193.                 m_vMesh[iMesh]->m_pMaterial = m_vMaterials[iMat];
  194.                 break;
  195.             }
  196.         }
  197.         if (m_vMesh[iMesh]->m_pMaterial)
  198.         {
  199.             // scale texture coordinates
  200.             for( int i=0; i<m_vMesh[iMesh]->m_dwVertexCount; i++ )
  201.             {
  202.                 m_vMesh[iMesh]->m_pVertices[i].tu *=   m_vMesh[iMesh]->m_pMaterial->m_fUScale;
  203.                 m_vMesh[iMesh]->m_pVertices[i].tv *= - m_vMesh[iMesh]->m_pMaterial->m_fVScale;
  204.             }
  205.         }
  206.         for( int i=0; i<m_vMesh[iMesh]->m_dwVertexCount; i++ )
  207.         {
  208.             //m_vMesh[iMesh]->m_pVertices[ i ].x *= -1;
  209.             //m_vMesh[iMesh]->m_pVertices[ i ].y *= -1;
  210.             m_vMesh[iMesh]->m_pVertices[ i ].z *= -1;
  211.         }
  212.         m_vMesh[iMesh]->CalculateNormals();
  213.     }
  214.     // load textures if needed
  215.     Texture* tm = Texture::GetInstance();
  216.     for( int iMat=0; iMat<m_vMaterials.size(); iMat++ )
  217.     {
  218.         if (m_vMaterials[iMat]->m_bHasTexture)
  219.         {
  220.             m_vMaterials[iMat]->m_iTextureID = tm->LoadTexture( m_vMaterials[iMat]->m_strTextureName );
  221.             if(m_vMaterials[iMat]->m_iTextureID==0xffff)
  222.                 return false;
  223.         }
  224.     }
  225.     return true;
  226. }