added support for GL_ARB_texture_env_combine, currently only used on wall rendering...
authorlordhavoc <lordhavoc@d7cf8633-e32d-0410-b094-e92efae38249>
Tue, 30 Oct 2001 21:55:46 +0000 (21:55 +0000)
committerlordhavoc <lordhavoc@d7cf8633-e32d-0410-b094-e92efae38249>
Tue, 30 Oct 2001 21:55:46 +0000 (21:55 +0000)
git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@988 d7cf8633-e32d-0410-b094-e92efae38249

gl_poly.c
gl_rmain.c
gl_rsurf.c
gl_screen.c
glquake.h
model_brush.h
render.h
vid_shared.c

index 67def33..0992cb1 100644 (file)
--- a/gl_poly.c
+++ b/gl_poly.c
@@ -420,12 +420,54 @@ void wallpolyrender(void)
        }
        else if (r_multitexture.value)
        {
-               qglSelectTexture(gl_mtex_enum+0);
-               glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
-               glEnable(GL_TEXTURE_2D);
-               qglSelectTexture(gl_mtex_enum+1);
-               glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-               glEnable(GL_TEXTURE_2D);
+               if (gl_combine.value)
+               {
+                       qglSelectTexture(gl_mtex_enum+0);
+                       glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
+                       glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE);
+                       glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
+                       glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE);
+                       glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_TEXTURE);
+                       glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
+                       glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);
+                       glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_COLOR);
+                       glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
+                       glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_TEXTURE);
+                       glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA_ARB, GL_TEXTURE);
+                       glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
+                       glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_ARB, GL_SRC_ALPHA);
+                       glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA_ARB, GL_SRC_ALPHA);
+                       glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1.0);
+                       glTexEnvf(GL_TEXTURE_ENV, GL_ALPHA_SCALE, 1.0);
+                       glEnable(GL_TEXTURE_2D);
+                       qglSelectTexture(gl_mtex_enum+1);
+                       glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
+                       glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
+                       glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
+                       glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
+                       glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_TEXTURE);
+                       glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
+                       glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);
+                       glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_COLOR);
+                       glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
+                       glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_PREVIOUS_ARB);
+                       glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA_ARB, GL_TEXTURE);
+                       glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
+                       glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_ARB, GL_SRC_ALPHA);
+                       glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA_ARB, GL_SRC_ALPHA);
+                       glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 4.0);
+                       glTexEnvf(GL_TEXTURE_ENV, GL_ALPHA_SCALE, 1.0);
+                       glEnable(GL_TEXTURE_2D);
+               }
+               else
+               {
+                       qglSelectTexture(gl_mtex_enum+0);
+                       glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+                       glEnable(GL_TEXTURE_2D);
+                       qglSelectTexture(gl_mtex_enum+1);
+                       glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+                       glEnable(GL_TEXTURE_2D);
+               }
                texnum = -1;
                lighttexnum = -1;
                for (i = 0,p = wallpoly;i < currentwallpoly;i++, p++)
index f11072e..57f7dd9 100644 (file)
@@ -329,6 +329,7 @@ GL_Init
 ===============
 */
 extern char *ENGINE_EXTENSIONS;
