From: SiegeLord <sie...@us...> - 2015-04-09 04:14:08
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Allegro". The branch, 5.1 has been updated via ec13af38fc5450f79daa08b1397dd2c7026facc4 (commit) via 5f873988fb35287eebb4e7808a91c2ee63368f03 (commit) via aa41ff06f37db5ef3063804fc43e176e726ca3fc (commit) via 2c7bdb2fc3743b5d5bec081b31642deab1b6806b (commit) via 4b716aa5d1a43bf46d2e68782ce6ccb37ea73b4a (commit) via 1c72c37f68b66f5367ab9a67b43be2e2d9c23b9a (commit) via ee0171a137a2deec45920f78ef9873fcbb4b14f6 (commit) via f01695f45b0502084944f334071fe793867d956c (commit) via 1ef40b358bf19ecb9c21e4e642398b980a31de08 (commit) from 30488d5370014a8aeff345b501ca63b77cf9a7ee (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit ec13af38fc5450f79daa08b1397dd2c7026facc4 Author: Pavel Sountsov <si...@go...> Date: Wed Apr 8 21:11:51 2015 -0700 Fix some documentation errors. commit 5f873988fb35287eebb4e7808a91c2ee63368f03 Author: Pavel Sountsov <si...@go...> Date: Wed Apr 8 20:47:19 2015 -0700 Add an option to hold bitmap drawing in ex_draw_bitmap. commit aa41ff06f37db5ef3063804fc43e176e726ca3fc Author: Pavel Sountsov <si...@go...> Date: Wed Apr 8 20:05:47 2015 -0700 Add more discussion about the transformation types. commit 2c7bdb2fc3743b5d5bec081b31642deab1b6806b Author: Pavel Sountsov <si...@go...> Date: Tue Apr 7 20:46:03 2015 -0700 Projection transforms do not pre-apply during held drawing. commit 4b716aa5d1a43bf46d2e68782ce6ccb37ea73b4a Author: Pavel Sountsov <si...@go...> Date: Wed Apr 1 20:11:04 2015 -0700 iOS projection reform. Send the resize event more often to catch some device rotations. commit 1c72c37f68b66f5367ab9a67b43be2e2d9c23b9a Author: Pavel Sountsov <si...@go...> Date: Wed Apr 1 20:10:44 2015 -0700 Android projection reform. Also, send a resize event after the display resume in case the app was restored in a different orientation. commit ee0171a137a2deec45920f78ef9873fcbb4b14f6 Author: Pavel Sountsov <si...@go...> Date: Wed Apr 1 20:10:17 2015 -0700 OSX projection reform. commit f01695f45b0502084944f334071fe793867d956c Author: Pavel Sountsov <si...@go...> Date: Wed Apr 1 20:09:36 2015 -0700 Direct3D projection reform. commit 1ef40b358bf19ecb9c21e4e642398b980a31de08 Author: Pavel Sountsov <si...@go...> Date: Wed Apr 1 20:07:44 2015 -0700 Make projection transform a bitmap local state. General API and desktop GL initially. ----------------------------------------------------------------------- Summary of changes: addons/primitives/high_primitives.c | 14 +- addons/ttf/ttf.c | 14 -- docs/src/refman/display.txt | 6 +- docs/src/refman/graphics.txt | 30 ++-- docs/src/refman/state.txt | 2 + docs/src/refman/transformations.txt | 111 ++++++++---- examples/CMakeLists.txt | 1 + examples/ex_camera.c | 7 +- examples/ex_draw_bitmap.c | 19 ++- examples/ex_projection.c | 2 +- examples/ex_projection2.c | 191 +++++++++++++++++++++ include/allegro5/internal/aintern_bitmap.h | 1 + include/allegro5/internal/aintern_direct3d.h | 5 +- include/allegro5/internal/aintern_display.h | 4 +- include/allegro5/tls.h | 1 + include/allegro5/transformations.h | 4 +- src/android/android_display.c | 35 +--- src/bitmap.c | 6 + src/bitmap_type.c | 25 +++- src/display.c | 8 +- src/iphone/EAGLView.m | 5 +- src/iphone/iphone_display.m | 6 - src/macosx/osxgl.m | 8 +- src/opengl/ogl_display.c | 29 ++- src/opengl/ogl_draw.c | 58 +++---- src/opengl/ogl_fbo.c | 19 +-- src/opengl/ogl_lock_es.c | 9 +- src/opengl/ogl_shader.c | 5 +- src/tls.c | 14 ++ src/transformations.c | 54 ++++-- src/win/d3d_disp.cpp | 237 ++++++++------------------ src/win/d3d_shader.cpp | 19 +-- tests/test_driver.c | 8 +- tests/test_prim2.ini | 4 +- 34 files changed, 545 insertions(+), 416 deletions(-) create mode 100644 examples/ex_projection2.c diff --git a/addons/primitives/high_primitives.c b/addons/primitives/high_primitives.c index 97e77c8..990f8dd 100644 --- a/addons/primitives/high_primitives.c +++ b/addons/primitives/high_primitives.c @@ -60,19 +60,13 @@ static float get_scale(void) const ALLEGRO_TRANSFORM* t = al_get_current_transform(); float scale_sq = DET2D(t); - ALLEGRO_DISPLAY* d = al_get_current_display(); - if (d) { - ALLEGRO_BITMAP* b = al_get_target_bitmap(); - ALLEGRO_TRANSFORM* p = al_get_projection_transform(d); - /* - * Sub-bitmaps are wonky when it comes to this. Right now they grab the - * projection from the parent bitmap (e.g. see _al_ogl_set_target_bitmap). - */ - if (al_is_sub_bitmap(b)) - b = al_get_parent_bitmap(b); + ALLEGRO_BITMAP* b = al_get_target_bitmap(); + if (b) { + const ALLEGRO_TRANSFORM* p = al_get_current_projection_transform(); /* Divide by 4.0f as the screen coordinates range from -1 to 1 on both axes. */ scale_sq *= DET2D(p) * al_get_bitmap_width(b) * al_get_bitmap_height(b) / 4.0f; } + return sqrtf(scale_sq); #undef DET2D diff --git a/addons/ttf/ttf.c b/addons/ttf/ttf.c index dd60ae5..fda6422 100644 --- a/addons/ttf/ttf.c +++ b/addons/ttf/ttf.c @@ -445,15 +445,6 @@ static int render_glyph(ALLEGRO_FONT const *f, FT_Face face = data->face; ALLEGRO_TTF_GLYPH_DATA *glyph = get_glyph(data, ft_index); int advance = 0; - ALLEGRO_DISPLAY *display; - ALLEGRO_TRANSFORM old_projection_transform; - - /* Workabout for bug 3484535 */ - display = al_get_current_display(); - if (display) { - al_copy_transform(&old_projection_transform, - al_get_projection_transform(display)); - } /* We don't try to cache all glyphs in a pre-pass before drawing them. * While that would indeed save us making separate texture uploads, it @@ -463,11 +454,6 @@ static int render_glyph(ALLEGRO_FONT const *f, */ cache_glyph(data, face, ft_index, glyph, false); - /* Workabout for bug 3484535 */ - if (display) { - al_set_projection_transform(display, &old_projection_transform); - } - advance += get_kerning(data, face, prev_ft_index, ft_index); if (glyph->page_bitmap) { diff --git a/docs/src/refman/display.txt b/docs/src/refman/display.txt index eeb5515..f659e28 100644 --- a/docs/src/refman/display.txt +++ b/docs/src/refman/display.txt @@ -480,7 +480,9 @@ from a resizable display, if they wish the display to be resized they must call this function to let the graphics driver know that it can now resize the display. Returns true on success. -Adjusts the clipping rectangle to the full size of the backbuffer. +Adjusts the clipping rectangle to the full size of the backbuffer. This also +resets the backbuffers projection transform to default orthographic transform +(see [al_use_projection_transform]). Note that a resize event may be outdated by the time you acknowledge it; there could be further resize events generated in the meantime. @@ -653,7 +655,7 @@ See also: [ALLEGRO_EVENT_DISPLAY_HALT_DRAWING] ### API: al_acknowledge_drawing_resume -Call this in reponse to the [ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING] event. +Call this in response to the [ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING] event. Since: 5.1.1 diff --git a/docs/src/refman/graphics.txt b/docs/src/refman/graphics.txt index 5922e03..335088b 100644 --- a/docs/src/refman/graphics.txt +++ b/docs/src/refman/graphics.txt @@ -324,7 +324,7 @@ Use this flag if a partial number of pixels need to be written to, even if reading is not needed. `format` indicates the pixel format that the returned buffer will be in. -To lock in the same format as the bitmap stores it's data internally, +To lock in the same format as the bitmap stores its data internally, call with `al_get_bitmap_format(bitmap)` as the format or use ALLEGRO_PIXEL_FORMAT_ANY. Locking in the native format will usually be faster. If the bitmap format is compressed, using ALLEGRO_PIXEL_FORMAT_ANY will choose @@ -455,17 +455,19 @@ See also: [al_create_bitmap] ### API: al_clone_bitmap -Create a new bitmap with [al_create_bitmap], and copy the pixel data -from the old bitmap across. +Create a new bitmap with [al_create_bitmap], and copy the pixel data from the +old bitmap across. If the new bitmap is a memory bitmap, its projection bitmap +is reset to be orthographic. See also: [al_create_bitmap], [al_set_new_bitmap_format], [al_set_new_bitmap_flags], [al_convert_bitmap] ### API: al_convert_bitmap -Converts the bitmap to the current bitmap flags and format. The bitmap -will be as if it was created anew with [al_create_bitmap] but retain its -contents. All of this bitmap's sub-bitmaps are also converted. +Converts the bitmap to the current bitmap flags and format. The bitmap will be +as if it was created anew with [al_create_bitmap] but retain its contents. All +of this bitmap's sub-bitmaps are also converted. If the new bitmap type is +memory, then the bitmap's projection bitmap is reset to be orthographic. If this bitmap is a sub-bitmap, then it, its parent and all the sibling sub-bitmaps are also converted. @@ -1245,15 +1247,15 @@ See also: [ALLEGRO_COLOR] ### API: al_hold_bitmap_drawing Enables or disables deferred bitmap drawing. This allows for efficient drawing -of many bitmaps that share a parent bitmap, such as sub-bitmaps from a -tilesheet or simply identical bitmaps. Drawing bitmaps that do not share a +of many bitmaps that share a parent bitmap, such as sub-bitmaps from a +tilesheet or simply identical bitmaps. Drawing bitmaps that do not share a parent is less efficient, so it is advisable to stagger bitmap drawing calls -such that the parent bitmap is the same for large number of those calls. -While deferred bitmap drawing is enabled, the only functions that can be used -are the bitmap drawing functions and font drawing functions. Changing the state -such as the blending modes will result in undefined behaviour. One exception to -this rule are the transformations. It is possible to set a new transformation -while the drawing is held. +such that the parent bitmap is the same for large number of those calls. While +deferred bitmap drawing is enabled, the only functions that can be used are the +bitmap drawing functions and font drawing functions. Changing the state such as +the blending modes will result in undefined behaviour. One exception to this +rule are the non-projection transformations. It is possible to set a new +transformation while the drawing is held. No drawing is guaranteed to take place until you disable the hold. Thus, the idiom of this function's usage is to enable the deferred bitmap drawing, draw as diff --git a/docs/src/refman/state.txt b/docs/src/refman/state.txt index 3c014e2..7bda019 100644 --- a/docs/src/refman/state.txt +++ b/docs/src/refman/state.txt @@ -23,6 +23,7 @@ The various state kept internally by Allegro can be displayed like this: deferred drawing current target bitmap current transformation + current projection transformation current clipping rectangle bitmap locking current shader @@ -59,6 +60,7 @@ object. The flags parameter can take any bit-combination of these flags: * ALLEGRO_STATE_TARGET_BITMAP - target_bitmap * ALLEGRO_STATE_BLENDER - blender * ALLEGRO_STATE_TRANSFORM - current_transformation +* ALLEGRO_STATE_PROJECTION_TRANSFORM - current_projection_transformation * ALLEGRO_STATE_NEW_FILE_INTERFACE - new_file_interface * ALLEGRO_STATE_BITMAP - same as ALLEGRO_STATE_NEW_BITMAP_PARAMETERS and ALLEGRO_STATE_TARGET_BITMAP diff --git a/docs/src/refman/transformations.txt b/docs/src/refman/transformations.txt index 4e9770c..8335709 100644 --- a/docs/src/refman/transformations.txt +++ b/docs/src/refman/transformations.txt @@ -9,11 +9,28 @@ These functions are declared in the main Allegro header file: Transformations allow you to transform the coordinates you use for drawing operations without additional overhead. Scaling, rotating, translating, and combinations of these are possible as well as using custom transformations. +There are two types of transformations that you can set, 'regular' +transformations and projection transformations. The projection transform is +rarely used in 2D games, but is common in 3D games to set up the projection +from the 3D world to the 2D screen. Typically, you would use the regular +transform for non-projective types of transformations (that is, translations, +rotations, scales, skews... i.e. transformations that are linear), while the +projection transform will be used for setting up perspective and possibly more +advanced effects. It is possible to do everything with just using the +projection transformation (that is, you'd compose the projection transformation +with the non-projection transformations that, e.g., move the camera in the +world), but it is more convenient to use both for two reasons: -Transformations are set per target-bitmap, i.e. a change of the target bitmap -will also change the active transformation. -It is also possible to specify custom projection transformations. These are set per -display. +- Regular transformations can be changed while the bitmap drawing is held (see + [al_hold_bitmap_drawing]). + +- Regular transformations work with memory bitmaps. + +As a result, if you're making a 2D game, it's best to leave the projection +transformations at their default values. + +Both types of transformations are set per target-bitmap, i.e. a change of the +target bitmap will also change the active transformation. Allegro provides convenience functions to construct transformations in 2D and 3D variants (the latter with a `_3d` suffix), so you don't have to deal with the @@ -126,6 +143,57 @@ Returns the transformation of the current target bitmap, as set by *Returns:* A pointer to the current transformation. +See also: [al_get_current_projection_transform] + +## API: al_use_projection_transform + +Sets the projection transformation to be used for the the drawing operations on +the target bitmap (each bitmap maintains its own projection transformation). +Every drawing operation after this call will be transformed using this +transformation. To return default behavior, call this function with an +orthographic transform like so: + +~~~~c +ALLEGRO_TRANSFORM trans; +al_identity_transform(&trans); +al_orthographic_transform(&trans, 0, 0, -1.0, al_get_bitmap_width(bitmap), + al_get_bitmap_height(bitmap), 1.0); + +al_set_target_bitmap(bitmap); +al_use_projection_transform(&trans); +~~~~ + +The orthographic transformation above is the default projection transform. + +This function does nothing if there is no target bitmap. This function also +does nothing if the bitmap is a memory bitmap (i.e. memory bitmaps always use +an orthographic transform like the snippet above). Note that the projection +transform will be reset to default if a video bitmap is converted to a memory +bitmap. Additionally, if the bitmap in question is the backbuffer, it's +projection transformation will be reset to default if it is resized. Lastly, +when you draw a memory bitmap to a video bitmap with a custom projection +transform, this transformation will be ignored (i.e. it'll be as if the +projection transform of the target bitmap was temporarily reset to default). + +The parameter is passed by reference as an optimization to avoid the overhead of +stack copying. The reference will not be stored in the Allegro library so it is +safe to pass references to local variables. + +Since: 5.1.9 + +See also: [al_get_current_projection_transform] + +## API: al_get_current_projection_transform + +If there is no target bitmap, this function returns NULL. + +*Returns:* +A pointer to the current transformation. + +Since: 5.1.9 + +See also: [al_use_projection_transform] + ## API: al_get_current_inverse_transform Returns the inverse of the current transformation of the target bitmap. @@ -350,7 +418,7 @@ near/far is the z-buffer range, if there is no z-buffer you can set it to Since: 5.1.3 -See also: [al_set_projection_transform], [al_perspective_transform] +See also: [al_use_projection_transform], [al_perspective_transform] ## API: al_perspective_transform @@ -364,7 +432,7 @@ To use a specific horizontal field of view you can use the relation: Since: 5.1.3 -See also: [al_set_projection_transform], [al_orthographic_transform] +See also: [al_use_projection_transform], [al_orthographic_transform] ## API: al_translate_transform_3d @@ -373,7 +441,7 @@ coordinates by the given vector. Since: 5.1.3 -See also: [al_set_projection_transform] +See also: [al_use_projection_transform] ## API: al_scale_transform_3d @@ -382,7 +450,7 @@ coordinates by the given vector. Since: 5.1.3 -See also: [al_set_projection_transform] +See also: [al_use_projection_transform] ## API: al_rotate_transform_3d @@ -391,33 +459,6 @@ coordinates around the given vector by the given angle in radians. Since: 5.1.3 -See also: [al_set_projection_transform] - -## API: al_get_projection_transform - -Returns the projection transformation of the display as set with -[al_set_projection_transform]. - -Since: 5.1.0 - -See also: [al_set_projection_transform] - -## API: al_set_projection_transform - -Replaces the projection transformation of the given display. - -> *Note:* Unlike the regular 2D transformations, the projection transformation -> affects all drawing operations done to the current display. This means -> for example that it is not affected by calls to al_set_target_bitmap (if -> the bitmap belongs to the same display). - -> *Note:* Drawing to memory bitmaps is not affected by the projection -> transformation. - -Since: 5.1.0 - -See also: [al_get_projection_transform] - ## API: al_horizontal_shear_transform Apply a horizontal shear to the transform diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 20b7688..d5a6c31 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -197,6 +197,7 @@ example(ex_font_justify ex_font_justify.cpp ${NIHGUI} ${IMAGE} ${TTF} ${DATA_IMA example(ex_font_multiline ex_font_multiline.cpp ${NIHGUI} ${IMAGE} ${TTF} ${COLOR} ${DATA_IMAGES} ${DATA_TTF}) example(ex_logo ${FONT} ${TTF} ${IMAGE} ${PRIM} DATA ${DATA_TTF}) example(ex_projection ${TTF} ${IMAGE} ${DATA_IMAGES} ${DATA_TTF}) +example(ex_projection2 ${PRIM} ${FONT} ${IMAGE} ${DATA_IMAGES}) example(ex_camera ${FONT} ${COLOR} ${PRIM}) example(ex_ttf ${TTF} ${PRIM} DATA ${DATA_TTF} ex_ttf.ini) diff --git a/examples/ex_camera.c b/examples/ex_camera.c index 13c430f..be1c3db 100644 --- a/examples/ex_camera.c +++ b/examples/ex_camera.c @@ -182,7 +182,7 @@ static void setup_3d_projection(void) al_perspective_transform(&projection, -1 * dw / dh * f, f, 1, f * dw / dh, -f, 1000); - al_set_projection_transform(display, &projection); + al_use_projection_transform(&projection); } /* Adds a new vertex to our scene. */ @@ -275,9 +275,8 @@ static void add_skybox(void) static void draw_scene(void) { Camera *c = &ex.camera; - ALLEGRO_DISPLAY *display = al_get_current_display(); /* We save Allegro's projection so we can restore it for drawing text. */ - ALLEGRO_TRANSFORM projection = *al_get_projection_transform(display); + ALLEGRO_TRANSFORM projection = *al_get_current_projection_transform(); setup_3d_projection(); @@ -313,7 +312,7 @@ static void draw_scene(void) /* Restore projection. */ al_identity_transform(&t); al_use_transform(&t); - al_set_projection_transform(display, &projection); + al_use_projection_transform(&projection); /* Draw some text. */ int th = al_get_font_line_height(ex.font); diff --git a/examples/ex_draw_bitmap.c b/examples/ex_draw_bitmap.c index 46431f3..8bc0ede 100644 --- a/examples/ex_draw_bitmap.c +++ b/examples/ex_draw_bitmap.c @@ -14,6 +14,7 @@ typedef struct Sprite { } Sprite; char const *text[] = { + "H - toggle held drawing", "Space - toggle use of textures", "B - toggle alpha blending", "Left/Right - change bitmap size", @@ -27,6 +28,7 @@ struct Example { int blending; ALLEGRO_DISPLAY *display; ALLEGRO_BITMAP *mysha, *bitmap; + bool hold_bitmap_drawing; int bitmap_size; int sprite_count; bool show_help; @@ -190,15 +192,24 @@ static void redraw(void) else if (example.blending == 3) al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); + if (example.hold_bitmap_drawing) { + al_hold_bitmap_drawing(true); + } for (i = 0; i < example.sprite_count; i++) { Sprite *s = example.sprites + i; al_draw_tinted_bitmap(example.bitmap, tint, s->x, s->y, 0); } + if (example.hold_bitmap_drawing) { + al_hold_bitmap_drawing(false); + } al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); if (example.show_help) { - for (i = 0; i < 5; i++) - al_draw_text(example.font, example.white, 0, h - 10 * fh + i * fh * 2 + fh * 0.5, 0, text[i]); + int dh = fh * 1.5; + for (i = 5; i >= 0; i--) { + al_draw_text(example.font, example.white, 0, h - dh, 0, text[i]); + dh += fh * 2; + } } al_draw_textf(example.font, example.white, 0, 0, 0, "count: %d", @@ -228,6 +239,7 @@ int main(int argc, char **argv) bool need_redraw = true; bool background = false; example.show_help = true; + example.hold_bitmap_drawing = false; (void)argc; (void)argv; @@ -345,6 +357,9 @@ int main(int argc, char **argv) if (example.blending == 4) example.blending = 0; } + else if (event.keyboard.keycode == ALLEGRO_KEY_H) { + example.hold_bitmap_drawing ^= 1; + } break; case ALLEGRO_EVENT_DISPLAY_CLOSE: diff --git a/examples/ex_projection.c b/examples/ex_projection.c index 23df658..bdf4a92 100644 --- a/examples/ex_projection.c +++ b/examples/ex_projection.c @@ -76,7 +76,7 @@ static void setup_3d_projection(ALLEGRO_TRANSFORM *projection) int dh = al_get_display_height(display); al_perspective_transform(projection, -180 * dw / dh, -180, 180, 180 * dw / dh, 180, 3000); - al_set_projection_transform(display, projection); + al_use_projection_transform(projection); } diff --git a/examples/ex_projection2.c b/examples/ex_projection2.c new file mode 100644 index 0000000..ae3526e --- /dev/null +++ b/examples/ex_projection2.c @@ -0,0 +1,191 @@ +#include <allegro5/allegro.h> +#include <allegro5/allegro_image.h> +#include <allegro5/allegro_font.h> +#include <allegro5/allegro_primitives.h> + +#include <math.h> + +#include "common.c" + +static void draw_pyramid(ALLEGRO_BITMAP* texture, float x, float y, float z, float theta) +{ + ALLEGRO_COLOR c = al_map_rgb_f(1, 1, 1); + ALLEGRO_TRANSFORM t; + ALLEGRO_VERTEX vtx[5] = { + /* x y z u v c */ + { 0, 1, 0, 0, 64, c}, + {-1, -1, -1, 0, 0, c}, + { 1, -1, -1, 64, 64, c}, + { 1, -1, 1, 64, 0, c}, + {-1, -1, 1, 64, 64, c}, + }; + int indices[12] = { + 0, 1, 2, + 0, 2, 3, + 0, 3, 4, + 0, 4, 1 + }; + + al_identity_transform(&t); + al_rotate_transform_3d(&t, 0, 1, 0, theta); + al_translate_transform_3d(&t, x, y, z); + al_use_transform(&t); + al_draw_indexed_prim(vtx, NULL, texture, indices, 12, ALLEGRO_PRIM_TRIANGLE_LIST); +} + +static void set_perspective_transform(ALLEGRO_BITMAP* bmp) +{ + ALLEGRO_TRANSFORM p; + float aspect_ratio = (float)al_get_bitmap_height(bmp) / al_get_bitmap_width(bmp); + al_set_target_bitmap(bmp); + al_identity_transform(&p); + al_perspective_transform(&p, -1, aspect_ratio, 1, 1, -aspect_ratio, 1000); + al_use_projection_transform(&p); +} + +int main(int argc, char **argv) +{ + ALLEGRO_DISPLAY *display; + ALLEGRO_TIMER *timer; + ALLEGRO_EVENT_QUEUE *queue; + ALLEGRO_BITMAP *texture; + ALLEGRO_BITMAP *display_sub_persp; + ALLEGRO_BITMAP *display_sub_ortho; + ALLEGRO_BITMAP *buffer; + ALLEGRO_FONT *font; + bool redraw = false; + bool quit = false; + bool fullscreen = false; + bool background = false; + int display_flags = ALLEGRO_RESIZABLE; + float theta = 0; + + if (argc > 1) { + if(strcmp(argv[1], "--use-shaders") == 0) { + display_flags |= ALLEGRO_PROGRAMMABLE_PIPELINE; + } + else { + abort_example("Unknown command line argument: %s\n", argv[1]); + } + } + + if (!al_init()) { + abort_example("Could not init Allegro.\n"); + } + al_init_image_addon(); + al_init_primitives_addon(); + al_init_font_addon(); + init_platform_specific(); + al_install_keyboard(); + + al_set_new_display_flags(display_flags); + al_set_new_display_option(ALLEGRO_DEPTH_SIZE, 16, ALLEGRO_SUGGEST); + /* Load everything as a POT bitmap to make sure the projection stuff works + * with mismatched backing texture and bitmap sizes. */ + al_set_new_display_option(ALLEGRO_SUPPORT_NPOT_BITMAP, 0, ALLEGRO_REQUIRE); + display = al_create_display(800, 600); + if (!display) { + abort_example("Error creating display\n"); + } + al_set_window_constraints(display, 256, 512, 0, 0); + set_perspective_transform(al_get_backbuffer(display)); + + /* This bitmap is a sub-bitmap of the display, and has a perspective transformation. */ + display_sub_persp = al_create_sub_bitmap(al_get_backbuffer(display), 0, 0, 256, 256); + set_perspective_transform(display_sub_persp); + + /* This bitmap is a sub-bitmap of the display, and has a orthographic transformation. */ + display_sub_ortho = al_create_sub_bitmap(al_get_backbuffer(display), 0, 0, 256, 512); + + /* This bitmap has a perspective transformation, purposefully non-POT */ + buffer = al_create_bitmap(200, 200); + set_perspective_transform(buffer); + + timer = al_create_timer(1.0 / 60); + font = al_create_builtin_font(); + + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_keyboard_event_source()); + al_register_event_source(queue, al_get_display_event_source(display)); + al_register_event_source(queue, al_get_timer_event_source(timer)); + + al_set_new_bitmap_flags(ALLEGRO_MIN_LINEAR | ALLEGRO_MAG_LINEAR | + ALLEGRO_MIPMAP); + + texture = al_load_bitmap("data/bkg.png"); + if (!texture) { + abort_example("Could not load data/bkg.png"); + } + + al_start_timer(timer); + while (!quit) { + ALLEGRO_EVENT event; + + al_wait_for_event(queue, &event); + switch (event.type) { + case ALLEGRO_EVENT_DISPLAY_CLOSE: + quit = true; + break; + case ALLEGRO_EVENT_DISPLAY_RESIZE: + al_acknowledge_resize(display); + set_perspective_transform(al_get_backbuffer(display)); + break; + case ALLEGRO_EVENT_KEY_DOWN: + switch (event.keyboard.keycode) { + case ALLEGRO_KEY_ESCAPE: + quit = true; + break; + case ALLEGRO_KEY_SPACE: + fullscreen = !fullscreen; + al_set_display_flag(display, ALLEGRO_FULLSCREEN_WINDOW, fullscreen); + set_perspective_transform(al_get_backbuffer(display)); + break; + } + break; + case ALLEGRO_EVENT_TIMER: + redraw = true; + theta = fmod(theta + 0.05, 2 * ALLEGRO_PI); + break; + case ALLEGRO_EVENT_DISPLAY_HALT_DRAWING: + background = true; + al_acknowledge_drawing_halt(display); + al_stop_timer(timer); + break; + case ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING: + background = false; + al_acknowledge_drawing_resume(display); + al_start_timer(timer); + break; + } + + if (!background && redraw && al_is_event_queue_empty(queue)) { + al_set_target_backbuffer(display); + al_set_render_state(ALLEGRO_DEPTH_TEST, 1); + al_clear_to_color(al_map_rgb_f(0, 0, 0)); + al_clear_depth_buffer(1000); + draw_pyramid(texture, 0, 0, -4, theta); + + al_set_target_bitmap(buffer); + al_set_render_state(ALLEGRO_DEPTH_TEST, 1); + al_clear_to_color(al_map_rgb_f(0, 0.1, 0.1)); + al_clear_depth_buffer(1000); + draw_pyramid(texture, 0, 0, -4, theta); + + al_set_target_bitmap(display_sub_persp); + al_set_render_state(ALLEGRO_DEPTH_TEST, 1); + al_clear_to_color(al_map_rgb_f(0, 0, 0.25)); + al_clear_depth_buffer(1000); + draw_pyramid(texture, 0, 0, -4, theta); + + al_set_target_bitmap(display_sub_ortho); + al_set_render_state(ALLEGRO_DEPTH_TEST, 0); + al_draw_text(font, al_map_rgb_f(1, 1, 1), 128, 16, ALLEGRO_ALIGN_CENTER, + "Press Space to toggle fullscreen"); + al_draw_bitmap(buffer, 0, 256, 0); + + al_flip_display(); + redraw = false; + } + } + return 0; +} diff --git a/include/allegro5/internal/aintern_bitmap.h b/include/allegro5/internal/aintern_bitmap.h index dcc57ee..d6a491f 100644 --- a/include/allegro5/internal/aintern_bitmap.h +++ b/include/allegro5/internal/aintern_bitmap.h @@ -77,6 +77,7 @@ struct ALLEGRO_BITMAP ALLEGRO_TRANSFORM transform; ALLEGRO_TRANSFORM inverse_transform; bool inverse_transform_dirty; + ALLEGRO_TRANSFORM proj_transform; /* Shader applied to this bitmap. Set this field with * _al_set_bitmap_shader_field to maintain invariants. diff --git a/include/allegro5/internal/aintern_direct3d.h b/include/allegro5/internal/aintern_direct3d.h index 8762749..acefc6b 100644 --- a/include/allegro5/internal/aintern_direct3d.h +++ b/include/allegro5/internal/aintern_direct3d.h @@ -48,6 +48,9 @@ typedef struct ALLEGRO_DISPLAY_D3D ALLEGRO_BITMAP backbuffer_bmp; ALLEGRO_BITMAP_EXTRA_D3D backbuffer_bmp_extra; + /* Contains the target video bitmap for this display. */ + ALLEGRO_BITMAP* target_bitmap; + bool device_lost; bool suppress_lost_events; @@ -56,7 +59,7 @@ typedef struct ALLEGRO_DISPLAY_D3D bool supports_separate_alpha_blend; TCHAR *device_name; - + int format; D3DFORMAT depth_stencil_format; int samples; diff --git a/include/allegro5/internal/aintern_display.h b/include/allegro5/internal/aintern_display.h index dbd42fc..cac7ca1 100644 --- a/include/allegro5/internal/aintern_display.h +++ b/include/allegro5/internal/aintern_display.h @@ -65,7 +65,6 @@ struct ALLEGRO_DISPLAY_INTERFACE void* (*prepare_vertex_cache)(ALLEGRO_DISPLAY *d, int num_new_vertices); void (*update_transformation)(ALLEGRO_DISPLAY* d, ALLEGRO_BITMAP *target); - void (*set_projection)(ALLEGRO_DISPLAY *d); /* Unused */ void (*shutdown)(void); @@ -142,8 +141,7 @@ struct ALLEGRO_DISPLAY ALLEGRO_SHADER* default_shader; - ALLEGRO_TRANSFORM proj_transform; - ALLEGRO_TRANSFORM view_transform; + ALLEGRO_TRANSFORM projview_transform; _ALLEGRO_RENDER_STATE render_state; diff --git a/include/allegro5/tls.h b/include/allegro5/tls.h index b6b4f08..a0dd641 100644 --- a/include/allegro5/tls.h +++ b/include/allegro5/tls.h @@ -34,6 +34,7 @@ typedef enum ALLEGRO_STATE_FLAGS ALLEGRO_STATE_BLENDER = 0x0010, ALLEGRO_STATE_NEW_FILE_INTERFACE = 0x0020, ALLEGRO_STATE_TRANSFORM = 0x0040, + ALLEGRO_STATE_PROJECTION_TRANSFORM = 0x0100, ALLEGRO_STATE_BITMAP = ALLEGRO_STATE_TARGET_BITMAP +\ ALLEGRO_STATE_NEW_BITMAP_PARAMETERS, diff --git a/include/allegro5/transformations.h b/include/allegro5/transformations.h index 31493fd..84368e7 100644 --- a/include/allegro5/transformations.h +++ b/include/allegro5/transformations.h @@ -17,6 +17,7 @@ struct ALLEGRO_TRANSFORM { /* Transformations*/ AL_FUNC(void, al_use_transform, (const ALLEGRO_TRANSFORM* trans)); +AL_FUNC(void, al_use_projection_transform, (const ALLEGRO_TRANSFORM* trans)); AL_FUNC(void, al_copy_transform, (ALLEGRO_TRANSFORM* dest, const ALLEGRO_TRANSFORM* src)); AL_FUNC(void, al_identity_transform, (ALLEGRO_TRANSFORM* trans)); AL_FUNC(void, al_build_transform, (ALLEGRO_TRANSFORM* trans, float x, float y, float sx, float sy, float theta)); @@ -36,12 +37,11 @@ AL_FUNC(void, al_transform_coordinates_3d, (const ALLEGRO_TRANSFORM *trans, AL_FUNC(void, al_compose_transform, (ALLEGRO_TRANSFORM* trans, const ALLEGRO_TRANSFORM* other)); AL_FUNC(const ALLEGRO_TRANSFORM*, al_get_current_transform, (void)); AL_FUNC(const ALLEGRO_TRANSFORM*, al_get_current_inverse_transform, (void)); +AL_FUNC(const ALLEGRO_TRANSFORM *, al_get_current_projection_transform, (void)); AL_FUNC(void, al_invert_transform, (ALLEGRO_TRANSFORM *trans)); AL_FUNC(int, al_check_inverse, (const ALLEGRO_TRANSFORM *trans, float tol)); AL_FUNC(void, al_orthographic_transform, (ALLEGRO_TRANSFORM *trans, float left, float top, float n, float right, float bottom, float f)); AL_FUNC(void, al_perspective_transform, (ALLEGRO_TRANSFORM *trans, float left, float top, float n, float right, float bottom, float f)); -AL_FUNC(ALLEGRO_TRANSFORM *, al_get_projection_transform, (ALLEGRO_DISPLAY *display)); -AL_FUNC(void, al_set_projection_transform, (ALLEGRO_DISPLAY *display, ALLEGRO_TRANSFORM *t)); AL_FUNC(void, al_horizontal_shear_transform, (ALLEGRO_TRANSFORM *trans, float theta)); AL_FUNC(void, al_vertical_shear_transform, (ALLEGRO_TRANSFORM *trans, float theta)); diff --git a/src/android/android_display.c b/src/android/android_display.c index 9d6b4e9..9f65880 100644 --- a/src/android/android_display.c +++ b/src/android/android_display.c @@ -133,9 +133,6 @@ JNI_FUNC(void, AllegroSurface, nativeOnChange, (JNIEnv *env, jobject obj, d->surface_object = (*env)->NewGlobalRef(env, obj); } - display->w = width; - display->h = height; - bool ret = _al_android_init_display(env, d); if (!ret && d->first_run) { al_broadcast_cond(d->cond); @@ -178,6 +175,11 @@ JNI_FUNC(void, AllegroSurface, nativeOnChange, (JNIEnv *env, jobject obj, } al_unlock_mutex(d->mutex); + + /* Send a resize event to signify that the display may have changed sizes. */ + if (!d->first_run) { + _al_android_resize_display(d, width, height); + } } JNI_FUNC(void, AllegroSurface, nativeOnJoystickAxis, (JNIEnv *env, jobject obj, @@ -231,20 +233,6 @@ void _al_android_clear_current(JNIEnv *env, ALLEGRO_DISPLAY_ANDROID *d) _jni_callVoidMethodV(env, d->surface_object, "egl_clearCurrent", "()V"); } -static void android_setup_opengl_view(ALLEGRO_DISPLAY *d) -{ - ALLEGRO_DEBUG("setup opengl view d->w=%d d->h=%d", d->w, d->h); - - glViewport(0, 0, d->w, d->h); - - al_identity_transform(&d->proj_transform); - al_orthographic_transform(&d->proj_transform, 0, 0, -1, d->w, d->h, 1); - al_set_projection_transform(d, &d->proj_transform); - - al_identity_transform(&d->view_transform); - al_use_transform(&d->view_transform); -} - static bool _al_android_init_display(JNIEnv *env, ALLEGRO_DISPLAY_ANDROID *display) { @@ -366,7 +354,7 @@ static void _al_android_resize_display(ALLEGRO_DISPLAY_ANDROID *d, display->h = height; ALLEGRO_DEBUG("resize backbuffer"); - _al_ogl_resize_backbuffer(display->ogl_extras->backbuffer, width, height); + _al_ogl_setup_gl(display); if (emitted_event) { d->resize_acknowledge2 = true; @@ -572,8 +560,6 @@ static ALLEGRO_DISPLAY *android_create_display(int w, int h) _al_android_clear_current(_al_android_get_jnienv(), d); _al_android_make_current(_al_android_get_jnienv(), d); - android_setup_opengl_view(display); - /* Don't need to repeat what this does */ android_set_display_option(display, ALLEGRO_SUPPORTED_ORIENTATIONS, al_get_new_display_option(ALLEGRO_SUPPORTED_ORIENTATIONS, NULL)); @@ -703,8 +689,6 @@ static bool android_acknowledge_resize(ALLEGRO_DISPLAY *dpy) ALLEGRO_DEBUG("acquire context"); _al_android_make_current(_al_android_get_jnienv(), d); - android_setup_opengl_view(dpy); - ALLEGRO_DEBUG("done"); return true; } @@ -853,13 +837,12 @@ static void android_acknowledge_drawing_resume(ALLEGRO_DISPLAY *dpy) dpy->default_shader = _al_create_default_shader(dpy->flags); } - al_set_target_backbuffer(dpy); - - android_setup_opengl_view(dpy); - // Bitmaps can still have stale shaders attached. _al_glsl_unuse_shaders(); + // Restore the transformations. + dpy->vt->update_transformation(dpy, al_get_target_bitmap()); + // Restore bitmaps // have to get this because new bitmaps could be created below for (i = 0; i < _al_vector_size(&dpy->bitmaps); i++) { diff --git a/src/bitmap.c b/src/bitmap.c index d849055..b77c169 100644 --- a/src/bitmap.c +++ b/src/bitmap.c @@ -69,6 +69,8 @@ static ALLEGRO_BITMAP *create_memory_bitmap(ALLEGRO_DISPLAY *current_display, al_identity_transform(&bitmap->transform); al_identity_transform(&bitmap->inverse_transform); bitmap->inverse_transform_dirty = false; + al_identity_transform(&bitmap->proj_transform); + al_orthographic_transform(&bitmap->proj_transform, 0, 0, -1.0, w, h, 1.0); bitmap->parent = NULL; bitmap->xofs = bitmap->yofs = 0; bitmap->memory = al_malloc(pitch * h); @@ -140,6 +142,8 @@ ALLEGRO_BITMAP *_al_create_bitmap_params(ALLEGRO_DISPLAY *current_display, al_identity_transform(&bitmap->transform); al_identity_transform(&bitmap->inverse_transform); bitmap->inverse_transform_dirty = false; + al_identity_transform(&bitmap->proj_transform); + al_orthographic_transform(&bitmap->proj_transform, 0, 0, -1.0, w, h, 1.0); bitmap->parent = NULL; bitmap->xofs = 0; bitmap->yofs = 0; @@ -430,6 +434,8 @@ ALLEGRO_BITMAP *al_create_sub_bitmap(ALLEGRO_BITMAP *parent, al_identity_transform(&bitmap->transform); al_identity_transform(&bitmap->inverse_transform); bitmap->inverse_transform_dirty = false; + al_identity_transform(&bitmap->proj_transform); + al_orthographic_transform(&bitmap->proj_transform, 0, 0, -1.0, w, h, 1.0); bitmap->shader = NULL; bitmap->parent = parent; bitmap->xofs = x; diff --git a/src/bitmap_type.c b/src/bitmap_type.c index effd561..5fd70f7 100644 --- a/src/bitmap_type.c +++ b/src/bitmap_type.c @@ -150,6 +150,7 @@ void al_convert_bitmap(ALLEGRO_BITMAP *bitmap) int new_bitmap_flags = al_get_new_bitmap_flags(); bool want_memory = (new_bitmap_flags & ALLEGRO_MEMORY_BITMAP) != 0; bool clone_memory; + ALLEGRO_BITMAP *target_bitmap; bitmap_flags &= ~_ALLEGRO_INTERNAL_OPENGL; @@ -190,7 +191,29 @@ void al_convert_bitmap(ALLEGRO_BITMAP *bitmap) bitmap->transform = clone->transform; bitmap->inverse_transform = clone->inverse_transform; bitmap->inverse_transform_dirty = clone->inverse_transform_dirty; - + + /* Memory bitmaps do not support custom projection transforms, + * so reset it to the orthographic transform. */ + if (new_bitmap_flags & ALLEGRO_MEMORY_BITMAP) { + al_identity_transform(&bitmap->proj_transform); + al_orthographic_transform(&bitmap->proj_transform, 0, 0, -1.0, bitmap->w, bitmap->h, 1.0); + } else { + bitmap->proj_transform = clone->proj_transform; + } + + /* If we just converted this bitmap, and the backing bitmap is the same + * as the target's backing bitmap, then the viewports and transformations + * will be messed up. Detect this, and just re-call al_set_target_bitmap + * on the current target. */ + target_bitmap = al_get_target_bitmap(); + if (target_bitmap) { + ALLEGRO_BITMAP *target_parent = + target_bitmap->parent ? target_bitmap->parent : target_bitmap; + if (bitmap == target_parent || bitmap->parent == target_parent) { + al_set_target_bitmap(target_bitmap); + } + } + al_destroy_bitmap(clone); } diff --git a/src/display.c b/src/display.c index 776b612..ea19311 100644 --- a/src/display.c +++ b/src/display.c @@ -40,7 +40,6 @@ ALLEGRO_DISPLAY *al_create_display(int w, int h) ALLEGRO_SYSTEM *system; ALLEGRO_DISPLAY_INTERFACE *driver; ALLEGRO_DISPLAY *display; - ALLEGRO_TRANSFORM identity; ALLEGRO_EXTRA_DISPLAY_SETTINGS *settings; int flags; @@ -75,6 +74,7 @@ ALLEGRO_DISPLAY *al_create_display(int w, int h) display->cache_enabled = false; display->vertex_cache_size = 0; display->cache_texture = 0; + al_identity_transform(&display->projview_transform); display->default_shader = NULL; @@ -90,8 +90,9 @@ ALLEGRO_DISPLAY *al_create_display(int w, int h) _al_vector_init(&display->bitmaps, sizeof(ALLEGRO_BITMAP*)); - if (settings->settings[ALLEGRO_COMPATIBLE_DISPLAY]) + if (settings->settings[ALLEGRO_COMPATIBLE_DISPLAY]) { al_set_target_bitmap(al_get_backbuffer(display)); + } else { ALLEGRO_DEBUG("ALLEGRO_COMPATIBLE_DISPLAY not set\n"); _al_set_current_display_only(display); @@ -105,9 +106,6 @@ ALLEGRO_DISPLAY *al_create_display(int w, int h) } } - al_identity_transform(&identity); - al_use_transform(&identity); - /* Clear the screen */ if (settings->settings[ALLEGRO_COMPATIBLE_DISPLAY]) { al_clear_to_color(al_map_rgb(0, 0, 0)); diff --git a/src/iphone/EAGLView.m b/src/iphone/EAGLView.m index 5f9bc0b..ae0218b 100644 --- a/src/iphone/EAGLView.m +++ b/src/iphone/EAGLView.m @@ -166,11 +166,8 @@ static touch_t* find_touch(_AL_LIST* list, UITouch* nativeTouch) */ allegro_display->w = backingWidth; allegro_display->h = backingHeight; - - } - else { - [self send_resize_event]; } + [self send_resize_event]; } - (BOOL)orientation_supported:(UIInterfaceOrientation) o { diff --git a/src/iphone/iphone_display.m b/src/iphone/iphone_display.m index 4f62cc3..89d5aad 100644 --- a/src/iphone/iphone_display.m +++ b/src/iphone/iphone_display.m @@ -29,7 +29,6 @@ void _al_iphone_setup_opengl_view(ALLEGRO_DISPLAY *d, bool manage_backbuffer) h = d->h; _al_iphone_reset_framebuffer(d); - glViewport(0, 0, w, h); _screen_w = w; _screen_h = h; @@ -37,11 +36,6 @@ void _al_iphone_setup_opengl_view(ALLEGRO_DISPLAY *d, bool manage_backbuffer) if (manage_backbuffer) { _al_ogl_setup_gl(d); } - else { - al_identity_transform(&d->proj_transform); - al_orthographic_transform(&d->proj_transform, 0, 0, -1, d->w, d->h, 1); - d->vt->set_projection(d); - } } void _al_iphone_translate_from_screen(ALLEGRO_DISPLAY *d, int *x, int *y) diff --git a/src/macosx/osxgl.m b/src/macosx/osxgl.m index 6fb2ab8..f5f2670 100644 --- a/src/macosx/osxgl.m +++ b/src/macosx/osxgl.m @@ -310,17 +310,11 @@ void _al_osx_mouse_was_installed(BOOL install) { { if ([NSOpenGLContext currentContext] != nil) { ALLEGRO_DISPLAY_OSX_WIN* dpy = (ALLEGRO_DISPLAY_OSX_WIN*) dpy_ptr; - NSRect rc = [self bounds]; - glViewport(0, 0, NSWidth(rc), NSHeight(rc)); - - al_identity_transform(&dpy_ptr->proj_transform); - al_orthographic_transform(&dpy_ptr->proj_transform, - 0, 0, -1, NSWidth(rc), NSHeight(rc), 1); if (dpy->tracking) { [self removeTrackingArea: dpy->tracking]; dpy->tracking = create_tracking_area(self); - [self addTrackingArea: dpy->tracking]; + [self addTrackingArea: dpy->tracking]; } } } diff --git a/src/opengl/ogl_display.c b/src/opengl/ogl_display.c index ae72e83..1a1013a 100644 --- a/src/opengl/ogl_display.c +++ b/src/opengl/ogl_display.c @@ -38,16 +38,20 @@ void _al_ogl_setup_gl(ALLEGRO_DISPLAY *d) { ALLEGRO_OGL_EXTRAS *ogl = d->ogl_extras; - glViewport(0, 0, d->w, d->h); - - al_identity_transform(&d->proj_transform); - al_orthographic_transform(&d->proj_transform, 0, 0, -1, d->w, d->h, 1); - d->vt->set_projection(d); - - if (ogl->backbuffer) + if (ogl->backbuffer) { + ALLEGRO_BITMAP *target = al_get_target_bitmap(); _al_ogl_resize_backbuffer(ogl->backbuffer, d->w, d->h); - else + /* If we are currently targetting the backbuffer, we need to update the + * transformations. */ + if (target && (target == ogl->backbuffer || + target->parent == ogl->backbuffer)) { + /* vt should be set at this point, but doesn't hurt to check */ + ASSERT(d->vt); + d->vt->update_transformation(d, target); + } + } else { ogl->backbuffer = _al_ogl_create_backbuffer(d); + } } @@ -164,6 +168,8 @@ bool _al_ogl_resize_backbuffer(ALLEGRO_BITMAP *b, int w, int h) b->ct = 0; b->cr_excl = w; b->cb_excl = h; + al_identity_transform(&b->proj_transform); + al_orthographic_transform(&b->proj_transform, 0, 0, -1.0, w, h, 1.0); /* There is no texture associated with the backbuffer so no need to care * about texture size limitations. */ @@ -237,17 +243,20 @@ ALLEGRO_BITMAP* _al_ogl_create_backbuffer(ALLEGRO_DISPLAY *disp) backbuffer->ct = 0; backbuffer->cr_excl = disp->w; backbuffer->cb_excl = disp->h; + al_identity_transform(&backbuffer->transform); + al_identity_transform(&backbuffer->proj_transform); + al_orthographic_transform(&backbuffer->proj_transform, 0, 0, -1.0, disp->w, disp->h, 1.0); ALLEGRO_TRACE_CHANNEL_LEVEL("display", 1)( "Created backbuffer bitmap (actual format: %s)\n", _al_pixel_format_name(al_get_bitmap_format(backbuffer))); ogl_backbuffer = backbuffer->extra; + ogl_backbuffer->true_w = disp->w; + ogl_backbuffer->true_h = disp->h; ogl_backbuffer->is_backbuffer = 1; backbuffer->_display = disp; - al_identity_transform(&disp->view_transform); - return backbuffer; } diff --git a/src/opengl/ogl_draw.c b/src/opengl/ogl_draw.c index 907ad03..6c26952 100644 --- a/src/opengl/ogl_draw.c +++ b/src/opengl/ogl_draw.c @@ -200,13 +200,13 @@ static void ogl_clear_android_2_1_workaround(ALLEGRO_DISPLAY *d, }; ALLEGRO_TRANSFORM bak1, bak2, t; - al_copy_transform(&bak1, &d->proj_transform); + al_copy_transform(&bak1, al_get_current_projection_transform()); al_copy_transform(&bak2, al_get_current_transform()); al_identity_transform(&t); al_orthographic_transform(&t, 0, 0, -1, d->w, d->h, 1); - al_set_projection_transform(d, &t); + al_use_projection_transform(&t); al_identity_transform(&t); al_use_transform(&t); @@ -228,7 +228,7 @@ static void ogl_clear_android_2_1_workaround(ALLEGRO_DISPLAY *d, vert_ptr_off(d); color_ptr_off(d); - al_set_projection_transform(d, &bak1); + al_use_projection_transform(&bak1); al_use_transform(&bak2); } @@ -467,49 +467,32 @@ static void ogl_flush_vertex_cache(ALLEGRO_DISPLAY *disp) static void ogl_update_transformation(ALLEGRO_DISPLAY* disp, ALLEGRO_BITMAP *target) { - ALLEGRO_TRANSFORM tmp; - - al_copy_transform(&tmp, &target->transform); - - if (target->parent) { - /* Sub-bitmaps have an additional offset. */ - al_translate_transform(&tmp, target->xofs, target->yofs); - } - if (disp->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) { #ifdef ALLEGRO_CFG_SHADER_GLSL GLint loc = disp->ogl_extras->varlocs.projview_matrix_loc; - al_copy_transform(&disp->view_transform, &tmp); + ALLEGRO_TRANSFORM projview; + al_copy_transform(&projview, &target->transform); + al_compose_transform(&projview, &target->proj_transform); + al_copy_transform(&disp->projview_transform, &projview); + if (disp->ogl_extras->program_object > 0 && loc >= 0) { - al_compose_transform(&tmp, &disp->proj_transform); - _al_glsl_set_projview_matrix(loc, &tmp); + _al_glsl_set_projview_matrix(loc, &disp->projview_transform); } #endif - return; + } else { + glMatrixMode(GL_PROJECTION); + glLoadMatrixf((float *)target->proj_transform.m); + glMatrixMode(GL_MODELVIEW); + glLoadMatrixf((float *)target->transform.m); } - glMatrixMode(GL_MODELVIEW); - glLoadMatrixf((float *)tmp.m); -} - -static void ogl_set_projection(ALLEGRO_DISPLAY *d) -{ - if (d->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) { -#ifdef ALLEGRO_CFG_SHADER_GLSL - GLint loc = d->ogl_extras->varlocs.projview_matrix_loc; - if (d->ogl_extras->program_object > 0 && loc >= 0) { - ALLEGRO_TRANSFORM t; - al_copy_transform(&t, &d->view_transform); - al_compose_transform(&t, &d->proj_transform); - _al_glsl_set_projview_matrix(loc, &t); - } -#endif - return; + if (target->parent) { + ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_extra = target->parent->extra; + /* glViewport requires the bottom-left coordinate of the corner. */ + glViewport(target->xofs, ogl_extra->true_h - (target->yofs + target->h), target->w, target->h); + } else { + glViewport(0, 0, target->w, target->h); } - - glMatrixMode(GL_PROJECTION); - glLoadMatrixf((float *)d->proj_transform.m); - glMatrixMode(GL_MODELVIEW); } static void ogl_clear_depth_buffer(ALLEGRO_DISPLAY *display, float x) @@ -538,7 +521,6 @@ void _al_ogl_add_drawing_functions(ALLEGRO_DISPLAY_INTERFACE *vt) vt->flush_vertex_cache = ogl_flush_vertex_cache; vt->prepare_vertex_cache = ogl_prepare_vertex_cache; vt->update_transformation = ogl_update_transformation; - vt->set_projection = ogl_set_projection; } /* vim: set sts=3 sw=3 et: */ diff --git a/src/opengl/ogl_fbo.c b/src/opengl/ogl_fbo.c index b3766b7..eb8d7ed 100644 --- a/src/opengl/ogl_fbo.c +++ b/src/opengl/ogl_fbo.c @@ -293,19 +293,9 @@ static void setup_fbo_backbuffer(ALLEGRO_DISPLAY *display, _al_ogl_bind_framebuffer(0); } -#ifndef ALLEGRO_IPHONE - glViewport(0, 0, display->w, display->h); - - al_identity_transform(&display->proj_transform); - /* We use upside down coordinates compared to OpenGL, so the bottommost - * coordinate is display->h not 0. - */ - al_orthographic_transform(&display->proj_transform, - 0, 0, -1, display->w, display->h, 1); -#else +#ifdef ALLEGRO_IPHONE _al_iphone_setup_opengl_view(display, false); #endif - display->vt->set_projection(display); } @@ -390,13 +380,6 @@ static void use_fbo_for_bitmap(ALLEGRO_DISPLAY *display, } else { display->ogl_extras->opengl_target = bitmap; - - glViewport(0, 0, bitmap->w, bitmap->h); - - al_identity_transform(&display->proj_transform); - al_orthographic_transform(&display->proj_transform, - 0, 0, -1, bitmap->w, bitmap->h, 1); - display->vt->set_projection(display); } } diff --git a/src/opengl/ogl_lock_es.c b/src/opengl/ogl_lock_es.c index 0ae367b..b58afa3 100644 --- a/src/opengl/ogl_lock_es.c +++ b/src/opengl/ogl_lock_es.c @@ -488,7 +488,6 @@ static void ogl_unlock_region_bb_proxy(ALLEGRO_BITMAP *bitmap, ALLEGRO_DEBUG("Drawing proxy to backbuffer\n"); { ALLEGRO_DISPLAY *disp; - ALLEGRO_TRANSFORM proj0; ALLEGRO_STATE state0; ALLEGRO_TRANSFORM t; bool held; @@ -498,21 +497,19 @@ static void ogl_unlock_region_bb_proxy(ALLEGRO_BITMAP *bitmap, if (held) { al_hold_bitmap_drawing(false); } - /* Projection transform is currently per-display. */ - al_copy_transform(&proj0, al_get_projection_transform(disp)); al_store_state(&state0, ALLEGRO_STATE_TARGET_BITMAP | - ALLEGRO_STATE_TRANSFORM | ALLEGRO_STATE_BLENDER); + ALLEGRO_STATE_TRANSFORM | ALLEGRO_STATE_BLENDER | + ALLEGRO_STATE_PROJECTION_TRANSFORM); { al_set_target_bitmap(bitmap); al_identity_transform(&t); al_use_transform(&t); al_orthographic_transform(&t, 0, 0, -1, disp->w, disp->h, 1); - al_set_projection_transform(disp, &t); + al_use_projection_transform(&t); al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); al_draw_bitmap(proxy, bitmap->lock_x, bitmap->lock_y, 0); } al_restore_state(&state0); - al_set_projection_transform(disp, &proj0); al_hold_bitmap_drawing(held); } diff --git a/src/opengl/ogl_shader.c b/src/opengl/ogl_shader.c index 0232331..163be74 100644 --- a/src/opengl/ogl_shader.c +++ b/src/opengl/ogl_shader.c @@ -226,11 +226,8 @@ static bool glsl_use_shader(ALLEGRO_SHADER *shader, ALLEGRO_DISPLAY *display, * itself. */ if (set_projview_matrix_from_display) { - ALLEGRO_TRANSFORM t; - al_copy_transform(&t, &display->view_transform); - al_compose_transform(&t, &display->proj_transform); _al_glsl_set_projview_matrix( - display->ogl_extras->varlocs.projview_matrix_loc, &t); + display->ogl_extras->varlocs.projview_matrix_loc, &display->projview_transform); } return true; diff --git a/src/tls.c b/src/tls.c index c54c370..1666e2f 100644 --- a/src/tls.c +++ b/src/tls.c @@ -107,6 +107,7 @@ typedef struct INTERNAL_STATE { thread_local_state tls; ALLEGRO_BLENDER stored_blender; ALLEGRO_TRANSFORM stored_transform; + ALLEGRO_TRANSFORM stored_projection_transform; int flags; } INTERNAL_STATE; @@ -661,6 +662,13 @@ void al_store_state(ALLEGRO_STATE *state, int flags) stored->stored_transform = target->transform; } + if (flags & ALLEGRO_STATE_PROJECTION_TRANSFORM) { + ALLEGRO_BITMAP *target = al_get_target_bitmap(); + if (target) { + stored->stored_projection_transform = target->proj_transform; + } + } + #undef _STORE } @@ -725,6 +733,12 @@ void al_restore_state(ALLEGRO_STATE const *state) al_use_transform(&stored->stored_transform); } + if (flags & ALLEGRO_STATE_PROJECTION_TRANSFORM) { + ALLEGRO_BITMAP *bitmap = al_get_target_bitmap(); + if (bitmap) + al_use_projection_transform(&stored->stored_projection_transform); + } + #undef _RESTORE } diff --git a/src/transformations.c b/src/transformations.c index f3d5528..49dd235 100644 --- a/src/transformations.c +++ b/src/transformations.c @@ -69,6 +69,31 @@ void al_use_transform(const ALLEGRO_TRANSFORM *trans) } } +/* Function: al_use_projection_transform + */ +void al_use_projection_transform(const ALLEGRO_TRANSFORM *trans) +{ + ALLEGRO_BITMAP *target = al_get_target_bitmap(); + ALLEGRO_DISPLAY *display; + + if (!target) + return; + + /* Memory bitmaps don't support custom projection transforms */ + if (al_get_bitmap_flags(target) & ALLEGRO_MEMORY_BITMAP) + return; + + /* Changes to a back buffer should affect the front buffer, and vice versa. + * Currently we rely on the fact that in the OpenGL drivers the back buffer + * and front buffer bitmaps are exactly the same, and the DirectX driver + * doesn't support front buffer bitmaps. + */ + + if (trans != &target->transform) { + al_copy_transform(&target->proj_transform, trans); + } +} + /* Function: al_get_current_transform */ const ALLEGRO_TRANSFORM *al_get_current_transform(void) @@ -81,6 +106,18 @@ const ALLEGRO_TRANSFORM *al_get_current_transform(void) return &target->transform; } +/* Function: al_get_current_projection_transform + */ +const ALLEGRO_TRANSFORM *al_get_current_projection_transform(void) +{ + ALLEGRO_BITMAP *target = al_get_target_bitmap(); + + if (!target) + return NULL; + + return &target->proj_transform; +} + /* Function: al_get_current_inverse_transform */ const ALLEGRO_TRANSFORM *al_get_current_inverse_transform(void) @@ -525,23 +562,6 @@ void al_perspective_transform(ALLEGRO_TRANSFORM *trans, al_compose_transform(trans, &tmp); } - -/* Function: al_get_projection_transform - */ -ALLEGRO_TRANSFORM *al_get_projection_transform(ALLEGRO_DISPLAY *display) -{ - return &display->proj_transform; -} - -/* Function: al_set_projection_transform - */ -void al_set_projection_transform(ALLEGRO_DISPLAY *display, ALLEGRO_TRANSFORM *t) -{ - al_copy_transform(&display->proj_transform, t); - display->vt->set_projection(display); -} - - /* Function: al_horizontal_shear_transform */ void al_horizontal_shear_transform(ALLEGRO_TRANSFORM* trans, float theta) diff --git a/src/win/d3d_disp.cpp b/src/win/d3d_disp.cpp index 98f842a..6c2948e 100644 --- a/src/win/d3d_disp.cpp +++ b/src/win/d3d_disp.cpp @@ -38,6 +38,9 @@ #include "d3d.h" +static void d3d_set_target_bitmap(ALLEGRO_DISPLAY *display, ALLEGRO_BITMAP *bitmap); +static void d3d_update_transformation(ALLEGRO_DISPLAY* disp, ALLEGRO_BITMAP *target); + // C++ needs to cast void pointers #define get_extra(b) ((ALLEGRO_BITMAP_EXTRA_D3D *)\ (b->parent ? b->parent->extra : b->extra)) @@ -48,8 +51,6 @@ ALLEGRO_DEBUG_CHANNEL("d3d") static ALLEGRO_DISPLAY_INTERFACE *vt = 0; -static ALLEGRO_BITMAP *previous_target = NULL; - static HMODULE _al_d3d_module = 0; typedef LPDIRECT3D9 (WINAPI *DIRECT3DCREATE9PROC)(UINT); @@ -66,9 +67,6 @@ LPDIRECT3D9 _al_d3d = 0; static D3DPRESENT_PARAMETERS d3d_pp; -static float d3d_ortho_w; -static float d3d_ortho_h; - static HWND fullscreen_focus_window; static bool ffw_set = false; @@ -352,72 +350,6 @@ static void d3d_reset_state(ALLEGRO_DISPLAY_D3D *disp) ALLEGRO_ERROR("SetSamplerState failed\n"); } -void _al_d3d_get_current_ortho_projection_parameters(float *w, float *h) -{ - *w = d3d_ortho_w; - *h = d3d_ortho_h; -} - -static void d3d_get_identity_matrix(D3DMATRIX *matrix) -{ - int i, j; - int one = 0; - - for (i = 0; i < 4; i++) { - for (j = 0; j < 4; j++) { - if (j == one) - matrix->m[j][i] = 1.0f; - else - matrix->m[j][i] = 0.0f; - } - one++; - } -} - -static void _al_d3d_set_ortho_projection(ALLEGRO_DISPLAY_D3D *disp, float w, float h) -{ - ALLEGRO_DISPLAY *display = (ALLEGRO_DISPLAY *)disp; - - if (disp->device_lost) - return; - - d3d_ortho_w = w; - d3d_ortho_h = h; - - if (display->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) { - al_identity_transform(&display->proj_transform); - al_orthographic_transform(&display->proj_transform, 0, 0, -1, w, h, 1); - -#ifdef ALLEGRO_CFG_SHADER_HLSL - LPD3DXEFFECT effect = disp->effect; - if (effect) { - ALLEGRO_TRANSFORM t; - al_copy_transform(&t, &display->view_transform); - al_compose_transform(&t, &display->proj_transform); - _al_hlsl_set_projview_matrix(effect, &t); - } -#endif - } - else { - D3DMATRIX matIdentity; - al_identity_transform(&display->proj_transform); - al_orthographic_transform(&display->proj_transform, 0, 0, -1, w, h, 1); - - /* - * Shift by half a pixel to make the output match the OpenGL output. - * Don't shift the actual proj_transform because if the user grabs it via - * al_get_projection_transform() and then sends it to - * al_set_projection_transform() the shift will be applied twice. - */ - ALLEGRO_TRANSFORM shifted; - al_copy_transform(&shifted, &display->proj_transform); - al_translate_transform(&shifted, -1.0 / w, 1.0 / h); - d3d_get_identity_matrix(&matIdentity); - disp->device->SetTransform(D3DTS_PROJECTION, (D3DMATRIX *)&shifted.m); - disp->device->SetTransform(D3DTS_WORLD, &matIdentity); - } -} - static bool d3d_display_mode_matches(D3DDISPLAYMODE *dm, int w, int h, int format, int refresh_rate) { if ((dm->Width == (unsigned int)w) && @@ -994,8 +926,6 @@ void _al_d3d_prepare_for_reset(ALLEGRO_DISPLAY_D3D *disp) (*d3d_release_callback)(al_display); } - previous_target = NULL; - d3d_call_callbacks(&al_display->display_... [truncated message content] |