1

我有一个模型,其中所有matdexs (读取矩阵索引)都是 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 的顶点旋转,其余的保持静止。相反,这会显示模型(否则会正确渲染)旋转,好像所有matdexs 值都等于 0。一点点cout告诉我它们不是。我不知道如何VER_IND在着色器中调试。
我试过

  • 使用uint而不是 的int所有化身matdex,这没有任何区别。
  • 更改BONE_MATRIX[VER_IND]BONE_MATRIX[0]in shader,导致崩溃(???)
  • 以各种方式更改的第二个和第四个参数glUniformMatrix4fv(boneID, 3 , GL_FALSE, &bonebends[0][0][0]);没有帮助。
  • 更改了matdexs 值,使得它们都不为 0,并且它仍然旋转,就好像着色器仅使用BONE_MATRIX[0].
  • 将下面的行更改// LOOK HEREbonebends[1]=glm::mat4(导致模型根本不旋转。

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

4

1 回答 1

3

有很多问题。

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

第二,

layout(location = 3) in int VER_IND;

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

这两件事不能一起工作。glVertexAttribPointer只能提供浮点输入。如果您使用整数格式GL_INT它们将被转换为浮点数。如果要提供整数输入,glVertexAttribIPointer则必须使用(注意I)。

或者只是做VER_IND一个浮动。并通过GLubytes 而不是GLints。真的,占用所有的记忆是没有意义的。

第三:

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(

上传后更改值不会神奇地导致上传的值更改。

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

于 2013-04-06T01:26:38.440 回答