gsub_lite.c
Go to the documentation of this file.
00001 /*
00002  *      gsub_lite.c
00003  *
00004  *      Graphics Subroutines (Lite) for ARToolKit.
00005  *
00006  *      Copyright (c) 2003-2007 Philip Lamb (PRL) phil@eden.net.nz. All rights reserved.
00007  *      
00008  *      Rev             Date            Who             Changes
00009  *  2.7.0   2003-08-13  PRL     Complete rewrite to ARToolKit-2.65 gsub.c API.
00010  *  2.7.1   2004-03-03  PRL             Avoid defining BOOL if already defined
00011  *      2.7.1   2004-03-03      PRL             Don't enable lighting if it was not enabled.
00012  *      2.7.2   2004-04-27      PRL             Added headerdoc markup. See http://developer.apple.com/darwin/projects/headerdoc/
00013  *      2.7.3   2004-07-02      PRL             Much more object-orientated through use of ARGL_CONTEXT_SETTINGS type.
00014  *      2.7.4   2004-07-14      PRL             Added gluCheckExtension hack for GLU versions pre-1.3.
00015  *      2.7.5   2004-07-15      PRL             Added arglDispImageStateful(); removed extraneous glPixelStorei(GL_UNPACK_IMAGE_HEIGHT,...) calls.
00016  *      2.7.6   2005-02-18      PRL             Go back to using int rather than BOOL, to avoid conflict with Objective-C.
00017  *      2.7.7   2005-07-26      PRL             Added cleanup routines for texture stuff.
00018  *      2.7.8   2005-07-29      PRL             Added distortion compensation enabling/disabling.
00019  *      2.7.9   2005-08-15      PRL             Added complete support for runtime selection of pixel format and rectangle/power-of-2 textures.
00020  *      2.8.0   2006-04-04      PRL             Move pixel format constants into toolkit global namespace (in config.h).
00021  *      2.8.1   2006-04-06      PRL             Move arglDrawMode, arglTexmapMode, arglTexRectangle out of global variables.
00022  *  2.8.2   2006-06-12  PRL             More stringent runtime GL caps checking. Fix zoom for DRAWPIXELS mode.
00023  *
00024  */
00025 /*
00026  * 
00027  * This file is part of ARToolKit.
00028  * 
00029  * ARToolKit is free software; you can redistribute it and/or modify
00030  * it under the terms of the GNU General Public License as published by
00031  * the Free Software Foundation; either version 2 of the License, or
00032  * (at your option) any later version.
00033  * 
00034  * ARToolKit is distributed in the hope that it will be useful,
00035  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00036  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00037  * GNU General Public License for more details.
00038  * 
00039  * You should have received a copy of the GNU General Public License
00040  * along with ARToolKit; if not, write to the Free Software
00041  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00042  * 
00043  */
00044 
00045 // ============================================================================
00046 //      Private includes.
00047 // ============================================================================
00048 #include <AR/gsub_lite.h>
00049 
00050 #include <stdio.h>              // fprintf(), stderr
00051 #include <string.h>             // strchr(), strstr(), strlen()
00052 #ifndef __APPLE__
00053 #  include <GL/glu.h>
00054 #  ifdef GL_VERSION_1_2
00055 #    include <GL/glext.h>
00056 #  endif
00057 #else
00058 #  include <OpenGL/glu.h>
00059 #  include <OpenGL/glext.h>
00060 #endif
00061 
00062 // ============================================================================
00063 //      Private types and defines.
00064 // ============================================================================
00065 #ifdef _MSC_VER
00066 #  pragma warning (disable:4068)        // Disable MSVC warnings about unknown pragmas.
00067 #endif
00068 
00069 // Make sure that required OpenGL constant definitions are available at compile-time.
00070 // N.B. These should not be used unless the renderer indicates (at run-time) that it supports them.
00071 
00072 // Define constants for extensions which became core in OpenGL 1.2
00073 #ifndef GL_VERSION_1_2
00074 #  if GL_EXT_bgra
00075 #    define GL_BGR                                                      GL_BGR_EXT
00076 #    define GL_BGRA                                                     GL_BGRA_EXT
00077 #  else
00078 #    define GL_BGR                                                      0x80E0
00079 #    define GL_BGRA                                                     0x80E1
00080 #  endif
00081 #  ifndef GL_APPLE_packed_pixels
00082 #    define GL_UNSIGNED_INT_8_8_8_8                     0x8035
00083 #    define GL_UNSIGNED_INT_8_8_8_8_REV         0x8367
00084 #  endif
00085 #  if GL_SGIS_texture_edge_clamp
00086 #    define GL_CLAMP_TO_EDGE                            GL_CLAMP_TO_EDGE_SGIS
00087 #  else
00088 #    define GL_CLAMP_TO_EDGE                            0x812F
00089 #  endif
00090 #endif
00091 
00092 // Define constants for extensions (not yet core).
00093 #ifndef GL_APPLE_ycbcr_422
00094 #  define GL_YCBCR_422_APPLE                            0x85B9
00095 #  define GL_UNSIGNED_SHORT_8_8_APPLE           0x85BA
00096 #  define GL_UNSIGNED_SHORT_8_8_REV_APPLE       0x85BB
00097 #endif
00098 #ifndef GL_EXT_abgr
00099 #  define GL_ABGR_EXT                                           0x8000
00100 #endif
00101 #if GL_NV_texture_rectangle
00102 #  define GL_TEXTURE_RECTANGLE                          GL_TEXTURE_RECTANGLE_NV
00103 #  define GL_PROXY_TEXTURE_RECTANGLE            GL_PROXY_TEXTURE_RECTANGLE_NV
00104 #  define GL_MAX_RECTANGLE_TEXTURE_SIZE         GL_MAX_RECTANGLE_TEXTURE_SIZE_NV
00105 #elif GL_EXT_texture_rectangle
00106 #  define GL_TEXTURE_RECTANGLE                          GL_TEXTURE_RECTANGLE_EXT
00107 #  define GL_PROXY_TEXTURE_RECTANGLE            GL_PROXY_TEXTURE_RECTANGLE_EXT
00108 #  define GL_MAX_RECTANGLE_TEXTURE_SIZE         GL_MAX_RECTANGLE_TEXTURE_SIZE_EXT
00109 #else
00110 #  define GL_TEXTURE_RECTANGLE                          0x84F5
00111 #  define GL_PROXY_TEXTURE_RECTANGLE            0x84F7
00112 #  define GL_MAX_RECTANGLE_TEXTURE_SIZE         0x84F8
00113 #endif
00114 #ifndef GL_MESA_ycbcr_texture
00115 #  define GL_YCBCR_MESA                                         0x8757
00116 #  define GL_UNSIGNED_SHORT_8_8_MESA            0x85BA
00117 #  define GL_UNSIGNED_SHORT_8_8_REV_MESA        0x85BB
00118 #endif
00119 
00120 //#define ARGL_DEBUG
00121 
00122 struct _ARGL_CONTEXT_SETTINGS {
00123         int             texturePow2CapabilitiesChecked;
00124         GLuint  texturePow2;
00125         GLuint  listPow2;
00126         int             initedPow2;
00127         int             textureRectangleCapabilitiesChecked;
00128         GLuint  textureRectangle;
00129         GLuint  listRectangle;
00130         int             initedRectangle;
00131         int             initPlease;             // Set to TRUE to request re-init of texture etc.
00132         int             asInited_texmapScaleFactor;
00133         float   asInited_zoom;
00134         int             asInited_xsize;
00135         int             asInited_ysize;
00136         GLsizei texturePow2SizeX;
00137         GLsizei texturePow2SizeY;
00138         GLenum  texturePow2WrapMode;
00139         int             disableDistortionCompensation;
00140         GLenum  pixIntFormat;
00141         GLenum  pixFormat;
00142         GLenum  pixType;
00143         GLenum  pixSize;
00144         int     arglDrawMode;
00145         int     arglTexmapMode;
00146         int arglTexRectangle;   
00147 };
00148 typedef struct _ARGL_CONTEXT_SETTINGS ARGL_CONTEXT_SETTINGS;
00149 
00150 // ============================================================================
00151 //      Public globals.
00152 // ============================================================================
00153 
00154 // These items relate to Apple's fast texture transfer support.
00155 #ifdef __APPLE__
00156 #  ifdef APPLE_TEXTURE_FAST_TRANSFER
00157 int arglAppleClientStorage = TRUE;
00158 int arglAppleTextureRange = TRUE;
00159 #  else
00160 int arglAppleClientStorage = FALSE;
00161 int arglAppleTextureRange = FALSE;
00162 #  endif // APPLE_TEXTURE_FAST_TRANSFER
00163 #endif // __APPLE__
00164 
00165 // ============================================================================
00166 //      Private globals.
00167 // ============================================================================
00168 
00169 
00170 #pragma mark -
00171 // ============================================================================
00172 //      Private functions.
00173 // ============================================================================
00174 
00175 //
00176 //  Provide a gluCheckExtension() function, since some platforms don't have GLU version 1.3 or later.
00177 //
00178 GLboolean arglGluCheckExtension(const GLubyte* extName, const GLubyte *extString)
00179 {
00180         const GLubyte *start;
00181         GLubyte *where, *terminator;
00182         
00183         // Extension names should not have spaces.
00184         where = (GLubyte *)strchr((const char *)extName, ' ');
00185         if (where || *extName == '\0')
00186                 return GL_FALSE;
00187         // It takes a bit of care to be fool-proof about parsing the
00188         //      OpenGL extensions string. Don't be fooled by sub-strings, etc.
00189         start = extString;
00190         for (;;) {
00191                 where = (GLubyte *) strstr((const char *)start, (const char *)extName);
00192                 if (!where)
00193                         break;
00194                 terminator = where + strlen((const char *)extName);
00195                 if (where == start || *(where - 1) == ' ')
00196                         if (*terminator == ' ' || *terminator == '\0')
00197                                 return GL_TRUE;
00198                 start = terminator;
00199         }
00200         return GL_FALSE;
00201 }
00202 
00203 //
00204 //  Checks for the presence of an OpenGL capability by version or extension.
00205 //  Reports whether the current OpenGL driver's OpenGL implementation version
00206 //  meets or exceeds a minimum value passed in in minVersion (represented as a binary-coded
00207 //  decimal i.e. version 1.0 is represented as 0x0100). If minVersion is zero, the
00208 //  version test will always fail. Alternately, the test is satisfied if an OpenGL extension
00209 //  identifier passed in as a character string
00210 //  is non-NULL, and is found in the current driver's list of supported extensions.
00211 //  Returns: TRUE If either of the tests passes, or FALSE if both fail.
00212 //
00213 static int arglGLCapabilityCheck(const unsigned short minVersion, const unsigned char *extension)
00214 {
00215         const GLubyte * strRenderer;
00216         const GLubyte * strVersion;
00217         const GLubyte * strVendor;
00218         const GLubyte * strExtensions;
00219         short j, shiftVal;
00220         unsigned short version = 0; // binary-coded decimal gl version (ie. 1.4 is 0x0140).
00221         
00222         strRenderer = glGetString(GL_RENDERER);
00223         strVendor = glGetString(GL_VENDOR);
00224         strVersion = glGetString(GL_VERSION);
00225         j = 0;
00226         shiftVal = 8;
00227         // Construct BCD version.
00228         while (((strVersion[j] <= '9') && (strVersion[j] >= '0')) || (strVersion[j] == '.')) { // Get only basic version info (until first non-digit or non-.)
00229                 if ((strVersion[j] <= '9') && (strVersion[j] >= '0')) {
00230                         version += (strVersion[j] - '0') << shiftVal;
00231                         shiftVal -= 4;
00232                 }
00233                 j++;
00234         }
00235         strExtensions = glGetString(GL_EXTENSIONS);
00236         
00237         if (0 < minVersion && version >= minVersion) return (TRUE);
00238         if (extension && arglGluCheckExtension(extension, strExtensions)) return (TRUE);
00239         return (FALSE);
00240 }
00241 
00242 static int arglDispImageTexPow2CapabilitiesCheck(const ARParam *cparam, ARGL_CONTEXT_SETTINGS_REF contextSettings)
00243 {
00244         GLint format;
00245         GLint texture1SizeMax;
00246 
00247         glGetIntegerv(GL_MAX_TEXTURE_SIZE, &texture1SizeMax);
00248         if (cparam->xsize > texture1SizeMax || cparam->ysize > texture1SizeMax) {
00249                 return (FALSE);
00250         }
00251         
00252         // Work out how big textures needs to be.
00253         contextSettings->texturePow2SizeX = contextSettings->texturePow2SizeY = 1;
00254         while (contextSettings->texturePow2SizeX < cparam->xsize) {
00255                 contextSettings->texturePow2SizeX *= 2;
00256                 if (contextSettings->texturePow2SizeX > texture1SizeMax) {
00257                         return (FALSE); // Too big to handle.
00258                 }
00259         }
00260         while (contextSettings->texturePow2SizeY < cparam->ysize) {
00261                 contextSettings->texturePow2SizeY *= 2;
00262                 if (contextSettings->texturePow2SizeY > texture1SizeMax) {
00263                         return (FALSE); // Too big to handle.
00264                 }
00265         }
00266         
00267         // Now check that the renderer can accomodate a texture of this size.
00268         glTexImage2D(GL_PROXY_TEXTURE_2D, 0, contextSettings->pixIntFormat, contextSettings->texturePow2SizeX, contextSettings->texturePow2SizeY, 0, contextSettings->pixFormat, contextSettings->pixType, NULL);
00269         glGetTexLevelParameteriv(GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &format);
00270         if (!format) {
00271                 return (FALSE);
00272         }
00273         
00274         // Decide whether we can use GL_CLAMP_TO_EDGE.
00275         if (arglGLCapabilityCheck(0x0120, (unsigned char *)"GL_SGIS_texture_edge_clamp")) {
00276                 contextSettings->texturePow2WrapMode = GL_CLAMP_TO_EDGE;
00277         } else {
00278                 contextSettings->texturePow2WrapMode = GL_REPEAT;
00279         }
00280         
00281         return (TRUE);
00282 }
00283 
00284 static int arglCleanupTexPow2(ARGL_CONTEXT_SETTINGS_REF contextSettings)
00285 {
00286         if (!contextSettings->initedPow2) return (FALSE);
00287         
00288         glDeleteTextures(1, &(contextSettings->texturePow2));
00289         glDeleteLists(contextSettings->listPow2, 1);
00290         contextSettings->texturePow2CapabilitiesChecked = FALSE;
00291         contextSettings->initedPow2 = FALSE;
00292         return (TRUE);
00293 }
00294 
00295 //
00296 // Blit an image to the screen using OpenGL power-of-two texturing.
00297 //
00298 static void arglDispImageTexPow2(ARUint8 *image, const ARParam *cparam, const float zoom, ARGL_CONTEXT_SETTINGS_REF contextSettings, const int texmapScaleFactor)
00299 {
00300     float       tsx, tsy, tex, tey;
00301     float       px, py, qx, qy;
00302     double      x1, x2, x3, x4, y1, y2, y3, y4;
00303     float       xx1, xx2, xx3, xx4, yy1, yy2, yy3, yy4;
00304     int         i, j;
00305 
00306     if(!contextSettings->initedPow2 || contextSettings->initPlease) {
00307 
00308                 contextSettings->initPlease = FALSE;
00309                 // Delete previous texture and list, unless this is our first time here.
00310                 if (contextSettings->initedPow2) arglCleanupTexPow2(contextSettings);
00311 
00312                 // If we have not done so, check texturing capabilities. If they have already been
00313                 // checked, and we got to here, then obviously the capabilities were insufficient,
00314                 // so just return without doing anything.
00315                 if (!contextSettings->texturePow2CapabilitiesChecked) {
00316                         contextSettings->texturePow2CapabilitiesChecked = TRUE;
00317                         if (!arglDispImageTexPow2CapabilitiesCheck(cparam, contextSettings)) {
00318                                 printf("argl error: Your OpenGL implementation and/or hardware's texturing capabilities are insufficient.\n"); // Windows bug: when running multi-threaded, can't write to stderr!
00319                                 return;
00320                         }
00321                 } else {
00322                         return;
00323                 }
00324 
00325                 // Set up the texture object.
00326                 glGenTextures(1, &(contextSettings->texturePow2));
00327                 glBindTexture(GL_TEXTURE_2D, contextSettings->texturePow2);
00328                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
00329                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
00330                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, contextSettings->texturePow2WrapMode);
00331                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, contextSettings->texturePow2WrapMode);
00332 
00333 #ifdef APPLE_TEXTURE_FAST_TRANSFER
00334                 // Can't use client storage or texture range.
00335                 glTextureRangeAPPLE(GL_TEXTURE_2D, 0, NULL);
00336                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_STORAGE_HINT_APPLE, GL_STORAGE_PRIVATE_APPLE);
00337                 glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, FALSE);
00338 #endif // APPLE_TEXTURE_FAST_TRANSFER
00339 
00340                 // Request OpenGL allocate memory for a power-of-two texture of the appropriate size.
00341                 if (texmapScaleFactor == 2) {
00342                         // If texmapScaleFactor is 2, pretend lines in the source image are
00343                         // twice as long as they are; glTexImage2D will read only the first
00344                         // half of each line, effectively discarding every second line in the source image.
00345                         glPixelStorei(GL_UNPACK_ROW_LENGTH, cparam->xsize*texmapScaleFactor);
00346                 }
00347                 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
00348                 glTexImage2D(GL_TEXTURE_2D, 0, contextSettings->pixIntFormat, contextSettings->texturePow2SizeX, contextSettings->texturePow2SizeY/texmapScaleFactor, 0, contextSettings->pixFormat, contextSettings->pixType, NULL);
00349                 if (texmapScaleFactor == 2) {
00350                         glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
00351                 }
00352                 
00353                 // Set up the surface which we will texture upon.
00354                 contextSettings->listPow2 = glGenLists(1);
00355                 glNewList(contextSettings->listPow2, GL_COMPILE); // NB Texture not specified yet so don't execute.
00356                 glEnable(GL_TEXTURE_2D);
00357                 glMatrixMode(GL_TEXTURE);
00358                 glLoadIdentity();
00359                 glMatrixMode(GL_MODELVIEW);
00360 
00361                 if (contextSettings->disableDistortionCompensation) {
00362                         glBegin(GL_QUADS);
00363                         glTexCoord2f(0.0f, (float)cparam->ysize/(float)contextSettings->texturePow2SizeY);
00364                         glVertex2f(0.0f, 0.0f);
00365                         glTexCoord2f((float)cparam->xsize/(float)contextSettings->texturePow2SizeX, (float)cparam->ysize/(float)contextSettings->texturePow2SizeY);
00366                         glVertex2f((float)cparam->xsize * zoom, 0.0f);
00367                         glTexCoord2f((float)cparam->xsize/(float)contextSettings->texturePow2SizeX, 0.0f);
00368                         glVertex2f((float)cparam->xsize * zoom, (float)cparam->ysize * zoom);
00369                         glTexCoord2f(0.0f, 0.0f);
00370                         glVertex2f(0.0f, (float)cparam->ysize * zoom);
00371                         glEnd();
00372                 } else {
00373                         qy = 0.0f;
00374                         tey = 0.0f;
00375                         for(j = 1; j <= 20; j++) {      // Do 20 rows.
00376                                 py = qy;
00377                                 tsy = tey;
00378                                 qy = cparam->ysize * j / 20.0f;
00379                                 tey = qy / contextSettings->texturePow2SizeY;
00380                                 
00381                                 qx = 0.0f;
00382                                 tex = 0.0f;
00383                                 for(i = 1; i <= 20; i++) {      // Draw 20 columns.
00384                                         px = qx;
00385                                         tsx = tex;
00386                                         qx = cparam->xsize * i / 20.0f;
00387                                         tex = qx / contextSettings->texturePow2SizeX;
00388                                         
00389                                         arParamObserv2Ideal(cparam->dist_factor, (double)px, (double)py, &x1, &y1);
00390                                         arParamObserv2Ideal(cparam->dist_factor, (double)qx, (double)py, &x2, &y2);
00391                                         arParamObserv2Ideal(cparam->dist_factor, (double)qx, (double)qy, &x3, &y3);
00392                                         arParamObserv2Ideal(cparam->dist_factor, (double)px, (double)qy, &x4, &y4);
00393                                         
00394                                         xx1 = (float)x1 * zoom;
00395                                         yy1 = (cparam->ysize - (float)y1) * zoom;
00396                                         xx2 = (float)x2 * zoom;
00397                                         yy2 = (cparam->ysize - (float)y2) * zoom;
00398                                         xx3 = (float)x3 * zoom;
00399                                         yy3 = (cparam->ysize - (float)y3) * zoom;
00400                                         xx4 = (float)x4 * zoom;
00401                                         yy4 = (cparam->ysize - (float)y4) * zoom;
00402                                         
00403                                         glBegin(GL_QUADS);
00404                                         glTexCoord2f(tsx, tsy); glVertex2f(xx1, yy1);
00405                                         glTexCoord2f(tex, tsy); glVertex2f(xx2, yy2);
00406                                         glTexCoord2f(tex, tey); glVertex2f(xx3, yy3);
00407                                         glTexCoord2f(tsx, tey); glVertex2f(xx4, yy4);
00408                                         glEnd();
00409                                 } // columns.
00410                         } // rows.
00411                 }
00412                 glDisable(GL_TEXTURE_2D);
00413         glEndList();
00414 
00415                 contextSettings->asInited_ysize = cparam->ysize;
00416                 contextSettings->asInited_xsize = cparam->xsize;
00417                 contextSettings->asInited_zoom = zoom;
00418         contextSettings->asInited_texmapScaleFactor = texmapScaleFactor;
00419                 contextSettings->initedPow2 = TRUE;
00420         }
00421 
00422     glBindTexture(GL_TEXTURE_2D, contextSettings->texturePow2);
00423 #ifdef APPLE_TEXTURE_FAST_TRANSFER
00424         // Can't use client storage or texture range.
00425         glTextureRangeAPPLE(GL_TEXTURE_2D, 0, NULL);
00426         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_STORAGE_HINT_APPLE, GL_STORAGE_PRIVATE_APPLE);
00427         glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, FALSE);
00428 #endif // APPLE_TEXTURE_FAST_TRANSFER
00429         if (texmapScaleFactor == 2) {
00430                 // If texmapScaleFactor is 2, pretend lines in the source image are
00431                 // twice as long as they are; glTexImage2D will read only the first
00432                 // half of each line, effectively discarding every second line in the source image.
00433                 glPixelStorei(GL_UNPACK_ROW_LENGTH, cparam->xsize*texmapScaleFactor);
00434         }
00435         glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
00436         glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, cparam->xsize, cparam->ysize/texmapScaleFactor, contextSettings->pixFormat, contextSettings->pixType, image);
00437         glCallList(contextSettings->listPow2);
00438         if (texmapScaleFactor == 2) {
00439                 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
00440         }
00441     glBindTexture(GL_TEXTURE_2D, 0);
00442 }
00443 
00444 static int arglDispImageTexRectangleCapabilitiesCheck(const ARParam *cparam, ARGL_CONTEXT_SETTINGS_REF contextSettings)
00445 {
00446         GLint textureRectangleSizeMax;
00447         GLint format;
00448 
00449     if (!arglGLCapabilityCheck(0, (unsigned char *)"GL_NV_texture_rectangle")) {
00450                 if (!arglGLCapabilityCheck(0, (unsigned char *)"GL_EXT_texture_rectangle")) { // Alternate name.
00451                         return (FALSE);
00452                 }
00453         }
00454     glGetIntegerv(GL_MAX_RECTANGLE_TEXTURE_SIZE, &textureRectangleSizeMax);
00455         if (cparam->xsize > textureRectangleSizeMax || cparam->ysize > textureRectangleSizeMax) {
00456                 return (FALSE);
00457         }
00458         
00459         // Now check that the renderer can accomodate a texture of this size.
00460         glTexImage2D(GL_PROXY_TEXTURE_RECTANGLE, 0, contextSettings->pixIntFormat, cparam->xsize, cparam->ysize, 0, contextSettings->pixFormat, contextSettings->pixType, NULL);
00461         glGetTexLevelParameteriv(GL_PROXY_TEXTURE_RECTANGLE, 0, GL_TEXTURE_INTERNAL_FORMAT, &format);
00462         if (!format) {
00463                 return (FALSE);
00464         }
00465         
00466         return (TRUE);
00467 }
00468 
00469 static int arglCleanupTexRectangle(ARGL_CONTEXT_SETTINGS_REF contextSettings)
00470 {
00471         if (!contextSettings->initedRectangle) return (FALSE);
00472         
00473         glDeleteTextures(1, &(contextSettings->textureRectangle));
00474         glDeleteLists(contextSettings->listRectangle, 1);
00475         contextSettings->textureRectangleCapabilitiesChecked = FALSE;
00476         contextSettings->initedRectangle = FALSE;
00477         return (TRUE);
00478 }
00479 
00480 //
00481 // Blit an image to the screen using OpenGL rectangle texturing.
00482 //
00483 static void arglDispImageTexRectangle(ARUint8 *image, const ARParam *cparam, const float zoom, ARGL_CONTEXT_SETTINGS_REF contextSettings, const int texmapScaleFactor)
00484 {
00485         float   px, py, py_prev;
00486     double      x1, x2, y1, y2;
00487     float       xx1, xx2, yy1, yy2;
00488         int             i, j;
00489         
00490     if(!contextSettings->initedRectangle || contextSettings->initPlease) {
00491                 
00492                 contextSettings->initPlease = FALSE;
00493                 // Delete previous texture and list, unless this is our first time here.
00494                 if (contextSettings->initedRectangle) arglCleanupTexRectangle(contextSettings);
00495                 
00496                 // If we have not done so, check texturing capabilities. If they have already been
00497                 // checked, and we got to here, then obviously the capabilities were insufficient,
00498                 // so just return without doing anything.
00499                 if (!contextSettings->textureRectangleCapabilitiesChecked) {
00500                         contextSettings->textureRectangleCapabilitiesChecked = TRUE;
00501                         if (!arglDispImageTexRectangleCapabilitiesCheck(cparam, contextSettings)) {
00502                                 printf("argl error: Your OpenGL implementation and/or hardware's texturing capabilities are insufficient to support rectangle textures.\n"); // Windows bug: when running multi-threaded, can't write to stderr!
00503                                 // Fall back to power of 2 texturing.
00504                                 contextSettings->arglTexRectangle = FALSE;
00505                                 arglDispImageTexPow2(image, cparam, zoom, contextSettings, texmapScaleFactor);
00506                                 return;
00507                         }
00508                 } else {
00509                         return;
00510                 }
00511                 
00512                 // Set up the rectangle texture object.
00513                 glGenTextures(1, &(contextSettings->textureRectangle));
00514                 glBindTexture(GL_TEXTURE_RECTANGLE, contextSettings->textureRectangle);
00515                 glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
00516                 glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
00517                 glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
00518                 glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
00519 
00520 #ifdef APPLE_TEXTURE_FAST_TRANSFER
00521                 if (arglAppleTextureRange) {
00522                         glTextureRangeAPPLE(GL_TEXTURE_RECTANGLE, cparam->xsize * cparam->ysize * contextSettings->pixSize, image);
00523                         glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_STORAGE_HINT_APPLE, GL_STORAGE_SHARED_APPLE);
00524                 } else {
00525                         glTextureRangeAPPLE(GL_TEXTURE_RECTANGLE, 0, NULL);
00526                         glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_STORAGE_HINT_APPLE, GL_STORAGE_PRIVATE_APPLE);
00527                 }
00528                 glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, arglAppleClientStorage);
00529 #endif // APPLE_TEXTURE_FAST_TRANSFER
00530                 
00531                 // Specify the texture to OpenGL.
00532                 if (texmapScaleFactor == 2) {
00533                         // If texmapScaleFactor is 2, pretend lines in the source image are
00534                         // twice as long as they are; glTexImage2D will read only the first
00535                         // half of each line, effectively discarding every second line in the source image.
00536                         glPixelStorei(GL_UNPACK_ROW_LENGTH, cparam->xsize*texmapScaleFactor);
00537                 }
00538                 glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // Our image data is tightly packed.
00539                 glTexImage2D(GL_TEXTURE_RECTANGLE, 0, contextSettings->pixIntFormat, cparam->xsize, cparam->ysize/texmapScaleFactor, 0, contextSettings->pixFormat, contextSettings->pixType, image);
00540                 if (texmapScaleFactor == 2) {
00541                         glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
00542                 }
00543                 
00544                 // Set up the surface which we will texture upon.
00545                 contextSettings->listRectangle = glGenLists(1);
00546                 glNewList(contextSettings->listRectangle, GL_COMPILE);
00547                 glEnable(GL_TEXTURE_RECTANGLE);
00548                 glMatrixMode(GL_TEXTURE);
00549                 glLoadIdentity();
00550                 glMatrixMode(GL_MODELVIEW);
00551                 
00552                 if (contextSettings->disableDistortionCompensation) {
00553                         glBegin(GL_QUADS);
00554                         glTexCoord2f(0.0f, (float)(cparam->ysize/texmapScaleFactor)); glVertex2f(0.0f, 0.0f);
00555                         glTexCoord2f((float)(cparam->xsize), (float)(cparam->ysize/texmapScaleFactor)); glVertex2f(cparam->xsize * zoom, 0.0f);
00556                         glTexCoord2f((float)(cparam->xsize), 0.0f); glVertex2f(cparam->xsize * zoom, cparam->ysize * zoom);
00557                         glTexCoord2f(0.0f, 0.0f); glVertex2f(0.0f, cparam->ysize * zoom);
00558                         glEnd();
00559                 } else {
00560                         py_prev = 0.0f;
00561                         for(j = 1; j <= 20; j++) {      // Do 20 rows.
00562                                 py = py_prev;
00563                                 py_prev = cparam->ysize * j / 20.0f;
00564                                 
00565                                 glBegin(GL_QUAD_STRIP);
00566                                 for(i = 0; i <= 20; i++) {      // Draw 21 pairs of vertices per row to make 20 columns.
00567                                         px = cparam->xsize * i / 20.0f;
00568                                         
00569                                         arParamObserv2Ideal(cparam->dist_factor, (double)px, (double)py, &x1, &y1);
00570                                         arParamObserv2Ideal(cparam->dist_factor, (double)px, (double)py_prev, &x2, &y2);
00571                                         
00572                                         xx1 = (float)x1 * zoom;
00573                                         yy1 = (cparam->ysize - (float)y1) * zoom;
00574                                         xx2 = (float)x2 * zoom;
00575                                         yy2 = (cparam->ysize - (float)y2) * zoom;
00576                                         
00577                                         glTexCoord2f(px, py/texmapScaleFactor); glVertex2f(xx1, yy1);
00578                                         glTexCoord2f(px, py_prev/texmapScaleFactor); glVertex2f(xx2, yy2);
00579                                 }
00580                                 glEnd();
00581                         }                       
00582                 }
00583                 glDisable(GL_TEXTURE_RECTANGLE);
00584                 glEndList();
00585 
00586                 contextSettings->asInited_ysize = cparam->ysize;
00587                 contextSettings->asInited_xsize = cparam->xsize;
00588                 contextSettings->asInited_zoom = zoom;
00589         contextSettings->asInited_texmapScaleFactor = texmapScaleFactor;
00590         contextSettings->initedRectangle = TRUE;
00591     }
00592 
00593     glBindTexture(GL_TEXTURE_RECTANGLE, contextSettings->textureRectangle);
00594 #ifdef APPLE_TEXTURE_FAST_TRANSFER
00595         if (arglAppleTextureRange) {
00596                 glTextureRangeAPPLE(GL_TEXTURE_RECTANGLE, cparam->xsize * cparam->ysize * contextSettings->pixSize, image);
00597                 glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_STORAGE_HINT_APPLE, GL_STORAGE_SHARED_APPLE);
00598         } else {
00599                 glTextureRangeAPPLE(GL_TEXTURE_RECTANGLE, 0, NULL);
00600                 glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_STORAGE_HINT_APPLE, GL_STORAGE_PRIVATE_APPLE);
00601         }
00602         glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, arglAppleClientStorage);
00603 #endif // APPLE_TEXTURE_FAST_TRANSFER
00604         if (texmapScaleFactor == 2) {
00605                 glPixelStorei(GL_UNPACK_ROW_LENGTH, cparam->xsize*texmapScaleFactor);
00606         }
00607         glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
00608         glTexSubImage2D(GL_TEXTURE_RECTANGLE, 0, 0, 0, cparam->xsize, cparam->ysize/texmapScaleFactor, contextSettings->pixFormat, contextSettings->pixType, image);
00609         glCallList(contextSettings->listRectangle);
00610         if (texmapScaleFactor == 2) {
00611                 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
00612         }
00613     glBindTexture(GL_TEXTURE_RECTANGLE, 0);     
00614 }
00615 
00616 #pragma mark -
00617 // ============================================================================
00618 //      Public functions.
00619 // ============================================================================
00620 
00621 ARGL_CONTEXT_SETTINGS_REF arglSetupForCurrentContext(void)
00622 {
00623         ARGL_CONTEXT_SETTINGS_REF contextSettings;
00624         
00625         contextSettings = (ARGL_CONTEXT_SETTINGS_REF)calloc(1, sizeof(ARGL_CONTEXT_SETTINGS));
00626         // Use default pixel format handed to us by <AR/config.h>.
00627         if (!arglPixelFormatSet(contextSettings, AR_DEFAULT_PIXEL_FORMAT)) {
00628                 printf("Unknown default pixel format defined in config.h.\n"); // Windows bug: when running multi-threaded, can't write to stderr!
00629                 return (NULL);
00630         }
00631         arglDrawModeSet(contextSettings, AR_DRAW_BY_TEXTURE_MAPPING);
00632         arglTexmapModeSet(contextSettings, AR_DRAW_TEXTURE_FULL_IMAGE);
00633         arglTexRectangleSet(contextSettings, TRUE);
00634 
00635         return (contextSettings);
00636 }
00637 
00638 void arglCleanup(ARGL_CONTEXT_SETTINGS_REF contextSettings)
00639 {
00640         arglCleanupTexRectangle(contextSettings);
00641         arglCleanupTexPow2(contextSettings);
00642         free(contextSettings);
00643 }
00644 
00645 //
00646 // Convert a camera parameter structure into an OpenGL projection matrix.
00647 //
00648 void arglCameraFrustum(const ARParam *cparam, const double focalmin, const double focalmax, GLdouble m_projection[16])
00649 {
00650         double   icpara[3][4];
00651     double   trans[3][4];
00652     double   p[3][3], q[4][4];
00653         int      width, height;
00654     int      i, j;
00655         
00656     width  = cparam->xsize;
00657     height = cparam->ysize;
00658 
00659     if (arParamDecompMat(cparam->mat, icpara, trans) < 0) {
00660         printf("arglCameraFrustum(): arParamDecompMat() indicated parameter error.\n"); // Windows bug: when running multi-threaded, can't write to stderr!
00661         return;
00662     }
00663         for (i = 0; i < 4; i++) {
00664         icpara[1][i] = (height - 1)*(icpara[2][i]) - icpara[1][i];
00665     }
00666                 
00667     for(i = 0; i < 3; i++) {
00668         for(j = 0; j < 3; j++) {
00669             p[i][j] = icpara[i][j] / icpara[2][2];
00670         }
00671     }
00672     q[0][0] = (2.0 * p[0][0] / (width - 1));
00673     q[0][1] = (2.0 * p[0][1] / (width - 1));
00674     q[0][2] = ((2.0 * p[0][2] / (width - 1))  - 1.0);
00675     q[0][3] = 0.0;
00676         
00677     q[1][0] = 0.0;
00678     q[1][1] = (2.0 * p[1][1] / (height - 1));
00679     q[1][2] = ((2.0 * p[1][2] / (height - 1)) - 1.0);
00680     q[1][3] = 0.0;
00681         
00682     q[2][0] = 0.0;
00683     q[2][1] = 0.0;
00684     q[2][2] = (focalmax + focalmin)/(focalmax - focalmin);
00685     q[2][3] = -2.0 * focalmax * focalmin / (focalmax - focalmin);
00686         
00687     q[3][0] = 0.0;
00688     q[3][1] = 0.0;
00689     q[3][2] = 1.0;
00690     q[3][3] = 0.0;
00691         
00692     for (i = 0; i < 4; i++) { // Row.
00693                 // First 3 columns of the current row.
00694         for (j = 0; j < 3; j++) { // Column.
00695             m_projection[i + j*4] = q[i][0] * trans[0][j] +
00696                                                                         q[i][1] * trans[1][j] +
00697                                                                         q[i][2] * trans[2][j];
00698         }
00699                 // Fourth column of the current row.
00700         m_projection[i + 3*4] = q[i][0] * trans[0][3] +
00701                                                                 q[i][1] * trans[1][3] +
00702                                                                 q[i][2] * trans[2][3] +
00703                                                                 q[i][3];
00704     }   
00705 }
00706 
00707 void arglCameraFrustumRH(const ARParam *cparam, const double focalmin, const double focalmax, GLdouble m_projection[16])
00708 {
00709         double   icpara[3][4];
00710     double   trans[3][4];
00711     double   p[3][3], q[4][4];
00712         int      width, height;
00713     int      i, j;
00714         
00715     width  = cparam->xsize;
00716     height = cparam->ysize;
00717         
00718     if (arParamDecompMat(cparam->mat, icpara, trans) < 0) {
00719         printf("arglCameraFrustum(): arParamDecompMat() indicated parameter error.\n"); // Windows bug: when running multi-threaded, can't write to stderr!
00720         return;
00721     }
00722         for (i = 0; i < 4; i++) {
00723         icpara[1][i] = (height - 1)*(icpara[2][i]) - icpara[1][i];
00724     }
00725         
00726     for(i = 0; i < 3; i++) {
00727         for(j = 0; j < 3; j++) {
00728             p[i][j] = icpara[i][j] / icpara[2][2];
00729         }
00730     }
00731     q[0][0] = (2.0 * p[0][0] / (width - 1));
00732     q[0][1] = (2.0 * p[0][1] / (width - 1));
00733     q[0][2] = -((2.0 * p[0][2] / (width - 1))  - 1.0);
00734     q[0][3] = 0.0;
00735         
00736     q[1][0] = 0.0;
00737     q[1][1] = -(2.0 * p[1][1] / (height - 1));
00738     q[1][2] = -((2.0 * p[1][2] / (height - 1)) - 1.0);
00739     q[1][3] = 0.0;
00740         
00741     q[2][0] = 0.0;
00742     q[2][1] = 0.0;
00743     q[2][2] = (focalmax + focalmin)/(focalmin - focalmax);
00744     q[2][3] = 2.0 * focalmax * focalmin / (focalmin - focalmax);
00745         
00746     q[3][0] = 0.0;
00747     q[3][1] = 0.0;
00748     q[3][2] = -1.0;
00749     q[3][3] = 0.0;
00750         
00751     for (i = 0; i < 4; i++) { // Row.
00752                 // First 3 columns of the current row.
00753         for (j = 0; j < 3; j++) { // Column.
00754             m_projection[i + j*4] = q[i][0] * trans[0][j] +
00755                         q[i][1] * trans[1][j] +
00756                         q[i][2] * trans[2][j];
00757         }
00758                 // Fourth column of the current row.
00759         m_projection[i + 3*4] = q[i][0] * trans[0][3] +
00760                                                                 q[i][1] * trans[1][3] +
00761                                                                 q[i][2] * trans[2][3] +
00762                                                                 q[i][3];
00763     }   
00764 }
00765 
00766 void arglCameraView(const double para[3][4], GLdouble m_modelview[16], const double scale)
00767 {
00768         m_modelview[0 + 0*4] = para[0][0]; // R1C1
00769         m_modelview[0 + 1*4] = para[0][1]; // R1C2
00770         m_modelview[0 + 2*4] = para[0][2];
00771         m_modelview[0 + 3*4] = para[0][3];
00772         m_modelview[1 + 0*4] = para[1][0]; // R2
00773         m_modelview[1 + 1*4] = para[1][1];
00774         m_modelview[1 + 2*4] = para[1][2];
00775         m_modelview[1 + 3*4] = para[1][3];
00776         m_modelview[2 + 0*4] = para[2][0]; // R3
00777         m_modelview[2 + 1*4] = para[2][1];
00778         m_modelview[2 + 2*4] = para[2][2];
00779         m_modelview[2 + 3*4] = para[2][3];
00780         m_modelview[3 + 0*4] = 0.0;
00781         m_modelview[3 + 1*4] = 0.0;
00782         m_modelview[3 + 2*4] = 0.0;
00783         m_modelview[3 + 3*4] = 1.0;
00784         if (scale != 0.0) {
00785                 m_modelview[12] *= scale;
00786                 m_modelview[13] *= scale;
00787                 m_modelview[14] *= scale;
00788         }
00789 }
00790 
00791 void arglCameraViewRH(const double para[3][4], GLdouble m_modelview[16], const double scale)
00792 {
00793         m_modelview[0 + 0*4] = para[0][0]; // R1C1
00794         m_modelview[0 + 1*4] = para[0][1]; // R1C2
00795         m_modelview[0 + 2*4] = para[0][2];
00796         m_modelview[0 + 3*4] = para[0][3];
00797         m_modelview[1 + 0*4] = -para[1][0]; // R2
00798         m_modelview[1 + 1*4] = -para[1][1];
00799         m_modelview[1 + 2*4] = -para[1][2];
00800         m_modelview[1 + 3*4] = -para[1][3];
00801         m_modelview[2 + 0*4] = -para[2][0]; // R3
00802         m_modelview[2 + 1*4] = -para[2][1];
00803         m_modelview[2 + 2*4] = -para[2][2];
00804         m_modelview[2 + 3*4] = -para[2][3];
00805         m_modelview[3 + 0*4] = 0.0;
00806         m_modelview[3 + 1*4] = 0.0;
00807         m_modelview[3 + 2*4] = 0.0;
00808         m_modelview[3 + 3*4] = 1.0;
00809         if (scale != 0.0) {
00810                 m_modelview[12] *= scale;
00811                 m_modelview[13] *= scale;
00812                 m_modelview[14] *= scale;
00813         }
00814 }
00815 
00816 void arglDispImage(ARUint8 *image, const ARParam *cparam, const double zoom, ARGL_CONTEXT_SETTINGS_REF contextSettings)
00817 {
00818         GLint texEnvModeSave;   
00819         GLboolean lightingSave;
00820         GLboolean depthTestSave;
00821 #ifdef ARGL_DEBUG
00822         GLenum                  err;
00823         const GLubyte   *errs;
00824 #endif // ARGL_DEBUG
00825 
00826         if (!image) return;
00827 
00828         // Prepare an orthographic projection, set camera position for 2D drawing, and save GL state.
00829         glGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &texEnvModeSave); // Save GL texture environment mode.
00830         if (texEnvModeSave != GL_REPLACE) glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
00831         lightingSave = glIsEnabled(GL_LIGHTING);                        // Save enabled state of lighting.
00832         if (lightingSave == GL_TRUE) glDisable(GL_LIGHTING);
00833         depthTestSave = glIsEnabled(GL_DEPTH_TEST);             // Save enabled state of depth test.
00834         if (depthTestSave == GL_TRUE) glDisable(GL_DEPTH_TEST);
00835         glMatrixMode(GL_PROJECTION);
00836         glPushMatrix();
00837         glLoadIdentity();
00838         gluOrtho2D(0, cparam->xsize, 0, cparam->ysize);
00839         glMatrixMode(GL_MODELVIEW);
00840         glPushMatrix();
00841         glLoadIdentity();               
00842         
00843         if (arDebug) { // Globals from ar.h: arDebug, arImage, arImageProcMode.
00844                 if (arImage) {
00845                         if (arImageProcMode == AR_IMAGE_PROC_IN_HALF) {
00846                                 ARParam cparamScaled = *cparam;
00847                                 cparamScaled.xsize /= 2;
00848                                 cparamScaled.ysize /= 2;
00849                                 arglDispImageStateful(arImage, &cparamScaled, zoom * 2.0, contextSettings);
00850                         } else {
00851                                 arglDispImageStateful(arImage, cparam, zoom, contextSettings);
00852                         }
00853                 }
00854         } else {
00855                 arglDispImageStateful(image, cparam, zoom, contextSettings);
00856         }
00857 
00858         // Restore previous projection, camera position, and GL state.
00859         glMatrixMode(GL_PROJECTION);
00860         glPopMatrix();
00861         glMatrixMode(GL_MODELVIEW);
00862         glPopMatrix();
00863         if (depthTestSave == GL_TRUE) glEnable(GL_DEPTH_TEST);                  // Restore enabled state of depth test.
00864         if (lightingSave == GL_TRUE) glEnable(GL_LIGHTING);                     // Restore enabled state of lighting.
00865         if (texEnvModeSave != GL_REPLACE) glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, texEnvModeSave); // Restore GL texture environment mode.
00866         
00867 #ifdef ARGL_DEBUG
00868         // Report any errors we generated.
00869         while ((err = glGetError()) != GL_NO_ERROR) {
00870                 errs = gluErrorString(err);     // fetch error code
00871                 fprintf(stderr, "GL error: %s (%i)\n", errs, (int)err); // write err code and number to stderr
00872         }
00873 #endif // ARGL_DEBUG
00874         
00875 }
00876 
00877 void arglDispImageStateful(ARUint8 *image, const ARParam *cparam, const double zoom, ARGL_CONTEXT_SETTINGS_REF contextSettings)
00878 {
00879         float zoomf;
00880         int texmapScaleFactor, params[4];
00881         
00882         zoomf = (float)zoom;
00883         texmapScaleFactor = contextSettings->arglTexmapMode + 1;
00884         if (contextSettings->arglDrawMode == AR_DRAW_BY_GL_DRAW_PIXELS) {
00885                 glDisable(GL_TEXTURE_2D);
00886                 glGetIntegerv(GL_VIEWPORT, (GLint *)params);
00887                 glPixelZoom(zoomf * ((float)(params[2]) / (float)(cparam->xsize)),
00888                                    -zoomf * ((float)(params[3]) / (float)(cparam->ysize)));
00889                 glRasterPos2f(0.0f, (float)(cparam->ysize));
00890                 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
00891                 glDrawPixels(cparam->xsize, cparam->ysize, contextSettings->pixFormat, contextSettings->pixType, image);
00892         } else {
00893                 // Check whether any settings in globals/parameters have changed.
00894                 // N.B. We don't check cparam->dist_factor[], but this is unlikely to change!
00895                 if ((texmapScaleFactor != contextSettings->asInited_texmapScaleFactor) ||
00896                         (zoomf != contextSettings->asInited_zoom) ||
00897                         (cparam->xsize != contextSettings->asInited_xsize) ||
00898                         (cparam->ysize != contextSettings->asInited_ysize)) {
00899                         contextSettings->initPlease = TRUE;
00900                 }
00901                 
00902                 if (contextSettings->arglTexRectangle) {
00903                         arglDispImageTexRectangle(image, cparam, zoomf, contextSettings, texmapScaleFactor);
00904                 } else {
00905                         arglDispImageTexPow2(image, cparam, zoomf, contextSettings, texmapScaleFactor);
00906                 }
00907         }       
00908 }
00909 
00910 int arglDistortionCompensationSet(ARGL_CONTEXT_SETTINGS_REF contextSettings, int enable)
00911 {
00912         if (!contextSettings) return (FALSE);
00913         contextSettings->disableDistortionCompensation = !enable;
00914         contextSettings->initPlease = TRUE;
00915         return (TRUE);
00916 }
00917 
00918 int arglDistortionCompensationGet(ARGL_CONTEXT_SETTINGS_REF contextSettings, int *enable)
00919 {
00920         if (!contextSettings) return (FALSE);
00921         *enable = !contextSettings->disableDistortionCompensation;
00922         return (TRUE);
00923 }
00924 
00925 int arglPixelFormatSet(ARGL_CONTEXT_SETTINGS_REF contextSettings, AR_PIXEL_FORMAT format)
00926 {
00927         if (!contextSettings) return (FALSE);
00928         switch (format) {
00929                 case AR_PIXEL_FORMAT_RGBA:
00930                         contextSettings->pixIntFormat = GL_RGBA;
00931                         contextSettings->pixFormat = GL_RGBA;
00932                         contextSettings->pixType = GL_UNSIGNED_BYTE;
00933                         contextSettings->pixSize = 4;
00934                         break;
00935                 case AR_PIXEL_FORMAT_ABGR:      // SGI.
00936                         if (arglGLCapabilityCheck(0, (unsigned char *)"GL_EXT_abgr")) {
00937                                 contextSettings->pixIntFormat = GL_RGBA;
00938                                 contextSettings->pixFormat = GL_ABGR_EXT;
00939                                 contextSettings->pixType = GL_UNSIGNED_BYTE;
00940                                 contextSettings->pixSize = 4;
00941                         } else {
00942                                 return (FALSE);
00943                         }
00944                         break;
00945                 case AR_PIXEL_FORMAT_BGRA:      // Windows.
00946                         if (arglGLCapabilityCheck(0x0120, (unsigned char *)"GL_EXT_bgra")) {
00947                                 contextSettings->pixIntFormat = GL_RGBA;
00948                                 contextSettings->pixFormat = GL_BGRA;
00949                                 contextSettings->pixType = GL_UNSIGNED_BYTE;
00950                                 contextSettings->pixSize = 4;
00951                         } else {
00952                                 return (FALSE);
00953                         }
00954                         break;
00955                 case AR_PIXEL_FORMAT_ARGB:      // Mac.
00956                         if (arglGLCapabilityCheck(0x0120, (unsigned char *)"GL_EXT_bgra")
00957                                 && arglGLCapabilityCheck(0x0120, (unsigned char *)"GL_APPLE_packed_pixels")) {
00958                                 contextSettings->pixIntFormat = GL_RGBA;
00959                                 contextSettings->pixFormat = GL_BGRA;
00960 #ifdef AR_BIG_ENDIAN
00961                                 contextSettings->pixType = GL_UNSIGNED_INT_8_8_8_8_REV;
00962 #else
00963                                 contextSettings->pixType = GL_UNSIGNED_INT_8_8_8_8;
00964 #endif
00965                                 contextSettings->pixSize = 4;
00966                         } else {
00967                                 return (FALSE);
00968                         }
00969                         break;
00970                 case AR_PIXEL_FORMAT_RGB:
00971                         contextSettings->pixIntFormat = GL_RGB;
00972                         contextSettings->pixFormat = GL_RGB;
00973                         contextSettings->pixType = GL_UNSIGNED_BYTE;
00974                         contextSettings->pixSize = 3;
00975                         break;
00976                 case AR_PIXEL_FORMAT_BGR:
00977                         if (arglGLCapabilityCheck(0x0120, (unsigned char *)"GL_EXT_bgra")) {
00978                                 contextSettings->pixIntFormat = GL_RGB;
00979                                 contextSettings->pixFormat = GL_BGR;
00980                                 contextSettings->pixType = GL_UNSIGNED_BYTE;
00981                                 contextSettings->pixSize = 3;
00982                         } else {
00983                                 return (FALSE);
00984                         }
00985                         break;
00986                 case AR_PIXEL_FORMAT_MONO:
00987                         contextSettings->pixIntFormat = GL_LUMINANCE;
00988                         contextSettings->pixFormat = GL_LUMINANCE;
00989                         contextSettings->pixType = GL_UNSIGNED_BYTE;
00990                         contextSettings->pixSize = 1;
00991                         break;
00992                 case AR_PIXEL_FORMAT_2vuy:
00993                         if (arglGLCapabilityCheck(0, (unsigned char *)"GL_APPLE_ycbcr_422")) {
00994                                 contextSettings->pixIntFormat = GL_RGB;
00995                                 contextSettings->pixFormat = GL_YCBCR_422_APPLE;
00996 #ifdef AR_BIG_ENDIAN
00997                                 contextSettings->pixType = GL_UNSIGNED_SHORT_8_8_REV_APPLE;
00998 #else
00999                                 contextSettings->pixType = GL_UNSIGNED_SHORT_8_8_APPLE;
01000 #endif
01001                         } else if (arglGLCapabilityCheck(0, (unsigned char *)"GL_MESA_ycbcr_texture")) {
01002                                 contextSettings->pixIntFormat = GL_YCBCR_MESA;
01003                                 contextSettings->pixFormat = GL_YCBCR_MESA;
01004 #ifdef AR_BIG_ENDIAN
01005                                 contextSettings->pixType = GL_UNSIGNED_SHORT_8_8_REV_MESA;
01006 #else
01007                                 contextSettings->pixType = GL_UNSIGNED_SHORT_8_8_MESA;
01008 #endif
01009                         } else {
01010                                 return (FALSE);
01011                         }
01012                         contextSettings->pixSize = 2;
01013                         break;
01014                 case AR_PIXEL_FORMAT_yuvs:
01015                         if (arglGLCapabilityCheck(0, (unsigned char *)"GL_APPLE_ycbcr_422")) {
01016                                 contextSettings->pixIntFormat = GL_RGB;
01017                                 contextSettings->pixFormat = GL_YCBCR_422_APPLE;
01018 #ifdef AR_BIG_ENDIAN
01019                                 contextSettings->pixType = GL_UNSIGNED_SHORT_8_8_APPLE;
01020 #else
01021                                 contextSettings->pixType = GL_UNSIGNED_SHORT_8_8_REV_APPLE;
01022 #endif
01023                         } else if (arglGLCapabilityCheck(0, (unsigned char *)"GL_MESA_ycbcr_texture")) {
01024                                 contextSettings->pixIntFormat = GL_YCBCR_MESA;
01025                                 contextSettings->pixFormat = GL_YCBCR_MESA;
01026 #ifdef AR_BIG_ENDIAN
01027                                 contextSettings->pixType = GL_UNSIGNED_SHORT_8_8_MESA;
01028 #else
01029                                 contextSettings->pixType = GL_UNSIGNED_SHORT_8_8_REV_MESA;
01030 #endif
01031                         } else {
01032                                 return (FALSE);
01033                         }
01034                         contextSettings->pixSize = 2;
01035                         break;
01036                 default:
01037                         return (FALSE);
01038                         break;
01039         }
01040         contextSettings->initPlease = TRUE;
01041         return (TRUE);
01042 }
01043 
01044 int arglPixelFormatGet(ARGL_CONTEXT_SETTINGS_REF contextSettings, AR_PIXEL_FORMAT *format, int *size)
01045 {
01046         if (!contextSettings) return (FALSE);
01047         switch (contextSettings->pixFormat) {
01048                 case GL_RGBA:
01049                         *format = AR_PIXEL_FORMAT_RGBA;
01050                         *size = 4;
01051                         break;
01052                 case GL_ABGR_EXT:
01053                         *format = AR_PIXEL_FORMAT_ABGR;
01054                         *size = 4;
01055                         break;
01056                 case GL_BGRA:
01057                         if (contextSettings->pixType == GL_UNSIGNED_BYTE) *format = AR_PIXEL_FORMAT_BGRA;
01058 #ifdef AR_BIG_ENDIAN
01059                         else if (contextSettings->pixType == GL_UNSIGNED_INT_8_8_8_8_REV) *format = AR_PIXEL_FORMAT_ARGB;
01060 #else
01061                         else if (contextSettings->pixType == GL_UNSIGNED_INT_8_8_8_8) *format = AR_PIXEL_FORMAT_ARGB;
01062 #endif
01063                         else  return (FALSE);
01064                         *size = 4;
01065                         break;
01066                 case GL_RGB:
01067                         *format = AR_PIXEL_FORMAT_RGB;
01068                         *size = 3;
01069                         break;
01070                 case GL_BGR:
01071                         *format = AR_PIXEL_FORMAT_BGR;
01072                         *size = 3;
01073                         break;
01074                 case GL_YCBCR_422_APPLE:
01075                 case GL_YCBCR_MESA:
01076 #ifdef AR_BIG_ENDIAN
01077                         if (contextSettings->pixType == GL_UNSIGNED_SHORT_8_8_REV_APPLE) *format = AR_PIXEL_FORMAT_2vuy; // N.B.: GL_UNSIGNED_SHORT_8_8_REV_APPLE = GL_UNSIGNED_SHORT_8_8_REV_MESA
01078                         else if (contextSettings->pixType == GL_UNSIGNED_SHORT_8_8_APPLE) *format = AR_PIXEL_FORMAT_yuvs; // GL_UNSIGNED_SHORT_8_8_APPLE = GL_UNSIGNED_SHORT_8_8_MESA
01079 #else
01080                         if (contextSettings->pixType == GL_UNSIGNED_SHORT_8_8_APPLE) *format = AR_PIXEL_FORMAT_2vuy;
01081                         else if (contextSettings->pixType == GL_UNSIGNED_SHORT_8_8_REV_APPLE) *format = AR_PIXEL_FORMAT_yuvs;
01082 #endif
01083                         else return (FALSE);
01084                         *size = 2;
01085                         break;
01086                 case GL_LUMINANCE:
01087                         *format = AR_PIXEL_FORMAT_MONO;
01088                         *size = 1;
01089                         break;
01090                 default:
01091                         return (FALSE);
01092                         break;
01093         }
01094         return (TRUE);
01095 }
01096 
01097 void arglDrawModeSet(ARGL_CONTEXT_SETTINGS_REF contextSettings, const int mode)
01098 {
01099         if (!contextSettings || mode < 0 || mode > 1) return; // Sanity check.
01100         contextSettings->arglDrawMode = mode;
01101 }
01102 
01103 int arglDrawModeGet(ARGL_CONTEXT_SETTINGS_REF contextSettings)
01104 {
01105         if (!contextSettings) return (-1); // Sanity check.
01106         return (contextSettings->arglDrawMode);
01107 }
01108 
01109 void arglTexmapModeSet(ARGL_CONTEXT_SETTINGS_REF contextSettings, const int mode)
01110 {
01111         if (!contextSettings || mode < 0 || mode > 1) return; // Sanity check.
01112         contextSettings->arglTexmapMode = mode;
01113 }
01114 
01115 int arglTexmapModeGet(ARGL_CONTEXT_SETTINGS_REF contextSettings)
01116 {
01117         if (!contextSettings) return (-1); // Sanity check.
01118         return (contextSettings->arglTexmapMode);
01119 }
01120 
01121 void arglTexRectangleSet(ARGL_CONTEXT_SETTINGS_REF contextSettings, const int state)
01122 {
01123         if (!contextSettings) return; // Sanity check.
01124         contextSettings->arglTexRectangle = state;
01125 }
01126 
01127 int arglTexRectangleGet(ARGL_CONTEXT_SETTINGS_REF contextSettings)
01128 {
01129         if (!contextSettings) return (-1); // Sanity check.
01130         return (contextSettings->arglTexRectangle);
01131 }
01132 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines


ar_recog
Author(s): Graylin Trevor Jay and Christopher Crick
autogenerated on Fri Jan 25 2013 12:15:00