我正在尝试制作一个OBJ loder程序,但无论我怎么努力,它只是无法正常工作。有几张脸丢失了。我打开三角形面,并在Blender中保持顶点顺序,但我无法使它工作
这是我的OBJLoader代码:
#include "OBJLoader.h"
void OBJLoader::Load(string file){
int lines = 0;
int indexsize = 0;
int offset = 0;
vector<string> datalines;
vector<vec3> position;
vector<vec3> normal;
vector<vec2> texturecoord;
bool progress[] = { false, false, false, false};
bool succes = IOManager::readFiletoLines(file, datalines, lines);
if (!succes){
char* tmp = "";
cin >> tmp;
exit(-1);
}
int facecount = 0;
string::size_type sz;
for (int i = 0; i < lines-1; i++){
string line = datalines[i];
if (line.at(0) == 'v'){
if (line.at(1) == ' '){
if (!progress[0]){
cout << "Loading positions..." << endl;
progress[0] = true;
}
offset = 2;
float x = stof(line.substr(offset), &sz);
offset += sz+1;
float y = stof(line.substr(offset), &sz);
offset += sz+1;
float z = stof(line.substr(offset), &sz);
position.push_back(vec3(x, y, z));
continue;
}
else if (line.at(1) == 't'){
if (!progress[1]){
cout << "Loading texture coordinates..." << endl;
progress[1] = true;
}
offset = 3;
float u = stof(line.substr(offset), &sz);
offset += sz+1;
float v = stof(line.substr(offset), &sz);
texturecoord.push_back(vec2(u, v));
continue;
}else if (line.at(1) == 'n'){
if (!progress[2]){
cout << "Loading normals..." << endl;
progress[2] = true;
}
offset = 3;
float x = stof(line.substr(offset), &sz);
offset += sz+1;
float y = stof(line.substr(offset), &sz);
offset += sz+1;
float z = stof(line.substr(offset), &sz);
normal.push_back(vec3(x, y, z));
cout << "a";
continue;
}
}else if (line.at(0) == 'f'){
if (!progress[3]){
cout << "Loading faces..." << endl;
data.resize(position.size());
progress[3] = true;
}
facecount++;
cout << facecount << endl;
Vertex vertex;
Vertex vertex2;
Vertex vertex3;
//First corner
offset = 2;
int pos1=stoi(line.substr(offset), &sz);
offset += sz+1;
int tex1=stoi(line.substr(offset), &sz);
offset += sz+1;
int norm1=stoi(line.substr(offset), &sz);
//Second corner
offset += sz+1;
int pos2 = stoi(line.substr(offset), &sz);
offset += sz + 1;
int tex2 = stoi(line.substr(offset), &sz);
offset += sz + 1;
int norm2 = stoi(line.substr(offset), &sz);
//Third corner
offset += sz+1;
int pos3 = stoi(line.substr(offset), &sz);
offset += sz + 1;
int tex3 = stoi(line.substr(offset), &sz);
offset += sz + 1;
int norm3 = stoi(line.substr(offset), &sz);
//put the values into the data vector
vertex.postion(position[pos1 - 1].x, position[pos1 - 1].y, position[pos1 - 1].z);
vertex.textureUV(texturecoord[tex1 - 1].x, texturecoord[tex1 - 1].y);
vertex.normal(normal[norm1 - 1].x, normal[norm1 - 1].y, normal[norm1 - 1].z);
vertex.colorRGBA(1, 1, 1, 1);
data[pos1 - 1] = vertex;
vertex2.postion(position[pos2 - 1].x, position[pos2 - 1].y, position[pos2 - 1].z);
vertex2.textureUV(texturecoord[tex2 - 1].x, texturecoord[tex2 - 1].y);
vertex2.normal(normal[norm2 - 1].x, normal[norm2 - 1].y, normal[norm2 - 1].z);
vertex2.colorRGBA(1, 1, 1, 1);
data[pos2 - 1] = vertex2;
vertex3.postion(position[pos3 - 1].x, position[pos3 - 1].y, position[pos3 - 1].z);
vertex3.textureUV(texturecoord[tex3 - 1].x, texturecoord[tex3 - 1].y);
vertex3.normal(normal[norm3 - 1].x, normal[norm3 - 1].y, normal[norm3 - 1].z);
vertex3.colorRGBA(1, 1, 1, 1);
data[pos3 - 1] = vertex3;
indexdata.push_back(pos1-1);
indexdata.push_back(pos2-1);
indexdata.push_back(pos3-1);
}
}
}
这是我的渲染功能。
void Loader::Model(char* model,int texture){
if (!models[0]){
openGL.Load(model);
data = openGL.data;
indexdata = openGL.indexdata;
models[0] = true;
}
initeverything();
glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
glBufferData(GL_ARRAY_BUFFER, data.size()*sizeof(Vertex), &data.front() , GL_STATIC_DRAW);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, data.size()*sizeof(int), &indexdata.front(), GL_STATIC_DRAW);
cout << data[0].pos.x << endl;
glEnableVertexArrayAttrib(vao, 0);
glEnableVertexArrayAttrib(vao, 1);
glEnableVertexArrayAttrib(vao, 2);
glVertexAttribPointer(0, 3, GL_FLOAT, false, sizeof(Vertex), (void*)offsetof(Vertex, pos));
glVertexAttribPointer(1, 4, GL_FLOAT, false, sizeof(Vertex), (void*)offsetof(Vertex, color));
glVertexAttribPointer(2, 2, GL_FLOAT, false, sizeof(Vertex), (void*)offsetof(Vertex, vertUV));
glDrawElementsBaseVertex(GL_TRIANGLES, openGL.indexdata.size()*sizeof(int), GL_UNSIGNED_INT, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
它也发生在一个简单的立方体上。
是。那应该是一个立方体。
答案 0 :(得分:3)
如果我不得不猜测,我会说&#34;保持顶点顺序&#34;旗帜可能是问题。 OpenGL通常会剔除不是CounterClockWise定向的面,并且基于被剔除的三角形(在表面上显示为受影响对象的每个其他面),它们可能是那些三角形的顶点以ClockWise顺序绘制。
为简单起见,您可以简单地告诉OpenGL不要剔除面孔:
<div class="collapse navbar-collapse" id = "main-nav-collapse">
<div class="nav navbar-nav navbar-right">
<% if current_user %>
<%= button_to "Sign Out", destroy_user_session_path, method: :delete, class: "btn btn-primary navbar-btn" %>"
<% else %>
<%= link_to "Log In", new_user_session_path, class: "btn btn-primary navbar-btn", method: :get %>
<%= link_to "Sign Up", new_user_registration_path, class: "btn btn-success navbar-btn", method: :get %>
<% end %>
<ul class="nav navbar-nav">
<li><%= link_to "About", about_path %></li>
<li><%= link_to "Contact Us", new_contact_path %></li>
</ul>
</div>
</div> <!-- /.navbar-collapse -->
但更好的解决方案可能是确保缠绕顺序在物体的所有面上都是一致的。