Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Page 1 of 2 12 LastLast
Results 1 to 10 of 20

Thread: glVertexAttribPointer + GLSL + Ati = grr

  1. #1
    Junior Member Newbie RickA's Avatar
    Join Date
    Sep 2006
    Location
    NL
    Posts
    19

    glVertexAttribPointer + GLSL + Ati = grr

    I'm trying to create a renderer using only the generic vertex attribute submission functions and GLSL. By all accounts this should be possible.

    However, I've run into problems on Ati cards. First the code:
    App:
    Code :
    virtual bool Render(const Scene& scene )
    {
    	prog.Bind();
    	Clear();
     
    	CUSTOMVERTEX *data = new CUSTOMVERTEX[scene.numVertices];
     
    	std::copy(scene.data, &scene.data[scene.numVertices], data);
    	data[1].x = 0.1;
     
    	glEnableVertexAttribArray(prog.GetLocationOfAttrib("color"));
    	glEnableVertexAttribArray(prog.GetLocationOfAttrib("pos"));
    	glVertexAttribPointer(prog.GetLocationOfAttrib("color"), 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(CUSTOMVERTEX), &scene.data[0].color);
    	glVertexAttribPointer(prog.GetLocationOfAttrib("pos"), 3, GL_FLOAT, GL_FALSE, sizeof(CUSTOMVERTEX), &data[0].x);
    	//glEnableClientState(GL_VERTEX_ARRAY);
    	glVertexPointer(3, GL_FLOAT, sizeof(CUSTOMVERTEX), &scene.data[0].x);
    	glDrawArrays( GL_TRIANGLES, 0, scene.numVertices );
     
    	delete [] data;
     
    	return true;
    }
    Vertex shader:
    Code :
    attribute vec3 pos;
    attribute vec4 color;
    varying vec4 colorI; 
    void main()
    {
    	colorI = color;
    	gl_Position = gl_ModelViewMatrix*vec4(pos, 1);
    }
    Fragment shader:
    Code :
    varying vec4 colorI; 
    void main()
    {	
    	gl_FragColor = colorI; 
    }
    Now on nVidia cards this works just fine. On Ati cards I need to uncomment the line with glEnableClientState(GL_VERTEX_ARRAY);
    The code then does work. The position is indeed sourced from the altered copy and not from whatever goes into glVertexPointer.

    What am I missing?

    A copy of my program can be downloaded here . If anyone with an Ati card can get something other than a black screen when running the OpenGL2.bat file, please let me know. The other profiles show the same scene running in different renderers.

    Edit: after a suggestion on GameDev that I check the locations it turns out that that was the problem. pos was at location 2, and color at location 1. Since I wasn't assigning anything to position 0, that appeared to break. By setting pos to location 0 explicitly before linking, the program does work on Ati cards.

    Now my next question: is this all expected behaviour according to the spec. If pos and color are at location 2 and 1, then what is at location 0? I assume vertex position, but gl_Vertex isn't used.

  2. #2
    Advanced Member Frequent Contributor
    Join Date
    May 2005
    Location
    Prague, Czech Republic
    Posts
    924

    Re: glVertexAttribPointer + GLSL + Ati = grr

    The generic vertex attribute 0 is special one according to the OGL specification. For example specifying it using the glVertexAttrib{234} call has the same effect as calling glVertex{234}.

    Additionally the definition (Chapter 2.8, page 27 of OGL 2.1 specification) of the behaviour of ArrayElement (which is part of definition of DrawArrays function) contains following code:

    Code :
    if (generic attribute array 0 enabled) {
       if (generic vertex attribute 0 array normalization flag is set, and type is not FLOAT or DOUBLE)
            VertexAttrib[size]N[type]v(0, generic vertex attribute 0 array element i);
        else
             VertexAttrib[size][type]v(0, generic vertex attribute 0 array element i);
    }
    else if (vertex array enabled) {
         Vertex[size][type]v(vertex array element i);
    }
    Based on this code it looks that if you do not enable generic attribute 0 or vertex pointer array, the vertex position is not specified and because none from commands that issue vertex is called, nothing should be rendered.

    EDIT: Clarified

  3. #3
    Advanced Member Frequent Contributor
    Join Date
    May 2005
    Location
    Prague, Czech Republic
    Posts
    924

    Re: glVertexAttribPointer + GLSL + Ati = grr

    It seems to me that in this case the ATI driver behaves more to the spec by not issuing any vertices into rendering.

    If you enable the vertex array, the vertex issuing is enabled (even if your shader ignores the vertex position completelly) any you see geometry that uses data from other generic attributes.

  4. #4
    Junior Member Newbie RickA's Avatar
    Join Date
    Sep 2006
    Location
    NL
    Posts
    19

    Re: glVertexAttribPointer + GLSL + Ati = grr

    After checking the code on nVidia hardware, it seems that on that hardware color is assigned location 1, and pos is assigned location 0. Thereby satisfying the 'upload data to location 0' requirement mentioned.

  5. #5
    Intern Newbie
    Join Date
    Nov 2005
    Location
    Poland
    Posts
    33

    Re: glVertexAttribPointer + GLSL + Ati = grr

    Originally posted by RickA:
    After checking the code on nVidia hardware, it seems that on that hardware color is assigned location 1, and pos is assigned location 0. Thereby satisfying the 'upload data to location 0' requirement mentioned.
    You just were lucky this time. Do not expect it to happen on other hardware or even on future forceware revisions.
    If you do not explicitly bind an attribute to a slot, the linker does it for you. But it does not touch the slot 0. If you do not use gl_Vertex in a vertex shader, you *must* bind one of the generic attributes to slot 0 before glLinkProgram call is issued.

  6. #6
    Junior Member Newbie RickA's Avatar
    Join Date
    Sep 2006
    Location
    NL
    Posts
    19

    Re: glVertexAttribPointer + GLSL + Ati = grr

    Does this also mean I should do the glVertexAttribPointer for whatever attribute is at location 0 last?

  7. #7
    Senior Member OpenGL Guru Relic's Avatar
    Join Date
    Apr 2000
    Posts
    2,527

    Re: glVertexAttribPointer + GLSL + Ati = grr

    No, it's only important that the vertex array set you use is completely defined when issueing the rendering call.

  8. #8
    Senior Member OpenGL Guru
    Join Date
    Mar 2001
    Posts
    3,768

    Re: glVertexAttribPointer + GLSL + Ati = grr

    If you do not use gl_Vertex in a vertex shader, you *must* bind one of the generic attributes to slot 0 before glLinkProgram call is issued.
    What is the point of making the user perform this kind of busywork? I mean, the driver knows at link time whether you've bound something to slot 0 or not. As such, it should therefore be able to bind one of the unbound ones to slot 0 so that you may have a valid rendering array set without doing any manual binding.

  9. #9
    Advanced Member Frequent Contributor
    Join Date
    May 2005
    Location
    Prague, Czech Republic
    Posts
    924

    Re: glVertexAttribPointer + GLSL + Ati = grr

    Originally posted by Korval:
    What is the point of making the user perform this kind of busywork? I mean, the driver knows at link time whether you've bound something to slot 0 or not. As such, it should therefore be able to bind one of the unbound ones to slot 0 so that you may have a valid rendering array set without doing any manual binding.
    Problem is that the OGL specification does not specify (at least I found nothing about that) that automatic assignment will bind stream to attribute 0 so driver is free to not use it.

    Actually the driver does not know at link time which attributes will be sourced per vertex from vertex arrays and which will serve as some form of low frequency constant trough glVertexAttribX() calls (even if application doing this without explicit binding of such attributes is asking for troubles) so that sort of fully automatic guaranteed assignment would be problematic to implement.

    This might be the reason why the specification does not request that automatic binding will utilize attribute 0.

  10. #10
    Junior Member Newbie RickA's Avatar
    Join Date
    Sep 2006
    Location
    NL
    Posts
    19

    Re: glVertexAttribPointer + GLSL + Ati = grr

    Originally posted by Komat:
    Originally posted by Korval:
    What is the point of making the user perform this kind of busywork? I mean, the driver knows at link time whether you've bound something to slot 0 or not. As such, it should therefore be able to bind one of the unbound ones to slot 0 so that you may have a valid rendering array set without doing any manual binding.
    Problem is that the OGL specification does not specify (at least I found nothing about that) that automatic assignment will bind stream to attribute 0 so driver is free to not use it.

    Actually the driver does not know at link time which attributes will be sourced per vertex from vertex arrays and which will serve as some form of low frequency constant trough glVertexAttribX() calls (even if application doing this without explicit binding of such attributes is asking for troubles) so that sort of fully automatic guaranteed assignment would be problematic to implement.

    This might be the reason why the specification does not request that automatic binding will utilize attribute 0.
    I don't quite follow this? Isn't it as simple as scanning the vertex shader for use of gl_Vertex? If there's no reference to gl_Vertex, then anything sent to the GPU with glVertexPointer won't be used, so location 0 is unused.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •