将不同类型的值传递给着色器
Passing values of different types to shader
我将 GLEW32 与 GLFW 结合使用,并在 C++ 上编写代码。我在将值传递给着色器时遇到了一些问题。我已经成功通过 vec2, uvec3
等。现在我想为每个顶点传递多个值:
uvec2
(或vec2
——不是很重要)——X和Y位置;
uvec4
- RGBA 颜色。我也可以使用 int
从 int32 解码 RGBA,但 uvec4
会更方便 :)
但还有另一个问题:我可以使用 glVertexAttribIPointer()
或 glVertexAttribPointer()
:
设置不同的属性类型
glVertexAttribIPointer(0, 2, GL_UNSIGNED_SHORT, ...);
glEnableVertexAttribArray(0);
glVertexAttribIPointer(1, 4, GL_UNSIGNED_BYTE, ...);
glEnableVertexAttribArray(1);
但我无法将不同类型的值传递给 glBufferData()
:
glBufferData(GL_ARRAY_BUFFER, sizeof(array), array, GL_DYNAMIC_DRAW); // Just one array!!!
我试着用 uniforms 来做这个,但是代码太庞大而且效率太低,所以我放弃了。有什么方法可以“正确地”进行这样的操作吗?
我在Kai Burjack的评论中找到了解决方案。我做了一个结构来保存数据并发送它。代码是:
struct dataToSend
{
GLushort x, y;
GLubyte r, g, b, a;
}
...
glVertexAttribIPointer(0, 2, GL_UNSIGNED_SHORT, sizeof(dataToSend), (GLvoid *) 0);
glEnableVertexAttribArray(0);
glVertexAttribIPointer(1, 4, GL_UNSIGNED_BYTE, sizeof(dataToSend), (GLvoid *) (2 * sizeof(GLushort)));
glEnableVertexAttribArray(1);
...
// (pixels) x y r g b a
dataToSend data [4] = {{width, height, 255, 255, 0, 255}, // Corner 1 (Up-Right)
{width, 0, 255, 0, 255, 255}, // Corner 2 (Down-Right)
{0, 0, 0, 255, 0, 0}, // Corner 3 (Down-Left)
{0, height, 0, 255, 255, 255}}; // Corner 4 (Up-Left)
glBufferData(GL_ARRAY_BUFFER, sizeof(data), (GLvoid *) data, GL_DYNAMIC_DRAW);
使用 GLvoid 并指向一个结构而不是数组是一种奇怪的体验,但这允许将几乎所有数据传递给着色器。结果图片在这里:
Rendered image
我将 GLEW32 与 GLFW 结合使用,并在 C++ 上编写代码。我在将值传递给着色器时遇到了一些问题。我已经成功通过 vec2, uvec3
等。现在我想为每个顶点传递多个值:
uvec2
(或vec2
——不是很重要)——X和Y位置;uvec4
- RGBA 颜色。我也可以使用int
从 int32 解码 RGBA,但uvec4
会更方便 :)
但还有另一个问题:我可以使用 glVertexAttribIPointer()
或 glVertexAttribPointer()
:
glVertexAttribIPointer(0, 2, GL_UNSIGNED_SHORT, ...);
glEnableVertexAttribArray(0);
glVertexAttribIPointer(1, 4, GL_UNSIGNED_BYTE, ...);
glEnableVertexAttribArray(1);
但我无法将不同类型的值传递给 glBufferData()
:
glBufferData(GL_ARRAY_BUFFER, sizeof(array), array, GL_DYNAMIC_DRAW); // Just one array!!!
我试着用 uniforms 来做这个,但是代码太庞大而且效率太低,所以我放弃了。有什么方法可以“正确地”进行这样的操作吗?
我在Kai Burjack的评论中找到了解决方案。我做了一个结构来保存数据并发送它。代码是:
struct dataToSend
{
GLushort x, y;
GLubyte r, g, b, a;
}
...
glVertexAttribIPointer(0, 2, GL_UNSIGNED_SHORT, sizeof(dataToSend), (GLvoid *) 0);
glEnableVertexAttribArray(0);
glVertexAttribIPointer(1, 4, GL_UNSIGNED_BYTE, sizeof(dataToSend), (GLvoid *) (2 * sizeof(GLushort)));
glEnableVertexAttribArray(1);
...
// (pixels) x y r g b a
dataToSend data [4] = {{width, height, 255, 255, 0, 255}, // Corner 1 (Up-Right)
{width, 0, 255, 0, 255, 255}, // Corner 2 (Down-Right)
{0, 0, 0, 255, 0, 0}, // Corner 3 (Down-Left)
{0, height, 0, 255, 255, 255}}; // Corner 4 (Up-Left)
glBufferData(GL_ARRAY_BUFFER, sizeof(data), (GLvoid *) data, GL_DYNAMIC_DRAW);
使用 GLvoid 并指向一个结构而不是数组是一种奇怪的体验,但这允许将几乎所有数据传递给着色器。结果图片在这里: Rendered image