Now that the newer version of allegro has 3D routines, I'm trying to set things up to play around with.
I've looked at ex_projection.c and tried to adapt what's going on there. I'm still at a block and haven't been able to find any general purpose tutorial, explanation on the wiki, or even any good discussions on the forums of the general "pipeline" of how a proper 3D scene could be achieved using Allegro 5.
I want to properly use vertex and index buffers, and I think I understand how they work (even though I haven't used one yet).
What do I need to set-up? How do I need to affect my models before render?
How does a camera fit into this?
Here's where I'm at:
I think if I get a bare-bones example that renders two rotating textured cubes that z-buffer properly, I would be ok.
I don't see a flip http://alleg.sourceforge.net/a5docs/refman/display.html#al_flip_display
Hmm, I was hoping I wouldn't have to describe my framework.
The Project class inherits Screen and then overrides Screen::primary_timer_func().
Afterwhich, the flip is called.
for (unsigned d=0; d<Display::displays.size(); d++) { Display::displays[d]->set_as_target_bitmap(); al_clear_to_color(Display::displays[d]->_background_color); for (unsigned i=0; i<screens.size(); i++) { if (screens[i]->display == Display::displays[d]) screens[i]->primary_timer_func(); } Display::displays[d]->flip(); // <-- here }
A Screen is anything, like a menu screen, a game screen, a world map screen. You can nest several screens at the same time, so you would have a world screen and a hud screen at the same time.
But that's all tangential.
TLDR; the flip is in there.
Interesting! I never thought about drawing a 3D model with an Allegro al_draw_prim... Does that even work? I'll try it myself later if no one else steps up.
Not cubes and not textured, but those parts are not really relevant, are they?
Not cubes and not textured, but those parts are not really relevant, are they?
Not at all. Your post was tremendously helpful. I managed to make some progress. I still don't quite get that the perspective_transform/projection_transform is not related to drawing the primitives themselves. When drawing the primitives, are they not (actually) fully drawn until the flip? And how they are drawn is relative to the projection as set at some point before the flip?
Also, after some digging in my framework code, I found that a line:
al_set_target_bitmap(al_get_backbuffer(d));
is causing the 3D to not render correctly. If I put it into your code thusly:
... if(al_is_event_queue_empty(queue) && redraw) { al_set_target_bitmap(al_get_backbuffer(d)); ... } ...
it has the same result. I initially use that line to "reset" the drawing back so that the next screen can be drawn without any states set by the prior screen.
When drawing the primitives, are they not (actually) fully drawn until the flip?
That is undefined, but that's not really what you want to know... they take into account the transformations that were active at the time of the function call.
is causing the 3D to not render correctly
Projection transforms are very poorly implemented in A5 right now. The usual transformations ( al_use_transform) are a bitmap-local state, while the projection transformations ( al_set_projection_transform) are display local and are reset to be orthographic whenever you change target bitmaps. This is a disaster I noticed years ago, but haven't had time to fix myself.
it has the same result.
So the solution is to do this:
Not too terribly exciting, but I'm happy with what I've managed to accomplish so far
{"name":"608537","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/0\/d\/0d38c4b169abf0c592eb6dbf494517bc.png","w":960,"h":540,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/0\/d\/0d38c4b169abf0c592eb6dbf494517bc"}
{"name":"608540","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/b\/1\/b1db0c150a901b24beae2da4b76d1717.png","w":960,"h":540,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/b\/1\/b1db0c150a901b24beae2da4b76d1717"}
Cool! How do you get the textures on there?
Textures are very easy. In the ALLEGRO_VERTEX there are 6 values:
struct ALLEGRO_VERTEX { float x, y, z; float u, v; ALLEGRO_COLOR color; };
(u, v) are the (x, y) coordinates of the texture in pixel coordinates. If you overshoot or undershoot (u, v) to the width/height of the texture then the texture will loop.
When you draw the prim (via al_draw_prim or whatnot) then you pass the ALLEGRO_BITMAP texture in to that function.
I see, I should have thought about it myself! Drat, now I want to program a classic dungeon crawler in Allegro... one day!