# Problem binding or creating attribute arrays

This topic is 3738 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I'm using the ARB extension for VBOs, and I'm trying to bind vertex attributes to my GLSL shader. However, it seems like it doesn't work - the data I access in the shader isn't the data I was supposed to send to it! I send 4 bone weights which should together sum to 1 and thus output red with the shader code I have below (I also send 4 bone indices, which I haven't yet tested), but when I render with this shader, the red component becomes larger than 1. Probably 2, because when I divide by 2 in the fragment shader I get RGB 1,0,0 as output and when I divide by 3 I get RGB 0.66,0,0 and so on. Rendering code:
	GLuint boneIndicesLocations;
glEnableVertexAttribArrayARB(boneIndicesLocations);
glVertexAttribPointerARB(boneIndicesLocations,4,GL_INT,false,0,0);

GLuint boneWeightsLocations;
glEnableVertexAttribArrayARB(boneWeightsLocations);
glVertexAttribPointerARB(boneWeightsLocations,4,GL_FLOAT,false,0,0);

... removed probably irrelevant code for activating vertex indices, positions, normals, uv

glDrawElements(GL_TRIANGLES, mesh->numIndices, GL_UNSIGNED_INT, 0);

... removed probably irrelevant code for deactivating vertex indices, positions, normals, uv

glDisableVertexAttribArrayARB(boneIndicesLocations);
glDisableVertexAttribArrayARB(boneWeightsLocations);


	glGenBuffersARB(1, &vbBoneIndices);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbBoneIndices);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(GLint)*4*mesh.numVertices, mesh.boneIndices, GL_STATIC_DRAW);

glGenBuffersARB(1, &vbBoneWeights);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbBoneWeights);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(float)*4*mesh.numVertices, mesh.boneWeights, GL_STATIC_DRAW);


attribute int boneIndices[4];
attribute float boneWeights[4];
varying float test;

void main()
{
test = boneWeights[0]+boneWeights[1]+boneWeights[2]+boneWeights[3];
gl_Position = ftransform();
}


varying float test;

void main()
{
gl_FragColor = vec4(test,0,0,1);
}


I suspect I may be doing something wrong with either the loading or rendering code. I tried writing "attribute vec4 boneWeights;" instead of "attribute float boneWeights[4];", but that caused a crash.

##### Share on other sites
I'm surprised that even compiles as the GLSL1.1 and GLSL1.2 specs both say;

Quote:
 Attribute variables cannot be declared as arrays or structures.

##### Share on other sites
Oh ok, so how are you supposed to get attributes with 4 floats? "attribute vec4 boneWeights" didn't work, it caused a crash. Any ideas? If all fails I guess I must have one attribute array for each separate value, as I've gotten that running in a test shader I wrote a while ago...

##### Share on other sites
"attribute vec4 boneWeights;" causes the program to crash, except when I never output the value read from the attribute (which presumably means the compiler optimizes away the reads from it, so the reads from it may be what causes the error). So perhaps it's still the binding that is not correct - the shader can't access the attribute buffer values properly.

I've tried both with array and with vec4 now and both give the same problem.

[Edited by - all_names_taken on December 2, 2007 3:41:15 PM]

##### Share on other sites
saying 'it crashes' doesn't give us any meaningful information to work with, however 'attribute vec4 boneWeight;' is the only way to supply 4 floats in one var to a vertex shader.

Secondly, as I and many others have said on the forums, removing 'probably irrelevant code' isn't any help; you don't know whats causing the problem, how are you to judge what is releveant and what isn't?

Finally; you load your source data into a VBO, yet you never rebind the VBO before telling OpenGL to use it as source data (for either the weights or the bone indices). This is probably the source of the problem...

##### Share on other sites
Ok first in rendering you have to give VBO pointers. glVertexPointer, glTexCoordPointer.

Second, I think you need all vertex data in one vbo, so indices and vertices need to be in one VBO, so just make it bigger. But you never even do step one. Therefore I'm assuming your vbo has never been drawn even without the shader.

##### Share on other sites
Just looking over your code and variable names, it seems like you have a ton of problems:

Bone weights are used for skeletal animation, yet you have no matrices for each bone.

You cant have indexed vertices if your trying to do that in a vbo.

I see that you actually did call glVertexAttributePointer() but you call it twice, so the only attribute used is the one you most recently called.

Like I said I dont know if you doing skeletal animation or wtf, but you dont even have vertex data??? for example, each vertex has (x,y,z), (normals), (color/bone weights).

Its maybe in another place in your code, but you never (in this code) call to actually use your shader.

##### Share on other sites
Quote:
 Original post by dpadam450Second, I think you need all vertex data in one vbo, so indices and vertices need to be in one VBO, so just make it bigger. But you never even do step one. Therefore I'm assuming your vbo has never been drawn even without the shader.

No, you don't. You can split vertex data across VBOs as you like, including having index data in another VBO.

##### Share on other sites
Quote:
 Original post by dpadam450I see that you actually did call glVertexAttributePointer() but you call it twice, so the only attribute used is the one you most recently called.

Yes, and if you look at the first snippet of code he gives he enables the VA for boneindices and sets the pointer, then he enables the VA for the bone weights and sets the pointer.

What he fails to do, as I've pointed out, is swap to the correct VBO for each source of data.
Quote:
 Like I said I dont know if you doing skeletal animation or wtf, but you dont even have vertex data??? for example, each vertex has (x,y,z), (normals), (color/bone weights).Its maybe in another place in your code, but you never (in this code) call to actually use your shader.

I'm gonna guess that it's in the code he 'helpfully' left out as he didn't think it was relivant (See my post above with what is probably the answer and the 3 points in it..)

##### Share on other sites
Quote:
 Original post by phantomsaying 'it crashes' doesn't give us any meaningful information to work with, however 'attribute vec4 boneWeight;' is the only way to supply 4 floats in one var to a vertex shader.Secondly, as I and many others have said on the forums, removing 'probably irrelevant code' isn't any help; you don't know whats causing the problem, how are you to judge what is releveant and what isn't?Finally; you load your source data into a VBO, yet you never rebind the VBO before telling OpenGL to use it as source data (for either the weights or the bone indices). This is probably the source of the problem...

Thanks, these two changes solved it - I forgot to bind it during rendering and used array instead of vec4 - now I got the boneWeights to work!

Edit: after a few hours with the integer values (called boneIndices above) it seems like I need to send them as GL_FLOAT from the program, but have them as ivec4 in the shader... Otherwise the values read in the shader aren't correct. Now, that works too.

Thanks for the help!

About the missing code: I thought the FAQ said you shouldn't post 500 lines of code at first if you had good reason to believe the error was located in a smaller piece of code that you could cut out. If this is wrong, I will try to post more code next time, since it feels like some of the responses are angry :( It would also have saved me 2 hours of systematically cutting down and debugging the code to localize the error to as small piece of code as possible ;)

[Edited by - all_names_taken on December 3, 2007 6:31:24 AM]

##### Share on other sites
Well the FAQ advise is more to stop people dumping their whole program in and saying 'it doesn't work! why?!?'.

In this case you'd already limited it to the drawing code, however leaving out large chunks of it, even if it didn't seem relivant, might not have helpped. Before now I've seen people ask a question with the answer in a chunk of code they didn't think mattered (or indeed people using pseudo code, which is even more dumb...).