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