[A5] What's the current, proper way to use both 2-D and 3-D functions
Chris Katko

Drawing text. Great.

Doing 3-D transformations. Great.

Together? Nope!

{"name":"tivuHw2.png","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/7\/4\/74ec4c724ed32098edcd70a2b9693b10.png","w":801,"h":624,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/7\/4\/74ec4c724ed32098edcd70a2b9693b10"}

I've tried saving and restoring the projection matrix and the transformation matrix. But it doesn't fix rotation for some reason (the text is rotated!), and restoring to the identity leaves screen position 0,0 in the center of the screen (the text should be top-left at (x,y)=(10,10)!)

I want 3-D stuff drawn. (Note my lines and circles are supposed to be transformed--as ugly as they are for now.) And then I want 2-D stuff drawn without perspective transformations.

So what's the modern, proper way to do this with Allegro 5?

Code snippets follow:

Before looping:

```  ALLEGRO_TRANSFORM projection; //active one for general use
ALLEGRO_TRANSFORM *allegro_2d_projection = al_get_projection_transform(display);
ALLEGRO_TRANSFORM *allegro_2d_transform = new ALLEGRO_TRANSFORM;
al_copy_transform(allegro_2d_transform, al_get_current_transform());
```

During looping:

1 2 // ALLEGRO 2-D DRAWING 3 al_set_projection_transform(display, allegro_2d_projection); 4 al_use_transform(allegro_2d_transform); 5 al_draw_textf(font, al_map_rgb(255,255,255), 10, 10, 0, "offset_vel [%f/%f]", offset_x_vel, offset_y_vel); 6 al_draw_textf(font, al_map_rgb(255,255,255), 10, 20, 0, "frame rate [%i]", frame_rate); 7 8 // ALLEGRO 3-D DRAWING 9 al_identity_transform(&projection); 10 al_rotate_transform_3d(&projection, 1, 0, 0, tilt_angle); 11 al_translate_transform_3d(&projection, 0, 0, zoom_distance); 12 al_perspective_transform(&projection, -180 * dw / dh, -180, 180, 180 * dw / dh, 180, 3000); 13 al_set_projection_transform(display, &projection); 14 15 universe.draw(); 16 17 // ALLEGRO 2-D DRAWING TOP LAYER 18 al_set_projection_transform(display, allegro_2d_projection); 19 al_use_transform(allegro_2d_transform); 20 21 //mouse cursor for testing 22 al_draw_circle(ms_state.x, 23 ms_state.y, 24 5, 25 al_map_rgb(255,0,0), 1); 26 27 al_flip_display();

I found this post but I wasn't sure if it was up-to-date or not since it's from 2012.

Thomas Fjellstrom

If you want billboard lime text, you may need to set an orthographic transform for that.

Chris Katko

But what is Allegro doing under the hood and why can't I just easily go back to that?

Thomas Fjellstrom

Allegro is using an orthographic transform. It pretty much ignores perspective and z coords (except things should still be z-index layered properly). In my latest program, I grab the perspective transform allegro sets up when I start up, so I can change it later, and switch back to it at any time.

Basically I do: (pseudo code)

1// startup 2al_proj_transform = al_get_projection_transform(); 3 4// draw 5al_store_state(ALL); 6al_set_projection_transform(dpy_, &al_proj_transform); 7 8glClear(GL_DEPTH_BUFFER_BIT); 9al_clear_to_color(al_map_rgb(255,255,255)); 10 11draw(); // draw 3d shit 12 13al_restore_state(&state); 14al_set_projection_transform(dpy_, &al_proj_transform); 15 16drawHud(); // draw a 2d layer on top of everything 17 18al_restore_state(&state); 19 20al_flip_display();

Chris Katko

You code isn't exactly correct. But after a few hours I think I got something that works.

What is Allegro 5 doing under-the-hood for 2-D drawing routines? Is it just drawing to a texture and then blitting that, or what?

I'm having trouble figuring out where I should use Allegro's tranformation routines, and where I should is OpenGL ones, and in what combination.

Arthur Kalliokoski

You're restricting yourself to OpenGL?

This is what I've been doing it (for shader stuff too, I don't know how to get A5 to draw text with shaders):

