Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Allegro5 and OpenGL. Problem with drawing Allegro primitives

This thread is locked; no one can reply to it. rss feed Print
Allegro5 and OpenGL. Problem with drawing Allegro primitives
Izual
Member #2,756
September 2002
avatar

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:

#SelectExpand
1#define ALLEGRO_UNSTABLE 2 3#include <stdio.h> 4#include <stdlib.h> 5 6#include "allegro5/allegro.h" 7#include "allegro5/allegro_font.h" 8#include "allegro5/allegro_opengl.h" 9#include "allegro5/allegro_primitives.h" 10 11ALLEGRO_SHADER *as; 12ALLEGRO_DISPLAY *display; 13ALLEGRO_BITMAP *bmp; 14ALLEGRO_FONT *font; 15ALLEGRO_TRANSFORM t; 16ALLEGRO_STATE state; 17 18const char *vertexShaderSource = 19 "#version 330 core\n" 20 "layout (location = 0) in vec3 aPos;\n" 21 "void main()\n" 22 "{\n" 23 " gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n" 24 "}\0"; 25 26const char *fragmentShaderSource = 27 "#version 330 core\n" 28 "out vec4 FragColor;\n" 29 "void main()\n" 30 "{\n" 31 "FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n" 32 "}\0"; 33 34float vertices[] = { -0.5f, -0.5f, 0.0f, 35 0.5f, -0.5f, 0.0f, 36 0.0f, 0.5f, 0.0f }; 37 38GLuint vbo; 39GLuint vao; 40GLuint vshader; 41GLuint fshader; 42GLuint shader_program; 43int glVersion[] = { -1, -1 }; 44 45int main() 46 { 47 printf( "OpenGL with Allegro!\n" ); 48 49 al_init(); 50 al_init_font_addon(); 51 al_init_primitives_addon(); 52 al_set_new_display_flags( ALLEGRO_OPENGL | ALLEGRO_PROGRAMMABLE_PIPELINE ); 53 display = al_create_display( 640, 480 ); 54 55// Test bitmap: 56 bmp = al_create_bitmap( 64, 64 ); 57 al_set_target_bitmap( bmp ); 58 al_clear_to_color( al_map_rgb( 0, 255, 0 ) ); 59 al_set_target_backbuffer( display ); 60 61// Test font: 62 font = al_create_builtin_font(); 63 64// OpenGL version check ( i get v.4.6 ): 65 glGetIntegerv(GL_MAJOR_VERSION, &glVersion[0]); 66 glGetIntegerv(GL_MINOR_VERSION, &glVersion[1]); 67 printf( "OpenGL %d.%d\n", glVersion[ 0 ], glVersion[ 1 ] ); 68 69// Allegro shaders: 70 as = al_create_shader( ALLEGRO_SHADER_GLSL ); 71 al_attach_shader_source( as, ALLEGRO_SHADER_GLSL, al_get_default_shader_source( ALLEGRO_SHADER_GLSL, ALLEGRO_VERTEX_SHADER ) ); 72 al_attach_shader_source( as, ALLEGRO_SHADER_GLSL, al_get_default_shader_source( ALLEGRO_SHADER_GLSL, ALLEGRO_PIXEL_SHADER ) ); 73 al_build_shader( as ); 74 75// Store Allegro state, all of it: 76 al_store_state( &state, ALLEGRO_STATE_ALL ); 77 78// Custom shaders: 79 vshader = glCreateShader( GL_VERTEX_SHADER ); 80 glShaderSource( vshader, 1, &vertexShaderSource, NULL ); 81 glCompileShader( vshader ); 82 83 fshader = glCreateShader( GL_FRAGMENT_SHADER ); 84 glShaderSource( fshader, 1, &fragmentShaderSource, NULL); 85 glCompileShader( fshader); 86 87 shader_program = glCreateProgram(); 88 glAttachShader( shader_program, vshader ); 89 glAttachShader( shader_program, fshader); 90 glLinkProgram( shader_program); 91 92 glUseProgram( shader_program ); 93 94// OpenGL stuff: 95 glViewport(0, 0, 640, 480); 96 glClearColor( 0.2f, 0.3f, 0.3f, 1.0f ); 97 glClear( GL_COLOR_BUFFER_BIT ); 98 99 glGenBuffers( 1, &vbo ); 100 glGenVertexArrays( 1, &vao ); 101 102// After commenting out this section Allegro primitives drawing works even 103// without drawing allegro bitmap or allegro text to the backbuffer first: 104 glBindVertexArray( vao ); 105 glBindBuffer( GL_ARRAY_BUFFER, vbo ); 106 glBufferData( GL_ARRAY_BUFFER, sizeof( vertices ), vertices, GL_STATIC_DRAW ); 107 glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), ( void* )0 ); 108 glEnableVertexAttribArray( 0 ); 109 glDrawArrays( GL_TRIANGLES, 0, 3 ); 110// End of section 111 112 glDeleteShader( vshader ); 113 glDeleteShader( fshader ); 114 glDeleteProgram( shader_program ); 115 116// Restore Allegro shaders, transform and target backbuffer: 117 al_restore_state( &state ); 118 119 al_set_current_opengl_context( display ); 120 al_set_target_backbuffer( display ); 121 al_use_shader( as ); 122 123 al_identity_transform( &t ); 124 al_use_transform( &t ); 125 126// Disabling this draw bitmap and draw text calls also prevents the primitives 127// to by drawn when drawing with OpenGL. Drawing bitmap or text at least once 128// will fix the primitives drawing problem: 129// al_draw_bitmap( bmp, 64, 64, 0 ); 130// al_draw_text( font, al_map_rgb( 0, 128, 255 ), 32, 32, 0, "Allegro text..." ); 131 132// Our primitives that refuses to be drawn when using OpenGL: 133 al_draw_circle( 128, 128, 34, al_map_rgb( 128, 255, 255 ), 1.0 ); 134 al_draw_line( 0, 0, 256, 256, al_map_rgb( 255, 0, 0 ), 1.0 ); 135 al_draw_rectangle( 16, 16, 240, 240, al_map_rgb( 255, 255, 128 ), 1.0 ); 136 137 al_flip_display(); 138 al_rest( 3 ); 139 140 al_destroy_bitmap( bmp ); 141 al_destroy_font( font ); 142 al_destroy_shader( as ); 143 144 return 0; 145 }

Edit: Updated the code to reflect the changes that has been made so far.

Dizzy Egg
Member #10,824
March 2009
avatar

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!)

----------------------------------------------------
Please check out my songs:
https://soundcloud.com/dont-rob-the-machina

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

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.

Izual
Member #2,756
September 2002
avatar

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.

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

Dizzy Egg
Member #10,824
March 2009
avatar

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!

----------------------------------------------------
Please check out my songs:
https://soundcloud.com/dont-rob-the-machina

Izual
Member #2,756
September 2002
avatar

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. :)

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

Dizzy Egg
Member #10,824
March 2009
avatar

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…

----------------------------------------------------
Please check out my songs:
https://soundcloud.com/dont-rob-the-machina

Peter Hull
Member #1,136
March 2001

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.

Izual
Member #2,756
September 2002
avatar

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.

Dizzy Egg
Member #10,824
March 2009
avatar

You can get around it by doing your OpenGL drawing onto a buffer, and then drawing that to the display before your primitives:

#SelectExpand
1#define ALLEGRO_UNSTABLE 2 3#include <stdio.h> 4#include <stdlib.h> 5 6#include "allegro5/allegro.h" 7#include "allegro5/allegro_font.h" 8#include "allegro5/allegro_opengl.h" 9#include "allegro5/allegro_primitives.h" 10 11ALLEGRO_SHADER* as; 12ALLEGRO_DISPLAY* display; 13ALLEGRO_BITMAP* bmp; 14ALLEGRO_BITMAP* buffer; 15ALLEGRO_FONT* font; 16ALLEGRO_STATE state; 17 18const char* vertexShaderSource = 19"#version 330 core\n" 20"layout (location = 0) in vec3 aPos;\n" 21"void main()\n" 22"{\n" 23" gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n" 24"}\0"; 25 26const char* fragmentShaderSource = 27"#version 330 core\n" 28"out vec4 FragColor;\n" 29"void main()\n" 30"{\n" 31"FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n" 32"}\0"; 33 34float vertices[] = { -0.5f, -0.5f, 0.0f, 35 0.5f, -0.5f, 0.0f, 36 0.0f, 0.5f, 0.0f }; 37 38GLuint vbo; 39GLuint vao; 40GLuint vshader; 41GLuint fshader; 42GLuint shader_program; 43int glVersion[] = { -1, -1 }; 44 45int main() 46{ 47 printf("OpenGL with Allegro!\n"); 48 49 al_init(); 50 al_init_font_addon(); 51 al_init_primitives_addon(); 52 al_set_new_display_flags(ALLEGRO_OPENGL | ALLEGRO_PROGRAMMABLE_PIPELINE); 53 display = al_create_display(640, 480); 54 55 //OpenGL buffer 56 buffer = al_create_bitmap(640, 480); 57 58 // Test bitmap: 59 bmp = al_create_bitmap(64, 64); 60 al_set_target_bitmap(bmp); 61 al_clear_to_color(al_map_rgb(0, 255, 0)); 62 63 // Test font: 64 font = al_create_builtin_font(); 65 66 // OpenGL version check ( i get v.4.6 ): 67 glGetIntegerv(GL_MAJOR_VERSION, &glVersion[0]); 68 glGetIntegerv(GL_MINOR_VERSION, &glVersion[1]); 69 printf("OpenGL %d.%d\n", glVersion[0], glVersion[1]); 70 71 // Allegro shaders: 72 as = al_create_shader(ALLEGRO_SHADER_GLSL); 73 al_attach_shader_source(as, ALLEGRO_VERTEX_SHADER, al_get_default_shader_source(ALLEGRO_SHADER_GLSL, ALLEGRO_VERTEX_SHADER)); 74 al_attach_shader_source(as, ALLEGRO_PIXEL_SHADER, al_get_default_shader_source(ALLEGRO_SHADER_GLSL, ALLEGRO_PIXEL_SHADER)); 75 al_build_shader(as); 76 77 // Store Allegro state, all of it: 78 al_store_state(&state, ALLEGRO_STATE_ALL); 79 80 //Set OpenGL buffer 81 al_set_target_bitmap(buffer); 82 83 // Custom shaders: 84 vshader = glCreateShader(GL_VERTEX_SHADER); 85 glShaderSource(vshader, 1, &vertexShaderSource, NULL); 86 glCompileShader(vshader); 87 88 fshader = glCreateShader(GL_FRAGMENT_SHADER); 89 glShaderSource(fshader, 1, &fragmentShaderSource, NULL); 90 glCompileShader(fshader); 91 92 shader_program = glCreateProgram(); 93 glAttachShader(shader_program, vshader); 94 glAttachShader(shader_program, fshader); 95 glLinkProgram(shader_program); 96 97 glUseProgram(shader_program); 98 99 // OpenGL stuff: 100 glGenBuffers(1, &vbo); 101 glGenVertexArrays(1, &vao); 102 103 glBindVertexArray(vao); 104 glBindBuffer(GL_ARRAY_BUFFER, vbo); 105 glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); 106 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); 107 glEnableVertexAttribArray(0); 108 109 glViewport(0, 0, 640, 480); 110 glClearColor(0.2f, 0.3f, 0.3f, 1.0f); 111 glClear(GL_COLOR_BUFFER_BIT); 112 glDrawArrays(GL_TRIANGLES, 0, 3); 113 // End of section 114 115 // Restore Allegro shaders and state 116 al_restore_state(&state); 117 al_use_shader(as); 118 119 //Use display bitmap 120 al_set_target_backbuffer(display); 121 122 //Draw OpenGL buffer 123 al_draw_bitmap(buffer, 0, 0, 0); 124 125 //Draw primitives 126 al_draw_circle(128, 128, 34, al_map_rgb(128, 255, 255), 1.0); 127 al_draw_line(0, 0, 256, 256, al_map_rgb(255, 0, 0), 1.0); 128 al_draw_rectangle(16, 16, 240, 240, al_map_rgb(255, 255, 128), 1.0); 129 130 al_flip_display(); 131 al_rest(3); 132 133 glDeleteShader(vshader); 134 glDeleteShader(fshader); 135 glDeleteProgram(shader_program); 136 137 al_destroy_bitmap(buffer); 138 al_destroy_bitmap(bmp); 139 al_destroy_font(font); 140 al_destroy_shader(as); 141 142 return 0; 143}

