add ogl paletted texture support (d1x r1.36, r1.38, r1.5, r1.24)
authorBradley Bell <btb@icculus.org>
Sat, 22 May 2004 08:43:11 +0000 (08:43 +0000)
committerBradley Bell <btb@icculus.org>
Sat, 22 May 2004 08:43:11 +0000 (08:43 +0000)
ChangeLog
arch/ogl/gr.c
arch/ogl/ogl.c
include/loadgl.h
include/ogl_init.h

index 90e448f..258b4c1 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 2004-05-22  Matthew Mueller  <donut@dakotacom.net>
 
+       * arch/ogl/gr.c, arch/ogl/ogl.c, include/loadgl.h,
+       include/ogl_init.h: add ogl paletted texture support (d1x r1.36,
+       r1.38, r1.5, r1.24)
+
        * 2d/font.c: memset ogl font bitmap data since the copy function
        leaves some (unused) parts uninitialized, which aggravates
        valgrind (d1x r1.14)
index a3d278f..a5e32e5 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: gr.c,v 1.26 2004-05-22 07:55:34 btb Exp $ */
+/* $Id: gr.c,v 1.27 2004-05-22 08:42:59 btb Exp $ */
 /*
  *
  * OGL video functions. - Added 9/15/99 Matthew Mueller
@@ -183,6 +183,7 @@ void ogl_get_verinfo(void)
        dglActiveTextureARB = (glActiveTextureARB_fp)wglGetProcAddress("glActiveTextureARB");
        dglMultiTexCoord2fSGIS = (glMultiTexCoord2fSGIS_fp)wglGetProcAddress("glMultiTexCoord2fSGIS");
        dglSelectTextureSGIS = (glSelectTextureSGIS_fp)wglGetProcAddress("glSelectTextureSGIS");
+       dglColorTableEXT = (glColorTableEXT_fp)wglGetProcAddress("glColorTableEXT");
 #endif
 
 #ifdef GL_ARB_multitexture
@@ -199,6 +200,10 @@ void ogl_get_verinfo(void)
        if (ogl_ext_texture_filter_anisotropic_ok)
                glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &anisotropic_max);
 
+#ifdef GL_EXT_paletted_texture
+       ogl_paletted_texture_ok = (strstr(gl_extensions, "GL_EXT_paletted_texture") != 0 && glColorTableEXT != 0);
+       ogl_shared_palette_ok = (strstr(gl_extensions, "GL_EXT_shared_texture_palette") != 0 && ogl_paletted_texture_ok);
+#endif
        //add driver specific hacks here.  whee.
        if ((stricmp(gl_renderer,"Mesa NVIDIA RIVA 1.0\n")==0 || stricmp(gl_renderer,"Mesa NVIDIA RIVA 1.2\n")==0) && stricmp(gl_version,"1.2 Mesa 3.0")==0){
                ogl_intensity4_ok=0;//ignores alpha, always black background instead of transparent.
@@ -226,6 +231,18 @@ void ogl_get_verinfo(void)
        }
        if (ogl_sgis_multitexture_ok)
                glGetIntegerv(GL_MAX_TEXTURES_SGIS, &sgi_max_textures);
+#endif
+#ifdef GL_EXT_paletted_texture
+       if ((t = FindArg("-gl_paletted_texture_ok")))
+       {
+               ogl_paletted_texture_ok = atoi(Args[t + 1]);
+       }
+       if ((t = FindArg("-gl_shared_palette_ok")))
+       {
+               ogl_shared_palette_ok = atoi(Args[t + 1]);
+       }
+       ogl_shared_palette_ok = ogl_shared_palette_ok && ogl_paletted_texture_ok; // shared palettes require palette support in the first place, obviously ;)
+       printf("gl_paletted_texture: %i  gl_shared_palette: %i  (using paletted textures: %i)\n", ogl_paletted_texture_ok, ogl_shared_palette_ok, ogl_shared_palette_ok);
 #endif
        if ((t=FindArg("-gl_intensity4_ok"))){
                ogl_intensity4_ok=atoi(Args[t+1]);
@@ -646,6 +663,8 @@ void gr_palette_load( ubyte *pal )
        gr_palette_step_up(0, 0, 0); // make ogl_setbrightness_internal get run so that menus get brightened too.
 
  init_computed_colors();
+
+       ogl_init_shared_palette();
 }
 
 
index 6f779bd..d1787c9 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: ogl.c,v 1.25 2004-05-20 07:43:57 btb Exp $ */
+/* $Id: ogl.c,v 1.26 2004-05-22 08:43:02 btb Exp $ */
 /*
  *
  * Graphics support functions for OpenGL.
@@ -91,6 +91,10 @@ int ogl_sgis_multitexture_ok=0;
 #endif
 int ogl_nv_texture_env_combine4_ok = 0;
 int ogl_ext_texture_filter_anisotropic_ok = 0;
+#ifdef GL_EXT_paletted_texture
+int ogl_shared_palette_ok = 0;
+int ogl_paletted_texture_ok = 0;
+#endif
 
 int sphereh=0;
 int cross_lh[2]={0,0};
@@ -116,7 +120,7 @@ extern GLubyte texbuf[OGLTEXBUFSIZE];
 void ogl_filltexbuf(unsigned char *data,GLubyte *texp,int truewidth,int width,int height,int dxo,int dyo,int twidth,int theight,int type);
 void ogl_loadbmtexture(grs_bitmap *bm);
 //void ogl_loadtexture(unsigned char * data, int width, int height,int dxo,intdyo , int *texid,float *u,float *v,char domipmap,float prio);
-void ogl_loadtexture(unsigned char * data, int dxo,int dyo, ogl_texture *tex);
+void ogl_loadtexture(unsigned char *data, int dxo, int dyo, ogl_texture *tex, int bm_flags);
 void ogl_freetexture(ogl_texture *gltexture);
 void ogl_do_palfx(void);
 
@@ -1134,7 +1138,7 @@ bool ogl_ubitblt_i(int dw,int dh,int dx,int dy, int sw, int sh, int sx, int sy,
        
 //     oldpal=ogl_pal;
        ogl_pal=gr_current_pal;
-       ogl_loadtexture(src->bm_data,sx,sy,&tex);
+       ogl_loadtexture(src->bm_data, sx, sy, &tex, src->bm_flags);
 //     ogl_pal=oldpal;
        ogl_pal=gr_palette;
        OGL_BINDTEXTURE(tex.handle);
@@ -1349,6 +1353,38 @@ void ogl_swap_buffers(void){
        glClear(GL_COLOR_BUFFER_BIT);
 }
 
+void ogl_init_shared_palette(void)
+{
+#ifdef GL_EXT_paletted_texture
+       if (ogl_shared_palette_ok)
+       {
+               int i;
+
+               glEnable(GL_SHARED_TEXTURE_PALETTE_EXT);
+               //glColorTableEXT(GL_SHARED_TEXTURE_PALETTE_EXT, GL_RGB, 256, GL_RGB, GL_UNSIGNED_BYTE, ogl_pal);
+
+               for (i = 0; i < 256; i++)
+               {
+                       if (i == 255)
+                       {
+                               texbuf[i * 4] = 0;
+                               texbuf[i * 4 + 1] = 0;
+                               texbuf[i * 4 + 2] = 0;
+                               texbuf[i * 4 + 3] = 0;
+                       }
+                       else
+                       {
+                               texbuf[i * 4] = gr_current_pal[i * 3] * 4;
+                               texbuf[i * 4 + 1] = gr_current_pal[i * 3 + 1] * 4;
+                               texbuf[i * 4 + 2] = gr_current_pal[i * 3 + 2] * 4;
+                               texbuf[i * 4 + 3] = 255;
+                       }
+               }
+               glColorTableEXT(GL_SHARED_TEXTURE_PALETTE_EXT, GL_RGBA, 256, GL_RGBA, GL_UNSIGNED_BYTE, texbuf);
+       }
+#endif
+}
+
 int tex_format_supported(int iformat,int format){
        switch (iformat){
                case GL_INTENSITY4:
@@ -1410,6 +1446,12 @@ void ogl_filltexbuf(unsigned char *data,GLubyte *texp,int truewidth,int width,in
                                                (*(texp++))=0;
                                                (*(texp++))=0;//transparent pixel
                                                break;
+                                       case GL_COLOR_INDEX:
+                                               (*(texp++)) = c;
+                                               break;
+                                       default:
+                                               Error("ogl_filltexbuf unknown texformat\n");
+                                               break;
                                }
 //                             (*(tex++))=0;
                        }else{
@@ -1431,6 +1473,12 @@ void ogl_filltexbuf(unsigned char *data,GLubyte *texp,int truewidth,int width,in
                                                (*(texp++))=255;//not transparent
                                                //                              (*(tex++))=(ogl_pal[c*3]>>1) + ((ogl_pal[c*3+1]>>1)<<5) + ((ogl_pal[c*3+2]>>1)<<10) + (1<<15);
                                                break;
+                                       case GL_COLOR_INDEX:
+                                               (*(texp++)) = c;
+                                               break;
+                                       default:
+                                               Error("ogl_filltexbuf unknown texformat\n");
+                                               break;
                                }
                        }
                }
@@ -1493,6 +1541,13 @@ void tex_set_size(ogl_texture *tex){
                glGetTexLevelParameteriv(GL_TEXTURE_2D,0,GL_TEXTURE_GREEN_SIZE,&t);a+=t;
                glGetTexLevelParameteriv(GL_TEXTURE_2D,0,GL_TEXTURE_BLUE_SIZE,&t);a+=t;
                glGetTexLevelParameteriv(GL_TEXTURE_2D,0,GL_TEXTURE_ALPHA_SIZE,&t);a+=t;
+#ifdef GL_EXT_paletted_texture
+               if (ogl_paletted_texture_ok)
+               {
+                       glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INDEX_SIZE_EXT, &t);
+                       a += t;
+               }
+#endif
        }else{
                w=tex->tw;
                h=tex->th;
@@ -1507,6 +1562,9 @@ void tex_set_size(ogl_texture *tex){
                case GL_RGBA:
                        bi=16;
                        break;
+               case GL_COLOR_INDEX:
+                       bi = 8;
+                       break;
                default:
                        Error("tex_set_size unknown texformat\n");
                        break;
@@ -1518,7 +1576,7 @@ void tex_set_size(ogl_texture *tex){
 //In theory this could be a problem for repeating textures, but all real
 //textures (not sprites, etc) in descent are 64x64, so we are ok.
 //stores OpenGL textured id in *texid and u/v values required to get only the real data in *u/*v
-void ogl_loadtexture(unsigned char * data, int dxo,int dyo, ogl_texture *tex)
+void ogl_loadtexture(unsigned char *data, int dxo, int dyo, ogl_texture *tex, int bm_flags)
 {
 //void ogl_loadtexture(unsigned char * data, int width, int height,int dxo,int dyo, int *texid,float *u,float *v,char domipmap,float prio){
 //     int internalformat=GL_RGBA;
@@ -1539,6 +1597,31 @@ void ogl_loadtexture(unsigned char * data, int dxo,int dyo, ogl_texture *tex)
        tex->u=(float)tex->w/(float)tex->tw;
        tex->v=(float)tex->h/(float)tex->th;
 
+#ifdef GL_EXT_paletted_texture
+       if (ogl_shared_palette_ok && tex->format == GL_RGBA)
+       {
+               // descent makes palette entries 254 and 255 both do double duty, depending upon the setting of BM_FLAG_SUPER_TRANSPARENT and BM_FLAG_TRANSPARENT.
+               // So if the texture doesn't have BM_FLAG_TRANSPARENT set, yet uses index 255, we cannot use the palette for it since that color would be incorrect. (this case is much less common than transparent textures, hence why we don't exclude those instead.)
+               // We don't handle super transparent textures with ogl yet, so we don't bother checking that here.
+               int usesthetransparentindexcolor = 0;
+               if (!(bm_flags & BM_FLAG_TRANSPARENT))
+               {
+                       int i;
+
+                       for (i=0; i < tex->w * tex->h; ++i)
+                               if (data[i] == 255)
+                                       usesthetransparentindexcolor += 1;
+               }
+               if (!usesthetransparentindexcolor)
+               {
+                       tex->internalformat = GL_COLOR_INDEX8_EXT;
+                       tex->format = GL_COLOR_INDEX;
+               }
+               //else
+               //      printf("bm data=%p w=%i h=%i used the transparent color %i times\n",data, tex->w, tex->h, usesthetransparentindexcolor);
+       }
+#endif
+
        //      if (width!=twidth || height!=theight)
        //              glmprintf((0,"sizing %ix%i texture up to %ix%i\n",width,height,twidth,theight));
        ogl_filltexbuf(data,texbuf,tex->lw,tex->w,tex->h,dxo,dyo,tex->tw,tex->th,tex->format);
@@ -1630,7 +1713,7 @@ void ogl_loadbmtexture_m(grs_bitmap *bm,int domipmap)
                }
                buf=decodebuf;
        }
-       ogl_loadtexture(buf,0,0,bm->gltexture);
+       ogl_loadtexture(buf, 0, 0, bm->gltexture, bm->bm_flags);
 }
 
 void ogl_loadbmtexture(grs_bitmap *bm)
index abdf39c..bf9c688 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: loadgl.h,v 1.7 2004-05-20 03:31:34 btb Exp $ */
+/* $Id: loadgl.h,v 1.8 2004-05-22 08:43:08 btb Exp $ */
 /*
  *
  * dynamic opengl loading - courtesy of Jeff Slutter
 #define GL_MAX_TEXTURES_SGIS 0x835D
 #endif
 
+#ifndef GL_EXT_paletted_texture
+#define GL_EXT_paletted_texture 1
+#define GL_COLOR_INDEX8_EXT 0x80E5
+#define GL_TEXTURE_INDEX_SIZE_EXT 0x80ED
+#endif
+
 #ifdef _cplusplus
 #define OEXTERN        extern "C"
 #else
 #define glMultiTexCoord2fSGIS dglMultiTexCoord2fSGIS
 #define glSelectTextureSGIS dglSelectTextureSGIS
 
+#define glColorTableEXT dglColorTableEXT
+
 #ifdef _WIN32
 #define wglCopyContext dwglCopyContext
 #define wglCreateContext dwglCreateContext
@@ -755,6 +763,7 @@ typedef void (OGLFUNCCALL *glMultiTexCoord2fARB_fp)(GLenum target, GLfloat s, GL
 typedef void (OGLFUNCCALL *glActiveTextureARB_fp)(GLenum target);
 typedef void (OGLFUNCCALL *glMultiTexCoord2fSGIS_fp)(GLenum target, GLfloat s, GLfloat t);
 typedef void (OGLFUNCCALL *glSelectTextureSGIS_fp)(GLenum target);
+typedef void (OGLFUNCCALL *glColorTableEXT_fp)(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table);
 
 #ifdef _WIN32
 typedef BOOL  (OGLFUNCCALL *wglCopyContext_fp)(HGLRC, HGLRC, UINT);
@@ -1121,6 +1130,7 @@ DEFVAR glMultiTexCoord2fARB_fp dglMultiTexCoord2fARB;
 DEFVAR glActiveTextureARB_fp dglActiveTextureARB;
 DEFVAR glMultiTexCoord2fSGIS_fp dglMultiTexCoord2fSGIS;
 DEFVAR glSelectTextureSGIS_fp dglSelectTextureSGIS;
+DEFVAR glColorTableEXT_fp dglColorTableEXT;
 
 #ifdef _WIN32
 DEFVAR wglCopyContext_fp dwglCopyContext;
@@ -1937,6 +1947,7 @@ void OpenGL_SetFuncsToNull(void)
        dglActiveTextureARB = NULL;
        dglMultiTexCoord2fSGIS = NULL;
        dglSelectTextureSGIS = NULL;
+       dglColorTableEXT = NULL;
 
 #ifdef _WIN32
        dwglCopyContext = NULL;
index b00a232..2d506e2 100644 (file)
@@ -26,6 +26,7 @@ int ogl_init_load_library(void);
 #if defined(__APPLE__) && defined(__MACH__)
 #include <OpenGL/gl.h>
 #else
+#define GL_GLEXT_PROTOTYPES
 #include <GL/gl.h>
 #endif
 #endif
@@ -105,6 +106,17 @@ extern int ogl_nv_texture_env_combine4_ok;
 #endif
 extern int ogl_ext_texture_filter_anisotropic_ok;
 
+#ifndef GL_EXT_shared_texture_palette
+#define GL_EXT_shared_texture_palette     1
+#define GL_SHARED_TEXTURE_PALETTE_EXT     0x81FB
+#endif
+
+#ifdef GL_EXT_paletted_texture
+extern int ogl_paletted_texture_ok;
+extern int ogl_shared_palette_ok;
+#endif
+void ogl_init_shared_palette(void);
+
 extern int gl_initialized;
 extern int GL_texmagfilt,GL_texminfilt,GL_needmipmaps;
 extern float GL_texanisofilt;