在3.2版本中使用VAO和VBO绘制OpenGL的线条和正方形

3
我一直在尝试使用OpenGL 3.2+。
我可以成功地将一条线或由两个三角形组成的正方形渲染到屏幕上...
我认为我正确地使用了VAO和VBO,但是我无法同时渲染它们... 我遇到了奇怪的渲染问题。
显然,我的代码有误... 但是当渲染不同数组中定义的多个对象时,应该如何使用VAO和VBO?
我的代码太长了,所以我在Pastebin上链接了一份副本> Here <

你能提供一张截图吗? - bwroga
3
我的代码太长了,无法在这里发布......然后缩短它 - genpfault
另外,你的着色器不见了。 - genpfault
首先,你应该开始使用SDL、SFML或其他类似的工具。纯WinApi并不是最好的选择。其次,我们不知道你的着色器类文件和着色器程序。 - trebor
5
我不一定会走得那么远。一旦你完成了设置渲染上下文和消息泵/事件处理程序的脏工作,SDL、SFML、GLUT、glfw等基本上是不相关的。确实,它会使代码移植更容易,编写SSCCE更简单;但这里讨论的问题是纯OpenGL API。但肯定有一些重要细节,比如着色器实现,在问题中是缺失的。 - Andon M. Coleman
1个回答

4
当您有多个要显示的对象,每个对象都有自己的缓冲区数组时,每个缓冲区都需要有自己的顶点数组对象句柄:
int curr_num_object = 0;

static const int vertex_array_object_fish = curr_num_object++;
static const int vertex_array_object_shark = curr_num_object++; 
static const int vertex_array_object_doughnut = curr_num_object++;


GLuint array_vertex_array_object[curr_num_object]; // one for each drawn object

glGenVertexArrays(curr_num_object, &array_vertex_array_object[0]);

然后针对每个缓冲数组进行绑定,将其数据加载到GPU上:
    // -----------------  fish

glBindVertexArray(array_vertex_array_object[vertex_array_object_fish]); // fish VAO

GLuint vertex_buffer_fish;
glGenBuffers(1, & vertex_buffer_fish);
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_fish);
glBufferData(GL_ARRAY_BUFFER, audio_model->get_sizeof_fish_array(), audio_model->get_address_fish_array(), GL_DYNAMIC_DRAW);

glVertexAttribPointer(
    0,                  // attribute. No particular reason for 0, but must match the layout in the shader.
    2,                  // size
    GL_FLOAT,           // type
    GL_FALSE,           // normalized?
    0,                  // stride
    (void*)0            // array buffer offset
);
glEnableVertexAttribArray(0);

上面只处理了第一个缓冲区数组fish。每个后续想要显示的对象都需要类似的一组OpenGL调用。上面在窗口事件循环(glfw、glut...)之外被调用一次。请注意,glVertexAttribPointer的第二个参数是一个二维数组... 这里是它的头部条目:

float molecules_location_fish[max_fish][num_dimensions_2D_grid]; //  X & Y per fish

这里是我想要展示的第二个对象(甜甜圈),与上面的鱼类相似,需要调用以下代码:

// -----------

glBindVertexArray(array_vertex_array_object[vertex_array_object_doughnut]); // doughnut VAO
GLuint vertex_buffer_doughnut_box;
glGenBuffers(1, & vertex_buffer_doughnut_box);
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_doughnut_box);
glBufferData(GL_ARRAY_BUFFER, audio_model->get_sizeof_doughnut_box_array(), audio_model->get_address_doughnut_box_array(), GL_DYNAMIC_DRAW);

glVertexAttribPointer(
    0,                  // attribute. No particular reason for 0, but must match the layout in the shader.
    3,                  // size
    GL_FLOAT,           // type
    GL_FALSE,           // normalized?
    0,                  // stride
    (void*)0            // array buffer offset
);
glEnableVertexAttribArray(0);

// -----------

现在,在您的窗口事件循环中,您可能还调用对象数据的更新位置(线条、三角形等),对于每个要显示的对象,您都会进行这些OpenGL调用:

    // ---------

    glBindVertexArray(array_vertex_array_object[vertex_array_object_fish]);

    glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_fish);

    glBufferData(GL_ARRAY_BUFFER, audio_model->get_sizeof_fish_array(), audio_model->get_address_fish_array(), GL_DYNAMIC_DRAW);
    glDrawArrays(GL_POINTS, 0, audio_model->get_curr_num_fish()); // 12*3 indices starting at 0 -> 12 triangles

为了完整起见,在您的事件循环中,这里是甜甜圈调用的列表:
    glBindVertexArray(array_vertex_array_object[vertex_array_object_doughnut]);

    glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_doughnut_box);
    glBufferData(GL_ARRAY_BUFFER,audio_model->get_sizeof_doughnut_box_array(),audio_model->get_address_doughnut_box_array(),GL_DYNAMIC_DRAW);

    glDrawArrays(GL_TRIANGLES, 0, audio_model->get_curr_num_doughnut_boxes());

我在我的鱼中展示了它的2D点,而甜甜圈是3D的,并且显示为一组三角形(未经索引)。
学习OpenGL的初期速度瓶颈可能会令人困扰。以下是一组非常好的教程:http://www.opengl-tutorial.org。请告诉我们您的进展情况。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接