PDA

View Full Version : OpenGL: 3D over 2D



jdarling
27-07-2010, 06:28 PM
I've managed to make a lot of progress with my rendering of 3D stuff. Managed to get a 2D HUD to display over my 3D world. And now I'm stuck on the problem of placing a 3D model onto the HUD.

Basically I'm "Poping Up" a dialog box as a HUD over the top of the scene. I want to display a rotating model in the dialog box. When I try and do this though, I don't get a model :(

Here is basically what I'm doing right now (note: I'm mainly using display lists since in the end this is for OpenGLES):


glLoadIdentity();
glTranslatef(0, 0, -6);
glPushMatrix();
glTranslatef(-1.5, 0, 0);
glRotatef(yrot,1.0,0.0,0.0);
glRotatef(xrot,0.0,1.0,0.0);
fBox.Render;
glPopMatrix();
glPushMatrix();
glTranslatef(1.5, 0, 0);
glRotatef(-rotation,0.0,1.0,0.0);
fObj2.Render;
glPopMatrix();
GLHUD.Begin2D;
glEnable(GL_TEXTURE_2D);
img.Bind;
glBegin(GL_QUADS);
// This will be converted to a set of display lists when complete
glTexCoord2f(0, 0);
glVertex2d(0, 200);
glTexCoord2f(1, 0);
glVertex2d(Engine.Width, 200);
glTexCoord2f(1, 1);
glVertex2d(Engine.Width, Engine.Height);
glTexCoord2f(0, 1);
glVertex2d(0, Engine.Height);
glEnd();
glDisable(GL_TEXTURE_2D);
GLHUD.End2D;
glPushMatrix();
glTranslatef(2, -1.5, 0);
glScalef(0.5, 0.5, 0.5);
fBox.Render;
glPopMatrix();


The .Render calls simply call glCallList(FGLCallList) with the proper list id.

Anyone have an example of placing a 3D model over the top of the HUD?

- Jeremy

User137
28-07-2010, 09:23 AM
Too difficult to tell from that little info. Are you using Ortho mode? In that case make sure that Z near and far values are set to limits of 3D model. Some set ortho from -1 to 1 so if your model is even 2x2x2 in size it won't propably show much. Make sure the scaling is right etc. Colors, even partially transparent texture enabled may cause your model to completely disappear if model has no texture coordinates.

Edit: Make sure you restore previous modelview matrix after your hud mode ends.
GLHUD.Begin2D; // This should first call glPushMatrix;

GLHUD.End2D; // This should end with glPopMatrix;

jdarling
28-07-2010, 12:31 PM
Here is the code I have in the GLHUD object:



procedure TGLHUD.Begin2D;
begin
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho( 0, engine.width, engine.height , 0, -1, 1 );
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
end;

procedure TGLHUD.End2D;
begin
glMatrixMode( GL_PROJECTION );
glPopMatrix();
glMatrixMode( GL_MODELVIEW );
glPopMatrix();
end;


As far as what mode I'm rendering the 3D stuff in, not sure LOL. If I remove the HUD stuff then I see the small cube in the bottom right corner with no problems. Just when I turn on the HUD I don't see it any more. Could this be a translation issue, or is it more likely the z index of the HUD and the object?

Seeing as this is my first real progress ever into 3D I'm totally lost on where to look next, and changing code blindly didn't help :)

- Jeremy

User137
28-07-2010, 02:20 PM
Look.. this code at the beginning:
glLoadIdentity();
glTranslatef(0, 0, -6); // In your example this translation is lost

Would this work?
procedure TGLHUD.Begin2D;
begin
glPushMatrix(); // Added
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho( 0, engine.width, engine.height , 0, -1, 1 );
glMatrixMode(GL_MODELVIEW);
//glPushMatrix(); // Moved to beginning
glLoadIdentity();
end;

