使用OpenGL和顶点数组对象渲染两个对象 [英] Rendering two objects with OpenGL and vertex array objects

查看:81
本文介绍了使用OpenGL和顶点数组对象渲染两个对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