opengl 2d and 3d
adamk kromm

Ok, this is something that i still cant seem to figure out. how to draw, for example a HUD, in a 3d world... i have this

#SelectExpand
1void C3DGraphics::set3D() 2{ 3 aspect = (float)al_get_display_width()/(float)al_get_display_height(); 4 glViewport(0, 0, al_get_display_width(), al_get_display_height()); 5 6 glMatrixMode(GL_PROJECTION); 7 glLoadIdentity(); 8 gluPerspective(45.0, aspect, 0.1, 1000); 9 10 glPushMatrix(); 11 glMatrixMode(GL_MODELVIEW); 12 glLoadIdentity(); 13 14 glEnable(GL_DEPTH_TEST); 15} 16 17void C3DGraphics::set2D() 18{ 19 //Return to Allegros 2D world 20 glMatrixMode(GL_PROJECTION); 21 glPopMatrix(); 22 glMatrixMode(GL_MODELVIEW); 23 glLoadIdentity(); 24 glOrtho(0.0f,800,600,0.0f,-1.0f,1.0f); 25}

i call set2D when i want to draw 2d and i call set 3d when i want to draw in 3d, the 3d part works. The 2d part doesnt.

here is the part where i do the drawing

  graphics->set2D();
  
  al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, al_map_rgba_f(1.0, 1.0, 1.0, 1.0));     
  al_draw_bitmap(compasBack, 100,100,NULL);
  al_draw_bitmap(compasPOV, 100,100,NULL);
  al_set_blender(ALLEGRO_ONE, ALLEGRO_ONE, al_map_rgba_f(1, 1, 1, 0));

  graphics->set3D();

mabey its a problem with the blending?

im lost when it comes to blending and changing between 2d and 3d

OnlineCop

#SelectExpand
20 glMatrixMode(GL_PROJECTION); 21 glPopMatrix(); 22 glMatrixMode(GL_MODELVIEW);

IIRC, GL_PROJECTION sets you into "2D" mode. But when you switch back to GL_MODELVIEW, you set your display back to "3D" mode. Try leaving it out (GL_MODELVIEW) and see if it changes anything for you.

gnolam
OnlineCop said:

IIRC, GL_PROJECTION sets you into "2D" mode. But when you switch back to GL_MODELVIEW, you set your display back to "3D" mode. Try leaving it out (GL_MODELVIEW) and see if it changes anything for you.

Utterly wrong. glMatrixMode() simply sets which matrix to affect with OpenGL's matrix/transformation ops: the projection matrix or the modelview matrix. Where (to simplify things quite a bit) the projection matrix is what projects your 3D points onto your 2D screen before drawing them and the modelview matrix is what moves your objects around before they are projected.

Which brings me to the OP's code:

void C3DGraphics::set2D()
{
  //Return to Allegros 2D world
  glMatrixMode(GL_PROJECTION);
  glPopMatrix(); 
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  glOrtho(0.0f,800,600,0.0f,-1.0f,1.0f);
}

So. glOrtho - "set an orthographic projection"[1] - does that sound like it belongs as a modelview or projection operation? :)
Also, it seems you're pushing and popping matrices without realizing what those functions actually do.

  // Go into 2D
  glMatrixMode(GL_PROJECTION); // We want to change the projection, so switch to the projection matrix
  glLoadIdentity(); // Reset it to identity
  glOrtho(0.0f,800,600,0.0f,-1.0f,1.0f); // Set an orthographic projection
  glMatrixMode(GL_MODELVIEW); // We've set a projection mode, so go back to the modelview matrix
  glLoadIdentity(); // Reset it to identity - we don't want to offset or rotate what we draw for now

References

  1. Well, "multiply the current matrix with a transformation that gives an orthographic projection" to be exact.
adamk kromm

ok, so i got rid of the pushing and popping, and moved the glOrtho to right after the glMatrixMode(GL_PROJECTION). but still nothing. i have a feeling it has something to do with blending.

IonBlade

This is what I use to do this, works fine for me. This is basically what gnolam said. Notice I am disabling depth testing, lighting, and textures initially - if I want any of those, something will have to turn it on again manually when it wants it.