----------------------------------------------------
Please check out my songs:
https://soundcloud.com/dont-rob-the-machina

Peter Hull
Member #1,136
March 2001

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

Dizzy Egg
Member #10,824
March 2009
avatar

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:

#SelectExpand
1#define ALLEGRO_UNSTABLE 2 3#include <stdio.h> 4#include <stdlib.h> 5 6#include "allegro5/allegro.h" 7#include "allegro5/allegro_font.h" 8#include "allegro5/allegro_opengl.h" 9#include "allegro5/allegro_primitives.h" 10 11ALLEGRO_SHADER* as; 12ALLEGRO_DISPLAY* display; 13ALLEGRO_BITMAP* bmp; 14ALLEGRO_FONT* font; 15ALLEGRO_STATE state; 16 17const char* vertexShaderSource = 18"#version 330 core\n" 19"layout (location = 0) in vec3 aPos;\n" 20"void main()\n" 21"{\n" 22" gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n" 23"}\0"; 24 25const char* fragmentShaderSource = 26"#version 330 core\n" 27"out vec4 FragColor;\n" 28"void main()\n" 29"{\n" 30"FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n" 31"}\0"; 32 33float vertices[] = { -0.5f, -0.5f, 0.0f, 34 0.5f, -0.5f, 0.0f, 35 0.0f, 0.5f, 0.0f }; 36 37GLuint vbo; 38GLuint vao; 39GLuint vshader; 40GLuint fshader; 41GLuint shader_program; 42int glVersion[] = { -1, -1 }; 43 44int main() 45{ 46 printf("OpenGL with Allegro!\n"); 47 48 al_init(); 49 al_init_font_addon(); 50 al_init_primitives_addon(); 51 al_set_new_display_flags(ALLEGRO_OPENGL | ALLEGRO_PROGRAMMABLE_PIPELINE); 52 display = al_create_display(640, 480); 53 54 // Test bitmap: 55 bmp = al_create_bitmap(64, 64); 56 al_set_target_bitmap(bmp); 57 al_clear_to_color(al_map_rgb(0, 255, 0)); 58 59 // Test font: 60 font = al_create_builtin_font(); 61 62 // OpenGL version check ( i get v.4.6 ): 63 glGetIntegerv(GL_MAJOR_VERSION, &glVersion[0]); 64 glGetIntegerv(GL_MINOR_VERSION, &glVersion[1]); 65 printf("OpenGL %d.%d\n", glVersion[0], glVersion[1]); 66 67 // Allegro shaders: 68 as = al_create_shader(ALLEGRO_SHADER_GLSL); 69 al_attach_shader_source(as, ALLEGRO_VERTEX_SHADER, al_get_default_shader_source(ALLEGRO_SHADER_GLSL, ALLEGRO_VERTEX_SHADER)); 70 al_attach_shader_source(as, ALLEGRO_PIXEL_SHADER, al_get_default_shader_source(ALLEGRO_SHADER_GLSL, ALLEGRO_PIXEL_SHADER)); 71 al_build_shader(as); 72 73 // Store Allegro state, all of it: 74 al_store_state(&state, ALLEGRO_STATE_ALL); 75 76 //Set OpenGL buffer 77 al_set_target_backbuffer(display); 78 79 // Custom shaders: 80 vshader = glCreateShader(GL_VERTEX_SHADER); 81 glShaderSource(vshader, 1, &vertexShaderSource, NULL); 82 glCompileShader(vshader); 83 84 fshader = glCreateShader(GL_FRAGMENT_SHADER); 85 glShaderSource(fshader, 1, &fragmentShaderSource, NULL); 86 glCompileShader(fshader); 87 88 shader_program = glCreateProgram(); 89 glAttachShader(shader_program, vshader); 90 glAttachShader(shader_program, fshader); 91 glLinkProgram(shader_program); 92 93 glUseProgram(shader_program); 94 95 // OpenGL stuff: 96 glGenBuffers(1, &vbo); 97 glGenVertexArrays(1, &vao); 98 99 glBindVertexArray(vao); 100 glBindBuffer(GL_ARRAY_BUFFER, vbo); 101 glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); 102 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); 103 glEnableVertexAttribArray(0); 104 105 glViewport(0, 0, 640, 480); 106 glClearColor(0.2f, 0.3f, 0.3f, 1.0f); 107 glClear(GL_COLOR_BUFFER_BIT); 108 glDrawArrays(GL_TRIANGLES, 0, 3); 109 // End of section 110 111 //Unbind vertex/buffer 112 glBindVertexArray(0); 113 glBindBuffer(GL_ARRAY_BUFFER, 0); 114 115 // Restore Allegro shaders and state 116 al_restore_state(&state); 117 al_use_shader(as); 118 119 //Use display bitmap 120 al_set_target_backbuffer(display); 121 122 //Draw primitives 123 al_draw_circle(128, 128, 34, al_map_rgb(128, 255, 255), 1.0); 124 al_draw_line(0, 0, 256, 256, al_map_rgb(255, 0, 0), 1.0); 125 al_draw_rectangle(16, 16, 240, 240, al_map_rgb(255, 255, 128), 1.0); 126 127 al_flip_display(); 128 al_rest(3); 129 130 glDeleteShader(vshader); 131 glDeleteShader(fshader); 132 glDeleteProgram(shader_program); 133 134 al_destroy_bitmap(bmp); 135 al_destroy_font(font); 136 al_destroy_shader(as); 137 138 return 0; 139}

----------------------------------------------------
Please check out my songs:
https://soundcloud.com/dont-rob-the-machina

Izual
Member #2,756
September 2002
avatar

Thank You!

Calling glBindVertexArray( 0 ) as well as glBindBuffer( 0 ) fixed it!
Now everything works like it should.

Thank you again.

Dizzy Egg
Member #10,824
March 2009
avatar

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.

----------------------------------------------------
Please check out my songs:
https://soundcloud.com/dont-rob-the-machina

Peter Hull
Member #1,136
March 2001

Nice one Dizzy Egg!

Go to: