I use OpenGL + OpenMesh to render a 3d mesh
My mesh reading and processing code:
void read(MyMesh &model, const string &path) {
model.request_vertex_colors();
model.request_face_normals();
OpenMesh::IO::Options opt;
opt += OpenMesh::IO::Options::VertexColor;
opt += OpenMesh::IO::Options::FaceNormals;
if (!OpenMesh::IO::read_mesh(model, path, opt)) {
cerr << "read error\n";
exit(1);
}
// fill the vertices and normals array
for (auto f : model.faces())
for (auto v : model.fv_range(f)){ // how can I get vertex texcoords based on face?
vertices.push_back(model.point(v));
normals.push_back(model.normal(f));
colors.push_back(model.color(v));
}
model.release_vertex_colors();
model.release_face_normals();
}
But I find that I can't get vertex texcoords based on the face in OpenMesh.
It seems there isn't a function called model.texcoords(face_handle, vertex_handle)
to let me get the vertex texcoords on this face.
Or can I get the texcoords index of each face like these in obj file:
f 481/1/1 480/2/1 24/3/1 25/4/1
f 477/5/2 7/6/2 17/7/2 18/8/2
f 1/9/3 326/10/3 11/11/3
f 482/12/4 481/1/4 25/4/4
f 478/13/5 477/5/5 18/8/5 19/14/5
f 2/15/6 1/9/6 11/11/6 12/16/6
f 479/17/7 478/13/7 19/14/7 20/18/7
f 3/19/8 2/15/8 12/16/8 13/20/8
f 8/21/9 479/17/9 20/18/9 21/22/9
I use glDrawArrays(...) to draw mesh.
Declarations
vector<MyMesh::Point> vertices; // `MyMesh::Point` is like float3 struct which has 3 float numbers in it
vector<MyMesh::Point> normals;
vector<MyMesh::Point> colors;
unsigned int model_vbo[3], model_vao;
Data bind
glGenBuffers(3, model_vbo);
glGenVertexArrays(1, &model_vao);
glBindBuffer(GL_ARRAY_BUFFER, model_vbo[0]);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * 3 * sizeof(float), vertices.data(), GL_DYNAMIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, model_vbo[1]);
glBufferData(GL_ARRAY_BUFFER, colors.size() * sizeof(float), colors.data(), GL_DYNAMIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, model_vbo[2]);
glBufferData(GL_ARRAY_BUFFER, normals.size() * sizeof(float), normals.data(), GL_DYNAMIC_DRAW);
glBindVertexArray(model_vao);
glBindBuffer(GL_ARRAY_BUFFER, model_vbo[0]);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), nullptr);
glBindBuffer(GL_ARRAY_BUFFER, model_vbo[1]);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), nullptr);
glBindBuffer(GL_ARRAY_BUFFER, model_vbo[2]);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), nullptr);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, 0);
Draw loop
s.use();
s.setMat4("model", Rotate * Scale);
s.setMat4("projection", cam.projection());
s.setMat4("view", cam.view());
glBindVertexArray(model_vao);
glDrawArray(GL_TRIANGLES, 0, vertices.size() / 3);
vertex shader
#version 450 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 color;
layout (location = 2) in vec3 normal;
uniform mat4 model;
uniform mat4 projection;
uniform mat4 view;
out vec3 Color;
out vec3 Normal;
void main(){
Normal = normal;
Color = color;
gl_Position = projection * view * model * vec4(position, 1.0);
}
fragment shader
#version 450 core
out vec4 scene_color;
in vec3 Color; // vertex color
in vec3 Normal;
void main(){
scene_color = vec4(Color,1.0);
}