+extern void VID_CheckCombine(void);
 void GL_Init (void)
 {
        gl_vendor = glGetString (GL_VENDOR);
@@ -345,6 +346,7 @@ void GL_Init (void)
 
        VID_CheckMultitexture();
        VID_CheckCVA();
+       VID_CheckCombine();
 
        // LordHavoc: report supported extensions
        Con_Printf ("\nengine extensions: %s\n", ENGINE_EXTENSIONS);
@@ -940,8 +942,6 @@ void R_RenderView (void)
        R_MoveParticles ();
        R_MoveExplosions();
 
-       lighthalf = gl_lightmode.value;
-
        FOG_framebegin();
 
        R_Clear();
index a5987aa..8797b9d 100644 (file)
@@ -194,63 +194,32 @@ int R_AddDynamicLights (msurface_t *surf)
 
 void R_ConvertLightmap (int *in, byte *out, int width, int height, int stride)
 {
-       int i, j;
+       int i, j, shift;
        stride -= (width*lightmapbytes);
-       if (lighthalf)
+       // deal with lightmap brightness scale
+       shift = 7 + lightscalebit;
+       if (lightmaprgba)
        {
-               // LordHavoc: I shift down by 8 unlike GLQuake's 7,
-               // the image is brightened as a processing pass
-               if (lightmaprgba)
+               for (i = 0;i < height;i++, out += stride)
                {
-                       for (i = 0;i < height;i++, out += stride)
+                       for (j = 0;j < width;j++, in += 3, out += 4)
                        {
-                               for (j = 0;j < width;j++, in += 3, out += 4)
-                               {
-                                       out[0] = min(in[0] >> 8, 255);
-                                       out[1] = min(in[1] >> 8, 255);
-                                       out[2] = min(in[2] >> 8, 255);
-                                       out[3] = 255;
-                               }
-                       }
-               }
-               else
-               {
-                       for (i = 0;i < height;i++, out += stride)
-                       {
-                               for (j = 0;j < width;j++, in += 3, out += 3)
-                               {
-                                       out[0] = min(in[0] >> 8, 255);
-                                       out[1] = min(in[1] >> 8, 255);
-                                       out[2] = min(in[2] >> 8, 255);
-                               }
+                               out[0] = min(in[0] >> shift, 255);
+                               out[1] = min(in[1] >> shift, 255);
+                               out[2] = min(in[2] >> shift, 255);
+                               out[3] = 255;
                        }
                }
        }
        else
        {
-               if (lightmaprgba)
-               {
-                       for (i = 0;i < height;i++, out += stride)
-                       {
-                               for (j = 0;j < width;j++, in += 3, out += 4)
-                               {
-                                       out[0] = min(in[0] >> 7, 255);
-                                       out[1] = min(in[1] >> 7, 255);
-                                       out[2] = min(in[2] >> 7, 255);
-                                       out[3] = 255;
-                               }
-                       }
-               }
-               else
+               for (i = 0;i < height;i++, out += stride)
                {
-                       for (i = 0;i < height;i++, out += stride)
+                       for (j = 0;j < width;j++, in += 3, out += 3)
                        {
-                               for (j = 0;j < width;j++, in += 3, out += 3)
-                               {
-                                       out[0] = min(in[0] >> 7, 255);
-                                       out[1] = min(in[1] >> 7, 255);
-                                       out[2] = min(in[2] >> 7, 255);
-                               }
+                               out[0] = min(in[0] >> shift, 255);
+                               out[1] = min(in[1] >> shift, 255);
+                               out[2] = min(in[2] >> shift, 255);
                        }
                }
        }
@@ -273,7 +242,7 @@ void R_BuildLightMap (msurface_t *surf, byte *dest, int stride)
        int             *bl;
 
        surf->cached_dlight = 0;
-       surf->cached_lighthalf = lighthalf;
+       surf->cached_lightscalebit = lightscalebit;
        surf->cached_ambient = r_ambient.value;
 
        smax = (surf->extents[0]>>4)+1;
@@ -658,7 +627,7 @@ void RSurf_DrawWall(msurface_t *s, texture_t *t, int transform)
        if (s->cached_dlight
         || (r_dynamic.value && r_dlightmap.value && s->dlightframe == r_framecount)
         || r_ambient.value != s->cached_ambient
-        || lighthalf != s->cached_lighthalf
+        || lightscalebit != s->cached_lightscalebit
         || (r_dynamic.value
         && ((s->styles[0] != 255 && d_lightstylevalue[s->styles[0]] != s->cached_light[0])
         || (s->styles[1] != 255 && d_lightstylevalue[s->styles[1]] != s->cached_light[1])
index 977c4a0..729e292 100644 (file)
@@ -65,7 +65,7 @@ console is:
        notify lines
        half
        full
-       
+
 
 */
 
@@ -98,6 +98,9 @@ qpic_t                *scr_turtle;
 int                    clearconsole;
 int                    clearnotify;
 
+int                    lightscalebit;
+float          lightscale;
+
 qboolean       scr_disabled_for_loading;
 //qboolean     scr_drawloading;
 //float                scr_disabled_time;
@@ -226,19 +229,19 @@ CalcFov
 */
 float CalcFov (float fov_x, float width, float height)
 {
-        float   a;
-        float   x;
+       float   a;
+       float   x;
 
-        if (fov_x < 1 || fov_x > 179)
-                Sys_Error ("Bad fov: %f", fov_x);
+       if (fov_x < 1 || fov_x > 179)
+               Sys_Error ("Bad fov: %f", fov_x);
 
-        x = width/tan(fov_x/360*M_PI);
+       x = width/tan(fov_x/360*M_PI);
 
-        a = atan (height/x);
+       a = atan (height/x);
 
-        a = a*360/M_PI;
+       a = a*360/M_PI;
 
-        return a;
+       return a;
 }
 
 /*
@@ -272,7 +275,7 @@ static void SCR_CalcRefdef (void)
        if (scr_fov.value > 170)
                Cvar_Set ("fov","170");
 
-// intermission is always full screen  
+// intermission is always full screen
        if (cl.intermission)
        {
                full = true;
@@ -315,7 +318,7 @@ static void SCR_CalcRefdef (void)
        r_refdef.vrect.x = (vid.width - r_refdef.vrect.width)/2;
        if (full)
                r_refdef.vrect.y = 0;
-       else 
+       else
                r_refdef.vrect.y = (h - r_refdef.vrect.height)/2;
 
        r_refdef.fov_x = scr_fov.value;
@@ -567,7 +570,7 @@ void SCR_DrawConsole (void)
 }
 
 
-/* 
+/*
 ============================================================================== 
  
                                                SCREEN SHOTS 
@@ -600,7 +603,7 @@ void SCR_ScreenShot_f (void)
                sprintf (checkname, "%s/%s", com_gamedir, filename);
                if (Sys_FileTime(checkname) == -1)
                        break;  // file doesn't exist
-       } 
+       }
        if (i==10000)
        {
                Con_Printf ("SCR_ScreenShot_f: Couldn't create a TGA file\n"); 
@@ -608,7 +611,7 @@ void SCR_ScreenShot_f (void)
        }
 
        buffer = qmalloc(glwidth*glheight*3);
-       glReadPixels (glx, gly, glwidth, glheight, GL_RGB, GL_UNSIGNED_BYTE, buffer); 
+       glReadPixels (glx, gly, glwidth, glheight, GL_RGB, GL_UNSIGNED_BYTE, buffer);
        Image_WriteTGARGB_preflipped(filename, glwidth, glheight, buffer);
 
        qfree(buffer);
@@ -686,7 +689,7 @@ void SCR_DrawNotifyString (void)
                x = (vid.width - l*8)/2;
                // LordHavoc: speedup
 //             for (j=0 ; j<l ; j++, x+=8)
-//                     Draw_Character (x, y, start[j]);        
+//                     Draw_Character (x, y, start[j]);
                Draw_String (x, y, start, l);
 
                y += 8;
@@ -809,6 +812,20 @@ void SCR_UpdateScreen (void)
 
        GL_BeginRendering (&glx, &gly, &glwidth, &glheight);
 
+       if (gl_combine.value && !gl_combine_extension)
+               Cvar_SetValue("gl_combine", false);
+
+       lighthalf = gl_lightmode.value;
+
+       lightscalebit = 0;
+       if (lighthalf)
+               lightscalebit += 1;
+
+       if (gl_combine.value)
+               lightscalebit += 2;
+
+       lightscale = 1.0f / (float) (1 << lightscalebit);
+
        //
        // determine size of refresh window
        //
index 7a521f1..1aae6b0 100644 (file)
--- a/glquake.h
+++ b/glquake.h
@@ -137,7 +137,7 @@ extern void (GLAPIENTRY *qglUnlockArraysEXT) (void);
 
 
 #ifndef GL_ACTIVE_TEXTURE_ARB
-// multitexture
+// GL_ARB_multitexture
 #define GL_ACTIVE_TEXTURE_ARB                  0x84E0
 #define GL_CLIENT_ACTIVE_TEXTURE_ARB   0x84E1
 #define GL_MAX_TEXTURES_UNITS_ARB              0x84E2
@@ -145,9 +145,65 @@ extern void (GLAPIENTRY *qglUnlockArraysEXT) (void);
 #define GL_TEXTURE1_ARB                                        0x84C1
 #define GL_TEXTURE2_ARB                                        0x84C2
 #define GL_TEXTURE3_ARB                                        0x84C3
-// LordHavoc: ARB supports 32+ texture units, but hey I only use 2 anyway...
+#define GL_TEXTURE4_ARB                                        0x84C4
+#define GL_TEXTURE5_ARB                                        0x84C5
+#define GL_TEXTURE6_ARB                                        0x84C6
+#define GL_TEXTURE7_ARB                                        0x84C7
+#define GL_TEXTURE8_ARB                                        0x84C8
+#define GL_TEXTURE9_ARB                                        0x84C9
+#define GL_TEXTURE10_ARB                               0x84CA
+#define GL_TEXTURE11_ARB                               0x84CB
+#define GL_TEXTURE12_ARB                               0x84CC
+#define GL_TEXTURE13_ARB                               0x84CD
+#define GL_TEXTURE14_ARB                               0x84CE
+#define GL_TEXTURE15_ARB                               0x84CF
+#define GL_TEXTURE16_ARB                               0x84D0
+#define GL_TEXTURE17_ARB                               0x84D1
+#define GL_TEXTURE18_ARB                               0x84D2
+#define GL_TEXTURE19_ARB                               0x84D3
+#define GL_TEXTURE20_ARB                               0x84D4
+#define GL_TEXTURE21_ARB                               0x84D5
+#define GL_TEXTURE22_ARB                               0x84D6
+#define GL_TEXTURE23_ARB                               0x84D7
+#define GL_TEXTURE24_ARB                               0x84D8
+#define GL_TEXTURE25_ARB                               0x84D9
+#define GL_TEXTURE26_ARB                               0x84DA
+#define GL_TEXTURE27_ARB                               0x84DB
+#define GL_TEXTURE28_ARB                               0x84DC
+#define GL_TEXTURE29_ARB                               0x84DD
+#define GL_TEXTURE30_ARB                               0x84DE
+#define GL_TEXTURE31_ARB                               0x84DF
+#endif
+
+#ifndef GL_COMBINE_ARB
+// GL_ARB_texture_env_combine
+#define GL_COMBINE_ARB                                 0x8570
+#define GL_COMBINE_RGB_ARB                             0x8571
+#define GL_COMBINE_ALPHA_ARB                   0x8572
+#define GL_SOURCE0_RGB_ARB                             0x8580
+#define GL_SOURCE1_RGB_ARB                             0x8581
+#define GL_SOURCE2_RGB_ARB                             0x8582
+#define GL_SOURCE0_ALPHA_ARB                   0x8588
+#define GL_SOURCE1_ALPHA_ARB                   0x8589
+#define GL_SOURCE2_ALPHA_ARB                   0x858A
+#define GL_OPERAND0_RGB_ARB                            0x8590
+#define GL_OPERAND1_RGB_ARB                            0x8591
+#define GL_OPERAND2_RGB_ARB                            0x8592
+#define GL_OPERAND0_ALPHA_ARB                  0x8598
+#define GL_OPERAND1_ALPHA_ARB                  0x8599
+#define GL_OPERAND2_ALPHA_ARB                  0x859A
+#define GL_RGB_SCALE_ARB                               0x8573
+#define GL_ADD_SIGNED_ARB                              0x8574
+#define GL_INTERPOLATE_ARB                             0x8575
+#define GL_SUBTRACT_ARB                                        0x84E7
+#define GL_CONSTANT_ARB                                        0x8576
+#define GL_PRIMARY_COLOR_ARB                   0x8577
+#define GL_PREVIOUS_ARB                                        0x8578
 #endif
 
+extern qboolean gl_combine_extension;
+extern cvar_t gl_combine;
+
 #ifdef WIN32
 #else
 //#ifndef MESA
index 2d2634e..bd233df 100644 (file)
@@ -133,9 +133,9 @@ typedef struct msurface_s
 
        int                     lightmaptexturenum;
        byte            styles[MAXLIGHTMAPS];
-       unsigned short  cached_light[MAXLIGHTMAPS];     // values currently used in lightmap
+       unsigned short cached_light[MAXLIGHTMAPS];      // values currently used in lightmap
        short           cached_dlight;                          // LordHavoc: if lightmap was lit by dynamic lights, update on frame after end of effect to erase it
-       short           cached_lighthalf;                       // LordHavoc: to cause lightmap to be rerendered when lighthalf changes
+       short           cached_lightscalebit;           // LordHavoc: to cause lightmap to be rerendered when lighthalf changes
        float           cached_ambient;                         // LordHavoc: rerender lightmaps when r_ambient changes
        byte            *samples;               // [numstyles*surfsize]
 } msurface_t;
index 041c3bc..9d1fb63 100644 (file)
--- a/render.h
+++ b/render.h
@@ -8,7 +8,7 @@ of the License, or (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
 See the GNU General Public License for more details.
 
@@ -41,6 +41,8 @@ extern char r_speeds2_string[1024];
 // lighting stuff
 extern vec3_t lightspot;
 extern cvar_t r_ambient;
+extern int lightscalebit;
+extern float lightscale;
 
 // model rendering stuff
 extern float *aliasvert;
index 8852c35..f799f7d 100644 (file)
@@ -10,10 +10,13 @@ qboolean gl_supportslockarrays = false;
 // LordHavoc: ARB multitexture support
 qboolean gl_mtexable = false;
 int gl_mtex_enum = 0;
+// LordHavoc: ARB texture_env_combine support
+qboolean gl_combine_extension = false;
 
 cvar_t vid_mode = {0, "vid_mode", "0"};
 cvar_t vid_mouse = {CVAR_SAVE, "vid_mouse", "1"};
 cvar_t vid_fullscreen = {0, "vid_fullscreen", "1"};
+cvar_t gl_combine = {0, "gl_combine", "0"};
 
 void (GLAPIENTRY *qglMTexCoord2f) (GLenum, GLfloat, GLfloat);
 void (GLAPIENTRY *qglSelectTexture) (GLenum);
@@ -25,10 +28,30 @@ void Force_CenterView_f (void)
        cl.viewangles[PITCH] = 0;
 }
 
+void VID_CheckCombine(void)
+{
+       // LordHavoc: although texture_env_combine doesn't require multiple TMUs
+       // (it does require the multitexture extension however), it is useless to
+       // darkplaces without multiple TMUs...
+       if (gl_mtexable && strstr(gl_extensions, "GL_ARB_texture_env_combine "))
+       {
+               gl_combine_extension = true;
+               Cvar_SetValue("gl_combine", true);
+               Con_Printf("GL_ARB_texture_env_combine detected\n");
+       }
+       else
+       {
+               gl_combine_extension = false;
+               Cvar_SetValue("gl_combine", false);
+               Con_Printf("GL_ARB_texture_env_combine not detected\n");
+       }
+}
+
 void VID_InitCvars(void)
 {
        Cvar_RegisterVariable(&vid_mode);
        Cvar_RegisterVariable(&vid_mouse);
        Cvar_RegisterVariable(&vid_fullscreen);
+       Cvar_RegisterVariable(&gl_combine);
        Cmd_AddCommand("force_centerview", Force_CenterView_f);
 }