使用OpenGL和顶点数组对象渲染两个对象 [英] Rendering two objects with OpenGL and vertex array objects
问题描述
我正在尝试将OpenGL与着色器一起使用,以在屏幕上渲染两个三角形.大红色,小蓝色.每个三角形由一组顶点位置和颜色以及一组顶点索引定义.我为每个三角形使用了不同的顶点数组对象.
I am trying to use OpenGL with shaders to render two triangles on my screen; a big red one, and a smaller blue one. Each triangle is defined by a set of vertex positions and colours, together with a set of vertex indices. I am using a different vertex array object for each triangle.
下面是我的代码,我将其简化为最小的可编译示例,该示例仍然给我带来了问题.问题在于仅渲染了第二个三角形(object2,小的蓝色三角形).因此,即使我将顶点数组对象绑定到第一个三角形(object1,大红色三角形),然后绘制元素,也不会渲染该对象.
Below is my code, which I have reduced to the smallest compilable example which is still giving me problems. The problem is that only the second triangle (object2, the small blue triangle) is rendered. So even though I am binding the vertex array object for the first triangle (object1, the big red triangle), and then drawing the elements, this object is not rendered.
我在做什么错了?
#include <GL/glew.h>
#include <GL/glut.h>
#include <Eigen/Eigen>
#include <fstream>
GLuint object1_vertex_buffer, object1_colour_buffer, object1_index_buffer, object1_vertex_array;
GLuint object2_vertex_buffer, object2_colour_buffer, object2_index_buffer, object2_vertex_array;
GLuint shader_program, vertex_shader, fragment_shader;
void RenderScene()
{
glClear(GL_COLOR_BUFFER_BIT);
glClear(GL_DEPTH_BUFFER_BIT);
glBindVertexArray(object1_vertex_array);
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, (void*)0);
glBindVertexArray(object2_vertex_array);
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, (void*)0);
glutSwapBuffers();
}
int main(int argc, char** argv)
{
// Make the objects
Eigen::Vector3f object1_vertices[3];
object1_vertices[0] << 0, 0, 0;
object1_vertices[1] << 0.8, 0, 0;
object1_vertices[2] << 0.8, 0.8, 0;
Eigen::Vector3f object1_colours[3];
object1_colours[0] << 1.0, 0.0, 0.0;
object1_colours[1] << 1.0, 0.0, 0.0;
object1_colours[2] << 1.0, 0.0, 0.0;
int object1_indices[3];
object1_indices[0] = 0;
object1_indices[1] = 1;
object1_indices[2] = 2;
Eigen::Vector3f object2_vertices[3];
object2_vertices[0] << 0, 0, 0;
object2_vertices[1] << 0.5, 0, 0;
object2_vertices[2] << 0.5, 0.5, 0;
Eigen::Vector3f object2_colours[3];
object2_colours[0] << 0.0, 0.0, 1.0;
object2_colours[1] << 0.0, 0.0, 1.0;
object2_colours[2] << 0.0, 0.0, 1.0;
int object2_indices[3];
object2_indices[0] = 0;
object2_indices[1] = 1;
object2_indices[2] = 2;
// Set up OpenGL
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowSize(1000, 1000);
glutCreateWindow("Test");
glutDisplayFunc(RenderScene);
glewInit();
glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
glEnable(GL_DEPTH_TEST);
// Make the buffers
glGenBuffers(1, &object1_vertex_buffer);
glGenBuffers(1, &object1_colour_buffer);
glGenBuffers(1, &object1_index_buffer);
glGenVertexArrays(1, &object1_vertex_array);
glGenBuffers(1, &object2_vertex_buffer);
glGenBuffers(1, &object2_colour_buffer);
glGenBuffers(1, &object2_index_buffer);
glGenVertexArrays(1, &object2_vertex_array);
// Fill the buffer data
glBindVertexArray(object1_vertex_array);
glBindBuffer(GL_ARRAY_BUFFER, object1_vertex_buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(object1_vertices), &object1_vertices[0], GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, object1_colour_buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(object1_colours), &object1_colours[0], GL_STATIC_DRAW);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, object1_index_buffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 3 * sizeof(int), &object1_indices[0], GL_STATIC_DRAW);
glBindVertexArray(object2_vertex_array);
glBindBuffer(GL_ARRAY_BUFFER, object2_vertex_buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(object2_vertices), &object2_vertices[0], GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, object2_colour_buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(object2_colours), &object2_colours[0], GL_STATIC_DRAW);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, object2_index_buffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 3 * sizeof(int), &object2_indices[0], GL_STATIC_DRAW);
// Make the shader program
shader_program = glCreateProgram();
vertex_shader = glCreateShader(GL_VERTEX_SHADER);
std::ifstream vertex_file_in;
vertex_file_in.open("../src/vertex-shader.glsl");
std::stringstream vertex_file_stream;
vertex_file_stream << vertex_file_in.rdbuf();
std::string vertex_shader_string = vertex_file_stream.str();
std::cout << vertex_shader_string << std::endl;
const GLchar* ptr_vertex_shader_string = &vertex_shader_string[0];
const GLchar** vertex_shader_strings = &ptr_vertex_shader_string;
int vertex_shader_lengths[] = {(int)vertex_shader_string.length()};
glShaderSource(vertex_shader, 1, vertex_shader_strings, vertex_shader_lengths);
glCompileShader(vertex_shader);
glAttachShader(shader_program, vertex_shader);
fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
std::ifstream fragment_file_in;
fragment_file_in.open("../src/fragment-shader.glsl");
std::stringstream fragment_file_stream;
fragment_file_stream << fragment_file_in.rdbuf();
std::string fragment_shader_string = fragment_file_stream.str();
const GLchar* ptr_fragment_shader_string = &fragment_shader_string[0];
const GLchar** fragment_shader_strings = &ptr_fragment_shader_string;
int fragment_shader_lengths[] = {(int)fragment_shader_string.length()};
glShaderSource(fragment_shader, 1, fragment_shader_strings, fragment_shader_lengths);
glCompileShader(fragment_shader);
glAttachShader(shader_program, fragment_shader);
glBindAttribLocation(shader_program, 0, "position");
glBindAttribLocation(shader_program, 1, "colour");
glLinkProgram(shader_program);
glUseProgram(shader_program);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
// Run the main loop
glutMainLoop();
}
........
........
........
// Vertex shader
#version 330
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 colour;
out vec4 frag_colour;
void main()
{
gl_Position = vec4(position, 1.0);
frag_colour = vec4(colour, 1.0);
}
........
........
........
// Fragment shader
#version 330
in vec4 frag_colour;
void main()
{
gl_FragColor = frag_colour;
}
推荐答案
glEnableVertexAttribArray
必须为每个变量调用:
glEnableVertexAttribArray
must be called for each vao:
// Fill the buffer data
glBindVertexArray(object1_vertex_array);
glBindBuffer(GL_ARRAY_BUFFER, object1_vertex_buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(object1_vertices), &object1_vertices[0], GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, object1_colour_buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(object1_colours), &object1_colours[0], GL_STATIC_DRAW);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, object1_index_buffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 3 * sizeof(int), &object1_indices[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glBindVertexArray(object2_vertex_array);
glBindBuffer(GL_ARRAY_BUFFER, object2_vertex_buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(object2_vertices), &object2_vertices[0], GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, object2_colour_buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(object2_colours), &object2_colours[0], GL_STATIC_DRAW);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, object2_index_buffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 3 * sizeof(int), &object2_indices[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
这篇关于使用OpenGL和顶点数组对象渲染两个对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!