/*!**************************************************************************** @Function LoadVbos @Description Loads the mesh data required for this training course into vertex buffer objects ******************************************************************************/ void OGLESOptimizeMesh::LoadVbos() { if(!m_puiVbo) m_puiVbo = new GLuint[m_ui32VBONo]; if(!m_puiIndexVbo) m_puiIndexVbo = new GLuint[m_ui32IndexVBONo]; glGenBuffers(m_ui32VBONo, m_puiVbo); glGenBuffers(m_ui32IndexVBONo, m_puiIndexVbo); // Create vertex buffer for Model // Load vertex data into buffer object unsigned int uiSize = m_Model.pMesh[0].nNumVertex * m_Model.pMesh[0].sVertex.nStride; glBindBuffer(GL_ARRAY_BUFFER, m_puiVbo[0]); glBufferData(GL_ARRAY_BUFFER, uiSize, m_Model.pMesh[0].pInterleaved, GL_STATIC_DRAW); // Load index data into buffer object if available uiSize = PVRTModelPODCountIndices(m_Model.pMesh[0]) * sizeof(GLshort); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_puiIndexVbo[0]); glBufferData(GL_ELEMENT_ARRAY_BUFFER, uiSize, m_Model.pMesh[0].sFaces.pData, GL_STATIC_DRAW); // Create vertex buffer for ModelOpt // Load vertex data into buffer object uiSize = m_ModelOpt.pMesh[0].nNumVertex * m_ModelOpt.pMesh[0].sVertex.nStride; glBindBuffer(GL_ARRAY_BUFFER, m_puiVbo[1]); glBufferData(GL_ARRAY_BUFFER, uiSize, m_ModelOpt.pMesh[0].pInterleaved, GL_STATIC_DRAW); // Load index data into buffer object if available uiSize = PVRTModelPODCountIndices(m_ModelOpt.pMesh[0]) * sizeof(GLshort); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_puiIndexVbo[1]); glBufferData(GL_ELEMENT_ARRAY_BUFFER, uiSize, m_ModelOpt.pMesh[0].sFaces.pData, GL_STATIC_DRAW); #ifdef ENABLE_LOAD_TIME_STRIP // Creat index data for the load time stripping uiSize = PVRTModelPODCountIndices(m_Model.pMesh[0]) * sizeof(GLshort); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_puiIndexVbo[2]); glBufferData(GL_ELEMENT_ARRAY_BUFFER, uiSize, m_pNewIdx, GL_STATIC_DRAW); #endif // Unbind buffers glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); }
/*!**************************************************************************** @Function LoadVbos @Description Loads the mesh data required for this training course into vertex buffer objects ******************************************************************************/ void OGLES3Refraction::LoadVbos() { if (!m_puiVbo) m_puiVbo = new GLuint[m_Scene.nNumMesh]; if (!m_puiIndexVbo) m_puiIndexVbo = new GLuint[m_Scene.nNumMesh]; /* Load vertex data of all meshes in the scene into VBOs The meshes have been exported with the "Interleave Vectors" option, so all data is interleaved in the buffer at pMesh->pInterleaved. Interleaving data improves the memory access pattern and cache efficiency, thus it can be read faster by the hardware. */ glGenBuffers(m_Scene.nNumMesh, m_puiVbo); for (unsigned int i = 0; i < m_Scene.nNumMesh; ++i) { // Load vertex data into buffer object SPODMesh& Mesh = m_Scene.pMesh[i]; unsigned int uiSize = Mesh.nNumVertex * Mesh.sVertex.nStride; glBindBuffer(GL_ARRAY_BUFFER, m_puiVbo[i]); glBufferData(GL_ARRAY_BUFFER, uiSize, Mesh.pInterleaved, GL_STATIC_DRAW); // Load index data into buffer object if available m_puiIndexVbo[i] = 0; if (Mesh.sFaces.pData) { glGenBuffers(1, &m_puiIndexVbo[i]); uiSize = PVRTModelPODCountIndices(Mesh) * sizeof(GLshort); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_puiIndexVbo[i]); glBufferData(GL_ELEMENT_ARRAY_BUFFER, uiSize, Mesh.sFaces.pData, GL_STATIC_DRAW); } } glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); }
/*!**************************************************************************** @Function LoadVbos @Description Loads the mesh data required for this training course into vertex buffer objects ******************************************************************************/ bool OGLESPVRScopeRemote::LoadVbos(CPVRTString* pErrorStr) { CPPLProcessingScoped PPLProcessingScoped(m_psSPSCommsData, __FUNCTION__, static_cast<unsigned int>(strlen(__FUNCTION__)), m_i32FrameCounter); if(m_Scene.nNumMesh == 0) // If there are no VBO to create return return true; if(!m_Scene.pMesh[0].pInterleaved) { *pErrorStr = "ERROR: IntroducingPOD requires the pod data to be interleaved. Please re-export with the interleaved option enabled."; return false; } if(!m_puiVbo) m_puiVbo = new GLuint[m_Scene.nNumMesh]; if(!m_puiIndexVbo) m_puiIndexVbo = new GLuint[m_Scene.nNumMesh]; /* Load vertex data of all meshes in the scene into VBOs The meshes have been exported with the "Interleave Vectors" option, so all data is interleaved in the buffer at pMesh->pInterleaved. Interleaving data improves the memory access pattern and cache efficiency, thus it can be read faster by the hardware. */ glGenBuffers(m_Scene.nNumMesh, m_puiVbo); for(unsigned int i = 0; i < m_Scene.nNumMesh; ++i) { // Load vertex data into buffer object SPODMesh& Mesh = m_Scene.pMesh[i]; unsigned int uiSize = Mesh.nNumVertex * Mesh.sVertex.nStride; glBindBuffer(GL_ARRAY_BUFFER, m_puiVbo[i]); glBufferData(GL_ARRAY_BUFFER, uiSize, Mesh.pInterleaved, GL_STATIC_DRAW); // Load index data into buffer object if available m_puiIndexVbo[i] = 0; if(Mesh.sFaces.pData) { glGenBuffers(1, &m_puiIndexVbo[i]); uiSize = PVRTModelPODCountIndices(Mesh) * sizeof(GLshort); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_puiIndexVbo[i]); glBufferData(GL_ELEMENT_ARRAY_BUFFER, uiSize, Mesh.sFaces.pData, GL_STATIC_DRAW); } } glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); return true; }
/*!**************************************************************************** @Function LoadVbos @Description Loads the mesh data required for this training course into vertex buffer objects ******************************************************************************/ void OGLESEvilSkull::LoadVbos() { if(!m_puiVbo) m_puiVbo = new GLuint[2]; if(!m_puiIndexVbo) m_puiIndexVbo = new GLuint[2]; glGenBuffers(2, m_puiVbo); glGenBuffers(2, m_puiIndexVbo); // Create vertex buffer for Skull // Load vertex data into buffer object unsigned int uiSize = m_Scene.pMesh[eSkull].nNumVertex * m_Scene.pMesh[eSkull].sVertex.nStride; glBindBuffer(GL_ARRAY_BUFFER, m_puiVbo[0]); glBufferData(GL_ARRAY_BUFFER, uiSize, m_Scene.pMesh[eSkull].pInterleaved, GL_STATIC_DRAW); // Load index data into buffer object if available uiSize = PVRTModelPODCountIndices(m_Scene.pMesh[eSkull]) * sizeof(GLshort); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_puiIndexVbo[0]); glBufferData(GL_ELEMENT_ARRAY_BUFFER, uiSize, m_Scene.pMesh[eSkull].sFaces.pData, GL_STATIC_DRAW); // Create vertex buffer for Jaw // Load vertex data into buffer object uiSize = m_Scene.pMesh[eJaw].nNumVertex * m_Scene.pMesh[eJaw].sVertex.nStride; glBindBuffer(GL_ARRAY_BUFFER, m_puiVbo[1]); glBufferData(GL_ARRAY_BUFFER, uiSize, m_Scene.pMesh[eJaw].pInterleaved, GL_STATIC_DRAW); // Load index data into buffer object if available uiSize = PVRTModelPODCountIndices(m_Scene.pMesh[eJaw]) * sizeof(GLshort); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_puiIndexVbo[1]); glBufferData(GL_ELEMENT_ARRAY_BUFFER, uiSize, m_Scene.pMesh[eJaw].sFaces.pData, GL_STATIC_DRAW); // Unbind buffers glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); }
/*!**************************************************************************** @Function LoadVbos @Description Loads the mesh data required for this training course into vertex buffer objects ******************************************************************************/ bool OGLES3EdgeDetection::LoadVbos(CPVRTString* pErrorStr) { // If there are no VBOs to create, return if(m_Scene.nNumMesh == 0) return true; // Checks to make sure that POD data is interleaved: // Although this training course doesn't use normals or texture data for the models, this is done for code re-use. if(!m_Scene.pMesh[0].pInterleaved) { *pErrorStr = "ERROR: EdgeDetection requires the pod data to be interleaved. Please re-export with the interleaved option enabled."; return false; } // Initialises the vertex buffer objects. if(!m_puiVbo) m_puiVbo = new GLuint[m_Scene.nNumMesh]; if(!m_puiIndexVbo) m_puiIndexVbo = new GLuint[m_Scene.nNumMesh]; /* The meshes have been exported with the "Interleave Vectors" option, so all data is interleaved in the buffer at pMesh->pInterleaved. Interleaving data improves the memory access pattern and cache efficiency, thus it can be read faster by the hardware. */ // Generates the vertex buffer objects. glGenBuffers(m_Scene.nNumMesh, m_puiVbo); // Load vertex data from all meshes in the scene into the VBOs for(unsigned int i = 0; i < m_Scene.nNumMesh; ++i) { // Load vertex data SPODMesh& Mesh = m_Scene.pMesh[i]; unsigned int uiSize = Mesh.nNumVertex * Mesh.sVertex.nStride; // Bind the associated VBO glBindBuffer(GL_ARRAY_BUFFER, m_puiVbo[i]); glBufferData(GL_ARRAY_BUFFER, uiSize, Mesh.pInterleaved, GL_STATIC_DRAW); // Load mesh index data into buffer object if available m_puiIndexVbo[i] = 0; if(Mesh.sFaces.pData) { glGenBuffers(1, &m_puiIndexVbo[i]); uiSize = PVRTModelPODCountIndices(Mesh) * sizeof(GLshort); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_puiIndexVbo[i]); glBufferData(GL_ELEMENT_ARRAY_BUFFER, uiSize, Mesh.sFaces.pData, GL_STATIC_DRAW); } } // Unbind the VBOs glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); return true; }
/*!**************************************************************************** @Function LoadVbos @Description Loads the mesh data required for this training course into vertex buffer objects ******************************************************************************/ bool OGLES2ParticleSystem::LoadVbos(CPVRTString* const pErrorStr) { glGenBuffers(1, &m_uiVbo); // Load vertex data into buffer object SPODMesh& Mesh = m_Scene.pMesh[0]; glBindBuffer(GL_ARRAY_BUFFER, m_uiVbo); glBufferData(GL_ARRAY_BUFFER, Mesh.nNumVertex * Mesh.sVertex.nStride, Mesh.pInterleaved, GL_STATIC_DRAW); // Load index data into buffer object glGenBuffers(1, &m_uiIbo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_uiIbo); glBufferData(GL_ELEMENT_ARRAY_BUFFER, PVRTModelPODCountIndices(Mesh) * sizeof(GLshort), Mesh.sFaces.pData, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); return true; }
/*!**************************************************************************** @Function LoadVbos @Description Loads the mesh data required for this training course into vertex buffer objects ******************************************************************************/ bool OGLES3IntroducingPOD::LoadVbos(CPVRTString* pErrorStr) { if(!m_Scene.pMesh[0].pInterleaved) { *pErrorStr = "ERROR: IntroducingPOD requires the pod data to be interleaved. Please re-export with the interleaved option enabled."; return false; } if (!m_puiVbo) m_puiVbo = new GLuint[m_Scene.nNumMesh]; if (!m_puiIndexVbo) m_puiIndexVbo = new GLuint[m_Scene.nNumMesh]; /* Load vertex data of all meshes in the scene into VBOs The meshes have been exported with the "Interleave Vectors" option, so all data is interleaved in the buffer at pMesh->pInterleaved. Interleaving data improves the memory access pattern and cache efficiency, thus it can be read faster by the hardware. */ glGenBuffers(m_Scene.nNumMesh, m_puiVbo); for (unsigned int i = 0; i < m_Scene.nNumMesh; ++i) { // Load vertex data into buffer object SPODMesh& Mesh = m_Scene.pMesh[i]; PVRTuint32 uiSize = Mesh.nNumVertex * Mesh.sVertex.nStride; glBindBuffer(GL_ARRAY_BUFFER, m_puiVbo[i]); glBufferData(GL_ARRAY_BUFFER, uiSize, Mesh.pInterleaved, GL_STATIC_DRAW); // Load index data into buffer object if available m_puiIndexVbo[i] = 0; if (Mesh.sFaces.pData) { glGenBuffers(1, &m_puiIndexVbo[i]); uiSize = PVRTModelPODCountIndices(Mesh) * Mesh.sFaces.nStride; glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_puiIndexVbo[i]); glBufferData(GL_ELEMENT_ARRAY_BUFFER, uiSize, Mesh.sFaces.pData, GL_STATIC_DRAW); } } glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); return true; }
/*!*********************************************************************** @Function BuildVBO @Access private @Returns void @Description *************************************************************************/ void Model::BuildVBO() { // Build VBO glGenBuffers(1, &m_puiVBO); glGenBuffers(1, &m_puiIndexVBO); SPODMesh& Mesh = m_Model.pMesh[0]; unsigned int uiSize = Mesh.nNumVertex * Mesh.sVertex.nStride; // Vertex data glBindBuffer(GL_ARRAY_BUFFER, m_puiVBO); glBufferData(GL_ARRAY_BUFFER, uiSize, Mesh.pInterleaved, GL_STATIC_DRAW); // Face data uiSize = PVRTModelPODCountIndices(Mesh) * sizeof(GLshort); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_puiIndexVBO); glBufferData(GL_ELEMENT_ARRAY_BUFFER, uiSize, Mesh.sFaces.pData, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); }
/*!**************************************************************************** @Function LoadVbos @Description Loads the mesh data required for this training course into vertex buffer objects ******************************************************************************/ bool OGLES3MagicLantern::LoadVbos(void) { // A bit of warning when the data is not in the expected format. // This demo uses interleaved triangle list vertex data. // Anything else will not work. This allows to keep then code simple. if(!m_Scene.pMesh[0].pInterleaved) { PVRShellSet(prefExitMessage, "ERROR: This demo requires the pod data to be interleaved. Please re-export with the interleaved option enabled."); return false; } // Allocate the pointers to hold the vertex buffer objects and // the index buffer objects. if (!m_puiVbo) m_puiVbo = new GLuint[m_Scene.nNumMesh]; if (!m_puiIndexVbo) m_puiIndexVbo = new GLuint[m_Scene.nNumMesh]; // Load vertex data of all meshes in the scene into VBOs. // The meshes have been exported with the "Interleave Vectors" option, // so all data is interleaved in the buffer at pMesh->pInterleaved. glGenBuffers(m_Scene.nNumMesh, m_puiVbo); for (unsigned int i = 0; i < m_Scene.nNumMesh; ++i) { // Load vertex data from POD into buffer object. SPODMesh& Mesh = m_Scene.pMesh[i]; unsigned int uiSize = Mesh.nNumVertex * Mesh.sVertex.nStride; glBindBuffer(GL_ARRAY_BUFFER, m_puiVbo[i]); glBufferData(GL_ARRAY_BUFFER, uiSize, Mesh.pInterleaved, GL_STATIC_DRAW); // Load index data into buffer object if available. m_puiIndexVbo[i] = 0; if (Mesh.sFaces.pData) { glGenBuffers(1, &m_puiIndexVbo[i]); uiSize = PVRTModelPODCountIndices(Mesh) * sizeof(GLshort); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_puiIndexVbo[i]); glBufferData(GL_ELEMENT_ARRAY_BUFFER, uiSize, Mesh.sFaces.pData, GL_STATIC_DRAW); } } glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); return true; }
// --------------------------------------------------------------- void MyPVRDemo::LoadVBOs() { glGenBuffers(enumMODEL_MAX, m_uiVBO); glGenBuffers(enumMODEL_MAX, m_uiVBOIdx); for (unsigned int i = 0; i < enumMODEL_MAX; ++i) { SPODMesh& Mesh = m_Model.pMesh[i]; unsigned int uiSize = Mesh.nNumVertex * Mesh.sVertex.nStride; glBindBuffer(GL_ARRAY_BUFFER, m_uiVBO[i]); glBufferData(GL_ARRAY_BUFFER, uiSize, Mesh.pInterleaved, GL_STATIC_DRAW); uiSize = PVRTModelPODCountIndices(Mesh) * sizeof(GLshort); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_uiVBOIdx[i]); glBufferData(GL_ELEMENT_ARRAY_BUFFER, uiSize, Mesh.sFaces.pData, GL_STATIC_DRAW); } glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); }
/*!**************************************************************************** @Function LoadVbos @Description Loads the mesh data required for this training course into vertex buffer objects ******************************************************************************/ Mesh3D::Mesh3D(const char *filename) : m_normalMap(0), m_cubeMap(0), m_shader(DEFAULT_SHADER), m_blendEnable(false), useSceneModel(true) { const char* cpath = [ [NSString stringWithFormat:@"%@/", [[NSBundle mainBundle] resourcePath]] cStringUsingEncoding: NSASCIIStringEncoding]; NSLog(@"Loading model at %s ",filename); m_filename = filename; //printf("cpath %s/%@\n", cpath); CPVRTResourceFile::SetReadPath(cpath); if(m_ModelPOD.ReadFromFile(filename) != PVR_SUCCESS) { NSLog(@"ERROR: Couldn't load %s.", filename); return; } else { if(!m_ModelPOD.pMesh[0].pInterleaved) { printf("ERROR: IntroducingPOD requires the pod data to be interleaved. Please re-export with the interleaved option enabled."); return; } m_numMeshes = m_ModelPOD.nNumMesh; iVertexVBO = new GLuint[m_ModelPOD.nNumMesh]; m_puiIndexVbo = new GLuint[m_ModelPOD.nNumMesh]; meshInfo = new MeshInfo[m_ModelPOD.nNumMesh]; /* Load vertex data of all meshes in the scene into VBOs The meshes have been exported with the "Interleave Vectors" option, so all data is interleaved in the buffer at pMesh->pInterleaved. Interleaving data improves the memory access pattern and cache efficiency, thus it can be read faster by the hardware. */ glGenBuffers(m_ModelPOD.nNumMesh, iVertexVBO); static int vertexCounts = 0; for (unsigned int i = 0; i < m_ModelPOD.nNumMesh; ++i) { // Load vertex data into buffer object SPODMesh& Mesh = m_ModelPOD.pMesh[i]; //PVRTModelPODToggleInterleaved(Mesh); vertexCounts += Mesh.nNumVertex; unsigned int uiSize = Mesh.nNumVertex * Mesh.sVertex.nStride; glBindBuffer(GL_ARRAY_BUFFER, iVertexVBO[i]); glBufferData(GL_ARRAY_BUFFER, uiSize, Mesh.pInterleaved, GL_STATIC_DRAW); //printf("Addr %x %x", Mesh.psUVW[0].pData, Mesh.sNormals.pData); meshInfo[i].vertexStride = Mesh.sVertex.nStride; meshInfo[i].materialIndex = m_ModelPOD.pNode[i].nIdxMaterial; meshInfo[i].normalStride = Mesh.sNormals.nStride; meshInfo[i].normalOffset = (size_t) Mesh.sNormals.pData; meshInfo[i].tangentStride = Mesh.sTangents.nStride; meshInfo[i].tangentOffset = (size_t) Mesh.sTangents.pData; meshInfo[i].uvStride = Mesh.psUVW[0].nStride; meshInfo[i].uvOffset = (size_t) Mesh.psUVW[0].pData; meshInfo[i].nNumFaces = Mesh.nNumFaces; meshInfo[i].nNumStrips = Mesh.nNumStrips; NSLog(@"Loading object name= %d vertices=%d TotalCount=%d", i,Mesh.nNumVertex, vertexCounts); // Load index data into buffer object if available m_puiIndexVbo[i] = 0; if (Mesh.sFaces.pData) { glGenBuffers(1, &m_puiIndexVbo[i]); uiSize = PVRTModelPODCountIndices(Mesh) * sizeof(GLshort); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_puiIndexVbo[i]); glBufferData(GL_ELEMENT_ARRAY_BUFFER, uiSize, Mesh.sFaces.pData, GL_STATIC_DRAW); NSLog(@"Loading object name= %d indexes=%d", i,uiSize); } } glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); //load any textures for the scene's materials. m_uiTexture = new GLuint[m_ModelPOD.nNumMaterial]; materialInfo = new MatInfo[m_ModelPOD.nNumMaterial]; m_numMaterials = m_ModelPOD.nNumMaterial; for(unsigned int i=0;i<m_ModelPOD.nNumMaterial;i++){ m_uiTexture[i] = INT_MAX; SPODMaterial* mat = &m_ModelPOD.pMaterial[i]; materialInfo[i].diffuseColor = mat->pfMatDiffuse; materialInfo[i].ambientColor = mat->pfMatAmbient; materialInfo[i].shiness = mat->fMatShininess; materialInfo[i].specularColor = mat->pfMatSpecular; if(mat->nIdxTexDiffuse != -1){ //load the texture file. CPVRTString filenamePVR = m_ModelPOD.pTexture[mat->nIdxTexDiffuse].pszName; m_uiTexture[i] = TextureManager::getInstance().getTexture( filenamePVR.c_str() ); //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); //glMaterialxv(GL_FRONT_AND_BACK, GL_AMBIENT, PVRTVec4(mat->pfMatAmbient, f2vt(1.0f)).ptr()); //glMaterialxv(GL_FRONT_AND_BACK, GL_DIFFUSE, PVRTVec4(mat->pfMatDiffuse, f2vt(1.0f)).ptr()); materialInfo[i].textureFileName = filenamePVR.c_str(); NSLog(@"Loaded texture %s %d", filenamePVR.c_str(), m_uiTexture[i]); } else { materialInfo[i].textureFileName = ""; //NSLog(@"Skipping texture"); } } } m_ModelPOD.Destroy(); }
/*!**************************************************************************** @Function LoadVbos @Description Loads the mesh data required for this training course into vertex buffer objects ******************************************************************************/ void OGLES2LevelOfDetail::LoadVbos() { if (!m_puiVbo) m_puiVbo = new GLuint[m_Scene.nNumMesh]; if (!m_puiIndexVbo) m_puiIndexVbo = new GLuint[m_Scene.nNumMesh]; /* Load vertex data of all meshes in the scene into VBOs The meshes have been exported with the "Interleave Vectors" option, so all data is interleaved in the buffer at pMesh->pInterleaved. Interleaving data improves the memory access pattern and cache efficiency, thus it can be read faster by the hardware. */ glGenBuffers(m_Scene.nNumMesh, m_puiVbo); for (unsigned int i = 0; i < m_Scene.nNumMesh; ++i) { // Load vertex data into buffer object SPODMesh& Mesh = m_Scene.pMesh[i]; unsigned int uiSize = Mesh.nNumVertex * Mesh.sVertex.nStride; glBindBuffer(GL_ARRAY_BUFFER, m_puiVbo[i]); glBufferData(GL_ARRAY_BUFFER, uiSize, Mesh.pInterleaved, GL_STATIC_DRAW); // Load index data into buffer object if available m_puiIndexVbo[i] = 0; if (Mesh.sFaces.pData) { glGenBuffers(1, &m_puiIndexVbo[i]); uiSize = PVRTModelPODCountIndices(Mesh) * sizeof(GLshort); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_puiIndexVbo[i]); glBufferData(GL_ELEMENT_ARRAY_BUFFER, uiSize, Mesh.sFaces.pData, GL_STATIC_DRAW); } if (i == 0) { PVRTVec3 vBoundingBoxMin, vBoundingBoxMax; // calculate bounding box for mesh 0 float* pfData = (float*)Mesh.pInterleaved; vBoundingBoxMin.x = vBoundingBoxMax.x = pfData[0]; vBoundingBoxMin.y = vBoundingBoxMax.y = pfData[1]; vBoundingBoxMin.z = vBoundingBoxMax.z = pfData[2]; for(unsigned int i = 1; i < Mesh.nNumVertex; ++i) { pfData = (float*)(((char*)pfData) + Mesh.sVertex.nStride); vBoundingBoxMin.x = PVRT_MIN(vBoundingBoxMin.x, pfData[0]); vBoundingBoxMin.y = PVRT_MIN(vBoundingBoxMin.y, pfData[1]); vBoundingBoxMin.z = PVRT_MIN(vBoundingBoxMin.z, pfData[2]); vBoundingBoxMax.x = PVRT_MAX(vBoundingBoxMax.x, pfData[0]); vBoundingBoxMax.y = PVRT_MAX(vBoundingBoxMax.y, pfData[1]); vBoundingBoxMax.z = PVRT_MAX(vBoundingBoxMax.z, pfData[2]); } for (int i = 0; i < 8; ++i) { m_avBoundingBox[i].x = (i & 1) ? vBoundingBoxMin.x : vBoundingBoxMax.x; m_avBoundingBox[i].y = (i & 2) ? vBoundingBoxMin.y : vBoundingBoxMax.y; m_avBoundingBox[i].z = (i & 4) ? vBoundingBoxMin.z : vBoundingBoxMax.z; m_avBoundingBox[i].w = 1.0f; } } } glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); }
static void WriteHMeshes( FILE * const pFile, const SPODScene &s, const char * const sName, const bool bChangeEndian) { char *pStr, buf[CFAH]; pStr = new char[s.nNumMesh * CFAH]; _ASSERT(pStr); *pStr = 0; for(unsigned int i = 0; i < s.nNumMesh; ++i) { strcat(pStr, " {\n"); sprintf(pStr, "%s %d,\n", pStr, s.pMesh[i].nNumVertex); sprintf(pStr, "%s %d,\n", pStr, s.pMesh[i].nNumFaces); sprintf(pStr, "%s %d,\n", pStr, s.pMesh[i].nNumUVW); sprintf(buf, "%s%d", sName, i); WriteHCPODData(pFile, pStr, s.pMesh[i].sFaces, PVRTModelPODCountIndices(s.pMesh[i]), true, bChangeEndian, buf, "sFaces"); if(s.pMesh[i].nNumStrips) { sprintf(buf, "%s%dpnStripLength", sName, i); WriteHData(pFile, (unsigned long*)s.pMesh[i].pnStripLength, s.pMesh[i].nNumStrips * sizeof(*s.pMesh[i].pnStripLength), buf, bChangeEndian); sprintf(pStr, "%s (unsigned int*)%s, %d,\n", pStr, buf, s.pMesh[i].nNumStrips); } else { sprintf(pStr, "%s (unsigned int*)0, 0,\n", pStr); } sprintf(buf, "%s%d", sName, i); WriteHCPODData(pFile, pStr, s.pMesh[i].sVertex, s.pMesh[i].nNumVertex, s.pMesh[i].pInterleaved == 0, bChangeEndian, buf, "sVertex"); WriteHCPODData(pFile, pStr, s.pMesh[i].sNormals, s.pMesh[i].nNumVertex, s.pMesh[i].pInterleaved == 0, bChangeEndian, buf, "sNormals"); WriteHCPODData(pFile, pStr, s.pMesh[i].sTangents, s.pMesh[i].nNumVertex, s.pMesh[i].pInterleaved == 0, bChangeEndian, buf, "sTangents"); WriteHCPODData(pFile, pStr, s.pMesh[i].sBinormals, s.pMesh[i].nNumVertex, s.pMesh[i].pInterleaved == 0, bChangeEndian, buf, "sBinormals"); if(s.pMesh[i].nNumUVW) { sprintf(buf, "%s%dpsUVW", sName, i); WriteHUVW(pFile, s.pMesh[i], s.pMesh[i].pInterleaved == 0, bChangeEndian, buf); sprintf(pStr, "%s (CPODData*)%s,\n", pStr, buf); } else { sprintf(pStr, "%s (CPODData*)0,\n", pStr); } sprintf(buf, "%s%d", sName, i); WriteHCPODData(pFile, pStr, s.pMesh[i].sVtxColours, s.pMesh[i].nNumVertex, s.pMesh[i].pInterleaved == 0, bChangeEndian, buf, "sVtxColours"); WriteHCPODData(pFile, pStr, s.pMesh[i].sBoneIdx, s.pMesh[i].nNumVertex, s.pMesh[i].pInterleaved == 0, bChangeEndian, buf, "sBoneIdx"); WriteHCPODData(pFile, pStr, s.pMesh[i].sBoneWeight, s.pMesh[i].nNumVertex, s.pMesh[i].pInterleaved == 0, bChangeEndian, buf, "sBoneWeight"); if(s.pMesh[i].pInterleaved) { sprintf(buf, "%s%dpInterleaved", sName, i); WriteHData(pFile, (unsigned long*)s.pMesh[i].pInterleaved, s.pMesh[i].nNumVertex * s.pMesh[i].sVertex.nStride, buf, bChangeEndian); sprintf(pStr, "%s (unsigned char*)%s,\n", pStr, buf); } else { sprintf(pStr, "%s (unsigned char*)0,\n", pStr); } if(s.pMesh[i].sBoneBatches.nBatchCnt) { sprintf(pStr, "%s {\n", pStr); sprintf(buf, "%s%dpnBatches", sName, i); WriteHData(pFile, (unsigned long*)s.pMesh[i].sBoneBatches.pnBatches, s.pMesh[i].sBoneBatches.nBatchCnt * sizeof(*s.pMesh[i].sBoneBatches.pnBatches) * s.pMesh[i].sBoneBatches.nBatchBoneMax, buf, bChangeEndian); sprintf(pStr, "%s (int*)%s,\n", pStr, buf); sprintf(buf, "%s%dpnBatchBoneCnt", sName, i); WriteHData(pFile, (unsigned long*)s.pMesh[i].sBoneBatches.pnBatchBoneCnt, s.pMesh[i].sBoneBatches.nBatchCnt * sizeof(*s.pMesh[i].sBoneBatches.pnBatchBoneCnt), buf, bChangeEndian); sprintf(pStr, "%s (int*)%s,\n", pStr, buf); sprintf(buf, "%s%dpnBatchOffset", sName, i); WriteHData(pFile, (unsigned long*)s.pMesh[i].sBoneBatches.pnBatchOffset, s.pMesh[i].sBoneBatches.nBatchCnt * sizeof(*s.pMesh[i].sBoneBatches.pnBatchOffset), buf, bChangeEndian); sprintf(pStr, "%s (int*)%s,\n", pStr, buf); sprintf(pStr, "%s %d,\n", pStr, s.pMesh[i].sBoneBatches.nBatchBoneMax); sprintf(pStr, "%s %d,\n", pStr, s.pMesh[i].sBoneBatches.nBatchCnt); sprintf(pStr, "%s }\n", pStr); } else { sprintf(pStr, "%s { (int*)0, (int*)0, (int*)0, 0, 0 },\n", pStr); } strcat(pStr, " },\n"); } fprintf(pFile, "const SPODMesh %s[%d] =\n{\n", sName, s.nNumMesh); fprintf(pFile, pStr); fprintf(pFile, "};\n\n"); delete [] pStr; }