Render game graphics using OpenGL
[mercenary-reloaded.git] / src / libsdl / opengl.c
index 3e046f0..6d72ed2 100644 (file)
@@ -89,6 +89,13 @@ 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)
 {
@@ -143,7 +150,7 @@ void opengl_viewport_legacy(int split)
 }
 
 /* render legacy image texture */
-void opengl_render_legacy(uint8_t *rgb, int filter)
+void opengl_blit_legacy(uint8_t *rgb, int filter)
 {
        double width = (double)image_width / (double)texture_size;
        double height = (double)image_height / (double)texture_size;
@@ -167,10 +174,8 @@ void opengl_render_legacy(uint8_t *rgb, int filter)
        glDisable(GL_TEXTURE_2D);
 }
 
-static double fov = 64.0;
-
 /* set viewport for improved rendering */
-void opengl_viewport_improved(int split, int benson_at_line)
+void opengl_viewport_improved(int split, int benson_at_line, double fov, double benson_size)
 {
        int view_x, view_y;
        int view_width, view_height;
@@ -218,32 +223,24 @@ void opengl_viewport_improved(int split, int benson_at_line)
        /* make frustum to center the view in the game view above benson */
        double left = -slope;
        double right = slope;
-       double top = slope * (double)benson_at_line / (double)image_width;
-       double bottom = -slope * ((double)image_height * 2.0 - (double)benson_at_line) / (double)image_width;
+       double benson_start_at_position = ((double)image_height - (double)benson_at_line) * benson_size;
+       double top = slope * ((double)image_height - benson_start_at_position) / (double)image_width;
+       double bottom = -slope * ((double)image_height * 2.0 - ((double)image_height - benson_start_at_position)) / (double)image_width;
        glFrustum(left, right, bottom, top, 1.0, 5000000000.0);
        glMatrixMode(GL_MODELVIEW);
-
-#if 1
-       /* test rectangle */
-       glColor3d(0.5, 0.4, 0.4);
-       glBegin(GL_QUADS);
-       glVertex3f(-1.0, -1.0, -1.0);
-       glVertex3f(1.0, -1.0, -1.0);
-       glVertex3f(1.0, 1.0, -1.0);
-       glVertex3f(-1.0, 1.0, -1.0);
-       glEnd();
-#endif
 }
 
 /* render only benson */
-void opengl_render_benson(uint8_t *rgb, int filter, int benson_at_line)
+void opengl_blit_benson(uint8_t *rgb, int filter, int benson_at_line, double fov, double benson_size, int pixel_size)
 {
-       double texture_left = 0.0;
-       double texture_right = (double)image_width / (double)texture_size;
-       double texture_top = (double)benson_at_line / (double)texture_size;
-       double texture_bottom = (double)image_height / (double)texture_size;
-       double benson_top = -(double)benson_at_line / (double)image_width;
-       double benson_bottom = -((double)image_height * 2.0 - (double)benson_at_line) / (double)image_width;
+       double border = (benson_size != 1.0) ? (double)pixel_size : 0.0;
+       double texture_left = border / (double)texture_size;
+       double texture_right = ((double)image_width - border) / (double)texture_size;
+       double texture_top = ((double)benson_at_line + border) / (double)texture_size;
+       double texture_bottom = ((double)image_height -border) / (double)texture_size;
+       double benson_start_at_position = ((double)image_height - (double)benson_at_line) * benson_size;
+       double benson_top = -((double)image_height - benson_start_at_position) / (double)image_width;
+       double benson_bottom = -((double)image_height * 2.0 - ((double)image_height - benson_start_at_position)) / (double)image_width;
 
        /* calculate field-of-view */
        double slope = tan(fov / 360 * M_PI);
@@ -258,17 +255,98 @@ void opengl_render_benson(uint8_t *rgb, int filter, int benson_at_line)
        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, benson_at_line, image_width, image_height - benson_at_line, GL_RGB, GL_UNSIGNED_BYTE, rgb);
        glBegin(GL_QUADS);
        glTexCoord2f(texture_left, texture_bottom);
-       glVertex3f(-2.0, 2.0 * benson_bottom, -2.0 / slope);
+       glVertex3f(-100.0 * benson_size, 100.0 * benson_bottom, -100.0 / slope);
        glTexCoord2f(texture_right, texture_bottom);
-       glVertex3f(2.0, 2.0 * benson_bottom, -2.0 / slope);
+       glVertex3f(100.0 * benson_size, 100.0 * benson_bottom, -100.0 / slope);
        glTexCoord2f(texture_right, texture_top);
-       glVertex3f(2.0, 2.0 * benson_top, -2.0 / slope);
+       glVertex3f(100.0 * benson_size, 100.0 * benson_top, -100.0 / slope);
        glTexCoord2f(texture_left, texture_top);
-       glVertex3f(-2.0, 2.0 * benson_top, -2.0 / slope);
+       glVertex3f(-100.0 * benson_size, 100.0 * benson_top, -100.0 / slope);
        glEnd();
        glDisable(GL_TEXTURE_2D);
 }
 
+static double transparency;
+
+/* start rendering scene */
+void opengl_transparency_set(double _transparency)
+{
+       if (transparency)
+               glDisable(GL_BLEND);
+
+       transparency = _transparency;
+
+       /* for debugging use transparent rendering */
+       if (transparency) {
+               glEnable(GL_BLEND);
+               glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+       }
+}
+
+void opengl_render_color(double r, double g, double b)
+{
+       if (transparency)
+               glColor4d(r, g, b, 1.0 - transparency);
+       else
+               glColor3d(r, g, b);
+}
+
+/* render polygon */
+void opengl_render_polygon(double *x, double *y, double *z, int count, int cull_face)
+{
+       int i;
+
+       if (cull_face) {
+               glEnable(GL_CULL_FACE);
+               glFrontFace(GL_CW);
+               glCullFace(GL_BACK);
+       }
+       glBegin(GL_POLYGON);
+       for (i = 0; i < count; i++)
+               glVertex3d(x[i], y[i], -z[i]);
+       glEnd();
+       if (cull_face)
+               glDisable(GL_CULL_FACE);
+}
+
+/* render polygon, but make sure any size of it is visible */
+void opengl_render_polygon_and_line(double *x, double *y, double *z, int count)
+{
+       int i;
+
+       glBegin(GL_POLYGON);
+       for (i = 0; i < count; i++)
+               glVertex3d(x[i], y[i], -z[i]);
+       glEnd();
+       glBegin(GL_LINE_LOOP);
+       for (i = 0; i < count; i++)
+               glVertex3d(x[i], y[i], -z[i]);
+       glEnd();
+}
+
+/* render line */
+void opengl_render_line(double x1, double y1, double z1, double x2, double y2, double z2, double size)
+{
+       if (size == 0.0) {
+               glBegin(GL_LINES);
+               glVertex3f(x1, y1, -z1);
+               glVertex3f(x2, y2, -z2);
+               glEnd();
+               return;
+       }
+}
+
+/* render point */
+void opengl_render_point(double x, double y, double z, double size)
+{
+       if (size == 0.0) {
+               glBegin(GL_POINTS);
+               glVertex3f(x, y, -z);
+               glEnd();
+               return;
+       }
+}
+
 /* free image texture */
 void exit_opengl(void)
 {