使用glUniformMatrix将数组发送到着色器

时间:2013-04-05 22:54:37

标签: opengl glsl vertex-shader

我有一个模型,其中所有matdex s(读取矩阵索引)大致均匀分布为0,1和2。 bonebends[matdex[whichvertex]]告诉我们应该在这个顶点上使用哪个矩阵 初始化,c ++:

std::vector< GLint >  matdex; //initialized to 0, 1, or 2 for each vertex loaded, not shown for brevity
std::vector<glm::mat4> bonebends;
int frames=0;
bonebends.push_back(glm::mat4(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)); //identity matrices initially
bonebends.push_back(glm::mat4(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1));
bonebends.push_back(glm::mat4(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)); // thats 3 bones
ver_ind = glGetAttribLocation(shaderID, "VER_IND");
boneID = glGetUniformLocation(shaderID, "BONE_MATRIX[0]");
glGenBuffers(1, &ind_buff);
glBindBuffer(GL_ARRAY_BUFFER, ind_buff);
glBufferData(GL_ARRAY_BUFFER, matdex.size() * sizeof(GLint), &matdex[0], GL_STATIC_DRAW);

在主循环中定期,c ++:

glEnableVertexAttribArray(3); //IND
glBindBuffer(GL_ARRAY_BUFFER, ind_buff);
glVertexAttribPointer( ver_ind, 1, GL_INT, GL_FALSE, 0, (void*)0 );
//ALSO LOOK HERE
glUniformMatrix4fv(boneID, 3 , GL_FALSE, &bonebends[0][0][0]);
frames+=1;
float cs=cos(3.14*2.0*(frames/100.0));
float sn=sin(3.14*2.0*(frames/100.0));
//  LOOK HERE
bonebends[0]=glm::mat4(
cs ,  0,-sn,0  ,
0 ,  1,  0,0  ,
sn,  0, cs,0  ,
0 ,  0,  0,1  );
着色器中的

,glsl:

layout(location = 3) in int VER_IND;
uniform mat4 BONE_MATRIX[3];

在着色器的主要功能中,glsl:

gl_Position =  BONE_MATRIX[VER_IND] * vec4(VER_POS,1); //VER_POS is the vertex's coordinates

我希望这会使重合matdex为0的所有顶点旋转,其余顶点保持静止。相反,这会显示模型(否则会正确呈现)旋转,就好像所有matdex的值都等于0.哪一点cout告诉我它们不是。我不知道如何在着色器中调试VER_IND。我试过

  • 使用uint代替int代替matdex的所有版本,但没有任何区别。
  • 在着色器中将BONE_MATRIX[VER_IND]更改为BONE_MATRIX[0],这使其崩溃(???)
  • 以各种方式更改glUniformMatrix4fv(boneID, 3 , GL_FALSE, &bonebends[0][0][0]);的第二和第四个参数,但没有帮助。
  • 更改了matdex个值,使得它们都不为0,并且它仍然像着色器仅使用BONE_MATRIX[0]一样旋转。
  • // LOOK HERE下面的行更改为bonebends[1]=glm::mat4(会导致模型根本不会旋转。

由此我得出结论,它只使用BONE_MATRIX[3]的第一个,可能是因为着色器没有正确接收它。我可以发布整个内容,但它有点冗长。
我想知道我做错了什么以及如何从着色器中获取信息。

1 个答案:

答案 0 :(得分:2)

有很多问题。

首先,matdex 为空。所以你没有得到任何实际的信息。

第二,

layout(location = 3) in int VER_IND;

glVertexAttribPointer( ver_ind, 1, GL_INT, GL_FALSE, 0, (void*)0 );

这两件事不能一起工作。 glVertexAttribPointer只能提供浮点输入。如果您使用GL_INTthey will be converted to floats等整数格式。如果您想提供整数输入,则必须使用glVertexAttribIPointer(请注意I)。

或者只是让VER_IND成为浮动。并传递GLubyte而不是GLint s。真的,没有必要占用所有的记忆。

第三

glEnableVertexAttribArray(3); //IND
glVertexAttribPointer( ver_ind, 1, GL_INT, GL_FALSE, 0, (void*)0 );

如果您尝试启用ver_ind,则这两个函数的第一个参数应该相同

第四:

//ALSO LOOK HERE
glUniformMatrix4fv(boneID, 3 , GL_FALSE, &bonebends[0][0][0]);

我没有看到您使用glUseProgram设置要更改统一数据的程序的位置。

第五:

//  LOOK HERE
bonebends[0]=glm::mat4(

在上传之后更改值并不会导致上传的值发生变化。

可能存在(并且可能存在)更多问题,但您发布的代码不完整,我不打算成为您的个人调试器。至少,从知道的代码开始,然后做出最小的改变,导致你想要的东西。让它工作,然后再做一次改变。等等。你一下子做了很多东西,但没有成功。