C++ 如何在GLSL中将4x4矩阵用作顶点属性?

C++ 如何在GLSL中将4x4矩阵用作顶点属性?,c++,opengl,glsl,vertex-shader,C++,Opengl,Glsl,Vertex Shader,我尝试使用4x4矩阵作为顶点属性,使用以下代码: Mat4 matrices[numVerts]; int mtxBoneID = glGetAttribLocation(hProgram, "aMtxBone"); glEnableVertexAttribArray(mtxBoneID + 0); glEnableVertexAttribArray(mtxBoneID + 1); glEnableVertexAttribArray(mtxBoneID + 2); glEnableVerte

我尝试使用4x4矩阵作为顶点属性,使用以下代码:

Mat4 matrices[numVerts];

int mtxBoneID = glGetAttribLocation(hProgram, "aMtxBone");

glEnableVertexAttribArray(mtxBoneID + 0);
glEnableVertexAttribArray(mtxBoneID + 1);
glEnableVertexAttribArray(mtxBoneID + 2);
glEnableVertexAttribArray(mtxBoneID + 3);
glVertexAttribPointer(mtxBoneID + 0, 4, GL_FLOAT, GL_FALSE, sizeof(Mat4), ((Vec4*)matrices) + 0);
glVertexAttribPointer(mtxBoneID + 1, 4, GL_FLOAT, GL_FALSE, sizeof(Mat4), ((Vec4*)matrices) + 1);
glVertexAttribPointer(mtxBoneID + 2, 4, GL_FLOAT, GL_FALSE, sizeof(Mat4), ((Vec4*)matrices) + 2);
glVertexAttribPointer(mtxBoneID + 3, 4, GL_FLOAT, GL_FALSE, sizeof(Mat4), ((Vec4*)matrices) + 3);

// shader:
// ...
attribute mat4 aMtxBone;
// ...

但我在屏幕上看到的只是垃圾。

首先需要为矩阵创建VBO(
glGenBuffers
),然后将其绑定为当前(
glBindBuffer
),然后使用

glVertexAttribPointer(mtxBoneID + 0, 4, GL_FLOAT, GL_FALSE, 0, 0);
glVertexAttribPointer(mtxBoneID + 1, 4, GL_FLOAT, GL_FALSE, 0, 4);
glVertexAttribPointer(mtxBoneID + 2, 4, GL_FLOAT, GL_FALSE, 0, 8);
glVertexAttribPointer(mtxBoneID + 3, 4, GL_FLOAT, GL_FALSE, 0, 12);

而不是调用
glvertexattributepointer

首先需要为矩阵创建VBO(
glGenBuffers
),然后将其绑定为当前(
glBindBuffer
),然后使用

glVertexAttribPointer(mtxBoneID + 0, 4, GL_FLOAT, GL_FALSE, 0, 0);
glVertexAttribPointer(mtxBoneID + 1, 4, GL_FLOAT, GL_FALSE, 0, 4);
glVertexAttribPointer(mtxBoneID + 2, 4, GL_FLOAT, GL_FALSE, 0, 8);
glVertexAttribPointer(mtxBoneID + 3, 4, GL_FLOAT, GL_FALSE, 0, 12);

不要调用
glvertexattributepointer
调用。

您可以尝试以下方法 在着色器中使用布局

layout(location=x) in mat4 <name>;

你可以试试这样的 在着色器中使用布局

layout(location=x) in mat4 <name>;

看起来你的偏移量被关闭了。应该是

((Vec4*)matrices) + sizeOf(Vec4)*i
而不是

((Vec4*)matrices) + i

看起来你的偏移量被关闭了。应该是

((Vec4*)matrices) + sizeOf(Vec4)*i
而不是

((Vec4*)matrices) + i

所以,我的答案被删除了,原因不明

我又来了,这次我会用不同的格式

我的问题和这个问题完全一样,东西会画得一团糟。至少这是描述

给我修的是电话

glDrawElementsInstancedBaseVertex(GL_TRIANGLES,
                                    d->drawCount,
                                    GL_UNSIGNED_INT,
                                    0,
                                    p_objects.size(),
                                    0);
来画我的东西,就这个,没别的了

然而

