]> git.mxchange.org Git - flightgear.git/blob - src/Instrumentation/render_area_2d.cxx
Remove unneeded inclusions of windows.h, GL.h and GLU.H
[flightgear.git] / src / Instrumentation / render_area_2d.cxx
1 // RenderArea2D.cxx - a class to manage 2D polygon-based drawing
2 //                    for a complex instrument (eg. GPS).
3 //
4 // Written by David Luff, started 2005.
5 //
6 // Copyright (C) 2005 - David C Luff - david.luff@nottingham.ac.uk
7 //
8 // This program is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU General Public License as
10 // published by the Free Software Foundation; either version 2 of the
11 // License, or (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful, but
14 // WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 // General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the Free Software
20 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 //
22 // $Id$
23
24
25 #ifdef HAVE_CONFIG_H
26 #  include <config.h>
27 #endif
28
29 #include "render_area_2d.hxx"
30
31
32 static const float dummy_normals[][3] = {{0.0f, 0.0f, 0.0f},
33                                          {0.0f, 0.0f, 0.0f},
34                                          {0.0f, 0.0f, 0.0f},
35                                          {0.0f, 0.0f, 0.0f}};
36
37 RA2DPrimitive::RA2DPrimitive() {
38         invert = false;
39         debug = false;
40 }
41                                                                                  
42 RenderArea2D::RenderArea2D(int logx, int logy, int sizex, int sizey, int posx, int posy) {
43         _logx = logx;
44         _logy = logy;
45         _sizex = sizex;
46         _sizey = sizey;
47         _posx = posx;
48         _posy = posy;
49         _clipx1 = 0;
50         _clipx2 = _logx - 1;
51         _clipy1 = 0;
52         _clipy2 = _logy - 1;
53         
54         _backgroundColor[0] = 0.0;
55         _backgroundColor[1] = 0.0;
56         _backgroundColor[2] = 0.0;
57         _backgroundColor[3] = 1.0;
58         _pixelColor[0] = 1.0;
59         _pixelColor[1] = 0.0;
60         _pixelColor[2] = 0.0;
61         _pixelColor[3] = 1.0;
62         
63         _ra2d_debug = false;
64 }
65
66 void RenderArea2D::draw() {
67 #if 0
68     glDisable(GL_TEXTURE_2D);
69         /*
70     glColor3f(1, 1, 0);
71         
72         float x1 = _posx;
73         float x2 = _posx + _sizex;
74         float y1 = _posy;
75         float y2 = _posy + _sizey;
76         
77         glBegin(GL_LINE_LOOP);
78     glVertex2f(x1, y1);
79     glVertex2f(x1, y2);
80     glVertex2f(x2, y2);
81     glVertex2f(x2, y1);
82     glEnd();
83         */
84         oldDrawBackground();
85         
86         for(unsigned int i = 0; i < drawing_list.size(); ++i) {
87                 RA2DPrimitive prim = drawing_list[i];
88                 switch(prim.type) {
89                 case RA2D_LINE:
90                         oldDrawLine(prim.x1, prim.y1, prim.x2, prim.y2);
91                         break;
92                 case RA2D_QUAD:
93                         if(prim.debug) {
94                                 //cout << "Clipping = " << _clipx1 << ", " << _clipy1 << " to " << _clipx2 << ", " << _clipy2 << '\n';
95                                 //cout << "Drawing quad " << prim.x1 << ", " << prim.y1 << " to " << prim.x2 << ", " << prim.y2 << '\n';
96                         }
97                         oldDrawQuad(prim.x1, prim.y1, prim.x2, prim.y2, prim.invert);
98                         break;
99                 case RA2D_PIXEL:
100                         oldDrawPixel(prim.x1, prim.y1, prim.invert);
101                         break;
102                 }
103         }
104         
105         glEnable(GL_TEXTURE_2D);
106 #endif
107 }
108
109 // Set clipping region in logical units
110 void RenderArea2D::SetClipRegion(int x1, int y1, int x2, int y2) {
111         _clipx1 = x1;
112         _clipx2 = x2;
113         _clipy1 = y1;
114         _clipy2 = y2;
115         //cout << "Set clip region, clip region = "  << _clipx1 << ", " << _clipy1 << " to " << _clipx2 << ", " << _clipy2 << '\n';
116 }
117
118 // Set clip region to be the same as the rendered area (default)
119 void RenderArea2D::ResetClipRegion() {
120         _clipx1 = 0;
121         _clipx2 = _logx - 1;
122         _clipy1 = 0;
123         _clipy2 = _logy - 1;
124         //cout << "Reset clip region, clip region = "  << _clipx1 << ", " << _clipy1 << " to " << _clipx2 << ", " << _clipy2 << '\n';
125 }
126
127 void RenderArea2D::SetPosition(int posx, int posy) {
128         _posx = posx;
129         _posy = posy;
130 }
131
132 void RenderArea2D::SetLogicalSize(int logx, int logy) {
133         _logx = logx;
134         _logy = logy;
135 }
136
137 void RenderArea2D::SetActualSize(int sizex, int sizey) {
138         _sizex = sizex;
139         _sizey = sizey;
140 }
141
142 void RenderArea2D::DrawPixel(int x, int y, bool invert) {
143         // Clipping is currently performed in oldDrawPixel - could clip here instead though.
144
145         RA2DPrimitive prim;
146         prim.x1 = x;
147         prim.y1 = y;
148         prim.x2 = 0;
149         prim.y2 = 0;
150         prim.type = RA2D_PIXEL;
151         prim.invert = invert;
152         drawing_list.push_back(prim);
153 }
154
155 void RenderArea2D::oldDrawPixel(int x, int y, bool invert) {
156         // Clip
157         if(x < _clipx1 || x > _clipx2 || y < _clipy1 || y > _clipy2) return;
158         
159         // Scale to position within background
160         float fx1 = (float)x, fy1 = (float)y;
161         float rx = (float)_sizex / (float)_logx;
162         float ry = (float)_sizey / (float)_logy;
163         fx1 *= rx;
164         fy1 *= ry;
165         float fx2 = fx1 + rx;
166         float fy2 = fy1 + ry;
167         
168         // Translate to final position
169         fx1 += (float)_posx;
170         fx2 += (float)_posx;
171         fy1 += (float)_posy;
172         fy2 += (float)_posy;
173         
174         //cout << "DP: " << fx1 << ", " << fy1 << " ... " << fx2 << ", " << fy2 << '\n';
175         
176         doSetColor(invert ? _backgroundColor : _pixelColor);
177         sgVec2 corners[4];
178         sgSetVec2(corners[0], fx1, fy1);
179         sgSetVec2(corners[1], fx2, fy1);
180         sgSetVec2(corners[2], fx2, fy2);
181         sgSetVec2(corners[3], fx1, fy2);
182         //cout << "Drawing pixel, x,y is " << x << ", " << y << ", fx is [x1,x2,y1,y2] " << fx1 << ", " << fx2 << ", " << fy1 << ", " << fy2 << '\n';
183         doDrawQuad(&corners[0], dummy_normals);
184 }
185
186 void RenderArea2D::DrawLine(int x1, int y1, int x2, int y2) {
187         RA2DPrimitive prim;
188         prim.x1 = x1;
189         prim.y1 = y1;
190         prim.x2 = x2;
191         prim.y2 = y2;
192         prim.type = RA2D_LINE;
193         prim.invert = false;
194         drawing_list.push_back(prim);
195 }
196
197 void RenderArea2D::oldDrawLine(int x1, int y1, int x2, int y2) {
198         // Crude implementation of Bresenham line drawing algorithm.
199         
200         // Our lines are non directional, so first order the points x-direction-wise to leave only 4 octants to consider.
201         if(x2 < x1) {
202                 int tmp_x = x1;
203                 int tmp_y = y1;
204                 x1 = x2;
205                 y1 = y2;
206                 x2 = tmp_x;
207                 y2 = tmp_y;
208         }
209         
210         bool flip_y = (y1 > y2 ? true : false);
211         int dx = x2 - x1;
212         int dy = (flip_y ? y1 - y2 : y2 - y1); 
213         if(dx > dy) {
214                 // push the x dir
215                 int y = y1;
216                 int yn = dx/2;
217                 for(int x=x1; x<=x2; ++x) {
218                         DrawPixel(x, y);
219                         yn += dy;
220                         if(yn >= dx) {
221                                 yn -= dx;
222                                 y = (flip_y ? y - 1 : y + 1);
223                         }
224                 }
225         } else {
226                 // push the y dir
227                 int x = x1;
228                 int xn = dy/2;
229                 // Must be a more elegant way to roll the next two cases into one!
230                 if(flip_y) {
231                         for(int y=y1; y>=y2; --y) {
232                                 DrawPixel(x, y);
233                                 xn += dx;
234                                 if(xn >= dy) {
235                                         xn -= dy;
236                                         x++;
237                                 }
238                         }
239                 } else {
240                         for(int y=y1; y<=y2; ++y) {
241                                 DrawPixel(x, y);
242                                 xn += dx;
243                                 if(xn >= dy) {
244                                         xn -= dy;
245                                         x++;
246                                 }
247                         }
248                 }
249         }
250 }
251
252 void RenderArea2D::DrawQuad(int x1, int y1, int x2, int y2, bool invert) {
253         // Clip and sanity-check.
254         if(x1 > x2) {
255                 int x = x2;
256                 x2 = x1;
257                 x1 = x;
258         }
259         if(y1 > y2) {
260                 int y = y2;
261                 y2 = y1;
262                 y1 = y;
263         }
264         x1 = x1 < _clipx1 ? _clipx1 : x1;
265         if(x1 > _clipx2) { return; }
266         x2 = x2 > _clipx2 ? _clipx2 : x2;
267         if(x2 < _clipx1) { return; }
268         y1 = y1 < _clipy1 ? _clipy1 : y1;
269         if(y1 > _clipy2) { return; }
270         y2 = y2 > _clipy2 ? _clipy2 : y2;
271         if(y2 < _clipy1) { return; }
272         
273         RA2DPrimitive prim;
274         prim.x1 = x1;
275         prim.y1 = y1;
276         prim.x2 = x2;
277         prim.y2 = y2;
278         prim.type = RA2D_QUAD;
279         prim.invert = invert;
280         if(_ra2d_debug) prim.debug = true;
281         drawing_list.push_back(prim);
282 }
283
284 void RenderArea2D::oldDrawQuad(int x1, int y1, int x2, int y2, bool invert) {
285         // Scale to position within background
286         float fx1 = (float)x1, fy1 = (float)y1;
287         float fx2 = (float)x2, fy2 = (float)y2;
288         float rx = (float)_sizex / (float)_logx;
289         float ry = (float)_sizey / (float)_logy;
290         fx1 *= rx;
291         fy1 *= ry;
292         fx2 *= rx;
293         fy2 *= ry;
294         
295         fx2 += rx;
296         fy2 += ry;
297         
298         // Translate to final position
299         fx1 += (float)_posx;
300         fx2 += (float)_posx;
301         fy1 += (float)_posy;
302         fy2 += (float)_posy;
303         
304         //cout << "DP: " << fx1 << ", " << fy1 << " ... " << fx2 << ", " << fy2 << '\n';
305         
306         doSetColor(invert ? _backgroundColor : _pixelColor);
307         sgVec2 corners[4];
308         sgSetVec2(corners[0], fx1, fy1);
309         sgSetVec2(corners[1], fx2, fy1);
310         sgSetVec2(corners[2], fx2, fy2);
311         sgSetVec2(corners[3], fx1, fy2);
312         doDrawQuad(&corners[0], dummy_normals);
313 }
314
315 void RenderArea2D::DrawBackground() {
316         // TODO
317 }
318
319 void RenderArea2D::oldDrawBackground() {
320         doSetColor(_backgroundColor);
321         sgVec2 corners[4];
322         sgSetVec2(corners[0], (float)_posx, (float)_posy);
323         sgSetVec2(corners[1], (float)(_posx + _sizex), (float)_posy);
324         sgSetVec2(corners[2], (float)(_posx + _sizex), (float)(_posy + _sizey));
325         sgSetVec2(corners[3], (float)_posx, (float)(_posy + _sizey));
326         doDrawQuad(&corners[0], dummy_normals);
327 }
328
329 void RenderArea2D::Flush() {
330         drawing_list.clear();
331 }
332
333 // -----------------------------------------
334 //
335 // Actual drawing routines copied from Atlas
336 //
337 // -----------------------------------------
338
339 void RenderArea2D::doSetColor( const float *rgba ) {
340   //OSGFIXME
341 #if 0
342   glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, rgba);
343   glColor4fv( rgba );
344 #endif
345 }
346
347 void RenderArea2D::doDrawQuad( const sgVec2 *p, const sgVec3 *normals ) {
348         //cout << "doDrawQuad: " << *p[0] << ", " << *(p[0]+1) << ", " << *p[1] << ", " << *(p[1]+1) << ", " << *p[2] << ", " << *p([2]+1) << ", " << *p[3] << ", " << *p([3]+1) <<'\n';
349   //OSGFIXME
350 #if 0
351   glBegin(GL_QUADS);
352   glNormal3fv( normals[0] ); glVertex2fv( p[0] );
353   glNormal3fv( normals[1] ); glVertex2fv( p[1] );
354   glNormal3fv( normals[2] ); glVertex2fv( p[2] );
355   glNormal3fv( normals[3] ); glVertex2fv( p[3] );
356   glEnd();
357 #endif
358 }
359
360 void RenderArea2D::doDrawQuad( const sgVec2 *p, const sgVec3 *normals, const sgVec4 *color ) {
361   //OSGFIXME
362 #if 0
363   glBegin(GL_QUADS);
364     glColor4fv( color[0] );glNormal3fv( normals[0] ); glVertex2fv( p[0] );
365     glColor4fv( color[1] );glNormal3fv( normals[1] ); glVertex2fv( p[1] );
366     glColor4fv( color[2] );glNormal3fv( normals[2] ); glVertex2fv( p[2] );
367     glColor4fv( color[3] );glNormal3fv( normals[3] ); glVertex2fv( p[3] );
368   glEnd();
369 #endif
370 }