I have a strange problem with vertex attributes in shader at OpenGL 4.2 (the same happens in 3.3). I have written simple program to learn about OpenGL shaders and VAO, it is quite simple because I draw only a couple of rectangles. My problem start with even two rectangles, so I will explain it at first using only this two rectangles. I have one rectangle that have color and texture and one that have only color, for each of this rectangles is separate shader. For rectangle with only color, shader takes vertex attributes for position and it's color, shader for rectangle that have texture take position, color and texture coordinates. Each of this rectangles have its own VAO that uses vertex buffer and index buffer. I know that drawing simple rectangle don't need index buffer, but it's test program. Here start my problem, when I draw only one of this rectangles every thing is fine, but when both of them is draw something is wrong. When I draw first rectangle witch color and then with texture, second rectangle (this with texture) don't have texture. When I draw first rectangle with texture it have texture but second rectangle doesn't draw at all. What is strange in this is that it happens from second swap buffers operation. I made a test and render everything only once, then everything is fine. Normally I rendering it in loop like for a game or some animation. I have found that when rectangle that should have texture don't have it, it's shader just gets texture coordinates that is (I think) default, that means (0, 0), and it looks like from some reason this attribute stops working.
I attached some files with source code to this question, to better explain what I doing:
rectColor.vs, rectColor.fs - vertex and fragment shader for rectangle with only color
rectTexutre.vs, rectTexture.fs - vertex and fragment shader for rectangle witch texture and color
VertexBuffer.cpp - here is how I made VAO for my rectangles, basically I made VAO, bind it, create buffer for vertex data and for indices, setup pointers and enable vertex attrib arrays. I don't know maybe here I made some mistakes. To draw this rectangles I use glDrawElements and off course before calling this function i call glUseProgram with program I want to use and glBindVertexArray.
As I see I can't attach more files but this should be enough to show how i doing VAO and what is in shaders. Important thing to mention here is that i testing it under windows 7 x64 and I created OpenGL context using windows api. First I creating dummy context then I using glew to get extensions, next i create real context core profile 4.2 and before making current 4.2 context I delete dummy context. But this should be ok since other things works fine.
That not the end of strange things that I have found. To explain other things I show how I set vertex attributes, I use layout(location=x) in shader files.
For rectangle with texture shader it looks like this:
layout(location=0) in vec4 in_Position;
layout(location=1) in vec4 in_Color;
layout(location=2) in vec4 in_TexCoord;
Rectangle with color only shader have this arguments:
layout(location=0) in vec4 in_Position;
layout(location=1) in vec4 in_Color;
And when it is used like above it doesn't working. But when i set vertex attributes of shader for rectangle with only color to:
layout(location=1) in vec4 in_Position;
layout(location=2) in vec4 in_Color;
and of course call glEnableVertexAttribArray with arguments 1 and 2 my test example start working as it should, rectangle have texture and second one is draw. This is really strange for me, I don't know why it works like that? It's normal behavior? I though that when one VAO have enabled 0,1,2 vertex attributes other VAO can have enabled 0,1 or only 0 attribute. I have tested this behavior using glBindAttribLocation and deleting layout(location=x) from shaders, it worked the same way, no changes.
And thats not the end I made another test, and I added triangle. But this time I don't used index array and I drawing this triangle with call to glDrawArrays. This triangle have separate shader with vertex attributes at locations 0, 1 (vertex position and color) not 1,2. Triangle is draw with my rectangles. This triangle draws like it should without any problems, and it draws with three other rectangles one with color only and two with textures, rectangles are draw fine, but this with color have attributes at locations 1,2.
I don't know if how it works is correct, and if I doing it right, so if anyone have some idea or explanation please for help.
I don't know if this is important but my hardware is Radeon HD 5670, driver is Catalyst 12.3. I have also made a test on my netbook that have AMD C-30 APU with Radeon 6250 (driver is also Catalyst 12.3), results are the same as at HD 5670.
Yes yesterday my friend let me test this application on his laptop with NV card. He have Geforce 8400M GS and application was working fine. So it appears that my test application don't working correct on my Radeon HD 5670 and 6250 but Geforce render it correctly.
I include whole my test project attached to this post. It is zipped Visual Studio 2010 project. I included all source files that have been used. I also included glew and FreeImage library that I have been using in this project. So to run it using Visual Studio it should need only compilation. I also included my test images that are used as textures. All used shader's are in ShaderSource directory.
Please remember that this is test / learning project so in many places there are some code that have been written for fast test and sometimes it's isn't perfect (or just ugly).
I have found another interesting thing about my problem. Actually it is even some kind of solution. As I described in my first post, I draw 3 rectangles and one triangle, two rectangles have texture and color and one have only color. This rectangles uses indices to draw, and I draw them using glDrawElements. I stored this indices as GLubyte. This should be fine especially that I send this indices to OpenGL in right way and I call glDrawElements with argument "type" set to GL_UNSIGNED_BYTE. I think this is right. But I find that when I change my indices to GLuint, this means I store them as GLuint and I call glDrawElements with type set to GL_UNSIGNED_INT, my example start working fine. What is strange, it is enough to use indices of type GLuint only in one rectangle to let example working correct. I have checked that when I use GLuint for rectangle with only color and GLubyte for rectangles with texture and color test application works correct. The same happen when I use GLubyte for rectangle with only color and GLuint for rectangles with texture and color. Of course when I use GLuint for all rectangles it also working fine.
In previous post I included my test project, to show what I have changed I include source files that has changed from last time. Most of changes are in VertexBuffer, I added overloaded methods to initialize it using GLuint indices, and I added some if instruction to call glDrawElements with right arguments depending on type of used indices. In Sprite.cpp and OpenGLContext.cpp I added arrays with indices as GLuint (OpenGLContext.cpp line 446, Sprite.cpp line 41).
What I described in this post solves in some way my vertex attributes problem. But shouldn't it work with only GLubyte indices too? I know that storing indices in single byte isn't very useful because there may be a lot of them so whole integer is a good idea but now I'm just curious.
I have tested my application on my Radeon 5670 using released two days ago Catalyst 12.4 drivers. I have also tested this application on my netbook with Radeon 6250 and Catalyst 12.3 (I haven't updated it yet) drivers and it worked the same way as on my desktop Radeon.
I registered with this forum JUST to say that this solution fixed a problem that has been driving us crazy for over a week. Thank you for finding it! It was the same exact issue to the letter. Reading your posts was like reading about our own test program, it was almost creepy. So glad you found the root cause of the driver bug. Sure Catalyst 12.10 fixes it, but before knowing the solution we were confused how anyone was able to render a texture on a quad with a Radeon card before October 2012. Once again, amazing.
It have been some time since I reported problems that I described in previous posts. Until now my test application didn't working fine with indices stored on bytes (see previous posts). But from release of Catalist 12.10 drivers problem disappeared . I have check it today after installation of new drivers. Now everything working as I think it should . I just wont to mention it here if someone else have similar problem that actually now looks completely solved on Catalist 12.10.