|
Stepping Into the Third Dimension |
Todd Cope
Member #998
November 2000
|
I am interested in adding support for 3D rendering to my framework. To begin, I'll explain how my framework functions with regard to rendering. In T³ Framework you select a view with t3f_select_view(). A view is defined with t3f_create_view(offset_x, offset_y, width, height, vp_x, vp_y, flags). The first four arguments represent the position and size of the view within the ALLEGRO_DISPLAY. vp_x and vp_y are the coordinates of the vanishing point within the view itself. Views utilize what I call a virtual resolution that is defined during initialization of the framework. A default view is created during this step that, assuming no other steps are taken, gives you an ALLEGRO_DISPLAY with dimensions equal to the virtual resolution. If I initialize the framework with a virtual resolution of 640x480, then select a view that was created with <code>t3f_create_view(0, 0, 320, 240, 320, 240, ...), drawing a pixel to <code>(320, 240)<code> will render that pixel at (160, 120) within the ALLEGRO_DISPLAY. If I use the framework's projection routines with this view selected, the vanishing point will be located at (160, 120) within the ALLEGRO_DISPLAY. For my purposes, I need to be able to have the same kind of functionality while working with actual 3D code. Ultimately, what I need to know is how do I set up Allegro so I can use its primitives functions to render 3D objects into one of these views with the vanishing point being what's defined in the view? When trying to do actual 3D rendering I was unable to find a way to make the perspective such that the vanishing point was anything other than the center of the ALLEGRO_DISPLAY. |
MikiZX
Member #17,092
June 2019
|
For what is worth... :| EDIT: I might have misunderstood your post when I originally posted - If you are only looking at setting up a 'window' within your display then possibly https://www.allegro.cc/manual/5/al_build_transform will help you out. Original post: Then again, I can only see the center of the view be offset using vertex shaders - though this I do not believe will have any effect on the vanishing points - only effect of this would be that the further away the objects are in the 3d world the smaller and closer to the offset point they will be on your 2d view. |
Todd Cope
Member #998
November 2000
|
Well, Google's definition fits my understanding of vanishing points just fine. I use my own projection routines to place sprites in 3D space already and they move toward the vanishing point within my view if I push them away from the camera far enough. I'm just trying to find out if there is a way to cause OpenGL to render a 3D scene to a portion of the ALLEGRO_DISPLAY and have it work as if that portion is all there is. Ultimately, I need to be able to create up to four views for split screen games and be able to render 3D scenes within each of those views and have the perspective be correct (the vanishing point being at the center of each view for the scene rendered in that view). When I search for a solution to this problem, glViewport() comes up and seems like it should work for what I'm trying to do. I tried calling it before rendering my primitives, but it didn't seem to do anything. Is this something that I would need to do with straight OpenGL? Maybe Allegro is doing things behind the scenes that is overwriting my viewport settings. Or maybe I am misunderstanding how this all works. I think what I'm trying to do is common enough that it shouldn't require a hack like altering the scene's geometry. |
MikiZX
Member #17,092
June 2019
|
I see now what you mean. I haven't done this before so I can only suggest what to try - if you do no succeed let me know and I will do it for you though you sound like you will be able to figure this out on your own. EDIT: You could also (likely in the easiest way) achieve this effect by drawing your 3d scene directly to Allegro5 bitmap and then drawing that bitmap directly on the screen at screen position that you wish. To make this work like this you would need to look into https://www.allegro.cc/manual/5/al_set_target_bitmap |
Edgar Reynaldo
Major Reynaldo
May 2007
|
glViewPort Also, vanishing points don't depend on the projection matrix used, but more so the alignment of the objects in the view. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
Todd Cope
Member #998
November 2000
|
I mentioned glViewport(). I tried using it in combination with Allegro functions, but the scene would not adjust to the new viewport. Here's the code I'm using to set everything up (borrowed from ex_camera): static void setup_3d_projection(void) { ALLEGRO_TRANSFORM projection; ALLEGRO_DISPLAY *display = al_get_current_display(); double dw = al_get_display_width(display); double dh = al_get_display_height(display); double f; al_identity_transform(&projection); al_translate_transform_3d(&projection, 0, 0, -1); f = tan(ex.camera.vertical_field_of_view / 2); al_perspective_transform(&projection, -1 * dw / dh * f, f, 1, f * dw / dh, -f, 1000); glViewport(0, 0, dw / 2, dh / 2); al_use_projection_transform(&projection); } With this code, I would expect the entire contents of the scene to be rendered at (0, dh / 2) and fill up the bottom left corner of the screen. Instead, it just renders exactly the same thing as before. |
Edgar Reynaldo
Major Reynaldo
May 2007
|
Allegro is probably setting the viewport too. Move it after your al_use_projection_transform and see if its different. glViewport is the only thing that can do this, other than clipping and making your own projection. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
Todd Cope
Member #998
November 2000
|
I tried that and got the same result. Edit: I think I found a good solution to my problem. If I create a sub-bitmap of the backbuffer the size and position of my desired viewport and set that bitmap as the target, the rendering works as expected. For example, if I wanted to make a four way split screen for a game, I can do something like this: 1ALLEGRO_DISPLAY * display;
2ALLEGRO_BITMAP * backuffer = NULL;
3ALLEGRO_BITMAP * viewport[4] = {NULL};
4int dw, dh;
5
6display = al_create_display(640, 480);
7if(!display)
8{
9 error_out();
10}
11dw = al_get_display_width(display);
12dh = al_get_display_height(display);
13backbuffer = al_get_backbuffer(display);
14
15viewport[0] = al_create_sub_bitmap(backbuffer, 0, 0, dw / 2, dh / 2);
16viewport[1] = al_create_sub_bitmap(backbuffer, dw / 2, dh / 2, dw / 2, dh / 2);
17viewport[2] = al_create_sub_bitmap(backbuffer, dw / 2, 0, dw / 2, dh / 2);
18viewport[3] = al_create_sub_bitmap(backbuffer, 0, dh / 2, dw / 2, dh / 2);
When it's time to render: int i; for(i = 0; i < 4; i++) { al_set_target_bitmap(viewport[i]); render_scene(); } I think this method will integrate nicely with my framework. |
|