Hello.
I am trying to learn some OpenGL from https://learnopengl.com/ and i am trying to use Allegro 5 instead of GLFW that the tutorial uses.
It seems that i got the OpenGL part working. I can see my triangle on the screen. The problem is when i want to switch back to Allegro primitives drawing functions, they do not work after using OpenGL draw calls.
Then when you use any Allegro bitmap or text drawing function at least once, the primitives drawing functions also starts to work again.
My question are:
1) Is this the correct way of using OpenGL with Allegro? If not is there other way to go about it?
2) By any chance am i messing some Allegro internal state with the VBO and VBA stuff i am using in the OpenGL? ( This is my second day trying to learn OpenGL so i have no idea how it all works togetger ).
I am using:
Ubuntu 22.04 TLS
Allegro 5.2.8
NVIDIA GT1050 2GB with 510.85.02 driver
My code:
Edit: Updated the code to reflect the changes that has been made so far.
I imagine you want to call al_set_target_backbuffer again after doing your opengl calls. Not sure why calling al_draw_bitmap or al_draw_text does that for you, but that should fix it (I think!)
OpenGL is a state engine. Allegro changes GL state when it does its thing, so things may not be as you left it once allegro touches it. You may need to reset the projection and view transforms. There is also a default shader per bitmap and other things I can't think of or don't know about.
Thank you for the tips.
I tried to store and restore entire Allegro state using ALLEGRO_STATE_ALL parameter.
Setting OpenGL current context, setting target bitmap to backbuffer and
reseting the transformation to default.
Nothing helped so far.
I have updated the code in opening post to reflect the changes i made so far.
Store the allegro state before changing opengl stuff and when you're done restore it. I can't tell if you did that or not I don't see any changes in your code.
You can also get the primitives to draw by locking the bakbuffer before drawing and unlocking after, so changing your primitive code to this:
al_lock_bitmap(al_get_backbuffer(display), ALLEGRO_PIXEL_FORMAT_ANY, 0); al_draw_circle(128, 128, 34, al_map_rgb(128, 255, 255), 1.0); al_draw_line(0, 0, 256, 256, al_map_rgb(255, 0, 0), 1.0); al_draw_rectangle(16, 16, 240, 240, al_map_rgb(255, 255, 128), 1.0); al_unlock_bitmap(al_get_backbuffer(display));
Will work, so there's something happening with the openGL stuff that isn't being released until you either draw a bitmap (or text) to the backbuffer, or lock it before drawing primitives....
....will need someone with more knowledge on the subject than me to tell you why though!
Thank you Dizzy. Locking the bitmaps allows me to draw the primitives but when the backbuffer is unlocked the drawing does not work again.
It seems like using VBOs and VAOs does mess up Allegros internal state somehow and the bitmap drawing functions restores it again somehow.
It is not a deal breaker, for now i can keep learning OpenGL this way and maybe one day when i know what is going on i will be able to solve this problem.
You shouldn't ever have to lock the backbuffer. In fact to draw on it allegro has to unlock it.
The projection transform might be getting changed somehow, that would make primitives 'disappear'.
Odd that they appear if you draw an image or text first though, leads me to believe it’s more of an fbo issue or similar…
Don't know if this is your problem but the second argument of al_attach_shader_source is a ALLEGRO_SHADER_TYPE not ALLEGRO_SHADER_PLATFORM i.e. should be ALLEGRO_VERTEX_SHADER or ALLEGRO_PIXEL_SHADER
https://liballeg.org/a5docs/5.2.6/shader.html#al_attach_shader_source
[edit]
The shader type thing above doesn't fix it (but you should change it anyway!) however unbinding the array buffer made it work for me, i.e.
glBindBuffer( GL_ARRAY_BUFFER, 0);
round about line 111.
Thank you Peter. Fixed the shader stuff.
Adding glBindBuffer( GL_ARRAY_BUFFER, 0); causes a Segmentation Fault when trying to use any primitive drawing functions.
And again after using any bitmap drawing function everything works fine.
You can get around it by doing your OpenGL drawing onto a buffer, and then drawing that to the display before your primitives:
I do think this ought to work, it shouldn't need 'getting around'. Unfortunately I can't help much more, mainly because I don't know much about OpenGL and also because it worked for me (on Debian).
However, I wonder if it's right to delete the shaders and programs before the screen flip. Doesn't OpenGL batch up graphic operations sometimes?
Also, when you say there's a segfault, can you get a backtrace? Where's it coming from?
Pete
If you only unbind the buffer, the al_draw_circle function cases an exception (at least, on Windows). And even if you don't draw the circle, although they don't crash, the other 2 primitives still aren't drawn.
It seems you have to unbind the vertext buffer as well, calling glBindVertexArray(0) as well as glBindBuffer(0). Then you have to re-set the display as active.
This example works without any workarounds and no locking bitmaps etc:
Thank You!
Calling glBindVertexArray( 0 ) as well as glBindBuffer( 0 ) fixed it!
Now everything works like it should.
Thank you again.
You’re very welcome! We got there in the end! I don’t know much about OpenGL but after Peter said about binding the buffer back to 0 I figured it would be a case of getting allegro back to where it was before binding the OpenGL bits. Glad it’s all working, happy coding.
Nice one Dizzy Egg!