]> Shamusworld >> Repos - virtualjaguar/commitdiff
Expended OpenGL rendering with 16, 24 and 32 bit texture types.
authorNeils Wagenaar <sdlemu@ngemu.com>
Wed, 6 Oct 2004 14:20:31 +0000 (14:20 +0000)
committerNeils Wagenaar <sdlemu@ngemu.com>
Wed, 6 Oct 2004 14:20:31 +0000 (14:20 +0000)
src/sdlemu_opengl.c
src/video.cpp

index 6b92f1858fa3024442311bb96966cf13d9c135c9..41f92a77f3cad8becb77b746f2dd6c07e764a46f 100644 (file)
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
+/*
+    Version 1.0.001 - 4-10-2004
+    
+    - Added support for 16, 24 and 32 bit textures * new *;
+    - Added support for 16, 24 and 32 bit texture rendering *new*;
+
+*/
 
 #include "sdlemu_opengl.h"
 
@@ -23,6 +31,7 @@ static SDL_Surface *texture      = 0;
 static GLuint       texid        = 0;
 static GLfloat      texcoord[4];
 static unsigned int glFilter;
+static unsigned int texturebpp  = 0; // 16, 24 or 32 bpp
 
 static inline int power_of_two(int input)
 {
@@ -34,15 +43,24 @@ static inline int power_of_two(int input)
        return value;
 }
 
