为什么我的网格没有正确绘制?我从文件中加载了一个.OBJ模型并尝试绘制它但它总是变形。任何帮助将不胜感激。
这是我的代码:
void Renderer::draw_model(const std::vector<Vector3>& vertex_array, const std::vector<unsigned int>& element_array, const std::vector<Vector2>& uv_array, const std::vector<Vector3>& normal_array, double x, double y, double z, double rx, double ry, double rz, double sx, double sy, double sz, const std::vector<Texture *>& texture_array, double red, double green, double blue, double alpha)
{
#ifdef DOKUN_OPENGL // OpenGL is defined
if(get_current_rendering_API() != "OpenGL") // but it is not set as the current rendering API
return;
#ifdef __windows__
if(!wglGetCurrentContext())
{
Logger("Rendering Failed : No OpenGL Context found");
return;
}
#endif
#ifdef __gnu_linux__
#ifdef DOKUN_X11
if(!glXGetCurrentContext())
{
Logger("Rendering failed : No OpenGL Context found");
return;
}
#endif
#endif
if(vertex_array.empty())
{
Logger("Rendering failed : Vertex list is empty!");
return;
}
if(element_array.empty())
{
Logger("Rendering failed : Element list is empty!");
return;
}
const GLchar * vertex_source[] =
{
"#version 400\n"
"layout(location = 0) in vec3 position;\n"
"layout(location = 1) in vec2 tex_coord;\n"
"layout(location = 2) in vec3 normal;\n"
" \n"
" \n"
" \n"
"uniform mat4 proj; // zooming \n"
"uniform mat4 view; // camera pos \n"
"uniform mat4 model; // object \n"
" \n"
" \n"
" \n"
" \n"
"out vec3 Normal ;\n"
"out vec2 Texcoord;\n"
"\n"
"out vec3 frag_position;\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"void main(void) \n"
"{ \n"
"//frag_position = vec3(model * vec4(position, 1));\n"
"Texcoord = tex_coord;\n"
"Normal = mat3(transpose(inverse(model))) * normal;//normal;\n"
"gl_Position = proj * view * model * vec4(position, 1.0);\n"
"} \n"
};
const GLchar * fragment_source[] = // holds all color
{
"#version 400 \n"
" \n"
"out vec4 out_color; \n"
"uniform vec4 color;\n"
"\n"
"\n"
"in vec3 Normal ;\n"
"in vec2 Texcoord;\n"
"\n"
"in vec3 frag_position;\n"
"\n"
"\n"
"\n"
"uniform vec3 light_color ;\n"
"uniform vec3 light_position;\n"
"\n"
"\n"
"\n"
"void main(void) \n"
"{ \n"
"\n"
"vec3 light_direction = normalize(light_position - frag_position);\n"
"vec3 ambient = 0.1f * light_color;\n"
"vec3 diffuse = max(dot(normalize(Normal), light_direction), 0.0) * light_color;\n"
"\n"
"\n"
"out_color = vec4((ambient + diffuse) * color.xyz, 1.0); \n"
"} \n"
};
glEnable(GL_DEPTH_TEST); // enable depth
glEnable(GL_CULL_FACE );
// Set mode
//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); // GL_POINT, GL_LINE, GL_FILL,
//--------------
// shaders
Shader vertex_shader ;
Shader fragment_shader;
vertex_shader.create(DOKUN_SHADER_VERTEX);
vertex_shader.set_source(vertex_source);
vertex_shader.compile();
fragment_shader.create(DOKUN_SHADER_FRAGMENT);
fragment_shader.set_source(fragment_source);
fragment_shader.compile();
// program
Program program;
program.create();
program.attach(vertex_shader );
program.attach(fragment_shader);
program.link();
// delete shaders after linking them to the program
vertex_shader.destroy ();
fragment_shader.destroy();
// use program
program.use ();
//---------------
// set uniforms
////////////////////////
// light
if(program.get_uniform("light_color" ) != -1) program.set_uniform("light_color", 1.0f, 1.0f, 1.0f);//, (alpha / 255));
if(program.get_uniform("light_position" ) != -1) program.set_uniform("light_position", 1,1,1);//static_cast<float>(x), static_cast<float>(y), static_cast<float>(z));//, (alpha / 255));
////////////////////////
// camera
glm::vec3 eye = glm::vec3(camera->get_position().x, camera->get_position().y, camera->get_position().z);
glm::vec3 center = glm::vec3(camera->get_position().x + camera->get_view().x, camera->get_position().y + camera->get_view().y, camera->get_position().z + camera->get_view().z);
glm::vec3 up = glm::vec3(camera->get_up().x , camera->get_up().y , camera->get_up().z);
////////////////////////
#ifdef use_glm
glm::mat4 model;
model = glm::scale(model, glm::vec3(static_cast<float>(sx),
static_cast<float>(sy),
static_cast<float>(sz)));
model = glm::rotate(model, static_cast<float>(rx), glm::vec3(1, 0, 0));
model = glm::rotate(model, static_cast<float>(ry), glm::vec3(0, 1, 0));
model = glm::rotate(model, static_cast<float>(rz), glm::vec3(0, 0, 1));
model = glm::translate(model, glm::vec3(static_cast<float>(x),
static_cast<float>(y),
static_cast<float>(z)));
glm::mat4 view = glm::lookAt(eye, center, up);
glm::mat4 proj = glm::perspective(67.5f, static_cast<float>(800 / 600), 1.0f, 1024.0f); // average fov = 67.5 45 + 90 = 135 / 2 = 67.5 | znear=1 zfar=1024
glm::mat4 modelview = model * view;
glUniformMatrix4fv(glGetUniformLocation((GLuint)program.get_id(), "model"), 1, false, glm::value_ptr(model) ); // object
glUniformMatrix4fv(glGetUniformLocation((GLuint)program.get_id(), "view"), 1, false, glm::value_ptr(view) ); // camera
glUniformMatrix4fv(glGetUniformLocation((GLuint)program.get_id(), "proj"), 1, false, glm::value_ptr(proj) ); // zoom
#endif
////////////////////////
if(program.get_uniform("color") != -1) program.set_uniform("color", (red / 255), (green / 255), (blue / 255), (alpha / 255));
//program.get_default()->set_uniform("base", static_cast<int>(0)); // bind to texture unit 0
////////////////////////
// texture data
/*
GLuint * texture = new GLuint[8]; // 256 would be ideal
for(unsigned int i = 0; i < texture_array.size(); i++) // for each texture
{
std::cout << "GENERATING TEXTURES...." << std::endl;
glGenTextures(8, texture); // generate 256 textures
glActiveTexture(GL_TEXTURE0 + i);
glBindTexture( GL_TEXTURE_2D, (GLuint)texture[i] );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, texture_array[i]->get_width(), texture_array[i]->get_height(), 0, GL_RGBA,
GL_UNSIGNED_BYTE, texture_array[i]->get_data() );
glGenerateMipmap(GL_TEXTURE_2D);
}
*/
///////////////////////
///////////////////////
// vertex array obj
GLuint vertex_array_obj;
glGenVertexArrays(1, &vertex_array_obj);
// vertex buffer obj - for drawing
glBindVertexArray(vertex_array_obj); // bind vertex array obj to vertex attrib ptr
GLuint vertex_buffer_obj;
glGenBuffers(1, & vertex_buffer_obj);
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_obj);
glBufferData(GL_ARRAY_BUFFER, vertex_array.size() , &vertex_array[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_DOUBLE, GL_FALSE, 0, static_cast<void*>(0));
glBindVertexArray(0); // unbind
// tex_coord buffer obj - for texture mapping
GLuint uv_buffer_obj;
if(!uv_array.empty())
{
glBindVertexArray(vertex_array_obj); // bind
glGenBuffers(1, & uv_buffer_obj);
glBindBuffer(GL_ARRAY_BUFFER, uv_buffer_obj);
glBufferData(GL_ARRAY_BUFFER, uv_array.size() , &uv_array[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_DOUBLE, GL_FALSE, 0, static_cast<void*>(0));
glBindVertexArray(0); // unbind
}
// normal buffer - for lighting
GLuint normal_buffer_obj;
if(!normal_array.empty())
{
glBindVertexArray(vertex_array_obj); // bind
glGenBuffers(1, & normal_buffer_obj);
glBindBuffer(GL_ARRAY_BUFFER, normal_buffer_obj);
glBufferData(GL_ARRAY_BUFFER, normal_array.size(), &normal_array[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 3, GL_DOUBLE, GL_FALSE, 0, static_cast<void*>(0));
glBindVertexArray(0); // unbind
}
// element buffer - specifies order in which vertices are to be drawn
glBindVertexArray(vertex_array_obj); // bind
GLuint index_buffer_obj;
glGenBuffers(1, & index_buffer_obj);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer_obj);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, element_array.size(), &element_array[0], GL_STATIC_DRAW);
glBindVertexArray(0);
// Draw the model !
glBindVertexArray(vertex_array_obj); // bind
glDrawElements(GL_TRIANGLES, element_array.size(), GL_UNSIGNED_INT, 0);//glDrawElements(GL_TRIANGLES, element_array.size(), GL_UNSIGNED_INT, &element_array[0]); // elements - order in which vertices are to be drawn
glBindVertexArray(0); // unbind
////////////////////////
// cleanup
// textures
//if(texture_array.size() > 0)
// glDeleteTextures(8, texture);
// attributes
glDisableVertexAttribArray(0); // drawing
glDisableVertexAttribArray(1); // texture mapping
glDisableVertexAttribArray(2); // lighting
// buffers
glDeleteBuffers(1, & vertex_buffer_obj );
glDeleteBuffers(1, & uv_buffer_obj );
glDeleteBuffers(1, & normal_buffer_obj );
glDeleteBuffers(1, & index_buffer_obj );
// arrays
glDeleteVertexArrays(1, & vertex_array_obj);
//glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
// program
program.disable();
#endif
}
这是以下代码的结果:
答案 0 :(得分:1)
所有glBufferData
次调用中的size参数都是错误的。此函数需要 byte 中的数据量,但是例如在此行中提供:
glBufferData(GL_ARRAY_BUFFER, vertex_array.size() , &vertex_array[0], GL_STATIC_DRAW);
作为元素的数量。你真正需要的是这样的:
glBufferData(GL_ARRAY_BUFFER, vertex_array.size() * sizeof(Vector3), &vertex_array[0], GL_STATIC_DRAW);
(假设Vector3恰好包含3个双打)。
作为旁注:以双精度提供顶点信息的情况并不常见。因此,如果没有特殊原因,我建议改为使用float
。