Main Page | Alphabetical List | Compound List | File List | Compound Members | File Members

OGLDrv.c

Go to the documentation of this file.
00001 /****************************************************************************************/
00002 /*  OglDrv.c                                                                            */
00003 /*                                                                                      */
00004 /*  Author: George McBay (gfm@my-deja.com)                                              */
00005 /*  Description: Exposed interface for OpenGL version of Genesis Driver                 */
00006 /*                                                                                      */
00007 /*  The contents of this file are subject to the Genesis3D Public License               */
00008 /*  Version 1.01 (the "License"); you may not use this file except in                   */
00009 /*  compliance with the License. You may obtain a copy of the License at                */
00010 /*  http://www.genesis3d.com                                                            */
00011 /*                                                                                      */
00012 /*  Software distributed under the License is distributed on an "AS IS"                 */
00013 /*  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See                */
00014 /*  the License for the specific language governing rights and limitations              */
00015 /*  under the License.                                                                  */
00016 /*                                                                                      */
00017 /*                                                                                      */
00018 /****************************************************************************************/
00019 
00020 #include <windows.h>
00021 #include <stdio.h>
00022 #include <math.h>
00023 #include <gl/gl.h>
00024 
00025 #include "OglDrv.h"
00026 #include "OglMisc.h"
00027 #include "THandle.h"
00028 #include "Render.h"
00029 #include "Win32.h"
00030 
00031 
00032 int32 LastError;
00033 char LastErrorStr[255];         
00034 
00035 GLfloat CurrentGamma = 1.0f;
00036 DRV_Window      ClientWindow;
00037 static DRV_CacheInfo    CacheInfo;
00038 
00039 GLint maxTextureSize = 0;
00040 
00041 // Toggle and function pointers for OpenGL multitexture extention
00042 GLboolean multitexture = GE_FALSE;
00043 PFNGLACTIVETEXTUREARBPROC glActiveTextureARB;
00044 PFNGLMULTITEXCOORD4FARBPROC glMultiTexCoord4fARB;
00045 
00046 
00047 
00048 DRV_Driver OGLDRV = 
00049 {
00050 
00051         "OpenGL driver. v"DRV_VMAJS"."DRV_VMINS". Copyright 1999, Eclipse Inc.; All Rights Reserved.",
00052 
00053         DRV_VERSION_MAJOR,
00054         DRV_VERSION_MINOR,
00055 
00056         DRV_ERROR_NONE,
00057         NULL,
00058         
00059         EnumSubDrivers,
00060         EnumModes,
00061         
00062         EnumPixelFormats,
00063 
00064         DrvInit,
00065         DrvShutdown,
00066         DrvResetAll,
00067         DrvUpdateWindow,
00068         DrvSetActive,
00069 
00070         THandle_Create,
00071         THandle_Destroy,
00072 
00073         THandle_Lock,
00074         THandle_UnLock,
00075 
00076         NULL, 
00077         NULL, 
00078 
00079         NULL, 
00080         NULL, 
00081 
00082         THandle_GetInfo,
00083 
00084         BeginScene,
00085         EndScene,
00086         BeginWorld,
00087         EndWorld,
00088         BeginMeshes,
00089         EndMeshes,
00090         BeginModels,
00091         EndModels,
00092 
00093         Render_GouraudPoly,
00094         Render_WorldPoly,
00095         Render_MiscTexturePoly,
00096 
00097         DrawDecal,
00098 
00099         0,0,0,
00100 
00101         &CacheInfo,
00102 
00103         ScreenShot,
00104 
00105         SetGamma, 
00106         GetGamma,
00107 
00108         SetFogEnable, 
00109 
00110         NULL,
00111         NULL,                                                           // Init to NULL, engine SHOULD set this (SetupLightmap)
00112         NULL,
00113 };
00114 
00115 // Not implemented, but you noticed that already huh?
00116 geBoolean DRIVERCC SetFogEnable(geBoolean Enable, float r, float g, float b, float Start, float End)
00117 {
00118 
00119         return GE_TRUE;
00120 }
00121 
00122 
00123 geBoolean DRIVERCC DrvInit(DRV_DriverHook *Hook)
00124 {
00125         RECT            WRect;
00126         
00127 
00128         WindowSetup(Hook);
00129         
00130         if(Hook->Width == -1 && Hook->Height == -1)
00131         {
00132                 GetClientRect(Hook->hWnd, &WRect);
00133                 
00134                 Hook->Width = (WRect.right - WRect.left);
00135                 Hook->Height = (WRect.bottom - WRect.top);
00136         }
00137         else if(!SetFullscreen(Hook))
00138         {
00139                 return GE_FALSE;
00140         } 
00141 
00142         SetGLPixelFormat(Hook);
00143 
00144         ClientWindow.Width = Hook->Width;
00145         ClientWindow.Height = Hook->Height;
00146         ClientWindow.hWnd = Hook->hWnd;
00147         
00148 #ifdef USE_LIGHTMAPS
00149         if(ExtensionExists("GL_ARB_multitexture"))
00150         {
00151                 glActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC)wglGetProcAddress("glActiveTextureARB");
00152                 glMultiTexCoord4fARB = (PFNGLMULTITEXCOORD4FARBPROC)wglGetProcAddress("glMultiTexCoord4fARB");
00153 
00154                 if(glActiveTextureARB != NULL && glMultiTexCoord4fARB != NULL)
00155                 {
00156                         multitexture = GL_TRUE;
00157                 }
00158         }
00159         else 
00160 #endif
00161         {
00162                 multitexture = GL_FALSE;
00163         } 
00164 
00165 
00166         glPixelStorei(GL_PACK_ALIGNMENT, 1);
00167         glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
00168 
00169         glEnable(GL_TEXTURE_2D);
00170         glEnable(GL_DEPTH_TEST);
00171 
00172         glEnable(GL_BLEND);    
00173         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00174 
00175         glShadeModel(GL_SMOOTH);
00176         glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
00177 
00178         if(multitexture)
00179         {
00180                 glActiveTextureARB(GL_TEXTURE1_ARB);
00181 
00182                 glDisable(GL_TEXTURE_1D);
00183                 glDisable(GL_TEXTURE_2D);               
00184 
00185                 glActiveTextureARB(GL_TEXTURE0_ARB);
00186         } 
00187 
00188         SetFogEnable(GE_FALSE, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);
00189 
00190         InitMatrices(ClientWindow.Width, ClientWindow.Height);
00191 
00192         glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
00193 
00194         glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
00195 
00196         if (!THandle_Startup())
00197         {
00198                 SetLastDrvError(DRV_ERROR_GENERIC, "OGL_DrvInit:  THandle_Startup failed...\n");
00199                 return GE_FALSE;
00200         }
00201 
00202         return GE_TRUE;
00203 }
00204 
00205 
00206 geBoolean DRIVERCC DrvShutdown(void)
00207 {
00208         // Tell OpenGL to finish whatever is in the pipe, because we're closing up shop.
00209         glFinish();
00210 
00211         WindowCleanup();
00212 
00213         return GE_TRUE;
00214 }
00215 
00216 
00217 // Should handle a resize and re-InitMatrices here...
00218 geBoolean DRIVERCC DrvUpdateWindow(void)
00219 {
00220 
00221         return  GE_TRUE;
00222 }
00223 
00224 
00225 geBoolean       DRIVERCC DrvSetActive(geBoolean Active)
00226 {
00227 
00228         return  GE_TRUE;
00229 }
00230 
00231 
00232 geBoolean DRIVERCC SetGamma(float Gamma)
00233 {       
00234         GLfloat lut[256];
00235         GLint   i;
00236         
00237         CurrentGamma = Gamma;
00238         
00239         for(i = 0; i < 256; i++)
00240         {
00241                 lut[i] = (GLfloat)pow(i / 255.0, 1.0 / CurrentGamma);
00242         }
00243 
00244         glPixelTransferi(GL_MAP_COLOR, GL_TRUE);
00245         glPixelMapfv(GL_PIXEL_MAP_R_TO_R, 256, lut);
00246         glPixelMapfv(GL_PIXEL_MAP_G_TO_G, 256, lut);
00247         glPixelMapfv(GL_PIXEL_MAP_B_TO_B, 256, lut); 
00248 
00249         return GE_TRUE;
00250 }
00251 
00252 
00253 geBoolean DRIVERCC GetGamma(float *Gamma)
00254 {
00255         *Gamma = CurrentGamma;
00256         
00257         return TRUE;
00258 }
00259 
00260 
00261 DRV_EngineSettings EngineSettings;
00262 
00263 DllExport BOOL DriverHook(DRV_Driver **Driver)
00264 {
00265 
00266         EngineSettings.CanSupportFlags = (DRV_SUPPORT_ALPHA | DRV_SUPPORT_COLORKEY);
00267         EngineSettings.PreferenceFlags = 0;
00268 
00269         OGLDRV.EngineSettings = &EngineSettings;
00270     
00271         *Driver = &OGLDRV;
00272 
00273         // Make sure the error string ptr is not null, or invalid!!!
00274     OGLDRV.LastErrorStr = LastErrorStr;
00275 
00276         SetLastDrvError(DRV_ERROR_NONE, "OGL:  No error.");
00277 
00278         return GE_TRUE;
00279 }
00280 
00281 
00282 geBoolean DRIVERCC EnumModes(int32 Driver, char *DriverName, DRV_ENUM_MODES_CB *Cb, 
00283                                                          void *Context)
00284 {
00285         GLint modeCount = 0;
00286 
00287         modeCount = EnumNativeModes(Cb, Context);
00288 
00289         return GE_TRUE;
00290 }
00291 
00292 
00293 geBoolean DRIVERCC EnumSubDrivers(DRV_ENUM_DRV_CB *Cb, void *Context)
00294 {
00295 
00296         if(!Cb(0, "OpenGL Driver v"DRV_VMAJS"."DRV_VMINS".", Context))
00297         {
00298                 return GE_TRUE;
00299         }
00300 
00301         return GE_TRUE;
00302 }
00303 
00304 
00305 // For now, we keep it simple. In the future, we may want to added paletted support 
00306 // (or maybe not)...and also check for OpenGL extentions, like GL_EXT_abgr, GL_EXT_bgra, etc.
00307 // Note: OpenGL is traditionally RGBA based.  ABGR is used here because of endian-oddness in 
00308 // the naming of Genesis's pixel formats.
00309 // See: (Genesis Engine's) Bitmap/pixelformat.h for more information. 
00310 geRDriver_PixelFormat   PixelFormats[] =
00311 {
00312         {GE_PIXELFORMAT_32BIT_ABGR,             RDRIVER_PF_3D | RDRIVER_PF_COMBINE_LIGHTMAP},
00313         {GE_PIXELFORMAT_24BIT_RGB,              RDRIVER_PF_2D | RDRIVER_PF_CAN_DO_COLORKEY},
00314         {GE_PIXELFORMAT_24BIT_RGB,              RDRIVER_PF_LIGHTMAP},
00315 };
00316 
00317 #define NUM_PIXEL_FORMATS       (sizeof(PixelFormats)/sizeof(geRDriver_PixelFormat))
00318 
00319 
00320 geBoolean DRIVERCC EnumPixelFormats(DRV_ENUM_PFORMAT_CB *Cb, void *Context)
00321 {
00322         GLint i;
00323 
00324         for(i = 0; i < NUM_PIXEL_FORMATS; i++)
00325         {
00326                 if(!Cb(&PixelFormats[i], Context))
00327                 {
00328                         return GE_TRUE;
00329                 }
00330         }
00331 
00332         return GE_TRUE;
00333 }
00334 
00335 
00336 void SetLastDrvError(int32 Error, char *ErrorStr)
00337 {
00338         LastError = Error;
00339         
00340         if(ErrorStr)
00341         {
00342                 strcpy(LastErrorStr, ErrorStr);
00343         }
00344         else
00345         {
00346                 LastErrorStr[0] = 0;
00347         }
00348 
00349         OGLDRV.LastErrorStr = LastErrorStr;
00350         OGLDRV.LastError = LastError;
00351 }
00352 
00353 
00354 // I break the rules here.  There's an implied assumption that screenshot will produce
00355 // a BMP, I use TGA instead.  BMP is so...Windows.  This screws up GTest a bit, as GTest looks
00356 // for files ending in .bmp before writing, and will thus keep overwriting one screenshot.
00357 geBoolean DRIVERCC ScreenShot(const char *Name)
00358 {
00359         unsigned char tgaHeader[18];
00360         GLubyte *buffer;
00361         FILE *fp;
00362         char *newName;
00363         int nameLen;
00364 
00365         buffer = (GLubyte *)malloc(sizeof(GLubyte) * ClientWindow.Width * ClientWindow.Height * 3);     
00366 
00367         glFinish();
00368 
00369         glReadPixels(0, 0, ClientWindow.Width, ClientWindow.Height, 
00370                 GL_BGR_EXT, GL_UNSIGNED_BYTE, buffer);
00371  
00372         memset(tgaHeader, 0, sizeof(tgaHeader));
00373         tgaHeader[2] = 2;
00374         tgaHeader[12] = (unsigned char)ClientWindow.Width;
00375         tgaHeader[13] = (unsigned char)((unsigned long)ClientWindow.Width >> 8);
00376         tgaHeader[14] = (unsigned char)ClientWindow.Height;
00377         tgaHeader[15] = (unsigned char)((unsigned long)ClientWindow.Height >> 8);
00378         tgaHeader[16] = 24;
00379  
00380         // Convert the extention (if one exists) to .tga.  They probably expect a .bmp.
00381         newName = strdup(Name);
00382 
00383         nameLen = strlen(newName);
00384 
00385         if(nameLen > 3)
00386         {
00387                 if(newName[nameLen - 4] == '.')
00388                 {
00389                         strcpy(newName + nameLen - 3, "tga");
00390                 }
00391         }
00392 
00393     fp = fopen(newName, "wb");
00394     
00395         free(newName);
00396 
00397         if(fp == NULL) 
00398         {
00399                 free(buffer);
00400         return GE_FALSE;
00401     }
00402  
00403     fwrite(tgaHeader, 1, 18, fp);
00404     fwrite(buffer, 3, ClientWindow.Width * ClientWindow.Height, fp);
00405     fclose(fp);
00406  
00407         free(buffer);
00408         
00409         return GE_TRUE;
00410 }
00411 

Generated on Tue Sep 30 12:36:03 2003 for GTestAndEngine by doxygen 1.3.2