正确地更新顶点缓冲对象 [英] Properly update vertex buffer objects

查看:237
本文介绍了正确地更新顶点缓冲对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个培训的应用程序写在WINAPI 所以,我有GL初始化那里,我有节点为基础的系统,可以通过几个类描述

I've got a training app written in winapi So, I've got GL initialized there and I've got node-based system, that can be described by couple of classes

class mesh
{
GLuint vbo_index; //this is for having unique vbo
float *vertex_array;
float *normal_array;
unsigned int vertex_count;

etc.. //all those mesh things.
....
}

class node
{
bool is_mesh; //the node may or may not represent a mesh
mesh * mesh_ptr; //if it does then this pointer is a valid address
}

我也得到了2全局变量保持渲染网格的记录。

I've also got 2 global variables for keeping record of renderable mesh..

mesh **mesh_table;
unsigned int mesh_count;

现在,我尝试对2个对象。所以我创建类型网格2节点::立方体的xy和z段自定义的数量。我的应用程序的预期的行为是让2节点CUBE0,CUBE1之间的用户点击和展示自己的自定义属性 - 部分X,部分Y,段ž。用户调整这两个objecs参数,他们正在呈现出彼此的线框模式的顶部,所以我们可以看到他们的实时拓扑结构的变化。

Right now I'm experimenting on 2 objects. So I create 2 nodes of type mesh::cube with customizable number of x y and z segments. Expected behaviour of my app is let the user click between 2 of the nodes CUBE0, CUBE1 and show their customizable attributes - segments x, segments y, segments z. The user tweaks both objecs' parameters and they are being rendered out on top of each other in wireframe mode, so we can see the changing in their topology in real time.

当所述节点被首次建立,如果该节点类型是目,则该网格对象产生和它的mesh_ptr被写入在 mesh_table mesh_count 的增量。之后,我的OpenGL窗口类创建了一个独特的顶点缓冲区对象作为新的网格,并将其存储的指数在 mesh_ptr.vbo_index

When the node is being created for the first time, if the node type is mesh, then the mesh object is generated and it's mesh_ptr is written into the mesh_table and mesh_count increments. After that my opengl window class creates a unique vertex buffer object for the new mesh and stores it's index in the mesh_ptr.vbo_index

void window_glview::add_mesh_to_GPU(mesh* mesh_data)
{
    glGenBuffers(1,&mesh_data->vbo_index);
    glBindBuffer(GL_ARRAY_BUFFER ,mesh_data->vbo_index);
    glBufferData(GL_ARRAY_BUFFER ,mesh_data->vertex_count*3*4,mesh_data->vertex_array,GL_DYNAMIC_DRAW);
    glVertexAttribPointer(5,3,GL_FLOAT,GL_FALSE,0,NULL);//set vertex attrib (0)
    glEnableVertexAttribArray(5);
}

在该用户是能够调整的参数和每个时间参数值改变对象的网格信息是基于所述新的参数值重新评估,同时仍是相同的网状实例,在这之后VBO数据是被通过

After that the user is able to tweak the parameters and each time the parameter value changes the object's mesh information is being re-evaluated based on the new parameter values, while still being the same mesh instance, after that VBO data is being updated by

void window_glview::update_vbo(mesh *_mesh)
{
    glBindBuffer(GL_ARRAY_BUFFER,_mesh->vbo_vertex);
    glBufferData(GL_ARRAY_BUFFER,_mesh->vertex_count*12,_mesh->vertex_array,GL_DYNAMIC_DRAW);
    glBindBuffer(GL_ARRAY_BUFFER,0);
}

和整个场景重绘由

for (unsigned short i=0;i<mesh_count;i++)
    draw_mesh(mesh_table[i],GL_QUADS,false);
SwapBuffers(hDC);

该功能对于单个网格

The function for a single mesh is

bool window_glview::draw_mesh(mesh* mesh_data,unsigned int GL_DRAW_METHOD,bool indices)
{
    glUseProgram(id_program);
    glBindBuffer(GL_ARRAY_BUFFER,mesh_data->vbo_index);
    GLuint id_matrix_loc = glGetUniformLocation(id_program, "in_Matrix");
    glUniformMatrix4fv(id_matrix_loc,1,GL_TRUE,cam.matrixResult.get());
    GLuint id_color_loc=glGetUniformLocation(id_program,"uColor");

    glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
    glUniform3f(id_color_loc,mesh_color[0],mesh_color[1],mesh_color[2]);
    glDrawArrays(GL_DRAW_METHOD,0,mesh_data->vertex_count);
    glBindBuffer(GL_ARRAY_BUFFER,0);
    glUseProgram(0);
    return true;
}

的问题是,在堆只有最后对象被绘制的方式,以及其他对象的点都在0 0 0,所以在视口中它呈现一个多维数据集具有适当参数和一个立方体只是作为一个DOT

The problem is that only the last object in stack is being drawn that way, and the other object's points are all in 0 0 0, so in the viewport it's rendered one cube with proper parameters and one cube just as a DOT

问:在哪里?我做错什么了。

QUESTION: Where did I go wrong?

推荐答案

在你的画 glBindBuffer(GL_ARRAY_BUFFER,mesh_data-&GT; vbo_index); 实际上并没有做任何事情;关于顶点属性的信息被未绑定到缓冲的。它被设置在 glVertexAttribPointer(5,3,GL_FLOAT,GL_FALSE,0,NULL); 调用它获取一个新的网格上载每次重写

in your draw glBindBuffer(GL_ARRAY_BUFFER,mesh_data->vbo_index); doesn't actually do anything; the information about the vertex attribute is not bound to the buffer at all. it is set in the glVertexAttribPointer(5,3,GL_FLOAT,GL_FALSE,0,NULL); call which gets overwritten each time a new mesh is uploaded.

无论是创建和使用VAO或移动从 add_mesh_to_GPU 的调用 draw_mesh

either create and use a VAO or move that call from add_mesh_to_GPU to draw_mesh:

对于VAO你会怎么做:

for the VAO you would do:

void window_glview::add_mesh_to_GPU(mesh* mesh_data)
{
    glGenVertexArrays(1, &mesh_data->vao_index);//new GLInt field
    glBindVertexArray(mesh_data->vao_index);
    glGenBuffers(1,&mesh_data->vbo_index);
    glBindBuffer(GL_ARRAY_BUFFER ,mesh_data->vbo_index);
    glBufferData(GL_ARRAY_BUFFER ,mesh_data->vertex_count*3*4,mesh_data->vertex_array,GL_DYNAMIC_DRAW);
    glVertexAttribPointer(5,3,GL_FLOAT,GL_FALSE,0,NULL);//set vertex attrib (0)
    glEnableVertexAttribArray(5);
    glBindVertexArray(0);
}

bool window_glview::draw_mesh(mesh* mesh_data,unsigned int GL_DRAW_METHOD,bool indices)
{
    glBindVertexArray(mesh_data->vao_index);
    glUseProgram(id_program);
    GLuint id_matrix_loc = glGetUniformLocation(id_program, "in_Matrix");
    glUniformMatrix4fv(id_matrix_loc,1,GL_TRUE,cam.matrixResult.get());
    GLuint id_color_loc=glGetUniformLocation(id_program,"uColor");

    glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
    glUniform3f(id_color_loc,mesh_color[0],mesh_color[1],mesh_color[2]);
    glDrawArrays(GL_DRAW_METHOD,0,mesh_data->vertex_count);
    glUseProgram(0);
    glBindVertexArray(0);
    return true;
}

这篇关于正确地更新顶点缓冲对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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