如果你的东西画错了,这可能不是你唯一的问题。所有你需要纠正的东西清单都是巨大的。所以我要在这里放一个链接,它有一个关于如何画很多东西的很棒的教程。此外,您还可以获取源代码并自己尝试

资料来源:

再次投票否决我并删除我的答案,它的内容并没有改变


禁止我进入网站,你的损失。

因此,我的答案因未知原因被删除

我又来了,这次我会用不同的格式

我的问题和这个问题完全一样,东西会画得一团糟。至少这是描述

给我修的是电话

glDrawElementsInstancedBaseVertex(GL_TRIANGLES,
                                    d->drawCount,
                                    GL_UNSIGNED_INT,
                                    0,
                                    p_objects.size(),
                                    0);
来画我的东西,就这个,没别的了

然而

如果你的东西画错了,这可能不是你唯一的问题。所有你需要纠正的东西清单都是巨大的。所以我要在这里放一个链接,它有一个关于如何画很多东西的很棒的教程。此外,您还可以获取源代码并自己尝试

资料来源:

再次投票否决我并删除我的答案,它的内容并没有改变



禁止我进入网站,你的损失。

如果你想进行网格蒙皮,最好将矩阵作为制服传递,并使用一个或多个整型向量属性来尊重它们。你找到解决方案了吗?我遇到了完全相同的问题。检查这个@sak,就像Luca说的,你可以将一个整数索引作为顶点属性传递到数组中,但是你可以将矩阵作为制服发送(着色器的制服数量最多,这可能不够)而不是将矩阵存储在浮点纹理中,然后使用最近邻采样对其进行采样。Mat4类型是什么样的?如果要进行网格蒙皮,最好将矩阵作为统一体进行传递,并使用一个或多个整数向量属性对其进行区分。您找到解决方案了吗?我遇到了完全相同的问题。检查这个@sak,就像Luca说的,你可以将一个整数索引作为顶点属性传递到数组中,但是你可以将矩阵作为制服发送(着色器的制服数量最多,这可能不够)而不是将矩阵存储在浮点纹理中,然后使用最近邻采样对它们进行采样。Mat4类型是什么样的?顶点缓冲区对象不是必需的。所以,不,这不是解决方案。更新了我的答案。但看起来您正在使用OpenGL 2。我建议切换到OpenGL 3,因为它似乎没有那么多错误(我在使用OpenGL 2时经常会遇到一些奇怪的行为,OpenGL 3没有这个问题)。现在答案完全过时了,只是展示了他已经使用的代码。只有一个区别,这个区别使得你的答案甚至是错误的,因为
12*sizeof(float)
的步幅不起作用。您需要从一个顶点开始到下一个顶点的字节,因此很可能
16*sizeof(float)
或者更好的是
sizeof(Mat4)
。但是等一下,那就完全是他的代码了,你可以删除答案了。@AntonGuryanov OpenGL 2的错误丝毫没有OpenGL 3少。唯一可能出现错误的是您的实现(硬件+驱动程序)(您没有使用ATI或Intel GPU,是吗?)。可能只是核心OpenGL 3更干净、更简单的界面减少了驱动程序失败的机会。@ChristianRau oops,我的错。那么我所能建议的就是用OpenGL3尝试VBO,问题就会出现。关于我的GPU,当我使用OpenGL2时,我有NVIDIAGPU,我有一些奇怪的问题。然后我切换到OpenGL3,买了一台带有AMD Radeon的新电脑。从那以后,我没有注意到任何错误或奇怪的行为。顶点缓冲区对象不是强制性的。所以,不,这不是解决方案。更新了我的答案。但看起来您正在使用OpenGL 2。我建议切换到OpenGL 3,因为它似乎没有那么多错误(我在使用OpenGL 2时经常会遇到一些奇怪的行为,OpenGL 3没有这个问题)。现在答案完全过时了,只是展示了他已经使用的代码。只有一个区别,这个区别使得你的答案甚至是错误的,因为
12*sizeof(float)
的步幅不起作用。您需要从一个顶点开始到下一个顶点的字节,因此很可能
16*sizeof(float)
或者更好的是
sizeof(Mat4)
。但是等一下,那就完全是他的代码了,你可以删除答案了。@AntonGuryanov OpenGL 2的错误丝毫没有OpenGL 3少。唯一可能出现错误的是您的实现(硬件+驱动程序)(您没有使用ATI或Intel)