]> git.mxchange.org Git - simgear.git/blob - simgear/screen/tr.cxx
- remove the SG_GLxxxx_H #defines, since OSG provides its own versions
[simgear.git] / simgear / screen / tr.cxx
1 /* $Id$ */
2
3 /*
4  * $Log$
5  * Revision 1.5  2008/07/27 16:10:37  ehofman
6  *
7  *
8  *  - remove the SG_GLxxxx_H #defines, since OSG provides its own versions
9  *  - this exposed a bizarre issue on Mac where dragging in <AGL/agl.h> in
10  *    extensions.hxx was pulling in all of Carbon to the global namespace
11  *    - very scary. As a result, I now need to explicitly include CoreFoundation
12  *    in fg_init.cxx.
13  *  - change SG_USING_STD(x) to using std::x
14  *
15  * Issues:
16  *
17  *  - the logic for X11 and Win32 in RenderTexture and extensions is tortured,
18  *    please see if you agree I got all the ifdefs correct.
19  *
20  * Revision 1.4  2006/10/29 19:27:11  frohlich
21  * Modified Files:
22  *      configure.ac simgear/environment/visual_enviro.cxx
23  *      simgear/ephemeris/ephemeris.cxx
24  *      simgear/ephemeris/ephemeris.hxx simgear/ephemeris/stardata.cxx
25  *      simgear/ephemeris/stardata.hxx simgear/math/SGMatrix.hxx
26  *      simgear/math/SGQuat.hxx simgear/math/SGVec3.hxx
27  *      simgear/math/SGVec4.hxx simgear/scene/Makefile.am
28  *      simgear/scene/material/mat.cxx simgear/scene/material/mat.hxx
29  *      simgear/scene/material/matlib.cxx
30  *      simgear/scene/material/matlib.hxx
31  *      simgear/scene/material/matmodel.cxx
32  *      simgear/scene/material/matmodel.hxx
33  *      simgear/scene/model/Makefile.am
34  *      simgear/scene/model/animation.cxx
35  *      simgear/scene/model/animation.hxx
36  *      simgear/scene/model/custtrans.hxx
37  *      simgear/scene/model/model.cxx simgear/scene/model/model.hxx
38  *      simgear/scene/model/modellib.cxx
39  *      simgear/scene/model/modellib.hxx
40  *      simgear/scene/model/personality.cxx
41  *      simgear/scene/model/personality.hxx
42  *      simgear/scene/model/placement.cxx
43  *      simgear/scene/model/placement.hxx
44  *      simgear/scene/model/placementtrans.cxx
45  *      simgear/scene/model/placementtrans.hxx
46  *      simgear/scene/model/shadanim.cxx
47  *      simgear/scene/model/shadowvolume.hxx
48  *      simgear/scene/sky/cloud.cxx simgear/scene/sky/cloud.hxx
49  *      simgear/scene/sky/cloudfield.cxx simgear/scene/sky/dome.cxx
50  *      simgear/scene/sky/dome.hxx simgear/scene/sky/moon.cxx
51  *      simgear/scene/sky/moon.hxx simgear/scene/sky/newcloud.cxx
52  *      simgear/scene/sky/oursun.cxx simgear/scene/sky/oursun.hxx
53  *      simgear/scene/sky/sky.cxx simgear/scene/sky/sky.hxx
54  *      simgear/scene/sky/sphere.cxx simgear/scene/sky/sphere.hxx
55  *      simgear/scene/sky/stars.cxx simgear/scene/sky/stars.hxx
56  *      simgear/scene/tgdb/apt_signs.cxx
57  *      simgear/scene/tgdb/apt_signs.hxx simgear/scene/tgdb/leaf.cxx
58  *      simgear/scene/tgdb/leaf.hxx simgear/scene/tgdb/obj.cxx
59  *      simgear/scene/tgdb/obj.hxx simgear/scene/tgdb/pt_lights.cxx
60  *      simgear/scene/tgdb/pt_lights.hxx
61  *      simgear/scene/tgdb/userdata.cxx
62  *      simgear/scene/tgdb/userdata.hxx simgear/scene/tgdb/vasi.hxx
63  *      simgear/screen/jpgfactory.cxx simgear/screen/tr.cxx
64  *      simgear/structure/Makefile.am simgear/threads/SGThread.hxx
65  * Added Files:
66  *      simgear/scene/util/Makefile.am
67  *      simgear/scene/util/SGDebugDrawCallback.hxx
68  *      simgear/scene/util/SGNodeMasks.hxx
69  *      simgear/scene/util/SGStateAttributeVisitor.hxx
70  *      simgear/scene/util/SGTextureStateAttributeVisitor.hxx
71  *      simgear/scene/util/SGUpdateVisitor.hxx
72  * Removed Files:
73  *      simgear/screen/ssgEntityArray.cxx
74  *      simgear/screen/ssgEntityArray.hxx
75  *      simgear/structure/ssgSharedPtr.hxx
76  *      Big BLOB on the way to OSG.
77  *
78  * Revision 1.3  2006-02-21 10:47:21  ehofman
79  * Back out the previous patch.
80  *
81  * Revision 1.2  2004/11/18 19:10:34  curt
82  * Abstract out location of gl.h, glut.h, and glu.h includes so that we can
83  * make the Mac platform happy since they put these in a different place compared
84  * to the rest of the world.
85  *
86  * Revision 1.1.1.1  2002/09/07 02:58:19  curt
87  * Initial revsion of Simgear-0.3.0
88  *
89  * Revision 1.3  2001/07/30 20:34:21  curt
90  * Various MSVC fixes.
91  *
92  * Revision 1.2  2001/06/27 02:48:01  curt
93  * Fixed a type conversion bug that could trip up some of the pickier compilers
94  * out there.
95  *
96  * Revision 1.1  2001/06/26 15:19:39  curt
97  * Added tr.cxx / tr.h, Brian Paul's LGPL'd tiled rendering support libs for
98  * rendering ultra high res "tiled" screen shots.
99  *
100  * Revision 1.9  1998/01/29  16:56:54  brianp
101  * allow trOrtho() and trFrustum() to be called at any time, minor clean-up
102  *
103  * Revision 1.8  1998/01/28  19:47:39  brianp
104  * minor clean-up for C++
105  *
106  * Revision 1.7  1997/07/21  17:34:38  brianp
107  * added tile borders
108  *
109  * Revision 1.6  1997/07/21  15:47:35  brianp
110  * renamed all "near" and "far" variables
111  *
112  * Revision 1.5  1997/04/26  21:23:25  brianp
113  * added trRasterPos3f function
114  *
115  * Revision 1.4  1997/04/26  19:59:36  brianp
116  * set CurrentTile to -1 before first tile and after last tile
117  *
118  * Revision 1.3  1997/04/22  23:51:15  brianp
119  * added WIN32 header stuff, removed tabs
120  *
121  * Revision 1.2  1997/04/19  23:26:10  brianp
122  * many API changes
123  *
124  * Revision 1.1  1997/04/18  21:53:05  brianp
125  * Initial revision
126  *
127  */
128
129
130 /*
131  * Tiled Rendering library
132  * Version 1.1
133  * Copyright (C) Brian Paul
134  */
135
136
137 #include <simgear/compiler.h>
138
139 #include <assert.h>
140 #include <math.h>
141 #include <stdlib.h>
142 #include <stdio.h>
143 #ifdef WIN32
144 #include <windows.h>
145 #endif
146
147 #include <osg/GLU>
148
149 #include "tr.h"
150
151
152 #define DEFAULT_TILE_WIDTH  256
153 #define DEFAULT_TILE_HEIGHT 256
154 #define DEFAULT_TILE_BORDER 0
155
156
157 struct _TRctx {
158    /* Final image parameters */
159    GLint ImageWidth, ImageHeight;
160    GLenum ImageFormat, ImageType;
161    GLvoid *ImageBuffer;
162
163    /* Tile parameters */
164    GLint TileWidth, TileHeight;
165    GLint TileWidthNB, TileHeightNB;
166    GLint TileBorder;
167    GLenum TileFormat, TileType;
168    GLvoid *TileBuffer;
169
170    /* Projection parameters */
171    GLboolean Perspective;
172    GLdouble Left;
173    GLdouble Right;
174    GLdouble Bottom;
175    GLdouble Top;
176    GLdouble Near;
177    GLdouble Far;
178
179    /* Misc */
180    TRenum RowOrder;
181    GLint Rows, Columns;
182    GLint CurrentTile;
183    GLint CurrentTileWidth, CurrentTileHeight;
184    GLint CurrentRow, CurrentColumn;
185
186    GLint ViewportSave[4];
187 };
188
189
190
191 /*
192  * Misc setup including computing number of tiles (rows and columns).
193  */
194 static void Setup(TRcontext *tr)
195 {
196    if (!tr)
197       return;
198
199    tr->Columns = (tr->ImageWidth + tr->TileWidthNB - 1) / tr->TileWidthNB;
200    tr->Rows = (tr->ImageHeight + tr->TileHeightNB - 1) / tr->TileHeightNB;
201    tr->CurrentTile = 0;
202
203    assert(tr->Columns >= 0);
204    assert(tr->Rows >= 0);
205 }
206
207
208
209 TRcontext *trNew(void)
210 {
211    TRcontext *tr = (TRcontext *) calloc(1, sizeof(TRcontext));
212    if (tr) {
213       tr->TileWidth = DEFAULT_TILE_WIDTH;
214       tr->TileHeight = DEFAULT_TILE_HEIGHT;
215       tr->TileBorder = DEFAULT_TILE_BORDER;
216       tr->RowOrder = TR_BOTTOM_TO_TOP;
217       tr->CurrentTile = -1;
218    }
219    return (TRcontext *) tr;
220 }
221
222
223 void trDelete(TRcontext *tr)
224 {
225    if (tr)
226       free(tr);
227 }
228
229
230
231 void trTileSize(TRcontext *tr, GLint width, GLint height, GLint border)
232 {
233    if (!tr)
234       return;
235
236    assert(border >= 0);
237    assert(width >= 1);
238    assert(height >= 1);
239    assert(width >= 2*border);
240    assert(height >= 2*border);
241
242    tr->TileBorder = border;
243    tr->TileWidth = width;
244    tr->TileHeight = height;
245    tr->TileWidthNB = width - 2 * border;
246    tr->TileHeightNB = height - 2 * border;
247    Setup(tr);
248 }
249
250
251
252 void trTileBuffer(TRcontext *tr, GLenum format, GLenum type, GLvoid *image)
253 {
254    if (!tr)
255       return;
256
257    tr->TileFormat = format;
258    tr->TileType = type;
259    tr->TileBuffer = image;
260 }
261
262
263
264 void trImageSize(TRcontext *tr, GLint width, GLint height)
265 {
266    if (!tr)
267       return;
268
269    tr->ImageWidth = width;
270    tr->ImageHeight = height;
271    Setup(tr);
272 }
273
274
275 void trImageBuffer(TRcontext *tr, GLenum format, GLenum type, GLvoid *image)
276 {
277    if (!tr)
278       return;
279
280    tr->ImageFormat = format;
281    tr->ImageType = type;
282    tr->ImageBuffer = image;
283 }
284
285
286 GLint trGet(TRcontext *tr, TRenum param)
287 {
288    if (!tr)
289       return 0;
290    switch (param) {
291       case TR_TILE_WIDTH:
292          return tr->TileWidth;
293       case TR_TILE_HEIGHT:
294          return tr->TileHeight;
295       case TR_TILE_BORDER:
296          return tr->TileBorder;
297       case TR_IMAGE_WIDTH:
298          return tr->ImageWidth;
299       case TR_IMAGE_HEIGHT:
300          return tr->ImageHeight;
301       case TR_ROWS:
302          return tr->Rows;
303       case TR_COLUMNS:
304          return tr->Columns;
305       case TR_CURRENT_ROW:
306          if (tr->CurrentTile<0)
307             return -1;
308          else
309             return tr->CurrentRow;
310       case TR_CURRENT_COLUMN:
311          if (tr->CurrentTile<0)
312             return -1;
313          else
314             return tr->CurrentColumn;
315       case TR_CURRENT_TILE_WIDTH:
316          return tr->CurrentTileWidth;
317       case TR_CURRENT_TILE_HEIGHT:
318          return tr->CurrentTileHeight;
319       case TR_ROW_ORDER:
320          return (GLint) tr->RowOrder;
321       default:
322          return 0;
323    }
324 }
325
326 GLdouble trGetD(TRcontext *tr, TRenum param)
327 {
328         if (!tr)
329                 return 0.0;
330         switch (param) {
331         case TR_LEFT:
332                 return tr->Left;
333         case TR_RIGHT:
334                 return tr->Right;
335         case TR_BOTTOM:
336                 return tr->Bottom;
337         case TR_TOP:
338                 return tr->Top;
339         case TR_NEAR:
340                 return tr->Near;
341         case TR_FAR:
342                 return tr->Far;
343         default:
344                 return 0.0;
345         }
346 }
347
348 void trRowOrder(TRcontext *tr, TRenum order)
349 {
350    if (!tr)
351       return;
352
353    if (order==TR_TOP_TO_BOTTOM || order==TR_BOTTOM_TO_TOP)
354       tr->RowOrder = order;
355 }
356
357
358 void trOrtho(TRcontext *tr,
359              GLdouble left, GLdouble right,
360              GLdouble bottom, GLdouble top,
361              GLdouble zNear, GLdouble zFar)
362 {
363    if (!tr)
364       return;
365
366    tr->Perspective = GL_FALSE;
367    tr->Left = left;
368    tr->Right = right;
369    tr->Bottom = bottom;
370    tr->Top = top;
371    tr->Near = zNear;
372    tr->Far = zFar;
373 }
374
375
376 void trFrustum(TRcontext *tr,
377                GLdouble left, GLdouble right,
378                GLdouble bottom, GLdouble top,
379                GLdouble zNear, GLdouble zFar)
380 {
381    if (!tr)
382       return;
383
384    tr->Perspective = GL_TRUE;
385    tr->Left = left;
386    tr->Right = right;
387    tr->Bottom = bottom;
388    tr->Top = top;
389    tr->Near = zNear;
390    tr->Far = zFar;
391 }
392
393
394 void trPerspective(TRcontext *tr,
395                    GLdouble fovy, GLdouble aspect,
396                    GLdouble zNear, GLdouble zFar )
397 {
398    GLdouble xmin, xmax, ymin, ymax;
399    ymax = zNear * tan(fovy * 3.14159265 / 360.0);
400    ymin = -ymax;
401    xmin = ymin * aspect;
402    xmax = ymax * aspect;
403    trFrustum(tr, xmin, xmax, ymin, ymax, zNear, zFar);
404 }
405
406
407 void trBeginTile(TRcontext *tr)
408 {
409    GLint matrixMode;
410    GLint tileWidth, tileHeight, border;
411    GLdouble left, right, bottom, top;
412
413    if (!tr)
414       return;
415
416    if (tr->CurrentTile <= 0) {
417       Setup(tr);
418       /* Save user's viewport, will be restored after last tile rendered */
419       glGetIntegerv(GL_VIEWPORT, tr->ViewportSave);
420    }
421
422    /* which tile (by row and column) we're about to render */
423    if (tr->RowOrder==TR_BOTTOM_TO_TOP) {
424       tr->CurrentRow = tr->CurrentTile / tr->Columns;
425       tr->CurrentColumn = tr->CurrentTile % tr->Columns;
426    }
427    else if (tr->RowOrder==TR_TOP_TO_BOTTOM) {
428       tr->CurrentRow = tr->Rows - (tr->CurrentTile / tr->Columns) - 1;
429       tr->CurrentColumn = tr->CurrentTile % tr->Columns;
430    }
431    else {
432       /* This should never happen */
433       abort();
434    }
435    assert(tr->CurrentRow < tr->Rows);
436    assert(tr->CurrentColumn < tr->Columns);
437
438    border = tr->TileBorder;
439
440    /* Compute actual size of this tile with border */
441    if (tr->CurrentRow < tr->Rows-1)
442       tileHeight = tr->TileHeight;
443    else
444       tileHeight = tr->ImageHeight - (tr->Rows-1) * (tr->TileHeightNB) + 2 * border;
445
446    if (tr->CurrentColumn < tr->Columns-1)
447       tileWidth = tr->TileWidth;
448    else
449       tileWidth = tr->ImageWidth - (tr->Columns-1) * (tr->TileWidthNB) + 2 * border;
450
451    /* Save tile size, with border */
452    tr->CurrentTileWidth = tileWidth;
453    tr->CurrentTileHeight = tileHeight;
454
455    glViewport(0, 0, tileWidth, tileHeight);  /* tile size including border */
456
457    /* save current matrix mode */
458    glGetIntegerv(GL_MATRIX_MODE, &matrixMode);
459    glMatrixMode(GL_PROJECTION);
460    glLoadIdentity();
461
462    /* compute projection parameters */
463    left = tr->Left + (tr->Right - tr->Left)
464         * (tr->CurrentColumn * tr->TileWidthNB - border) / tr->ImageWidth;
465    right = left + (tr->Right - tr->Left) * tileWidth / tr->ImageWidth;
466    bottom = tr->Bottom + (tr->Top - tr->Bottom)
467           * (tr->CurrentRow * tr->TileHeightNB - border) / tr->ImageHeight;
468    top = bottom + (tr->Top - tr->Bottom) * tileHeight / tr->ImageHeight;
469
470    // OSGFIXME
471 //    ssgSetFrustum ( left, right, bottom, top, tr->Near, tr->Far );
472
473    /* restore user's matrix mode */
474    glMatrixMode( (GLenum)matrixMode );
475 }
476
477
478
479 int trEndTile(TRcontext *tr)
480 {
481    GLint prevRowLength, prevSkipRows, prevSkipPixels /*, prevAlignment */;
482
483    if (!tr)
484       return 0;
485
486    assert(tr->CurrentTile>=0);
487
488    /* be sure OpenGL rendering is finished */
489    glFlush();
490
491    /* save current glPixelStore values */
492    glGetIntegerv(GL_PACK_ROW_LENGTH, &prevRowLength);
493    glGetIntegerv(GL_PACK_SKIP_ROWS, &prevSkipRows);
494    glGetIntegerv(GL_PACK_SKIP_PIXELS, &prevSkipPixels);
495    /*glGetIntegerv(GL_PACK_ALIGNMENT, &prevAlignment);*/
496
497    if (tr->TileBuffer) {
498       GLint srcX = tr->TileBorder;
499       GLint srcY = tr->TileBorder;
500       GLint srcWidth = tr->TileWidthNB;
501       GLint srcHeight = tr->TileHeightNB;
502       glReadPixels(srcX, srcY, srcWidth, srcHeight,
503                    tr->TileFormat, tr->TileType, tr->TileBuffer);
504    }
505
506    if (tr->ImageBuffer) {
507       GLint srcX = tr->TileBorder;
508       GLint srcY = tr->TileBorder;
509       GLint srcWidth = tr->CurrentTileWidth - 2 * tr->TileBorder;
510       GLint srcHeight = tr->CurrentTileHeight - 2 * tr->TileBorder;
511       GLint destX = tr->TileWidthNB * tr->CurrentColumn;
512       GLint destY = tr->TileHeightNB * tr->CurrentRow;
513
514       /* setup pixel store for glReadPixels */
515       glPixelStorei(GL_PACK_ROW_LENGTH, tr->ImageWidth);
516       glPixelStorei(GL_PACK_SKIP_ROWS, destY);
517       glPixelStorei(GL_PACK_SKIP_PIXELS, destX);
518       /*glPixelStorei(GL_PACK_ALIGNMENT, 1);*/
519
520       /* read the tile into the final image */
521       glReadPixels(srcX, srcY, srcWidth, srcHeight,
522                    tr->ImageFormat, tr->ImageType, tr->ImageBuffer);
523    }
524
525    /* restore previous glPixelStore values */
526    glPixelStorei(GL_PACK_ROW_LENGTH, prevRowLength);
527    glPixelStorei(GL_PACK_SKIP_ROWS, prevSkipRows);
528    glPixelStorei(GL_PACK_SKIP_PIXELS, prevSkipPixels);
529    /*glPixelStorei(GL_PACK_ALIGNMENT, prevAlignment);*/
530
531    /* increment tile counter, return 1 if more tiles left to render */
532    tr->CurrentTile++;
533    if (tr->CurrentTile >= tr->Rows * tr->Columns) {
534       /* restore user's viewport */
535       glViewport(tr->ViewportSave[0], tr->ViewportSave[1],
536                  tr->ViewportSave[2], tr->ViewportSave[3]);
537       tr->CurrentTile = -1;  /* all done */
538       return 0;
539    }
540    else
541       return 1;
542 }
543
544
545 /*
546  * Replacement for glRastePos3f() which avoids the problem with invalid
547  * raster pos.
548  */
549 void trRasterPos3f(TRcontext *tr, GLfloat x, GLfloat y, GLfloat z)
550 {
551    if (tr->CurrentTile<0) {
552       /* not doing tile rendering right now.  Let OpenGL do this. */
553       glRasterPos3f(x, y, z);
554    }
555    else {
556       GLdouble modelview[16], proj[16];
557       GLint viewport[4];
558       GLdouble winX, winY, winZ;
559
560       /* Get modelview, projection and viewport */
561       glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
562       glGetDoublev(GL_PROJECTION_MATRIX, proj);
563       viewport[0] = 0;
564       viewport[1] = 0;
565       viewport[2] = tr->CurrentTileWidth;
566       viewport[3] = tr->CurrentTileHeight;
567
568       /* Project object coord to window coordinate */
569       if (gluProject(x, y, z, modelview, proj, viewport, &winX, &winY, &winZ)){
570
571          /* set raster pos to window coord (0,0) */
572          glMatrixMode(GL_MODELVIEW);
573          glPushMatrix();
574          glLoadIdentity();
575          glMatrixMode(GL_PROJECTION);
576          glPushMatrix();
577          glLoadIdentity();
578          glOrtho(0.0, tr->CurrentTileWidth,
579                  0.0, tr->CurrentTileHeight, 0.0, 1.0);
580          glRasterPos3f(0.0, 0.0, -winZ);
581
582          /* Now use empty bitmap to adjust raster position to (winX,winY) */
583          {
584             GLubyte bitmap[1] = {0};
585             glBitmap(1, 1, 0.0, 0.0, winX, winY, bitmap);
586          }
587
588          /* restore original matrices */
589          glPopMatrix(); /*proj*/
590          glMatrixMode(GL_MODELVIEW);
591          glPopMatrix();
592       }
593 #ifdef DEBUG
594       if (glGetError())
595          printf("GL error!\n");
596 #endif
597    }
598 }
599