-void sdlemu_init_opengl(SDL_Surface * src, int texturetype, float size, int filter)
+void sdlemu_init_opengl(SDL_Surface * src, int texturetype, float size, int filter, int src_bpp)
 {
        int w, h;
-
+       Uint32 rmask, gmask, bmask, amask;
+
+       // We allow the developer to set its own texture bpp. But if the value is NULL or
+       // not equal to 16, 24 or 32, we make the texturebpp the same as the BPP from src.
+       if ( (src_bpp != NULL) && ( (src_bpp == 16) || (src_bpp == 24) || (src_bpp == 32) ) )
+       texturebpp = src_bpp;
+    else
+       texturebpp = src->format->BitsPerPixel;
+       
        printf("\nOpenGL driver information :\n");
        printf("\n");
-       printf("Vendor:            %s\n", glGetString(GL_VENDOR));
-       printf("Renderer:          %s\n", glGetString(GL_RENDERER));
-       printf("Version:           %s\n", glGetString(GL_VERSION));
+       printf("Vendor:             %s\n", glGetString(GL_VENDOR));
+       printf("Renderer:           %s\n", glGetString(GL_RENDERER));
+       printf("Version:            %s\n", glGetString(GL_VERSION));
+       printf("OpenGL Texture BPP: %d\n", texturebpp);
        printf("OpenGL drawmethod: ");
 
        switch (texturetype)
@@ -59,22 +77,95 @@ void sdlemu_init_opengl(SDL_Surface * src, int texturetype, float size, int filt
 
        // Texture width/height should be power of 2
        // So, find the largest power of two that will contain both the width and height
-       w = power_of_two(src->w);
-       h = power_of_two(src->h);
+       // w = power_of_two(src->w);
+       // h = power_of_two(src->h);
+       w = 512;
+       h = 512;
+
+       switch ( texturebpp )
+       {
+    case 16:
+    #if SDL_BYTEORDER == SDL_BIG_ENDIAN
+       
+//         rmask = 0xff000000;
+//         gmask = 0x00ff0000;
+//         bmask = 0x0000ff00;
+//         amask = 0x00000000;
+
+        rmask = 0x0000;
+               gmask = 0x0000;
+               bmask = 0x0000;
+               amask = 0x0000;
+
+       #else
+
+//         rmask = 0x000000ff;
+//         gmask = 0x0000ff00;
+//         bmask = 0x00ff0000;
+//         amask = 0x00000000;
+
+      rmask = 0x0000;
+      gmask = 0x0000;
+      bmask = 0x0000;
+      amask = 0x0000;
+
+    #endif
+        
+        break;
+    case 24:
+    #if SDL_BYTEORDER == SDL_BIG_ENDIAN
+           rmask = 0x00ff0000;
+               gmask = 0x0000ff00;
+               bmask = 0x000000ff;
+               amask = 0x00000000;
+       #else
+           rmask = 0x000000ff;
+           gmask = 0x0000ff00;
+           bmask = 0x00ff0000;
+           amask = 0x00000000;
+    #endif
+       break;
+    case 32: 
+    default:
+    #if SDL_BYTEORDER == SDL_BIG_ENDIAN
+           rmask = 0xff000000;
+               gmask = 0x00ff0000;
+               bmask = 0x0000ff00;
+               amask = 0x000000ff;
+       #else
+           rmask = 0x000000ff;
+           gmask = 0x0000ff00;
+           bmask = 0x00ff0000;
+           amask = 0xff000000;
+    #endif
+        break;
+    }    
 
        // create texture surface
-       texture = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32,
-       #if SDL_BYTEORDER == SDL_LIL_ENDIAN 
+       texture = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, texturebpp, rmask, gmask, bmask, amask);
+/*     
+    #if SDL_BYTEORDER == SDL_LIL_ENDIAN 
                0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000);
        #else
                0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF);
        #endif
+*/
 
        // setup 2D gl environment
-       glPushAttrib(GL_ENABLE_BIT);
-       glDisable(GL_DEPTH_TEST);
+       //glPushAttrib(GL_ENABLE_BIT);
+       //glDisable(GL_DEPTH_TEST);
+       //glDisable(GL_CULL_FACE);
+       //glEnable(GL_TEXTURE_2D);
+
+       glDisable(GL_FOG);
+       glDisable(GL_LIGHTING);
        glDisable(GL_CULL_FACE);
+       glDisable(GL_DEPTH_TEST);
+       glDisable(GL_BLEND);
+       glDisable(GL_NORMALIZE);
+       glDisable(GL_ALPHA_TEST);
        glEnable(GL_TEXTURE_2D);
+       glBlendFunc (GL_SRC_ALPHA, GL_ONE);
 
        glViewport(0, 0, src->w * size, src->h * size);
 
@@ -109,20 +200,62 @@ void sdlemu_init_opengl(SDL_Surface * src, int texturetype, float size, int filt
           glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
           glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
     }
+    
+    switch ( texturebpp )
+    {
+    case 16:
+           glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB5, texture->w, texture->h, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
+        break;
+    case 24:
+           glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, texture->w, texture->h, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
+        break;
+    case 32:
+    default:
+           glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, texture->w, texture->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+        break;        
+    }    
 
-       glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture->w, texture->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture->pixels);
 }
 
 void sdlemu_draw_texture(SDL_Surface * dst, SDL_Surface * src, int texturetype)
 {
+       //SDL_Rect rect = { 0, 0, src->w, src->h };
 
        // convert color-indexed surface to RGB texture
+       //SDL_BlitSurface(src, &rect, texture, &rect);
+       //glFlush();
+       
        SDL_BlitSurface(src, NULL, texture, NULL);
 
+//     printf("Rmask - src : %d\n", src->format->Rmask);
+//     printf("Gmask - src : %d\n", src->format->Gmask);
+//     printf("Bmask - src : %d\n", src->format->Bmask);
+//     printf("Amask - src : %d\n", src->format->Amask);
+
+//     printf("Rmask - texture : %d\n", texture->format->Rmask);
+//     printf("Gmask - texture : %d\n", texture->format->Gmask);
+//     printf("Bmask - texture : %d\n", texture->format->Bmask);
+//     printf("Amask - texture : %d\n", texture->format->Amask);
+
        // Texturemap complete texture to surface so we have free scaling 
-       // and antialiasing 
-       glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, texture->w, texture->h,
-               GL_RGBA, GL_UNSIGNED_BYTE, texture->pixels);
+       // and antialiasing
+    switch ( texturebpp )
+    {
+    case 16:
+        // GL_UNSIGNED_SHORT_5_6_5
+        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, texture->w, texture->h,
+                       GL_RGB, GL_UNSIGNED_SHORT_5_6_5, texture->pixels);
+        break;
+    case 24:
+        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, texture->w, texture->h,
+                       GL_RGB, GL_UNSIGNED_BYTE, texture->pixels);
+        break;
+    case 32:
+    default:
+        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, texture->w, texture->h,
+                       GL_RGBA, GL_UNSIGNED_BYTE, texture->pixels);
+        break;
+    }     
        
        switch (texturetype)
        {
@@ -146,8 +279,11 @@ void sdlemu_draw_texture(SDL_Surface * dst, SDL_Surface * src, int texturetype)
                                glTexCoord2f(texcoord[2], texcoord[3]); glVertex3i(dst->w, dst->h, 0);
                glEnd();
        }
