我正在使用 PMP(多边形网格处理)库来执行网格细分。首先,我使用函数 mesh.add_vertex_property
我的主要功能是
Assimp::Importer importer;
const aiScene* scene = importer.ReadFile("bun_zipper.ply", aiProcess_Triangulate | aiProcess_GenNormals);
pmp::SurfaceMesh mesh_;
auto normals = mesh_.add_vertex_property<pmp::Normal>("v:normal");
auto positions = mesh_.add_vertex_property<pmp::Point>("v:position");
auto originPositions = mesh_.add_vertex_property<pmp::vec3>("v:oriPos");
if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode)
{
cout << !scene << endl;
cout << "ERROR::ASSIMP:: " << importer.GetErrorString() << endl;
return 0;
}
int num = 0;
for (unsigned int i = 0; i < scene->mNumMeshes; i++)
{
const aiMesh* mesh = scene->mMeshes[i];
std::vector<pmp::Vertex> vertices;
for (unsigned int k = 0; k < mesh->mNumVertices; k++)
{
aiVector3D pos = mesh->mVertices[k];
aiVector3D normal = mesh->mNormals[k];
pmp::Vertex v = mesh_.add_vertex(pmp::Point(pos.x, pos.y, pos.z));
positions[v] = pmp::Point(pos.x, pos.y, pos.z);
originPositions[v] = pmp::vec3(pos.x, pos.y, pos.z);
normals[v] = pmp::Normal(normal.x, normal.y, normal.z);
vertices.push_back(v);
}
for (unsigned int k = 0; k < mesh->mNumFaces; k++)
{
const aiFace& face = mesh->mFaces[k];
if (face.mNumIndices != 3)
{
cout << face.mNumIndices;
}
mesh_.add_triangle(vertices[face.mIndices[0]], vertices[face.mIndices[1]], vertices[face.mIndices[2]]);
}
}
pmp::Subdivision subdivision(mesh_);
subdivision.loop();
auto oripos = mesh_.get_vertex_property<pmp::vec3>("v:oriPos");
auto norm = mesh_.get_vertex_property<pmp::Normal>("v:normal");
for (unsigned int k = 0; k < mesh->mNumFaces; k++)
{
const aiFace& face = mesh->mFaces[k];
if (face.mNumIndices != 3)
{
cout << face.mNumIndices;
}
mesh_.add_triangle(vertices[face.mIndices[0]],vertices[face.mIndices[1]],vertices[face.mIndices[2]]);
}
}
pmp::Subdivision subdivision(mesh_);
subdivision.loop();
auto oripos = mesh_.get_vertex_property<pmp::vec3>("v:oriPos");
auto norm = mesh_.get_vertex_property<pmp::Normal>("v:normal");
std::vector<GLfloat> vertices;
for (auto v : mesh_.vertices()) {
vertices.push_back(oripos[v][0]);
vertices.push_back(oripos[v][1]);
vertices.push_back(oripos[v][2]);
vertices.push_back(norm[v][0]);
vertices.push_back(norm[v][1]);
vertices.push_back(norm[v][2]);
}
std::vector<GLuint> indices;
for (auto face: mesh_.faces())
{
for (auto v : mesh_.vertices(face))
{
indices.push_back(v.idx());
}
}
Shader lineShader("bunny_shader.vert", "bunny_line_shader.fs");
unsigned int VAO, VBO, EBO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * vertices.size(), vertices.data(), GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 6, (void*)(0));
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 6, (void*)(sizeof(GLfloat) * 3));
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLfloat)* indices.size(), indices.data(), GL_STATIC_DRAW);
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
while (!glfwWindowShouldClose(window))
{
float currentFrame = static_cast\<float\>(glfwGetTime());
deltaTime = currentFrame - lastFrame;
lastFrame = currentFrame;
processInput(window);
glClearColor(0.5, 0.5, 0.5, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
lineShader.use();
glm::mat4 projection = glm::perspective(glm::radians(camera.Zoom), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);
glm::mat4 view = camera.getViewMat();
lineShader.setMat4("projection", projection);
lineShader.setMat4("view", view);
glm::mat4 model1 = glm::mat4(1.0f);
model1 = glm::rotate(model1, glm::radians(180.0f), glm::vec3(0.0f, 0.0f, 1.0f));
model1 = glm::scale(model1, glm::vec3(1.0f, 1.0f, 1.0f));
lineShader.setMat4("model", model1);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES,static_cast<unsigned int>(indices.size()),GL_UNSIGNED_INT,0);
glfwPollEvents();
glfwSwapBuffers(window);
}
属性一和属性二的代码唯一不同的是,从mesh_中导入了数据
std::vector<GLfloat> vertices
,如下:
属性一(无法渲染)
std::vector<GLfloat> vertices;
for (auto v : mesh_.vertices()) {
vertices.push_back(oripos[v][0]);
vertices.push_back(oripos[v][1]);
vertices.push_back(oripos[v][2]);
vertices.push_back(norm[v][0]);
vertices.push_back(norm[v][1]);
vertices.push_back(norm[v][2]);
}
属性二(可渲染)
std::vector<GLfloat> vertices;
for (auto v : mesh_.vertices()) {
vertices.push_back(mesh_.position(v)[0]);
vertices.push_back(mesh_.position(v)[1]);
vertices.push_back(mesh_.position(v)[2]);
vertices.push_back(norm[v][0]);
vertices.push_back(norm[v][1]);
vertices.push_back(norm[v][2]);
}