Fix rendering buffer handling
authorAndreas Eversberg <jolly@eversberg.eu>
Thu, 5 Apr 2018 16:58:44 +0000 (18:58 +0200)
committerAndreas Eversberg <jolly@eversberg.eu>
Thu, 5 Apr 2018 17:03:39 +0000 (19:03 +0200)
- clear_screen clears the entire screen now, since obsolete back-buffer-copy
  has been removed.
- If no OpenGL rendering is available (yet), fallback to legacy image.
  This avoids flicker when switching to OpenGL rendering.

src/libsdl/opengl.c
src/libsdl/opengl.h
src/mercenary/main.c
src/mercenary/render.c
src/mercenary/render.h

index 74fcfe3..f795cf2 100644 (file)
@@ -130,16 +130,9 @@ void resize_opengl(int _screen_width, int _screen_height)
        screen_height = _screen_height;
 }
 
-void opengl_copy_last(void)
-{
-       // FIXME: is it ok to copy full window height??? or just the current viewport
-       glReadBuffer(GL_FRONT);
-       glCopyPixels(0, 0, screen_width, screen_height, GL_COLOR);
-       glReadBuffer(GL_BACK);
-}
-
 void opengl_clear(void)
 {
+       /* clear screen */
        glClearColor(0.0, 0.0, 0.0, 1.0);
        glClear(GL_COLOR_BUFFER_BIT);
 }
@@ -182,7 +175,7 @@ void opengl_viewport_legacy(int split)
        if (view_width < 1 || view_height < 1)
                return;
 
-       /* viewport and projection matrix */
+       /* viewport and projection matrix to view rectangle */
        glViewport((GLsizei)view_x, (GLsizei)view_y, (GLsizei)view_width, (GLsizei)view_height);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
index edfdc5f..cd7fb38 100644 (file)
@@ -2,7 +2,6 @@
 int init_opengl(int _image_width, int _image_height);
 int init_osd(int num, int _osd_width, int _osd_height);
 void resize_opengl(int _screen_width, int _screen_height);
-void opengl_copy_last(void);
 void opengl_clear(void);
 void opengl_viewport_legacy(int top);
 void opengl_blit_legacy(uint8_t *rgb, int filter);
index 27935dd..cd0bd6a 100644 (file)
@@ -298,6 +298,7 @@ static void main_loop(void)
 {
        double frame_step, frame_time = 0.0, frame_render = 1;
        int had_first_irq = 0;
+       int render_improved_rc;
        static uint32_t current_time, last_time = 0, diff;
        int i, rc;
        int space, length;
@@ -337,10 +338,8 @@ static void main_loop(void)
                        /* be sure to clean all capture history, so we don't get glichtes when turning on improved rendering again */
                        render_capture_reset();
                }
-               if (render_improved) {
+               if (render_improved)
                        opengl_viewport_improved(debug_opengl, (double_pixel_size) ? BENSON_AT_LINE * 2 : BENSON_AT_LINE, config_fov, benson_size);
-                       opengl_copy_last();
-               }
                /* STEP 1: let the CPU render/process the game, also improve rendering via OpenGL, if enabled */
                /* amgia speed: don't render if we still delay */
                /* non amiga speed: render if we need a new frame */
@@ -378,7 +377,9 @@ static void main_loop(void)
                }
                /* render improved graphics, interpolate, if required */
                if (render_improved)
-                       render_all_items((config_amiga_speed) ? 1.0 : frame_time);
+                       render_improved_rc = render_all_items((config_amiga_speed) ? 1.0 : frame_time);
+               else
+                       render_improved_rc = -1;
                /* advance frame time, if we are not in help view  */
                if (!(had_first_irq && help_view)) {
 //printf("frame rate: %.6f, frame-step=%.5f frame-time=%.5f\n", 1.0 / vbl_duration, frame_step,frame_time);
@@ -394,11 +395,11 @@ static void main_loop(void)
                        /* render game view without benson
                         * because benson is not updated before VBL IRQ, we don't want old image from double buffer
                         */
-                       if (render_legacy)
+                       if (render_legacy || render_improved_rc)
                                emul_video(image, memory, palette, IMAGE_WIDTH, IMAGE_HEIGHT, IMAGE_DIWSTART, chipreg, 0, BENSON_AT_LINE, double_pixel_size);
                }
                /* render benson + osd ontop of improved opengl rendering, if enabled */
-               if (render_improved) {
+               if (render_improved && render_improved_rc == 0) {
                        opengl_blit_benson(image, config_video_filter, (double_pixel_size) ? BENSON_AT_LINE * 2 : BENSON_AT_LINE, config_fov, benson_size, (double_pixel_size) ? 2 : 1);
                        if (help_view)
                                opengl_blit_osd(0, help_osd, config_video_filter, (double_pixel_size) ? BENSON_AT_LINE * 2 : BENSON_AT_LINE, config_fov, benson_size, 1.0, 1.0, 0.0, 0.0);
@@ -409,7 +410,8 @@ static void main_loop(void)
                        }
                }
                /* setup viewport for legacy image and render image, if enabled */
-               if (render_legacy) {
+               /* also render legacy, if render_improved failed due to not (yet) available items */
+               if (render_legacy || (render_improved && render_improved_rc)) {
                        opengl_viewport_legacy(debug_opengl);
                        opengl_blit_legacy(image, config_video_filter);
                        if (help_view)
index 37380db..5ac62a9 100644 (file)
@@ -2478,8 +2478,9 @@ static void interpolate_objects(double inter)
 /* always renders NEW! items
  * use inter == 1.0 to render motion to vertices of NEW items
  * use inter 0.0 .. 1.0 to interpolate motion between OLD and NEW items
+ * return 0, if the scene was rendered, returns < 0, if there is no scene
  */
-void render_all_items(double inter)
+int render_all_items(double inter)
 {
        render_item_object_info = NULL;
        render_item_vertices_0 = render_item_vertices_1 = render_item_vertices_2 = NULL;
@@ -2529,21 +2530,15 @@ void render_all_items(double inter)
                interpolate_objects(inter);
        }
 
-       /* add a blank background, if render list is empty */
-       if (!render_list_new) {
-               render_item_t blank;
-               memset(&blank, 0, sizeof(blank));
-               blank.type = RENDER_ITEM_SKY;
-               blank.u.sky.red = 0.5;
-               blank.u.sky.green = 0.5;
-               blank.u.sky.blue = 0.5;
-               render_one_item(&blank);
-               return;
-       }
+       /* return failure, if nothing can be rendered */
+       if (!render_list_new)
+               return -1;
 
        for (render_item = render_list_new; render_item; render_item = render_item->next) {
                render_one_item(render_item);
        }
+
+       return 0;
 }
 
 void render_capture_reset(void)
index beeeebb..6ff93e7 100644 (file)
@@ -2,7 +2,7 @@
 void render_capture_start(double _fov, int _extend_roads, int debug);
 void render_capture_stop(void);
 void render_capture_event(int event);
-void render_all_items(double inter);
+int render_all_items(double inter);
 void render_capture_reset(void);
 int render_capture_is_interstellar(void);