Make it build with -DCOMPILE_AMALGATION=ON. Still not certain how intern_draw/next_po...
[supertux.git] / src / video / gl / gl_renderer.hpp
1 //  SuperTux
2 //  Copyright (C) 2006 Matthias Braun <matze@braunis.de>
3 //
4 //  This program is free software: you can redistribute it and/or modify
5 //  it under the terms of the GNU General Public License as published by
6 //  the Free Software Foundation, either version 3 of the License, or
7 //  (at your option) any later version.
8 //
9 //  This program is distributed in the hope that it will be useful,
10 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
11 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 //  GNU General Public License for more details.
13 //
14 //  You should have received a copy of the GNU General Public License
15 //  along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
17 #ifndef HEADER_SUPERTUX_VIDEO_GL_RENDERER_HPP
18 #define HEADER_SUPERTUX_VIDEO_GL_RENDERER_HPP
19
20 #include "math/size.hpp"
21 #include "video/drawing_request.hpp"
22 #include "video/renderer.hpp"
23
24 #include <math.h>
25
26 namespace {
27
28 inline void intern_draw(float left, float top, float right, float bottom,
29                         float uv_left, float uv_top,
30                         float uv_right, float uv_bottom,
31                         float angle, float alpha,
32                         const Color& color,
33                         const Blend& blend,
34                         DrawingEffect effect)
35 {
36   if(effect & HORIZONTAL_FLIP)
37     std::swap(uv_left, uv_right);
38  
39   if(effect & VERTICAL_FLIP) 
40     std::swap(uv_top, uv_bottom);
41
42   glBlendFunc(blend.sfactor, blend.dfactor);
43   glColor4f(color.red, color.green, color.blue, color.alpha * alpha);
44  
45   // unrotated blit
46   if (angle == 0.0f) {
47     float vertices[] = {
48       left, top,
49       right, top,
50       right, bottom,
51       left, bottom,
52     };
53     glVertexPointer(2, GL_FLOAT, 0, vertices);
54
55     float uvs[] = {
56       uv_left, uv_top,
57       uv_right, uv_top,
58       uv_right, uv_bottom,
59       uv_left, uv_bottom,
60     };
61     glTexCoordPointer(2, GL_FLOAT, 0, uvs);
62
63     glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
64   } else {
65     // rotated blit
66     float center_x = (left + right) / 2;
67     float center_y = (top + bottom) / 2;
68
69     float sa = sinf(angle/180.0f*M_PI);
70     float ca = cosf(angle/180.0f*M_PI);
71
72     left  -= center_x;
73     right -= center_x;
74
75     top    -= center_y;
76     bottom -= center_y;
77
78     float vertices[] = {
79       left*ca - top*sa + center_x, left*sa + top*ca + center_y,
80       right*ca - top*sa + center_x, right*sa + top*ca + center_y,
81       right*ca - bottom*sa + center_x, right*sa + bottom*ca + center_y,
82       left*ca - bottom*sa + center_x, left*sa + bottom*ca + center_y
83     };
84     glVertexPointer(2, GL_FLOAT, 0, vertices);
85
86     float uvs[] = {
87       uv_left, uv_top,
88       uv_right, uv_top,
89       uv_right, uv_bottom,
90       uv_left, uv_bottom,
91     };
92     glTexCoordPointer(2, GL_FLOAT, 0, uvs);
93
94     glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
95   }
96
97   // FIXME: find a better way to restore the blend mode
98   glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
99   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
100 }
101
102 } // namespace
103
104
105
106 class GLRenderer : public Renderer
107 {
108 private:
109   Size desktop_size;
110   Size screen_size;
111   bool fullscreen_active;
112
113 public:
114   GLRenderer();
115   ~GLRenderer();
116
117   void draw_surface(const DrawingRequest& request);
118   void draw_surface_part(const DrawingRequest& request);
119   void draw_text(const DrawingRequest& request);
120   void draw_gradient(const DrawingRequest& request);
121   void draw_filled_rect(const DrawingRequest& request);
122   void draw_inverse_ellipse(const DrawingRequest& request);
123   void do_take_screenshot();
124   void flip();
125   void resize(int w, int h);
126   void apply_config();
127   void apply_video_mode(const Size& size, bool fullscreen);
128 };
129
130 #endif
131
132 /* EOF */