void init_VBO() { // 1 vertex, 1 normal, + N element sets num_buffer_objects = 2 + model.getNumberOfMeshes(); bufferObjects = (GLuint*) malloc( sizeof(GLuint) * num_buffer_objects ); glGenBuffers( num_buffer_objects, bufferObjects ); // // Copy data to video memory // // Vertices array stores Vertex data & Normal Data glBindBuffer( GL_ARRAY_BUFFER, bufferObjects[VERTEX_DATA] ); glBufferData( GL_ARRAY_BUFFER, model.getVertexSize() * model.getNumberOfVertices(), model.getVertexBuffer(), GL_STATIC_DRAW ); /* Normal data if ( model.hasNormals()) { glBindBuffer( GL_ARRAY_BUFFER, bufferObjects[NORMAL_DATA] ); glBufferData( GL_ARRAY_BUFFER, sizeof(float)* model.getNumberOfVertices() * 3, model.getVertexBuffer()->normal, GL_STATIC_DRAW ); } */ for ( int i = 0; i < model.getNumberOfMeshes(); ++i ) { const ModelOBJ::Mesh *pMesh = &model.getMesh(i); // Indexes glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, bufferObjects[INDEX_DATA+i] ); glBufferData( GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * pMesh->triangleCount * 3, model.getIndexBuffer() + pMesh->startIndex, GL_STATIC_DRAW ); } }
//MODEL - vertex array version void draw_test_model_Vertex_Arrays() { const ModelOBJ::Mesh *pMesh = 0; const ModelOBJ::Material *pMaterial = 0; for (int i = 0; i < model.getNumberOfMeshes(); ++i) { pMesh = &model.getMesh(i); pMaterial = pMesh->pMaterial; glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, pMaterial->ambient); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, pMaterial->diffuse); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, pMaterial->specular); glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, pMaterial->shininess * 128.0f); if (model.hasPositions()) { glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(3, GL_FLOAT, model.getVertexSize(), model.getVertexBuffer()->position); } if ( model.hasNormals()) { glEnableClientState(GL_NORMAL_ARRAY); glNormalPointer(GL_FLOAT, model.getVertexSize(), model.getVertexBuffer()->normal); } glDrawElements(GL_TRIANGLES, pMesh->triangleCount * 3, GL_UNSIGNED_INT, model.getIndexBuffer() + pMesh->startIndex); if (model.hasNormals()) glDisableClientState(GL_NORMAL_ARRAY); if (model.hasPositions()) glDisableClientState(GL_VERTEX_ARRAY); } }
void draw_test_model_VBO() { glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_INDEX_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); // Here’s where the data is now // Vertex data glBindBuffer( GL_ARRAY_BUFFER, bufferObjects[VERTEX_DATA] ); glVertexPointer( 3, GL_FLOAT, model.getVertexSize(), 0 ); // Normal data if ( model.hasNormals()) { //glBindBuffer( GL_ARRAY_BUFFER, bufferObjects[NORMAL_DATA] ); glBindBuffer( GL_ARRAY_BUFFER, bufferObjects[VERTEX_DATA] ); glNormalPointer( GL_FLOAT, model.getVertexSize(), model.getVertexBuffer()->normal /* pointer? */ ); } for ( int i = 0; i < model.getNumberOfMeshes(); ++i ) { const ModelOBJ::Mesh * pMesh = &model.getMesh(i); // Indexes glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, bufferObjects[INDEX_DATA+i] ); glDrawElements( GL_TRIANGLES, pMesh->triangleCount * 3, GL_UNSIGNED_INT, 0 ); } // free the VBO context for regular Vertex Array calls glBindBuffer( GL_ARRAY_BUFFER, 0 ); glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 ); glDisableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_INDEX_ARRAY); }
void DrawFrame() { glViewport(0, 0, g_windowWidth, g_windowHeight); glClearColor(0.3f, 0.5f, 0.9f, 0.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(CAMERA_FOVY, static_cast<float>(g_windowWidth) / static_cast<float>(g_windowHeight), CAMERA_ZNEAR, CAMERA_ZFAR); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(g_cameraPos[0], g_cameraPos[1], g_cameraPos[2], g_targetPos[0], g_targetPos[1], g_targetPos[2], 0.0f, 1.0f, 0.0f); glRotatef(g_pitch, 1.0f, 0.0f, 0.0f); glRotatef(g_heading, 0.0f, 1.0f, 0.0f); const ModelOBJ::Mesh *pMesh = 0; const ModelOBJ::Material *pMaterial = 0; const ModelOBJ::Vertex *pVertices = 0; ModelTextures::const_iterator iter; for (int i = 0; i < g_model.getNumberOfMeshes(); ++i) { pMesh = &g_model.getMesh(i); pMaterial = pMesh->pMaterial; pVertices = g_model.getVertexBuffer(); glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, pMaterial->ambient); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, pMaterial->diffuse); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, pMaterial->specular); glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, pMaterial->shininess * 128.0f); if (g_enableTextures) { iter = g_modelTextures.find(pMaterial->colorMapFilename); if (iter == g_modelTextures.end()) { glDisable(GL_TEXTURE_2D); } else { glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, iter->second); } } else { glDisable(GL_TEXTURE_2D); } glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(3, GL_FLOAT, g_model.getVertexSize(), g_model.getVertexBuffer()->position); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointer(2, GL_FLOAT, g_model.getVertexSize(), g_model.getVertexBuffer()->texCoord); glEnableClientState(GL_NORMAL_ARRAY); glNormalPointer(GL_FLOAT, g_model.getVertexSize(), g_model.getVertexBuffer()->normal); glDrawElements(GL_TRIANGLES, pMesh->triangleCount * 3, GL_UNSIGNED_INT, g_model.getIndexBuffer() + pMesh->startIndex); glDisableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_VERTEX_ARRAY); } }
bool Convert(const char* pFilePath) { ModelOBJ model; FILE* pOutput = 0; SubMesh subMesh; static char pOutPath[MAX_PATH]; //open mesh if (!model.import(pFilePath)) { printf("Failed to open file '%s'!\n", pFilePath); return false; } //open output file ConvertFileName(pFilePath, pOutPath); if (fopen_s(&pOutput, pOutPath, "wb") != 0) { printf("Could not open output file '%s'!\n", pOutPath); return false; } //write basic info int verticesCount = model.getNumberOfVertices(); int indiciesCount = model.getNumberOfIndices(); int subMeshesCount = model.getNumberOfMeshes(); printf("Veritces count: %i\n", verticesCount); printf("Indicies count: %i\n", indiciesCount); printf("Submeshes count: %i\n", subMeshesCount); fwrite("nfm", 4, 1, pOutput); //signature fwrite(&verticesCount, sizeof(int), 1, pOutput); fwrite(&indiciesCount, sizeof(int), 1, pOutput); fwrite(&subMeshesCount, sizeof(int), 1, pOutput); //write verticies XVertex* pVertices = (XVertex*)malloc(verticesCount * sizeof(XVertex)); const ModelOBJ::Vertex* pModelVertices = model.getVertexBuffer(); for (int i = 0; i < verticesCount; i++) { //vertex position pVertices[i].pos[0] = pModelVertices[i].position[0]; pVertices[i].pos[1] = pModelVertices[i].position[1]; pVertices[i].pos[2] = -pModelVertices[i].position[2]; //vertex texture coordinates pVertices[i].texCoord[0] = pModelVertices[i].texCoord[0]; pVertices[i].texCoord[1] = pModelVertices[i].texCoord[1]; //vertex normal if (ISNAN(pModelVertices[i].normal[0]) || ISNAN(pModelVertices[i].normal[1]) || ISNAN(pModelVertices[i].normal[2])) { pVertices[i].normal[0] = 0; pVertices[i].normal[1] = 127; pVertices[i].normal[2] = 0; } else { pVertices[i].normal[0] = FloatToChar(pModelVertices[i].normal[0]); pVertices[i].normal[1] = FloatToChar(pModelVertices[i].normal[1]); pVertices[i].normal[2] = FloatToChar(-pModelVertices[i].normal[2]); } //vertex tangent if (ISNAN(pModelVertices[i].tangent[0]) || ISNAN(pModelVertices[i].tangent[1]) || ISNAN(pModelVertices[i].tangent[2])) { pVertices[i].tangent[0] = 127; pVertices[i].tangent[1] = 0; pVertices[i].tangent[2] = 0; } else { pVertices[i].tangent[0] = FloatToChar(pModelVertices[i].tangent[0]); pVertices[i].tangent[1] = FloatToChar(pModelVertices[i].tangent[1]); pVertices[i].tangent[2] = FloatToChar(-pModelVertices[i].tangent[2]); } pVertices[i].normal[3] = 0; pVertices[i].tangent[3] = 0; } fwrite(pVertices, sizeof(XVertex), verticesCount, pOutput); free(pVertices); //write indicies fwrite(model.getIndexBuffer(), sizeof(int), indiciesCount, pOutput); //write submeshes UINT triCounter = 0; for (int i = 0; i < model.getNumberOfMeshes(); i++) { ModelOBJ::Mesh srcMesh = model.getMesh(i); subMesh.indexOffset = srcMesh.startIndex; subMesh.triangleCount = srcMesh.triangleCount; ZeroMemory(subMesh.materialName, MAT_NAME_MAX_LENGTH); strcpy(subMesh.materialName, srcMesh.pMaterial->name.c_str()); fwrite(&subMesh, sizeof(SubMesh), 1, pOutput); } //close output file fclose(pOutput); //generate material files int matCount = model.getNumberOfMaterials(); for (int i = 0; i < matCount; i++) { const ModelOBJ::Material& mat = model.getMaterial(i); char fileName[MAX_PATH]; ExtractFileDir(pFilePath, fileName); strcat(fileName, "..\\Materials\\"); strcat(fileName, mat.name.c_str()); strcat(fileName, ".cfg"); //check if material already exists if (FileExists(fileName)) { printf("Material %s already exists. Skipping cfg generation...\n", mat.name.c_str()); continue; } FILE* pMatFile = fopen(fileName, "w"); fprintf(pMatFile, "Layers = \n(\n\t{\n"); if (mat.colorMapFilename.length()) fprintf(pMatFile, "\t\tDiffuseTexture = \"%s\"\n", mat.colorMapFilename.c_str()); if (mat.bumpMapFilename.length()) fprintf(pMatFile, "\t\tNormalTexture = \"%s\"\n", mat.bumpMapFilename.c_str()); fprintf(pMatFile, "\t}\n);"); fclose(pMatFile); } }