-
+       
+//  glFlush();
        SDL_GL_SwapBuffers();    
+//     glFinish();
+
 }
 
 void sdlemu_close_opengl(void)
@@ -163,30 +299,121 @@ void sdlemu_close_opengl(void)
 // but, at the moment, it doesn't...
 // Now it does...!
 //
-void sdlemu_resize_texture(SDL_Surface * src, SDL_Surface * dst, int filter)
+void sdlemu_resize_texture(SDL_Surface * src, SDL_Surface * dst, int filter, int src_bpp)
 {
        // Texture width/height should be power of 2
        // So, find the largest power of two that will contain both the width and height
-       int w = power_of_two(src->w), h = power_of_two(src->h);
-
+       //int w = power_of_two(src->w), h = power_of_two(src->h);
+       int w = 512, h = 512;
+       Uint32 rmask, gmask, bmask, amask;
+       
+       // We allow the developer to set its own texture bpp. But if the value is NULL or
+       // not equal to 16, 24 or 32, we make the texturebpp the same as the BPP from src.
+       if ( (src_bpp != NULL) && ( (src_bpp == 16) || (src_bpp == 24) || (src_bpp == 32) ) )
+       texturebpp = src_bpp;
+    else
+       texturebpp = src->format->BitsPerPixel;
+       
        // Delete old texture (if allocated)
        if (texture)
                SDL_FreeSurface(texture);
 
        // create texture surface
-//NOTE: Seems the byte order here *is* important! (Perhaps only for 32 BPP?)
-       texture = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32,
+       //NOTE: Seems the byte order here *is* important! (Perhaps only for 32 BPP?)
+       //
+       // NOTE : Nope! Not any more. We can now producte textures based upon 16, 24 or 32 bpp.
+       switch ( texturebpp )
+       {
+    case 16:
+    #if SDL_BYTEORDER == SDL_BIG_ENDIAN
+
+//         rmask = 0xff000000;
+//             gmask = 0x00ff0000;
+//             bmask = 0x0000ff00;
+//             amask = 0x00000000;
+
+        rmask = 0x0000;
+               gmask = 0x0000;
+               bmask = 0x0000;
+               amask = 0x0000;
+               
+       #else
+
+//         rmask = 0x000000ff;
+//         gmask = 0x0000ff00;
+//         bmask = 0x00ff0000;
+//         amask = 0x00000000;
+
+        rmask = 0x0000;
+               gmask = 0x0000;
+               bmask = 0x0000;
+               amask = 0x0000;
+
+    #endif
+        break;
+    case 24:
+    #if SDL_BYTEORDER == SDL_BIG_ENDIAN
+           rmask = 0x00ff0000;
+               gmask = 0x0000ff00;
+               bmask = 0x000000ff;
+               amask = 0x00000000;
+       #else
+           rmask = 0x000000ff;
+           gmask = 0x0000ff00;
+           bmask = 0x00ff0000;
+           amask = 0x00000000;
+    #endif
+       break;
+    case 32: 
+    default:
+    #if SDL_BYTEORDER == SDL_BIG_ENDIAN
+           rmask = 0xff000000;
+               gmask = 0x00ff0000;
+               bmask = 0x0000ff00;
+               amask = 0x000000ff;
+       #else
+           rmask = 0x000000ff;
+           gmask = 0x0000ff00;
+           bmask = 0x00ff0000;
+           amask = 0xff000000;
+    #endif
+        break;
+    }    
+
+       // create texture surface
+       texture = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, texturebpp, rmask, gmask, bmask, amask);
+/*     
+    #if SDL_BYTEORDER == SDL_LIL_ENDIAN 
+               0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000);
+       #else
+               0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF);
+       #endif
+*/
+       
+/* 
+    texture = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32,
        #if SDL_BYTEORDER == SDL_LIL_ENDIAN 
                0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000);
        #else
                0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF);
        #endif
-
+*/
        // setup 2D gl environment
-       glPushAttrib(GL_ENABLE_BIT);
-       glDisable(GL_DEPTH_TEST);
+       //glPushAttrib(GL_ENABLE_BIT);
+       //glDisable(GL_DEPTH_TEST);
+       //glDisable(GL_CULL_FACE);
+       //glEnable(GL_TEXTURE_2D);
+
+       glDisable(GL_FOG);
+       glDisable(GL_LIGHTING);
        glDisable(GL_CULL_FACE);
