gpt4 book ai didi

c++ - OpenGL 顶点数组对象的使用

转载 作者:行者123 更新时间:2023-11-30 04:01:23 25 4
gpt4 key购买 nike

我一直在努力让 OpenGL 在场景中渲染多个不同的实体。

根据 http://www.opengl.org/wiki/Vertex_Specification ,

Vertex Array Object应该记住什么Vertex Buffer Object被绑定(bind)到GL_ARRAY_BUFFER, GL_ELEMENT_ARRAY_BUFFER。 (或者至少我是这样理解它在说什么的)

然而,即使我在绑定(bind)任何 vao 后调用 draw,应用程序也只会使用绑定(bind)到 GL_ARRAY_BUFFER 的最后一个。

问题 - 我的理解正确吗?考虑下面的代码,是否所有调用 gl 函数的顺序都是正确的?

void OglLayer::InitBuffer()
{
std::vector<float> out;
std::vector<unsigned> ibOut;

glGenVertexArrays(V_COUNT, vaos);
glGenBuffers(B_COUNT, buffers);

// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= //
glBindVertexArray(vaos[V_PLANE]);

PlaneBuffer(out, ibOut, 0.5f, 0.5f, divCount, divCount);

OGL_CALL(glBindBuffer(GL_ARRAY_BUFFER, buffers[B_PLANE_VERTEX]));
OGL_CALL(glBufferData(GL_ARRAY_BUFFER, out.size()*sizeof(float), out.data(), GL_DYNAMIC_DRAW));
//GLuint vPosition = glGetAttribLocation( programs[P_PLANE], "vPosition" );
OGL_CALL(glEnableVertexAttribArray(0));
//OGL_CALL(glVertexAttribPointer( vPosition, 3, GL_FLOAT, GL_FALSE, sizeof(float)*3, BUFFER_OFFSET(0) ));
OGL_CALL(glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, sizeof(float)*3, BUFFER_OFFSET(0) ));
bufferData[B_PLANE_VERTEX].cbSize = sizeof(float) * out.size();
bufferData[B_PLANE_VERTEX].elementCount = out.size()/3;
OGL_CALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[B_PLANE_INDEX]));
OGL_CALL(glBufferData(GL_ELEMENT_ARRAY_BUFFER, ibOut.size()*sizeof(unsigned), ibOut.data(), GL_STATIC_DRAW));
bufferData[B_PLANE_INDEX].cbSize = sizeof(float) * ibOut.size();
bufferData[B_PLANE_INDEX].elementCount = ibOut.size();

// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= //
glBindVertexArray(vaos[V_CUBE]);

out.clear();
ibOut.clear();

GenCubeMesh(out, ibOut);

glBindBuffer(GL_ARRAY_BUFFER, buffers[B_CUBE_VERTEX]);
glBufferData(GL_ARRAY_BUFFER, out.size()*sizeof(float), out.data(), GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), BUFFER_OFFSET(0));
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[B_CUBE_INDEX]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned), ibOut.data(), GL_STATIC_DRAW);
}


void RenderPlane::Render( float dt )
{
// Putting any vao here always results in using the lastly buffer bound.
OGL_CALL(glBindVertexArray(g_ogl.vaos[m_pRender->vao]));

{
OGL_CALL(glUseProgram(g_ogl.programs[m_pRender->program]));

// uniform location
GLint loc = 0;

// Send Transform Matrix ( Rotate Cube over time )
loc = glGetUniformLocation(g_ogl.programs[m_pRender->program], "transfMat");
auto transf = m_pRender->pParent->m_transform->CreateTransformMatrix();
glUniformMatrix4fv(loc, 1, GL_TRUE, &transf.matrix()(0,0));

// Send View Matrix
loc = glGetUniformLocation(g_ogl.programs[m_pRender->program], "viewMat");
mat4 view = g_ogl.camera.transf().inverse();
glUniformMatrix4fv(loc, 1, GL_TRUE, &view(0,0));

// Send Projection Matrix
loc = glGetUniformLocation(g_ogl.programs[m_pRender->program], "projMat");
mat4 proj = g_ogl.camera.proj();
glUniformMatrix4fv(loc, 1, GL_TRUE, &proj(0,0));
}

OGL_CALL(glDrawElements(GL_TRIANGLES, g_ogl.bufferData[m_pRender->ib].elementCount, GL_UNSIGNED_INT, 0));
}

最佳答案

GL_ARRAY_BUFFER 绑定(bind)不是 VAO 状态的一部分。您链接的维基页面正确解释了这一点:

Note: The GL_ARRAY_BUFFER​ binding is NOT part of the VAO's state! I know that's confusing, but that's the way it is.

另一方面,GL_ELEMENT_ARRAY_BUFFER 绑定(bind)是 VAO 状态的一部分。

虽然我并不完全不同意这种令人困惑的说法,但如果您开始考虑它,它实际上是有道理的。 VAO 的目标是捕获您通常在进行绘制调用之前设置的所有顶点状态。使用索引渲染时,这包括绑定(bind)用于绘制调用的正确索引缓冲区。因此,在 VAO 状态中包含 GL_ELEMENT_ARRAY_BUFFER 绑定(bind)是完全合理的。

另一方面,当前的 GL_ARRAY_BUFFER 绑定(bind)根本不影响绘制调用。重要的是在调用 glVertexAttribPointer() 之前建立正确的绑定(bind)。并且 glVertexAttribPointer() 设置的所有状态 都是 VAO 状态的一部分。因此 VAO 状态包含用于每个属性 的顶点缓冲区引用,它由 glVertexAttribPointer() 调用建立。另一方面,当前 GL_ARRAY_BUFFER 不是 VAO 状态的一部分,因为绘制调用时的当前绑定(bind)对绘制调用没有任何影响。

另一种看待这个问题的方式:由于用于绘制调用的属性可以从不同的顶点缓冲区中提取,因此在 VAO 状态中跟踪单个顶点缓冲区绑定(bind)是没有用的。另一方面,由于 OpenGL 仅使用单个索引缓冲区进行绘制调用,并使用当前索引缓冲区绑定(bind)进行绘制调用,因此在 VAO 中跟踪索引缓冲区绑定(bind)是有意义的。

关于c++ - OpenGL 顶点数组对象的使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25794454/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com