- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我想使用 OpenGL 4.5 渲染一个三角形。我在网上找到了很多使用旧版本 OpenGL 的示例,但没有一个使用 OpenGL 4.5 函数。因此,我尝试自己“升级”一些代码。这是旧的工作代码:
// 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);
然后我将它“更新”为这段代码,它似乎没有在屏幕上绘制任何东西:
// 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
谁能告诉我我做错了什么?
编辑:三角形片段
#version 450
in vec4 gl_FragCoord;
out vec4 fColor;
void main ()
{
fColor = vec4 (0.0, 0.0, 1.0, 1.0);
}
三角形.vert
#version 450
layout (location = 0) in vec3 vPosition;
uniform mat3 projectionMatrix;
void main ()
{
vec3 tmp = projectionMatrix*vPosition;
gl_Position = vec4 (tmp, 1.0f);
}
最佳答案
罪魁祸首很可能是这一行:
glVertexArrayVertexBuffer(vaos, 0, buffers, 0, 0);
最后一个参数是stride
,表示两个连续数组元素之间的距离。在传统的glVertexAttribPointer
调用中,也有一个stride
参数,但在语义上略有不同:
如果在 glVertexAttribPointer
中使用 0
的 stride
,这是编写 count * sizeof(type) 的便捷快捷方式
,并将采用一个紧密打包的属性数组。
对于 glVertexArrayVertexBuffer
,0
的步幅就意味着 0
,因此它将为该绘制调用的每个顶点提供完全相同的元素. glVertexArrayVertexBuffer
不能提供相同的快捷方式,因为它不直接绑定(bind)到任何顶点属性,并且多个属性可以(并且通常)引用相同的缓冲区索引。 (而且界面也会很奇怪,因为你可以在设置绑定(bind)之前或之后设置顶点格式,所以它必须在以后进行评估。)
所以从概念上讲,跨度不是属性格式的一部分。该格式仅描述了单个 顶点所需的所有内容。请注意,此更改与直接状态访问无关。它实际上是用 ARB_vertex_attrib_binding
引入的(自 GL 4.3 以来的核心),它确实将缓冲区绑定(bind)与属性格式描述分开。该文件中的问题(2)和(3)与这个问题非常相关:
(2) How is a stride of zero interpreted in
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
?RESOLVED:
BindVertexBuffer
has no knowledge of the attrib format, soVertexAttribPointer
needs to compute the stride itself. However, if an application specifies a stride of zero and then queriesVERTEX_ATTRIB_ARRAY_STRIDE
, it returns zero. So the derived stride that's passed toBindVertexBuffer
must be tracked separately from the stride originally passed toVertexAttribPointer
, so this spec introduces a separate piece of state (VERTEX_BINDING_STRIDE
). Rendering always usesVERTEX_BINDING_STRIDE
.This can potentially lead to misleading state queries if the API is abused. 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.
长话短说:对于您的用例,您需要
glVertexArrayVertexBuffer(vaos, 0, buffers, 0, 3*sizeof(GLfloat));
关于c++ - 如何在 OpenGL 4.5 中使用 vao 和缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40029947/
我遇到了一个恐怕很难解决的问题,至少就谷歌搜索而言是这样。 我有一个使用 Qt 的编辑器实用程序,它为编辑器中的不同工具创建多个 OpenGL 上下文,它们是一个“世界”编辑器,它托管我的游戏场景的
我正在再次尝试 OpenGL,我想知道如何设计稍后呈现的类。现在,只有一种类型的形状,所以我创建了一个 Shape 类,它有一个静态 VAO 成员,当第一个时调用 glGenVertexArrays(
环境:OpenGL 3.3+、C 编程、Windows。 我有一个函数,可以从模型加载所有顶点数据,但只返回 VAO id 和顶点数。在此过程中,它生成 VBO id,并将顶点数组数据传递到缓冲区..
假设我有 2 个不同的对象,每个对象都有自己的 VAO 和绘制调用。像这样的事情: void Object::Draw() { glBindVertexArray(vao); glDr
1 VAO 是 OpenGL 技术中提出来的 参考: 外链 其中有一段文字记录了 VAO 是什么: A Vertex Array Object (VAO) is an object which con
我最近使用顶点数组对象 (VAO) 编写了一些 OpenGL 3.3 代码,后来在英特尔图形适配器上对其进行了测试,令我失望的是,元素数组缓冲区绑定(bind)显然不是 VAO 状态的一部分,因为调用
我正在使用 OpenGL 编写一个小图形引擎(通过 OpenTK 和 C#)。 为了定义顶点属性,我有一个 VertexDeclaration 类,其中包含一组 VertexElement 结构,这些
我面临一个问题,我认为该问题与 VAO 相关,但我不确定.. 我不确定 VAO 的正确用法,我在 GL 初始化期间所做的很简单 glGenVertexArrays(1,&vao) 后跟 glBindV
假设我们将两个程序上的顶点属性位置绑定(bind)到相同的值。使用相同的顶点数组对象来使用这两个程序进行绘制是否正确? 最佳答案 定义“正确”。 如果两个程序对象使用兼容的属性位置,则它们使用相同的属
我一直在阅读一些有关 VAO 如何与 VBO 配合使用的内容。据我了解,当我们调用 glVertexAttribPointer 时,VAO 仅存储有关 VBO 的状态信息。我的问题是,它何时存储有关
我做了一个加载器类来加载 V.A.Os 纹理等但是当我使用这个方法时 GLuint Loader::loadToVAO(GLfloat* vertices) { GLuint VertexAr
据我所知,顶点获取阶段由 VAO 封装,并且 VAO 需要包含顶点获取阶段状态,以便在缓冲区对象和顶点属性之间进行管道传输以及格式化缓冲区对象中的数据。 我一直在阅读的关于这个主题的两本书,红皮书,蓝
我最近开始学习 OpenGL,我一直在尝试编写一个程序,使用带有着色器的 VAO 和 VBO 在屏幕上显示钻石。我的代码主要基于本教程: https://www.opengl.org/wiki/Tut
我刚刚开始使用 OpenGL,并且我正在尝试仅使用 3.x 及更高版本的功能。我不明白的一件事是 VAO。 我知道 VAO 封装了渲染状态,所以我可以在渲染循环之前调用所有设置函数,然后绑定(bind
VAO 是顶点数组对象,VBO 是顶点缓冲区对象。创建和绑定(bind)/解除绑定(bind) VAO 和 VBO 的调用具有如下一般格式: GLuint VAO, VBO; glGenVertexA
我希望在 Cocoa 上制作一个自定义的 NSOpenGL View 。但是,我在使用 VAO 时遇到了问题。特别是,运行时,这个虚拟测试 View : /// OpenGLTestView.h: @
我和我的 friend 正在开发一个使用 C++ 和 OpenGL 的项目。我们为“ModelObject”创建了一个C++类,每个ModelObject都有一个GLuint vao作为成员变量。然后
我很难理解 VAO 到底是如何处理缓冲区映射的。我正在做的事情可以用这个伪代码来描述: SetUp: BindVAO BindArrayBuffer glBufferData(GL_ARR
我想知道如果我想画画最好做什么超过约 6000 个不同的 VAO 使用相同的着色器。 目前,我绑定(bind)我的着色器,然后为其提供所需的所有信息(统一),然后循环遍历每个 VAO 来绑定(bind
目前我有一个包含 2 个缓冲区的系统,一个创建 CPU 端并设置为一个缓冲区。然后一个来自 ssbo 并从另一个着色器填充。 这是 ssbo 数据的结构: struct ssbo_data_t {
我是一名优秀的程序员,十分优秀!