1 //The 3d projection is in effect here 2 glMatrixMode(GL_TEXTURE); 3 glPushMatrix(); 4 glLoadIdentity(); 5 glMatrixMode(GL_PROJECTION); 6 glPushMatrix(); 7 glLoadIdentity(); 8 glMatrixMode(GL_MODELVIEW); 9 glPushMatrix(); 10 glLoadIdentity(); 11 glDisable(GL_TEXTURE_2D); 12 glDisable(GL_CULL_FACE); 13 glMatrixMode(GL_PROJECTION); 14 glOrtho(0.0, display_width, display_height, 0.0, -1.0, 1000.0); 15 16 al_draw_textf(font,al_map_rgb_f(1.0,1.0,1.0),20.0,40.0,0,"blah blah -- blah blah blah"); 17 18 //Restore the 3d projection 19 glMatrixMode(GL_MODELVIEW); 20 glPopMatrix(); 21 glMatrixMode(GL_PROJECTION); 22 glPopMatrix(); 23 glMatrixMode(GL_TEXTURE); 24 glPopMatrix(); 25 glMatrixMode(GL_MODELVIEW);

Chris Katko

I'll try that code when I get home from work today, thanks!

You're restricting yourself to OpenGL?

Is that implying I shouldn't? I thought Allegro ran on top of OpenGL. What else would I use for polygons?

Arthur Kalliokoski

Is that implying I shouldn't? I thought Allegro ran on top of OpenGL. What else would I use for polygons?

The A5 primitives etc. are calling DirectX functions on windows by default, unless OpenGL is specified as an display option. Cross compatibility or something.

Chris Katko

I'm on Linux. I wasn't aware of the DirectX under-the-hood, though. Running OpenGL doesn't "break" anything in Allegro does it?

Arthur Kalliokoski

Running OpenGL doesn't "break" anything in Allegro does it?

If it did, it would get fixed by the awesome devs.

Chris Katko

Back to my earlier question though, how does Allegro 5 run it's own drawing routines within the context of OpenGL? Are they all just drawn to a texture and a single quad is drawn? And what is the default frustum in Allegro? It appears to be clipping like crazy when I rotate or try to zoom in.

Arthur Kalliokoski

Back to my earlier question though, how does Allegro 5 run it's own drawing routines within the context of OpenGL? Are they all just drawn to a texture and a single quad is drawn?

As far as I've been able to tell, FreeType sets a bitmap (using actual bits, not pixels) to render a glyph, and A5 sets pixels on a texture, then these textures are drawn aligned with the pixels on the screen.

Quote:

And what is the default frustum in Allegro? It appears to be clipping like crazy when I rotate or try to zoom in.

When you're doing the 3D stuff, use glFrustum or gluPerspective or even set your own, then restore the 2D stuff as above before drawing text.

1void set_perspective(float *m, float fov, float aspect, 2 float znear, float zfar) 3{ 4 float xymax = znear * tan(fov * (M_PI/360.0)); 5 float ymin = -xymax; 6 float xmin = -xymax; 7 8 float width = xymax - xmin; 9 float height = xymax - ymin; 10 11 float depth = zfar - znear; 12 float q = -(zfar + znear) / depth; 13 float qn = -2 * (zfar * znear) / depth; 14 15 float w = 2 * znear / width; 16 w = w / aspect; 17 float h = 2 * znear / height; 18 19 m[0] = w; 20 m[1] = 0; 21 m[2] = 0; 22 m[3] = 0; 23 24 m[4] = 0; 25 m[5] = h; 26 m[6] = 0; 27 m[7] = 0; 28 29 m[8] = 0; 30 m[9] = 0; 31 m[10] = q; 32 m[11] = -1; 33 34 m[12] = 0; 35 m[13] = 0; 36 m[14] = qn; 37 m[15] = 0; 38}

Chris Katko

Thank you very much for your help. That's the kind of detail I needed to solve the issues I'm having. I'll get back to you with my results when I have them.

Thomas Fjellstrom

I did mess up the code example but the code in github seems to work fine for a 2d overlay on a 3d view.

As for how allegro draws... Blitz are textured quads or triangles and the primitives addon uses generated lists of triangles to make up the various shapes.