#SelectExpand
1void Render::Set2D( ) 2{ 3 int viewport[4]; 4 glGetIntegerv( GL_VIEWPORT, viewport ); 5 6 glMatrixMode( GL_PROJECTION ); 7 glLoadIdentity(); 8 gluOrtho2D( 0, viewport[2], viewport[3], 0 ); 9 glMatrixMode( GL_MODELVIEW ); 10 glLoadIdentity(); 11 glDisable( GL_DEPTH_TEST ); 12 glDisable( GL_LIGHTING ); 13 glDisable( GL_TEXTURE_2D ); 14} 15 16void Render::Set3D( ) 17{ 18 int viewport[4]; 19 glGetIntegerv( GL_VIEWPORT, viewport ); 20 21 glMatrixMode( GL_PROJECTION ); 22 glLoadIdentity(); 23 gluPerspective( 60.0f, (GLdouble)viewport[2] / (GLdouble)viewport[3], 1, 10000 ); 24 glMatrixMode( GL_MODELVIEW ); 25 glLoadIdentity(); 26 27 glEnable( GL_DEPTH_TEST ); 28}

If this doesn't work, I think your problem might have to do with mixing Allegro's drawing routines with pure GL calls. See if you can draw some 2D rectangles on the screen using only GL after you call your 2D mode.

EDIT: Also, don't forget about backface culling. Make sure you're drawing things in the proper vertex order or disable culling entirely with glDisable(GL_CULL_FACE);

EDIT2: You probably want to draw your 3D stuff first, and THEN your 2D HUD or whatever (unless your HUD contains 3D elements... but still after everything else)

Albin Engström

Generally for GUI I would suggest doing something like this:

Render non GUI stuff.
Clear depth buffer. (don't disable depth testing..)
Render GUI stuff.

Also, the set3d and set2d functions are to specific in my opinion, it would be better not to make specific functions of those parts of the code.

But if it works for you :)..

adamk kromm

what do you mean by too specific?

Albin Engström

I don't like to create functions for short pieces of code that will only be called once or twice and contain code that I like to have more control over.

But that's my problem, hence "if it works for you". :)

adamk kromm

ok, gotcha... but so far its not working for me... the closest i got is that if i go to a specific spot in the 3d world i can see the bitmap but if i move (or rotate) it disapears, till i go back to that specific spot. So my guess is that im doing something wrong with glOrtho()...

Anyone willing to post a short working example of switching between 2d and 3d views (for drawing)? so that i can compare it to what im doing, and hopefully find what im doing wrong.

EDIT: here is what i got so far...

#SelectExpand
1 2 glMatrixMode(GL_PROJECTION); 3 glPushMatrix();//save the 3d matrix stuff 4 5 glLoadIdentity(); 6 glOrtho(0,800,600,0,0,1);//set to 2d projection 7 8 glMatrixMode(GL_MODELVIEW);//go back to model view to draw stuff 9 10 al_draw_bitmap(compasBack, 100,100,NULL);//draw bitmaps 11 al_draw_bitmap(compasPOV, 100,100,NULL); 12 13 glMatrixMode(GL_PROJECTION); 14 glPopMatrix();//restore 3d projection matrix 15 16 glMatrixMode(GL_MODELVIEW);//go back to drawing mode.

IonBlade

I don't see any reason why you would want to go back to 3D mode after switching to 2D mode, since everything that's 2D has to be on top of everything else. Again, the only thing I can think of is if you want to draw 3D elements on your HUD like Quake 3 ammo boxes or something.

#SelectExpand
1while ( Drawing ) { 2 //clear the screen 3 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); 4 5 //get the size of the GL viewport 6 int viewport[4]; 7 glGetIntegerv( GL_VIEWPORT, viewport ); 8 9 //set 3D mode with the correct aspect ratio based on the size of the viewport 10 glMatrixMode( GL_PROJECTION ); 11 glLoadIdentity(); 12 gluPerspective( 60.0f, (GLdouble)viewport[2] / (GLdouble)viewport[3], 1, 10000 ); 13 glMatrixMode( GL_MODELVIEW ); 14 glLoadIdentity(); 15 glEnable( GL_DEPTH_TEST ); //enable this for proper 3D viewing 16 17 //draw your 3D scene here 18 MyWorldDrawingFunction(); 19 MyOtherStuffDrawingFunction(); 20 21 //now go into 2D mode and draw the HUD. do this by setting the PROJECTION matrix to ortho. 22 glMatrixMode( GL_PROJECTION ); 23 glLoadIdentity(); 24 gluOrtho2D( 0, viewport[2], viewport[3], 0 ); 25 glMatrixMode( GL_MODELVIEW ); 26 glLoadIdentity(); //remember to call this so your modelview transformations are all reset. 27 glDisable( GL_DEPTH_TEST ); //disable this for proper 2D viewing 28 glDisable( GL_LIGHTING ); //disable these just incase 29 glDisable( GL_TEXTURE_2D ); //disable these just incase 30 31 //draw your 2D hud stuff. 32 DrawHUD(); 33 34 //flip the screen buffers 35 al_flip_display(); 36}

Notice I did not push or pop anything. Since you should only go into 2D after you've done your 3D scene (and probably shouldn't go back), you don't need to save any matrices.