jdarling
28-07-2010, 04:37 PM
Tried that, and no avail either :(.

Any ideas on where I can find a working example that places a 3D model over the top of a HUD? If nothing else I can dissect that and see where I'm going wrong. Unfortunately Googling for "3D over 2D OpenGL" and the likes returns things about placing a HUD over 3D not the exact opposite :(.

- Jeremy

User137
28-07-2010, 07:31 PM
Maybe it's depth-buffer. glDepthMask can be called in the begin and end of hud mode, to disable writing to depth-buffer when doing 2D.

glDepthMask(false) (or 0 depending on header)
...and true when disabling 2D.

Alternative is using glDisable(GL_DEPTH_TEST) during 2D and enable after.

Your model will otherwise be drawn behind the HUD. You can also try this rendering model without DEPTH_TEST but you may see that may have bad effects on the model itself :P

chronozphere
28-07-2010, 11:52 PM
There are different ways to achieve this. You could for example render the model to a texture and draw that texture as a quad (two triangles) on your HUD. In this case you should write some extra code to setup a rendertarget. If you are interested, have a look at the framebuffer object (FBO).

An easier way would be, to render the model directly where you want it. This may be tricky because you have to be carefull with your depth-buffer and render-order. An easy way is to draw all the background first and disable the depth-buffer before rendering your model.

You should first try to render the model in normal 3d space. If that works you have to figure out a way to transform the model so that it ends up on your HUD (Sorry it's 1:30am, I can't think of a quick way to do that now). You may want to set your viewport using glViewport() to limit the area where you are rendering to.

Hope this get's you started. ;)

jdarling
29-07-2010, 12:48 PM
There are different ways to achieve this. You could for example render the model to a texture and draw that texture as a quad (two triangles) on your HUD. In this case you should write some extra code to setup a rendertarget. If you are interested, have a look at the framebuffer object (FBO).

An easier way would be, to render the model directly where you want it. This may be tricky because you have to be carefull with your depth-buffer and render-order. An easy way is to draw all the background first and disable the depth-buffer before rendering your model.

You should first try to render the model in normal 3d space. If that works you have to figure out a way to transform the model so that it ends up on your HUD (Sorry it's 1:30am, I can't think of a quick way to do that now). You may want to set your viewport using glViewport() to limit the area where you are rendering to.

Hope this get's you started. ;)


Will rendering to a rendertarget and then rendering over the HUD work in OpenGL ES? Sorry, this is all very new to me :). Toggling the depth buffer seems to work, except that I have to really fiddle with the scale and position depending on whats in the scene. Simply turning off the depth buffer and then rendering the HUD and overlay object doesn't work as the quads (or triangles) get completely out of order on the model (and from what I've read that makes sense).

On another note, are display lists the best way to go? They seem like the only way to go in ES, but on the desktop there seem to be A LOT more options.

- Jeremy

jdarling
29-07-2010, 12:54 PM
Found my answer on Frame Buffers and ES, yep, they are supported and in fact (at least according to Apple) recommended.

Trying to follow along with the example at [purl=http://developer.apple.com/iphone/library/documentation/3DDrawing/Conceptual/OpenGLES_ProgrammingGuide/WorkingwithEAGLContexts/WorkingwithEAGLContexts.html]http://developer.apple.com/iphone/library/documentation/3DDrawing/Conceptual/OpenGLES_ProgrammingGuide/WorkingwithEAGLContexts/WorkingwithEAGLContexts.html[/url] I can't seem to locate the OpenGL calls:


glGenFramebuffersOES(1, &framebuffer);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, framebuffer);
glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, width, height);
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, colorRenderbuffer);
etc...


I'm guessing this is due to Lazarus not having the latest and greatest headers, or is this due to the fact that Apple (being Apple) doesn't use the standard headers. I'm not targeting iPhone (I'm looking at Android) but they were the first example I found :)

- Jeremy

jdarling
29-07-2010, 03:37 PM
Ok, I figured out my problem and switched to the proper OpenGL calls. After a bit of playing around I can now render to a Frame Buffer and overlay it when I render my HUD. This is all captured into a display list and seems to be working ok.

Few things I don't understand...
* Everything rendered to my FBO and then to the HUD is upside down, I rotate 180 deg and all is ok.
* My movement is all wrong, walk forward (arrow up) past box and star, use arrow to turn around and star is still on the right. Thus your still viewing from the front. I'm guessing I'm rotating on the world 0, 0, 0 instead of the local 0, 0, 0

Anyways, rather than keep trying to post partial code and etc I've uploaded a sample that runs and shows off all my issues. Any ideas or pointers on what I'm doing wrong, and what could be better would be greatly appreciated. I know this is "reinventing the wheel" but I'm trying to understand everything rather than just use something :)

Download link: http://www.eonclash.com/PGD/RenderingEngine.zip

- Jeremy