+       glDisable(GL_DEPTH_TEST);
+       glDisable(GL_BLEND);
+       glDisable(GL_NORMALIZE);
+       glDisable(GL_ALPHA_TEST);
        glEnable(GL_TEXTURE_2D);
+       glBlendFunc (GL_SRC_ALPHA, GL_ONE);
 
        glViewport(0, 0, dst->w, dst->h);
 
@@ -222,5 +449,19 @@ void sdlemu_resize_texture(SDL_Surface * src, SDL_Surface * dst, int filter)
           glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
     }
 
-       glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture->w, texture->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture->pixels);
+    switch ( texturebpp )
+    {
+    case 16:
+           glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB5, texture->w, texture->h, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
+        break;
+    case 24:
+           glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, texture->w, texture->h, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
+        break;
+    case 32:
+    default:
+           glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, texture->w, texture->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+        break;        
+    }    
+
+       //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, texture->w, texture->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
 }
index bfc3097662c23d08709457eab0b8ba12b7b15844..4d3ffea6578a719dc3845a638b502d478adbba58 100644 (file)
@@ -34,8 +34,12 @@ bool InitVideo(void)
 
        if (vjs.useOpenGL)
        {
-               mainSurfaceFlags = SDL_HWSURFACE | SDL_HWPALETTE | SDL_DOUBLEBUF | SDL_OPENGL;
-               SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
+           SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 0);
+        SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
+
+//             mainSurfaceFlags = SDL_HWSURFACE | SDL_HWPALETTE | SDL_DOUBLEBUF | SDL_OPENGL;
+               mainSurfaceFlags = SDL_OPENGL;
+               
        }
        else
        {
@@ -71,6 +75,7 @@ bool InitVideo(void)
        // Create the primary SDL display (16 BPP, 5/5/5 RGB format)
        surface = SDL_CreateRGBSurface(SDL_SWSURFACE, VIRTUAL_SCREEN_WIDTH,
                (vjs.hardwareTypeNTSC ? VIRTUAL_SCREEN_HEIGHT_NTSC : VIRTUAL_SCREEN_HEIGHT_PAL),
+//             16, 63488, 2016, 31, 0);
                16, 0x7C00, 0x03E0, 0x001F, 0);
 
        if (surface == NULL)
@@ -82,7 +87,7 @@ bool InitVideo(void)
        if (vjs.useOpenGL)
 //Should make another setting here, for either linear or nearest (instead of just picking one)
 //And we have! ;-)
-               sdlemu_init_opengl(surface, 1/*method*/, 2/*size*/, vjs.glFilter/*texture type (linear, nearest)*/);
+               sdlemu_init_opengl(surface, 1/*method*/, 2/*size*/, vjs.glFilter/*texture type (linear, nearest)*/, NULL);
 
        // Initialize Joystick support under SDL
        if (vjs.useJoystick)
@@ -161,8 +166,9 @@ void ResizeScreen(uint32 width, uint32 height)
        char window_title[256];
 
        SDL_FreeSurface(surface);
-       surface = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 16,
-               0x7C00, 0x03E0, 0x001F, 0);
+       surface = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 
+//             16, 63488, 2016, 31, 0);
+        16, 0x7C00, 0x03E0, 0x001F, 0);
 
        if (surface == NULL)
        {
@@ -178,7 +184,7 @@ void ResizeScreen(uint32 width, uint32 height)
 //Err, we should only do this *if* we changed from PAL to NTSC or vice versa... !!! FIX !!!
                mainSurface = SDL_SetVideoMode(VIRTUAL_SCREEN_WIDTH * 2, height * 2, 16, mainSurfaceFlags);
                // This seems to work well for resizing (i.e., changes in the pixel width)...
-               sdlemu_resize_texture(surface, mainSurface, vjs.glFilter);
+               sdlemu_resize_texture(surface, mainSurface, vjs.glFilter, NULL);
        }
        else
        {
@@ -209,8 +215,8 @@ uint32 GetSDLScreenPitch(void)
 void ToggleFullscreen(void)
 {
 //NOTE: This does *NOT* work with OpenGL rendering! !!! FIX !!!
-       if (vjs.useOpenGL)
-               return;                                                                         // Until we can fix it...
+//     if (vjs.useOpenGL)
+//             return;                                                                         // Until we can fix it...
 
        vjs.fullscreen = !vjs.fullscreen;
        mainSurfaceFlags &= ~SDL_FULLSCREEN;