ImLeftFooted

Ok, this is something that i still cant seem to figure out. how to draw, for example a HUD, in a 3d world... i have this

Well I recommend getting a piece of paper
{"name":"30423-Clipart-Illustration-Of-A-Blank-Lined-College-Ruled-Piece-Of-Paper-With-Binder-Ring-Holes.jpg","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/7\/d\/7d8cd5719640d98e9373ca036413796e.jpg","w":329,"h":450,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/7\/d\/7d8cd5719640d98e9373ca036413796e"}30423-Clipart-Illustration-Of-A-Blank-Lined-College-Ruled-Piece-Of-Paper-With-Binder-Ring-Holes.jpg
Then get a pen or pencil (your choice):
{"name":"1194984437330746720pen_pencil_darkon_01.svg.hi.png","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/a\/0\/a000bfcafdbb20044a80560bf92432df.png","w":600,"h":542,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/a\/0\/a000bfcafdbb20044a80560bf92432df"}1194984437330746720pen_pencil_darkon_01.svg.hi.png

At this point, you may enter the 3D world (assuming you were not there previously) and begin drawing as many HUDs as you would like onto the paper.

adamk kromm

IonBlade i tried the code you posted, and got the same results as what i was previously getting.

EDIT:: in an attempt to make it work, i even disabled every 3d part of the program (all drawing, all perspective setting...) so all it does is sets up the 2d perspective (like IonBlade has posted) then draws 2 bitmaps. still no go.

Tobias Dammers

Also, the set3d and set2d functions are to specific in my opinion, it would be better not to make specific functions of those parts of the code.

I disagree. At the point in your code where you would call these functions, you are usually only interested in the general picture - set display mode to 2D or 3D -, not in the actual implementation. This alone justifies putting them into dedicated functions.

OT: Make sure you have disabled every check and feature that may interfere with rendering. Most notorious:
- Alpha test
- Depth test
- Back-face culling
- Blending
- Color and texture mode (setting the color to black and the texture mode to "modulate" will produce a black polygon)

Also, make sure the 2D clip distance range includes 0 (the default for the z coordinate when you use the Vertex2x commands). I usually use -1 and 1. And make sure your coordinates are correct.

IonBlade

Can you attach all of your most recent rendering code? I don't get home from work until later tonight but I will look at it on my machine and try and find the problem.

OnlineCop

Since NeHe usually does excellent tutorials on OpenGL, Lesson 17 on displaying text to the screen (through various fonts) is done, usually, by switching to 2D mode and drawing the text, then back to 3D when it's done.

I haven't done more searching through NeHe, since I just wanted to give some quick replies before I have to leave, but figured that it should show how to switch into 2D mode to draw the fonts to screen... similar to what you're doing with your HUD.

adamk kromm

ok, now i feel dumb... I'm going to take a wild guess and say that everyone assumed i knew that you cant use al_draw_bitmap() to draw bitmaps in OGL mode? Cause if i change the code to use strictly opengl drawing stuff (eg. draw a square, bind a texture to it) it works... hahaha.

another lesson learned (why is learnt a typo?) :P

Thomas Fjellstrom

I think thats probably a bug of some sort, allegro functions should work fine, so long as your GL state is in the right... well, state.

verthex
IonBlade

ok, now i feel dumb... I'm going to take a wild guess and say that everyone assumed i knew that you cant use al_draw_bitmap() to draw bitmaps in OGL mode? Cause if i change the code to use strictly opengl drawing stuff (eg. draw a square, bind a texture to it) it works... hahaha.

I knew it had to be something to do with mixing Allegro routines with GL stuff. Glad you got it fixed ;)

adamk kromm

yea i got it fixed... but,

Thomas Fjellstrom: said:

I think thats probably a bug of some sort, allegro functions should work fine, so long as your GL state is in the right... well, state.

so is it a bug?

Thomas Fjellstrom

so is it a bug?

If by that you mean a bug in allegro, its possible. But its more likely you aren't using the functions correctly. Usually you have to set an "allegro mode" before using 2d allegro functions, or things won't seem to work right.

Thread #601538. Printed from Allegro.cc