I'm getting some interesting behavior using Allegro 5 with GLTools. I'm learning openGL in my computer graphics class and for a class project I'm creating a quick shooter demo. I've used Allegro 4 before, and since Allegro 5 supports openGL, I've decided to reduce some of the complexity and use Allegro 5. I've copied some code from the OpenGL Superbible 5ed, and want to use a shader to create a moving star background. The book uses GLTools to simplify things and I've got all the GLTools stuff to work, however I cant seem to draw both my sprites and the star background. I can either draw the star background, or I can draw the sprites. When I try to draw both the stars and the sprites the stars get replaced by my sprites in a weird combination. Could someone look at my code and let me know what needs to be fixed? Thanks.
I'm having trouble deciphering all your code, but it definitely sounds like a state issue, and probably related to the texture state.
For example, you only bind the starTexture once. It needs to be bound every time before you use it (render something that uses it).
EDIT: I'm going to take a wild guess and suggest you add glBindTexture(GL_TEXTURE_2D, starTexture); near the bottom of the render function.
I'm also having a hard time keeping track of the OpenGL state looking just at the code snippet. I'd try getting rid of the al_set_target_bitmap() and al_set_current_opengl_context() calls unless you know exactly why you need them and what they do.
Billybob, adding glBindTexture does remove the issue of the shader getting all screwed up, thanks. The example I took the code from only calls glBindTexture once, any idea why its different in Allegro?
Elias, I had al_set_target_bitmap() and al_set_current_opengl_context() in the code as an attempt to solve the issue, including them or excluding them doesn't seem to do anything. I added them in because I figured I wasn't being explicit enough in setting what opengl should use.
I still cant get my sprites to appear over the star field. Commenting out render() and starbatch.draw() gives me a blank screen, well commenting out setup_background(), lets me see me see my sprites. This would seem to indicate to me something in setup_background is the issue, but I really don't see anything in their that would cause my sprites not to be drawn.
thank you for the replies
The example I took the code from only calls glBindTexture once, any idea why its different in Allegro?
glBindTexture tells OpenGL what texture to use for all the OpenGL calls following it, until another glBindTexture is called. i.e.
glBindTexture(someTexture1); ... a bunch of OpenGL calls (all of this will be drawn using someTexture1) ... glBindTexture(someTexture2); ... more OpenGL calls (all of this will be drawn using someTexture2) ...
Now, al_draw_bitmap, internally, must call glBindTexture on the bitmap being drawn, so that it can ... well, draw it! So ...
al_draw_bitmap(some_awesome_image); ... a bunch of OpenGL calls (all of these will be drawn using some_awesome_image) ... glBindTexture(someTexture2); ... more OpenGL calls (all of these will be drawn using someTexture2)
So, as you can see, by calling al_draw_bitmap, you've changed what texture is currently being used by OpenGL.
I still cant get my sprites to appear over the star field.
You'll have to assist me in deciphering the specifics of your code. Is master->update_members the call that draws your sprites? or is it al_draw_bitmap(buffer, 0, 0, ALLEGRO_VIDEO_BITMAP)
My spritehandler class takes a pointer to an allegro bitmap and all the sprites it handles draw to that bitmap. In this case the allegro bitmap "buffer" is the destination. master->update_members(clock(), total_frames, scroll); runs through all the sprites and updates them, which includes drawing the sprite to the "buffer". Then after everything is placed on the "buffer", its drawn on the screen with al_draw_bitmap(buffer, 0, 0, ALLEGRO_VIDEO_BITMAP);
Thank you again for the reply.
Would you mind showing the code for update_members? Do you call:
al_set_target_bitmap(buffer);
At the top of update_members?
If you don't, that's the problem. Or do this, if master doesn't have buffer in its scope:
al_set_target_bitmap(buffer); master->update_members(clock(), total_frames, scroll);
Also, I don't think ALLEGRO_VIDEO_BITMAP is a valid flag for al_draw_bitmap. It should probably just be:
al_draw_bitmap(buffer, 0, 0, 0);
The spritehandler class doesn't do the drawing itself, it iterates through the sprites and calls draw for each sprite, which is derived from the sprite parent class.
So the destination bitmap is set in the code. I'm pretty sure its not an issue with spritehandler since I can get my sprites to draw, just not when my shader batch is drawn. I did try your suggestion, but no luck.
I fixed the flags, I think I got them messed up with another allegro function. It did not break/fix anything, but thanks for the heads up.
Well if setup_background is indeed causing the trouble, try commenting out pieces of setup_background one by one to narrow it down. I, too, can't see anything in there that would mess up the OpenGL state.
And just to double check, you commented out all of the starfield rendering related code, except for setup_background, and it displayed a black screen? But then also commenting out setup_background fixed it?
Commenting out the following lines lets me see my sprites
in setup_background()
starsBatch.Color4fv(fColors[iColor]);
starsBatch.Vertex3fv(vPosition);
in render()
glUseProgram(starFieldShader);
if any of those are not commented out, I just get a blank screen. I have no clue why this is.
Okay, this is going to be fun!
Try doing this before drawing your sprites:
glDisableVertexAttribArray(GLT_ATTRIBUTE_VERTEX); glDisableVertexAttribArray(GLT_ATTRIBUTE_COLOR); glDisableVertexAttribArray(GLT_ATTRIBUTE_NORMAL); glDisableVertexAttribArray(GLT_ATTRIBUTE_TEXTURE0); glDisableVertexAttribArray(GLT_ATTRIBUTE_TEXTURE1); glUseProgram(0); glBindBuffer(GL_ARRAY_BUFFER, 0);
If you call Color4fv, or Vertex3fv on a GLBatch, it will muck with OpenGL's state. And obviously glUseProgram will tell OpenGL to use the shading program, even while calling al_draw_bitmap
Hopefully the above will undo everything and make Allegro happy.
Yup that did it
!!! Thanks a ton billybob. Just so if anyone else has any issues with GLTools or GLBatch or shaders, I'll copy my final "drawing" code and post it below
Yup that did it
Thank goodness! I'm glad you got it working
And thank you for posting the working code, most people forget to post their solutions