简体   繁体   English

如何在OpenGL 4.5中使用vao和缓冲区

[英]How to use vao and buffers in OpenGL 4.5

I'd like to render a triangle using OpenGL 4.5. 我想用OpenGL 4.5渲染一个三角形。 I have found lot's of examples online using older versions of OpenGL but none using OpenGL 4.5 functions. 我在网上找到了许多使用旧版OpenGL的例子,但没有使用OpenGL 4.5函数。 Therefore I tried to "upgrade" some code myself. 因此我试图自己“升级”一些代码。 This is the old working code: 这是旧的工作代码:

// Triangles to render
vec3 vertices[2][3] = { { vec3(-0.90f, -0.90f, 1.0f), vec3(0.85f, -0.90f, 1.0f), vec3(-0.90f, 0.85f, 1.0f) },
                    { vec3(0.90f, -0.85f, 1.0f),  vec3(0.90f, 0.90f, 1.0f),  vec3(-0.85f, 0.90f, 1.0f) } };

//Initialize
glGenVertexArrays(1, &vaos);
glBindVertexArray(vaos);

glGenBuffers(1, &buffers);
glBindBuffer(GL_ARRAY_BUFFER, buffers);
glBufferData(GL_ARRAY_BUFFER, sizeof(triangles), triangles, GL_STATIC_DRAW);

ShaderInfo shaders[] = {
    { GL_VERTEX_SHADER, "triangles.vert" },
    { GL_FRAGMENT_SHADER, "triangles.frag" },
    { GL_NONE, NULL }
};
program = LoadShaders(shaders);
glUseProgram(program);

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
glEnableVertexAttribArray(0);

//Render
GLint index;
index = glGetUniformLocation(program, "projectionMatrix");
glUniformMatrix3fv(index, 1, true, value_ptr(projectionMatrix));
glClear(GL_COLOR_BUFFER_BIT);
glBindVertexArray(vaos);
glDrawArrays(GL_TRIANGLES, 0, nvertices);

And I "updated" it to this code, which doesn't appear to draw anything on screen: 并且我“更新”了这个代码,它似乎没有在屏幕上绘制任何内容:

// Same triangles
// Initialize
glCreateVertexArrays(1, &vaos);
glEnableVertexArrayAttrib(vaos, 0);
glVertexArrayAttribFormat(vaos, 0, 3, GL_FLOAT, GL_FALSE, 0);

glCreateBuffers(1, &buffers);
glNamedBufferData(buffers, sizeof(triangles), triangles, GL_STATIC_DRAW);

glVertexArrayAttribBinding(vaos, 0, 0);
glVertexArrayVertexBuffer(vaos, 0, buffers, 0, 0);

ShaderInfo shaders[] = {
    { GL_VERTEX_SHADER, "triangles.vert" },
    { GL_FRAGMENT_SHADER, "triangles.frag" },
    { GL_NONE, NULL }
};
program = LoadShaders(shaders);
glUseProgram(program);

// Same render

Could someone tell me what I did wrong? 有人能告诉我我做错了什么吗?

Edit: triangle.frag 编辑:triangle.frag

#version 450

in vec4 gl_FragCoord;
out vec4 fColor;

void main ()
{
    fColor = vec4 (0.0, 0.0, 1.0, 1.0);
}

triangle.vert triangle.vert

#version 450

layout (location = 0) in vec3 vPosition;

uniform mat3 projectionMatrix;

void main ()
{
    vec3 tmp = projectionMatrix*vPosition;
    gl_Position = vec4 (tmp, 1.0f);
}

The culprit is most likely this line: 罪魁祸首很可能就是这条线:

glVertexArrayVertexBuffer(vaos, 0, buffers, 0, 0);

The last parameter is the stride , which means the distance between two consecutive array elements. 最后一个参数是stride ,表示两个连续数组元素之间的距离。 In the traditional glVertexAttribPointer call, there is also a stride parameter, but there is a slight semantic difference: 在传统的glVertexAttribPointer调用中,还有一个stride参数,但是存在轻微的语义差异:

