- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试在 OpenGL 3.3 中渲染 Suzanne(来自 Blender),但缓冲区数据似乎不正确。我明白了:
https://gyazo.com/ab82f9acb6854a49fccc527ed96cc4e8
我还尝试渲染一个具有简单纹理的球体:
https://gyazo.com/85c1e87fcc4eab128ca37b1a0cb1deaa
我的导入器将顶点数据作为单个 float 插入到 std::vector 中:
if(line.substr(0,2) == "v ")
{
/** Vertex position */
std::istringstream s(line.substr(2));
float v[3];
s >> v[0]; s >> v[1]; s >> v[2];
this->vertices.push_back(v[0]);
this->vertices.push_back(v[1]);
this->vertices.push_back(v[2]);
}
我按如下方式设置数组缓冲区:
glGenBuffers(1, &this->vbo);
glBindBuffer(GL_ARRAY_BUFFER, this->vbo);
glBufferData(GL_ARRAY_BUFFER,
sizeof(float)*(this->vertices.size()+this->textures.size()+this->normals.size()),
NULL,
GL_STATIC_DRAW);
然后我使用 glBufferSubData 插入实际数据
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float)*this->vertices.size(), this->vertices.data());
glBufferSubData(GL_ARRAY_BUFFER, sizeof(float)*this->vertices.size(), sizeof(float)*this->textures.size(), this->textures.data());
glBufferSubData(GL_ARRAY_BUFFER, sizeof(float)*(this->vertices.size()+this->textures.size()), sizeof(float)*this->normals.size(), this->normals.data());
我也以同样的方式插入索引(当然是 GL_ELEMENT_ARRAY_BUFFER)。
然后我指向信息:
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), (GLvoid*)0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), (GLvoid*)(sizeof(float)*this->v.size()));
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), (GLvoid*)(sizeof(float)*this->v.size()+this->vt.size()));
我的顶点着色器接收这样的数据:
layout(location = 0) in vec3 position;
layout(location = 1) in vec2 texCoord;
layout(location = 2) in vec3 normals;
我是不是搞砸了偏移量?
编辑:我发现了最大的问题!我编写了一个外部 Lua 程序来将 obj 文件转换为更易于导入的格式,但它最终弄乱了数据并复制了 "f#/#/# #/#/# #/#/#"所以文件看起来像这样 (x->y->x) 而不是 (x->y->z)
由于以下回复,还修复了一些其他错误!
最佳答案
如果没有看到您的着色器,我无法 100% 确定您对 glVertexAttribPointer
的调用是否合法。我也不知道你是否想要在单个 VBO 中交错顶点数据。你目前拥有的首先是所有的顶点位置,然后是所有的纹理坐标,最后是所有的法线。
要交错数据,您首先要将所有数据放入一个数组(或 vector )中,以便每个顶点重复 PPPTTNNN
模式。其中 PPP
是三个位置 float ,TT
是两个 texcoord float ,NNN
是三个普通 float 。
它看起来像这样(使用伪造的类型、值和间距来帮助说明模式):
float[] vertices = {
/* pX, pY, pZ, tX, tY, nX, nY, nZ */
1, 1, 1, 0, 0, 1, 1, 1, // vertex 1
0, 0, 0, 1, 1, 0, 0, 0, // vertex 2
1, 1, 1, 0, 0, 1, 1, 1, // vertex 3
...
};
假设您将它们全部放入一个名为 vertices
的 vector 中,然后您可以使用一个命令上传它:
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * this->vertices.size(), this->vertices.data(), GL_STATIC_DRAW);
您还可以将每个属性放入其自己的 VBO 中。您决定如何将数据存储在 GPU 上最终取决于您。如果您有意按照自己的方式存储数据,请在评论中告诉我,我会更新答案。
好的,现在是着色器位。
假设您有一个如下所示的顶点着色器:
in vec3 position;
in vec2 texcoord;
in vec3 normal;
out vec2 uv;
void main() {
gl_Position = vec4(position, 1);
uv = texcoord;
}
还有一个看起来像这样的片段着色器:
in vec2 uv;
uniform sampler2D image;
out vec4 color;
void main() {
color = texture(image, uv);
}
然后您需要以下 glVertexAttribPointer
调用:
int stride = (3 + 2 + 3) * sizeof(float);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, stride, (GLvoid*)0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, stride, (GLvoid*)3);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, stride, (GLvoid*)5);
请注意每次调用的第一个参数是不同的数字。这分别对应顶点着色器中的position
、texcoord
、normal
。
此外,纹理坐标通常只是一对 float (例如 vec2 texcoord
),因此我将第二个参数更改为 2
以用于 texcoord 调用。
最后一个参数,当使用交错数组时,只需要指定每个顶点的偏移量。因此我们分别得到位置偏移、纹理坐标偏移和法线偏移的0
、3
和5
。
希望这能让你到达你想去的地方。
查看 docs.gl page on glVertexAttribPointer了解更多信息。
关于c++ - glBufferData 和 glBufferSubData 偏移量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36781322/
当创建一个 Buffer 并设置它的数据时,需要先将它绑定(bind)到一个 target,然后用一些数据填充绑定(bind)到该 target 的缓冲区: GLenum target = GL_AR
我想知道,如果我使用 glBufferData,它会在我调用它时准确地分配内存吗(也就是说,如果 size 参数大于此时的可用内存,它会崩溃)还是会它有某种特殊的即时规则,仅当我实际将数据复制到缓冲区
我所说的标志是 GL_STREAM_DRAW、GL_STATIC_DRAW 和 GL_DYNAMIC_DRAW。 The manual page is clear about when you sho
我尝试将索引加载到 GL_ELEMENT_ARRAY_BUFFER 中,但是当我尝试此操作时,它会用 0 分隔我的数据。 例如我加载了这些数据: [0 1 3 3 1 2] 使用函数glBufferD
我在 glBufferData 上有随机崩溃,它只发生在 Windows 上。 Mac OS 和 Linux 没有问题。这是我的上传功能,它将我保存在内存中的所有内容上传到 GPU。 vertex 是
我刚刚注意到,当我尝试使用大小:1085859108 和数据:NULL 调用 glBufferData 时,它会无提示地失败。 以下对 glBufferSubData 的调用失败并出现 OUT_OF_
我正在使用明确定义的顶点坐标数组创建 glBufferData,一切正常。使用未明确定义的数组时,结果完全不同,尽管我使用的是相同的坐标值。绘制调用以不同的顶点顺序渲染事物。 顶点是三角形网格。 代码
我正在尝试移植我的固定功能管线 openGL 代码以使用 GLSL,但我遇到了 glBufferData 的段错误。这一切都与固定功能的东西一起工作得很好(即我可以毫无问题地渲染加载的网格)。 这是加
This question询问是否可以依靠编译器不弄乱 struct 的值顺序和填充。 根据该问题的答案, OpenGL defines, very clearly, what the byte la
我不明白为什么这段代码会出现段错误: AxesMarker::AxesMarker(float size) : size_(size), vbo_vertices_(0), vbo_eleme
我正在使用 OpenGL实现某种批量绘图。为此,我创建了一个 vertex buffer来存储数据。 注意:这个缓冲区通常会在每一帧上更新,但永远不会减少大小(但仍然可以增加)。 我的问题是:使用 g
我正在使用 glBufferData 来保存一些渲染信息。 glBufferData(GL_ARRAY_BUFFER, vertex_size * sizeof(VertexData), vertic
在开发过程中,我注意到一个奇怪的“错误”,它只能在 Android 模拟器上重现。我正在使用具有 GPU 加速功能的 x86 版本。请查看以下代码: public class TestRenderer
我正在浏览 OGLdev教程,而且我一直坚持让顶点数组对象工作。相关代码如下: glBindBuffer(GL_ARRAY_BUFFER, buffers[POS_VB]); FloatBuffer
我有这段代码,它不起作用我不知道为什么,我认为它应该,但似乎第一个缓冲区数据被第二个缓冲区数据替换了。我想要实现的是第一个线条粗细与另一个不同, vector vert={-.4,.2,-.2,.6}
这个问题在这里已经有了答案: Can I delete a float array when I have used glBufferData? (2 个答案) When does OpenGL g
我有一个关于 OpenGL glBufferData() 方法的问题。我能否在 std::vector 、std::list 等结构中传递顶点数据,或者它必须是经典的 ( [] ) 数组? 最佳答案
在渲染器的初始化中,VBO被创建并绑定(bind)到GL_ARRAY_BUFFER或GL_ELEMENTS_ARRAY_BUFFER,第一个有三个顶点。调用glBufferData将这三个顶点的属性缓
我创建了一个顶点缓冲区对象类来管理应用程序中的大量顶点。用户调用构造函数创建一个glBuffer,调用glBufferData分配指定大小的空间。 有一个名为 resize 的类函数,允许用户通过再次
我是 OpenGL 的初学者,我正在尝试绘制一个彩色方 block ,我遵循了 OpenGL Book 上的教程。我正在使用示例绘制 here .因为这绘制了一个三角形,所以我修改了代码以绘制 4 个
我是一名优秀的程序员,十分优秀!