Cocoa 和 OpenGL,如何使用数组设置 GLSL 顶点属性?

发布于 2024-08-15 15:34:04 字数 1887 浏览 2 评论 0原文

我对 OpenGL 相当陌生,我似乎遇到了一些困难。我用 GLSL 编写了一个简单的着色器,它应该通过给定的关节矩阵来转换顶点,从而允许简单的骨骼动画。每个顶点最多有两个骨骼影响(存储为 Vec2 的 x 和 y 分量)、与变换矩阵数组关联的索引和相应权重,并在我的着色器中指定为“属性变量”,然后设置使用“glVertexAttribPointer”函数。

这就是问题出现的地方......我已经成功地正确设置了“统一变量”矩阵数组,当我在着色器中检查这些值时,所有这些值都已正确导入并且包含正确的数据。但是,当我尝试设置联合索引变量时,顶点将乘以任意变换矩阵!它们跳转到空间中看似随机的位置(每次都不同),因此我假设索引设置不正确,并且我的着色器正在将联合矩阵数组的末尾读取到以下内存中。我不太清楚为什么,因为在阅读了我能找到的有关该主题的所有信息后,我很惊讶地在他们的示例中看到相同(如果不是非常相似)的代码,并且它似乎对他们有用。

我已经尝试解决这个问题有一段时间了,它真的开始让我心烦意乱......我知道矩阵是正确的,当我手动将着色器中的索引值更改为任意整数时,它会读取正确的矩阵值并按其应有的方式工作,通过该矩阵转换所有顶点,但是当我尝试使用我编写的代码来设置属性变量时,它似乎不起作用。

我用来设置变量的代码如下...

// this works properly...
GLuint boneMatLoc = glGetUniformLocation([[[obj material] shader] programID], "boneMatrices");
glUniformMatrix4fv( boneMatLoc, matCount, GL_TRUE, currentBoneMatrices );

GLfloat testBoneIndices[8] = {1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0};

// this however, does not...
GLuint boneIndexLoc = glGetAttribLocation([[[obj material] shader] programID], "boneIndices");
glEnableVertexAttribArray( boneIndexLoc );
glVertexAttribPointer( boneIndexLoc, 2, GL_FLOAT, GL_FALSE, 0, testBoneIndices );

我的顶点着色器看起来像这样...

// this shader is supposed to transform the bones by a skeleton, a maximum of two
// bones per vertex with varying weights...

uniform mat4 boneMatrices[32];  // matrices for the bones
attribute vec2 boneIndices;  // x for the first bone, y for the second

//attribute vec2 boneWeight;  // the blend weights between the two bones

void main(void)
{
 gl_TexCoord[0] = gl_MultiTexCoord0; // just set up the texture coordinates...


 vec4 vertexPos1 = 1.0 * boneMatrices[ int(boneIndex.x) ] * gl_Vertex;
 //vec4 vertexPos2 = 0.5 * boneMatrices[ int(boneIndex.y) ] * gl_Vertex;

 gl_Position = gl_ModelViewProjectionMatrix * (vertexPos1);
}

这真的开始让我感到沮丧,任何和所有的帮助将不胜感激,

-Andrew Gotow

I'm fairly new to OpenGL, and I seem to be experiencing some difficulties. I've written a simple shader in GLSL, that is supposed to transform vertices by given joint matrices, allowing simple skeletal animation. Each vertex has a maximum of two bone influences (stored as the x and y components of a Vec2), indices and corresponding weights that are associated with an array of transformation matrices, and are specified as "Attribute variables" in my shader, then set using the "glVertexAttribPointer" function.

Here's where the problem arises... I've managed to set the "Uniform Variable" array of matrices properly, when I check those values in the shader, all of them are imported correctly and they contain the correct data. However, when I attempt to set the joint Indices variable the vertices are multiplied by arbitrary transformation matrices! They jump to seemingly random positions in space (which are different every time) from this I am assuming that the indices are set incorrectly and my shader is reading past the end of my joint matrix array into the following memory. I'm not exactly sure why, because upon reading all of the information I could find on the subject, I was surprised to see the same (if not very similar) code in their examples, and it seemed to work for them.

I have attempted to solve this problem for quite some time now and it's really beginning to get on my nerves... I know that the matrices are correct, and when I manually change the index value in the shader to an arbitrary integer, it reads the correct matrix values and works the way it should, transforming all the vertices by that matrix, but when I try and use the code I wrote to set the attribute variables, it does not seem to work.

The code I am using to set the variables is as follows...

// this works properly...
GLuint boneMatLoc = glGetUniformLocation([[[obj material] shader] programID], "boneMatrices");
glUniformMatrix4fv( boneMatLoc, matCount, GL_TRUE, currentBoneMatrices );

GLfloat testBoneIndices[8] = {1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0};

// this however, does not...
GLuint boneIndexLoc = glGetAttribLocation([[[obj material] shader] programID], "boneIndices");
glEnableVertexAttribArray( boneIndexLoc );
glVertexAttribPointer( boneIndexLoc, 2, GL_FLOAT, GL_FALSE, 0, testBoneIndices );

And my vertex shader looks like this...

// this shader is supposed to transform the bones by a skeleton, a maximum of two
// bones per vertex with varying weights...

uniform mat4 boneMatrices[32];  // matrices for the bones
attribute vec2 boneIndices;  // x for the first bone, y for the second

//attribute vec2 boneWeight;  // the blend weights between the two bones

void main(void)
{
 gl_TexCoord[0] = gl_MultiTexCoord0; // just set up the texture coordinates...


 vec4 vertexPos1 = 1.0 * boneMatrices[ int(boneIndex.x) ] * gl_Vertex;
 //vec4 vertexPos2 = 0.5 * boneMatrices[ int(boneIndex.y) ] * gl_Vertex;

 gl_Position = gl_ModelViewProjectionMatrix * (vertexPos1);
}

This is really beginning to frustrate me, and any and all help will be appreciated,

-Andrew Gotow

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

北笙凉宸 2024-08-22 15:34:04

好吧,我已经弄清楚了。 OpenGL 使用drawArrays 函数绘制三角形,方法是将每9 个值读取为一个三角形(3 个顶点,每个顶点有3 个分量)。因此,三角形之间的顶点会重复,因此如果两个相邻的三角形共享一个顶点,那么它会在数组中出现两次。所以我原本以为有 8 个顶点的立方体实际上有 36 个!

六个边,每边两个三角形,每个三角形三个顶点,所有这些相乘得到总共 36 个独立顶点,而不是 8 个共享顶点。

整个问题是指定太少的值的问题。当我将测试数组扩展为包含 36 个值时,它就完美地工作了。

Ok, I've figured it out. OpenGL draws triangles with the drawArrays function by reading every 9 values as a triangle (3 vertices with 3 components each). Because of this, vertices are repepated between triangles, so if two adjacent triangles share a vertex it comes up twice in the array. So my cube which I originally thought had 8 vertices, actually has 36!

six sides, two triangles a side, three vertices per triangle, all multiplies out to a total of 36 independent vertices instead of 8 shared ones.

The entire problem was an issue with specifying too few values. As soon as I extended my test array to include 36 values it worked perfectly.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文