If you use a stride of 0 in glVertexAttribPointer , this is a convenient shortcut for writing count * sizeof(type) , and will assume a tightly packed attribute array. 如果在glVertexAttribPointer使用stride0glVertexAttribPointer这是编写count * sizeof(type)的便捷快捷方式,并将采用紧密压缩的属性数组。

With glVertexArrayVertexBuffer a stride of 0 just means 0 , so it will feed you the very same element for every vertex of that draw call. 使用glVertexArrayVertexBuffer0的步幅意味着0 ,因此它将为该绘制调用的每个顶点提供相同的元素。 glVertexArrayVertexBuffer cannot provide the same shourtcut, because it is not directly tied to any vertex attribute, and several attributes can (and usually do) refer to the same buffer index. glVertexArrayVertexBuffer不能提供相同的shourtcut,因为它不直接绑定到任何顶点属性,并且几个属性可以(通常也是)引用相同的缓冲区索引。 (And the interface would also be very weird, because you could set the vertex format before or after you set the binding, so it would have to be evaluated later.) (并且界面也会非常奇怪,因为您可以在设置绑定之前或之后设置顶点格式,因此必须稍后进行评估。)

So conceptually, the stride is not part of the attribue format. 因此,从概念上讲,步幅不是属于attribue格式的一部分。 The format just describes all what is necessary for a single vertex. 格式只描述了单个顶点所需的全部内容。 Note that this change has nothing to do with the direct state access. 请注意,此更改与直接状态访问无关。 It was actually introduced with ARB_vertex_attrib_binding (core since GL 4.3), which did separate the buffer binding from the attribute format description. 它实际上是通过ARB_vertex_attrib_binding (自GL 4.3以来的核心)引入的,它确实将缓冲区绑定与属性格式描述分开。 The issues (2) and (3) in that document are very relevant to this question: 该文件中的问题(2)和(3)与这个问题非常相关:

(2) How is a stride of zero interpreted in BindVertexBuffer ? (2)在BindVertexBuffer如何解释零步?

RESOLVED: No error is generated, all array elements for a given attribute will be sourced from the same location in the buffer. 已解决:未生成错误,给定属性的所有数组元素都将来自缓冲区中的相同位置。

(3) How is a stride of zero handled in VertexAttribPointer ? (3) VertexAttribPointer如何处理零步?

RESOLVED: BindVertexBuffer has no knowledge of the attrib format, so VertexAttribPointer needs to compute the stride itself. 已解决: BindVertexBuffer不了解attrib格式,因此VertexAttribPointer需要计算步幅本身。 However, if an application specifies a stride of zero and then queries VERTEX_ATTRIB_ARRAY_STRIDE , it returns zero. 但是,如果应用程序指定步幅为零,然后查询VERTEX_ATTRIB_ARRAY_STRIDE ,则返回零。 So the derived stride that's passed to BindVertexBuffer must be tracked separately from the stride originally passed to VertexAttribPointer , so this spec introduces a separate piece of state ( VERTEX_BINDING_STRIDE ). 因此,传递给BindVertexBuffer的派生步幅必须与最初传递给VertexAttribPointer的步幅分开跟踪,因此该规范引入了一个单独的状态( VERTEX_BINDING_STRIDE )。 Rendering always uses VERTEX_BINDING_STRIDE . 渲染始终使用VERTEX_BINDING_STRIDE

This can potentially lead to misleading state queries if the API is abused. 如果API被滥用,这可能会导致误导性的状态查询。 For example: 例如:

  VertexAttribPointer(0, 3, FLOAT, FALSE, 12, 0); // VERTEX_ATTRIB_ARRAY_STRIDE = 12 // VERTEX_BINDING_STRIDE = 12 BindVertexBuffer(0, buffer, 0, 16) // now VERTEX_ATTRIB_ARRAY_STRIDE is still 12, but // VERTEX_BINDING_STRIDE = 16. 

To make a long story short: For your use case, you will need 简而言之:对于您的用例,您将需要

glVertexArrayVertexBuffer(vaos, 0, buffers, 0, 3*sizeof(GLfloat));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM