//----------------------------------------------------------------------- MeshReadHelper::Face MeshReadHelper::getFace(size_t _subMeshIndex, size_t _faceIndex) { if(_subMeshIndex != mCurSubMeshInfoFi) { prepareFaces(_subMeshIndex); } Face face; size_t indexInID = _faceIndex * 3 + mCurSubMeshInfoF->indexStart; switch(mIndexType) { case HardwareIndexBuffer::IT_16BIT: { face.i[0] = ((uint16*) mIndexPtr)[indexInID + 0]; face.i[1] = ((uint16*) mIndexPtr)[indexInID + 1]; face.i[2] = ((uint16*) mIndexPtr)[indexInID + 2]; break; } case HardwareIndexBuffer::IT_32BIT: { face.i[0] = ((uint32*) mIndexPtr)[indexInID + 0]; face.i[1] = ((uint32*) mIndexPtr)[indexInID + 1]; face.i[2] = ((uint32*) mIndexPtr)[indexInID + 2]; break; } } size_t ofs = mCurSubMeshInfoF->vertexStartInJoinedList - mCurSubMeshInfoF->vertexStart; face.i[0] += ofs; face.i[1] += ofs; face.i[2] += ofs; return face; }
//----------------------------------------------------------------------- const String& MeshReadHelper::getMaterialName(size_t _subMeshIndex) { if(_subMeshIndex != mCurSubMeshInfoFi) { prepareFaces(_subMeshIndex); } return mCurSubMeshInfoF->subMesh->getMaterialName(); }
//----------------------------------------------------------------------- size_t MeshReadHelper::getNumFaces(size_t _subMeshIndex) { if(_subMeshIndex != mCurSubMeshInfoFi) { prepareFaces(_subMeshIndex); } return mCurSubMeshInfoF->indexCount / 3; }
//------------------------------------------------------------------------------------------------------- bool Exporter::processMesh(RawMesh& rawMesh, const char* fileName) { rawMesh_ = &rawMesh; meshData_.reset(new(std::nothrow) Mesh::Data); if(!meshData_) { std::cout << "error: not enough memory" << std::endl; return false; } numVertices_ = rawMesh_->positions_.getSize(); meshData_->boundingBox = rawMesh_->boundingBox_; boneIndices_.destroy(); boneWeights_.destroy(); vertices_.clear(); newToOldVertexMapping_.clear(); std::cout << "processing raw mesh..." << std::endl; faces_ = rawMesh_->faces_; if(faces_.getSize() != rawMesh_->faces_.getSize()) { std::cout << "error: not enough memory" << std::endl; return false; } std::cout << "merging faces..." << std::endl; numVertices_ = mergeFaces(faces_, rawMesh_->normalFaces_, faces_, numVertices_); if(numVertices_ == 0) { std::cout << "error: could not merge faces" << std::endl; return false; } numVertices_ = mergeFaces(faces_, rawMesh_->textureFaces_, faces_, numVertices_); if(numVertices_ == 0) { std::cout << "error: could not merge faces" << std::endl; return false; } if(!rawMesh_->bones_.isEmpty()) { std::cout << "reading bone indices and weights..." << std::endl; if(!boneIndices_.create(numVertices_) || !boneWeights_.create(numVertices_)) { std::cout << "error: not enough memory" << std::endl; return false; } uint32_t numFaces = faces_.getSize(); for(uint32_t i = 0; i < numFaces; ++i) { const RawMesh::Face& face = rawMesh_->faces_[i]; for(uint8_t j = 0; j < 3; ++j) { uint32_t vertexIndex = faces_[i].indices[j]; boneIndices_[vertexIndex] = rawMesh_->boneIndices_[face.indices[j]]; boneWeights_[vertexIndex] = rawMesh_->boneWeights_[face.indices[j]]; } } } std::cout << "computing tangent space..." << std::endl; if(!computeTangentSpace()) { std::cout << "error: broken mesh" << std::endl; return false; } std::cout << "preparing vertex streams..." << std::endl; if(!prepareVertexStreams()) { std::cout << "error: not enough memory" << std::endl; return false; } std::cout << "preparing faces..." << std::endl; if(!prepareFaces()) { std::cout << "error: not enough memory" << std::endl; return false; } std::cout << "preparing subsets..." << std::endl; if(!prepareSubsets()) { std::cout << "error: not enough memory" << std::endl; return false; } if(!rawMesh_->bones_.isEmpty()) { std::cout << "preparing skeleton..."; auto& skeleton = meshData_->skeleton; skeleton.reset(new(std::nothrow) Skeleton); if(!skeleton) { std::cout << "error: not enough memory" << std::endl; return false; } skeleton->getBones() = rawMesh_->bones_; if(skeleton->getBones().getSize() != rawMesh_->bones_.getSize()) { std::cout << "error: not enough memory" << std::endl; return false; } } std::cout << "writing mesh to the file..." << std::endl; std::ofstream stream(fileName, std::ios_base::binary); MeshManager meshManager; if(!meshManager.writeMesh(stream, *meshData_)) { std::cout << "error: could not write mesh to the file" << std::endl; return false; } std::cout << "mesh has " << numVertices_; std::cout << " vertices and " << faces_.getSize() << " faces" << std::endl; return true; }
void Game::run() { // build and compile our shader program Shader ourShader("basic.vert", "basic.frag"); // load the map auto result = bsp.parse(mapName.c_str()); prepareFaces(); ///////////////////////////////////// glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); glEnable(GL_DEBUG_OUTPUT); glDebugMessageCallback(openglCallbackFunction, nullptr); GLuint VBO, VAO, EBO; glGenVertexArrays(1, &VAO); glGenBuffers(1, &VBO); glGenBuffers(1, &EBO); // Bind the Vertex Array Object first, then bind and set vertex buffer(s) and attribute pointer(s). glBindVertexArray(VAO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int)*indexes.size(), &indexes[0], GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, bsp.getVertexes().size() * sizeof(BSP_vertex), &bsp.getVertexes()[0], GL_STATIC_DRAW); // Position attribute glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(BSP_vertex), (GLvoid*)0); glEnableVertexAttribArray(0); // Color attribute glVertexAttribPointer(1, 4, GL_BYTE, GL_FALSE, sizeof(BSP_vertex), (GLvoid*)((10 * sizeof(GL_FLOAT)))); glEnableVertexAttribArray(1); // Texel attribute glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(BSP_vertex), (GLvoid*)((3 * sizeof(GL_FLOAT)))); glEnableVertexAttribArray(2); // Texture array depth/id attribute glVertexAttribIPointer(3, 1, GL_INT, sizeof(BSP_vertex), (GLvoid*)((4 * sizeof(GLbyte)) + (10 * sizeof(GL_FLOAT)))); glEnableVertexAttribArray(3); // Lightmap array depth/id attribute glVertexAttribIPointer(4, 1, GL_INT, sizeof(BSP_vertex), (GLvoid*)((1 * sizeof(GLint)) + (4 * sizeof(GLbyte)) + (10 * sizeof(GL_FLOAT)))); glEnableVertexAttribArray(4); // Lightmap uv glVertexAttribPointer(5, 2, GL_FLOAT, GL_FALSE, sizeof(BSP_vertex), (GLvoid*)(5 * sizeof(GL_FLOAT))); glEnableVertexAttribArray(5); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glBindVertexArray(0); // Unbind VAO glm::mat4 projection = camera.getProjection(); camera.setPosition(glm::vec3(0.0, 0.0, 40.0)); ourShader.Use(); auto texLocation = glGetUniformLocation(ourShader.Program, "_texture"); auto lmLocation = glGetUniformLocation(ourShader.Program, "_lightmap"); glUniform1i(texLocation, 0); glUniform1i(lmLocation, 1); assert(texLocation != -1, "texLocation uniform was optimized"); assert(lmLocation != -1, "lmLocation uniform was optimized"); while (!glfwWindowShouldClose(window)) { deltaTime = glfwGetTime() - lastFrameTime; lastFrameTime = glfwGetTime(); // Check if any events have been activiated (key pressed, mouse moved etc.) and call corresponding response functions glfwPollEvents(); processInputs(); // Render // Clear the colorbuffer glClearColor(0.3f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glActiveTexture(GL_TEXTURE0 + 0); glBindTexture(GL_TEXTURE_2D_ARRAY, bsp.getTextureHandle()); glActiveTexture(GL_TEXTURE0 + 1); glBindTexture(GL_TEXTURE_2D_ARRAY, bsp.getLightmapHandle()); GLint modelLoc = glGetUniformLocation(ourShader.Program, "model"); GLint viewLoc = glGetUniformLocation(ourShader.Program, "view"); GLint projLoc = glGetUniformLocation(ourShader.Program, "projection"); GLint angleLoc = glGetUniformLocation(ourShader.Program, "angle"); glm::mat4 view; camera.setDeltaTime(deltaTime); view = camera.getView(); // Get their uniform location glUniform1f(angleLoc, glfwGetTime()); glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view)); glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection)); glm::mat4 model = glm::mat4(1.0); // just identity glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model)); glBindVertexArray(VAO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); glDrawElements(GL_TRIANGLES, indexes.size(), GL_UNSIGNED_INT, 0); glBindVertexArray(0); glfwSwapBuffers(window); } // Properly de-allocate all resources once they've outlived their purpose glDeleteVertexArrays(1, &VAO); glDeleteBuffers(1, &VBO); glfwTerminate(); }