Vertex Buffer Attributes

Hi all,

I’m trying to perform parallax bump mapping on my meshes but it seems the mapping is acting weird. For example, I’m using a flat quad, with a brick wall texture. When i move the camera left or to the right of the quad, the parallax offsets the texture up and down, check out www.meshsoft.net/parallax.jpg for a screenie.
You can see the tangent space vectors at each vertex on the patch quad (which looks 100% correct to me).
What I’m suspecting is that the vertex attributes arn’t being picked up in the vertex shader because when i comment out all my glEnableVertexAttribArrayARB and glBindAttribLocationARB, it makes no difference at all to the rendering!
I would really appreciate some advice as to what I could be doing wrong.
I’m currently doing the following:

SetVertexBuffer()
{
glEnableVertexAttribArrayARB(1);
glEnableVertexAttribArrayARB(2);
glVertexAttribPointerARB(1, 3, GL_FLOAT, GL_TRUE, vSize, ptrTangents);
glVertexAttribPointerARB(2, 3, GL_FLOAT, GL_TRUE, vSize, ptrBiTangents);
}

SetGPUProgram()
{
glLinkProgramARB(m_Handle);
glBindAttribLocationARB(m_Handle, 1, "tangent");
glBindAttribLocationARB(m_Handle, 2, "bitangent");
}

And in the vertex shader file:

attribute vec3 tangent;
attribute vec3 bitangent;

Anything wrong?

Woops. I checked out the documentation on GL_ARB_vertex_shader and it seems i have to bind the attributes before linking. So, onto another problem. My quad is now black and non bumped like it was before. The screenie is updated. Any ideas guys?

I’ve also noticed that in the document for GL_ARB_vertex_shader, it says:

// Bind user attributes before linking the program object

But when I try to bind before I link, i get the blackness and no bump, and also when I test the return values of glGetAttribLocationARB of my previously bound attributes, I get -1.
But if I link my program and then bind my attributes, it works.

Please help someone, I’m losing motivation fast. The documentation and help on this subject plainly sucks, and no resources around on the web.

Dunno, did you get the latest version of the specs from SGI website ?

My understanding (can’t test, I don’t have support for that extension on my hardware :frowning: ), is that:
-GetActiveAttribARB allow you to loop through attributes to CHECK the named attribute for a given index. AFTER LINKING.
-BindAttribLocationARB allow you to SET the index of a given named attribute. BEFORE LINKING.
-GetAttribLocationARB allow you to GET the index of a given named attribute. AFTER LINKING.

My guess is that you want to use the third option, let the compiler/linker do its work, then ask it where it did put the attributes.

Feedback welcome since I tell you that from the specs w/o hardware to experiment.

Heres the code i use which doesnt work:

meBoolean drvOpenGLGPUProgram::Link()
{
	glBindAttribLocationARB(m_Handle, 1, "tangent");
	glBindAttribLocationARB(m_Handle, 2, "bitangent");

	glLinkProgramARB(m_Handle);

	//glBindAttribLocationARB(m_Handle, 1, "tangent");
	//glBindAttribLocationARB(m_Handle, 2, "bitangent");
	
	int a = glGetAttribLocationARB(m_Handle, "tangent");
	int b = glGetAttribLocationARB(m_Handle, "bitangent");

	m_IsLinked = ME_TRUE;

	return ME_TRUE;
}

Now when I uncomment the bottom lines, and comment out the top ones, it works. Regardless of what the spec says.

You must relink the shader after binding attribute locations for it to take effect. If it works without relinking, then you probably just got lucky that it matched the indexes assigned by the driver.

I had a feeling it was something to do with the default assignment of the attributes.
I’m just getting the wierdest bugs ever still though. The shader isn’t picking up the vertex buffer attributes even though the attribute related calls arn’t failing. I’ve verified the vectors and the buffer and the data is correct (as shown in the tangent space lines in the screenie). The parallax doesn’t work, but when i hard code them in the shader file for a flat quad, I get a twirl in the texture where the camera is facing, that moves when the camera ‘position only’ moves (doesn’y apply for direction).
Any ideas?

(By the way, thanks for your framework code from your site, I managed to solve alot of problems from reviewing your code).

Still no luck with a few more hours of fiddling.

I suppose I’ve been a little too vague up to now. Here’s what I’m doing per-frame in pseudo style:

ApplyCameraTransform();
SetGPUProgram(handleParallaxMappingShader);
SetVertexAndIndexBuffer();
SetMeshMaterialStates();
SetMaterialTextures();
DrawMesh();

And here’s a small breakdown of my above functions:

SetGPUProgram()
{
    if (!linked)
    {
        glLinkProgramARB
        glBindAttributes....
    }
    glUseProgramObjectARB
}

SetVertexAndIndexBuffer(VB *pBuffer)
{
...set vertex pointers from VBO (glVertexPointer etc..)
glEnableVertexAttribArrayARB(1);
glVertexAttribPointerARB(1, 3, GL_FLOAT, GL_FALSE, vSize, ptr);
glEnableVertexAttribArrayARB(2);
glVertexAttribPointerARB(2, 3, GL_FLOAT, GL_FALSE, vSize, ptr);
}

The rest are self explanatory.

        glLinkProgramARB
        glBindAttributes....

Flip the order of these calls. You need to bind the attributes before you link your program.

If I do that then my cube just shows black. If i keep them as they are, i can see the textures being stretched like parallax mapping should do, but it just goes odd when you move the camera because the tangents/bintangents are not being specified correctly in the shader which makes me think that attributes arn’t bound correctly.

You can’t link any attribute on channel 1. It’s reserved for normals. Use some other channels (for example tex2-6). I know this is not published in spec, but it happens on NV hardware! Actually on NV hardware channels 0 and 1 are reserved for position and normal.

Did you try to read gl error after binding attribute to channel?

yooyo

Hi guys,

Sorry for wasting your time but yes, if I had checked my return errors I would of known that the actual LinkProgram was failing. I checked the error log and it told me about the attribute conflict on channel 1 which is reserved for ‘gl_Normal’.
So I changed my channel, and binded my attributes before linking, and it all works perfectly.

Thanks all,
MeshMan

Originally posted by MeshMan:
[b]Hi guys,

Sorry for wasting your time but yes, if I had checked my return errors I would of known that the actual LinkProgram was failing. I checked the error log and it told me about the attribute conflict on channel 1 which is reserved for ‘gl_Normal’.
So I changed my channel, and binded my attributes before linking, and it all works perfectly.

Thanks all,
MeshMan[/b]
You’ve definately not wasted anyone’s time. I think your time was wasted. [passive voice hint.] What’s your development environment?

ARGH! There is no such thing as an “attribute conflict.”

The spec (ARB_vertex_shader) couldn’t be clearer on this:

ARB_vertex_shader:

There is no aliasing among generic attributes and conventional attributes.

Or from discussion of issue 20:

ARB_vertex_shader:

Conventional attributes are handled by the GL, and guaranteed to not alias with generic attributes.

-mr. bill

I know this is not published in spec, but it happens on NV hardware! Actually on NV hardware channels 0 and 1 are reserved for position and normal.
Then this is very clearly an nVidia driver bug, and needs to be fixed. Stend nVidia’s dev-rel people a bug report with a piece of offending code.

I am new to OpenGL shaders and I have played around a little with the custom vertex attributes. Is it just attributes 0 and 1 that nVidia has problems with? Are there any other conflicts of interest down the line at all?

Thanks!

They have problems with all conventional attributes AFAIK. My latest demo didn’t work on their drivers because primary color aliased with a generic attribute.

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.