From 12a67e501416dc44c9817bd3a412feba83bf4ce0 Mon Sep 17 00:00:00 2001 From: Bradley Bell Date: Thu, 20 May 2004 03:31:36 +0000 Subject: [PATCH] utilize hardware multitexturing support if possible (requires GL_NV_texture_env_combine4 extension) (d1x r1.32, r1.30, r1.4, 1.22) --- ChangeLog | 5 ++ arch/ogl/gr.c | 19 +++-- arch/ogl/ogl.c | 208 ++++++++++++++++++++++++++++----------------- include/loadgl.h | 6 +- include/ogl_init.h | 40 ++++++++- 5 files changed, 188 insertions(+), 90 deletions(-) diff --git a/ChangeLog b/ChangeLog index cac80421..589c4261 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ 2004-05-19 Matthew Mueller + * arch/ogl/gr.c, arch/ogl/ogl.c, include/loadgl.c, + include/ogl_init.h: utilize hardware multitexturing support if + possible (requires GL_NV_texture_env_combine4 extension) (d1x + r1.32, r1.30, r1.4, 1.22) + * arch/ogl/glx.c: add ogl_setbrightness_internal stub for glx (d1x r1.17) diff --git a/arch/ogl/gr.c b/arch/ogl/gr.c index 00425dc1..92a1fcb5 100644 --- a/arch/ogl/gr.c +++ b/arch/ogl/gr.c @@ -1,4 +1,4 @@ -/* $Id: gr.c,v 1.21 2004-05-20 02:04:26 btb Exp $ */ +/* $Id: gr.c,v 1.22 2004-05-20 03:31:31 btb Exp $ */ /* * * OGL video functions. - Added 9/15/99 Matthew Mueller @@ -160,8 +160,9 @@ void gr_update() const char *gl_vendor,*gl_renderer,*gl_version,*gl_extensions; -void ogl_get_verinfo(void){ - int t; +void ogl_get_verinfo(void) +{ + int t, arb_max_textures = -1, sgi_max_textures = -1; gl_vendor=glGetString(GL_VENDOR); gl_renderer=glGetString(GL_RENDERER); gl_version=glGetString(GL_VERSION); @@ -182,15 +183,15 @@ void ogl_get_verinfo(void){ dglSelectTextureSGIS = (glSelectTextureSGIS_fp)wglGetProcAddress("glSelectTextureSGIS"); #endif - //multitexturing doesn't work yet. #ifdef GL_ARB_multitexture - ogl_arb_multitexture_ok=0;//(strstr(gl_extensions,"GL_ARB_multitexture")!=0 && glActiveTextureARB!=0 && 0); + ogl_arb_multitexture_ok = (strstr(gl_extensions, "GL_ARB_multitexture") != 0 && glActiveTextureARB != 0); mprintf((0,"c:%p d:%p e:%p\n",strstr(gl_extensions,"GL_ARB_multitexture"),glActiveTextureARB,glBegin)); #endif #ifdef GL_SGIS_multitexture - ogl_sgis_multitexture_ok=0;//(strstr(gl_extensions,"GL_SGIS_multitexture")!=0 && glSelectTextureSGIS!=0 && 0); + ogl_sgis_multitexture_ok = (strstr(gl_extensions, "GL_SGIS_multitexture") != 0 && glSelectTextureSGIS != 0); mprintf((0,"a:%p b:%p\n",strstr(gl_extensions,"GL_SGIS_multitexture"),glSelectTextureSGIS)); #endif + ogl_nv_texture_env_combine4_ok = (strstr(gl_extensions, "GL_NV_texture_env_combine4") != 0); //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){ @@ -210,11 +211,15 @@ void ogl_get_verinfo(void){ if ((t=FindArg("-gl_arb_multitexture_ok"))){ ogl_arb_multitexture_ok=atoi(Args[t+1]); } + if (ogl_arb_multitexture_ok) + glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &arb_max_textures); #endif #ifdef GL_SGIS_multitexture if ((t=FindArg("-gl_sgis_multitexture_ok"))){ ogl_sgis_multitexture_ok=atoi(Args[t+1]); } + if (ogl_sgis_multitexture_ok) + glGetIntegerv(GL_MAX_TEXTURES_SGIS, &sgi_max_textures); #endif if ((t=FindArg("-gl_intensity4_ok"))){ ogl_intensity4_ok=atoi(Args[t+1]); @@ -236,7 +241,7 @@ void ogl_get_verinfo(void){ ogl_setgammaramp_ok = atoi(Args[t + 1]); } - con_printf(CON_VERBOSE, "gl_arb_multitexture:%i gl_sgis_multitexture:%i\n",ogl_arb_multitexture_ok,ogl_sgis_multitexture_ok); + con_printf(CON_VERBOSE, "gl_arb_multitexture:%i(%i units) gl_sgis_multitexture:%i(%i units) gl_nv_texture_env_combine4:%i\n", ogl_arb_multitexture_ok, arb_max_textures, ogl_sgis_multitexture_ok, sgi_max_textures, ogl_nv_texture_env_combine4_ok); con_printf(CON_VERBOSE, "gl_intensity4:%i gl_luminance4_alpha4:%i gl_rgba2:%i gl_readpixels:%i gl_gettexlevelparam:%i gl_setgammaramp_ok:%i\n",ogl_intensity4_ok,ogl_luminance4_alpha4_ok,ogl_rgba2_ok,ogl_readpixels_ok,ogl_gettexlevelparam_ok, ogl_setgammaramp_ok); } diff --git a/arch/ogl/ogl.c b/arch/ogl/ogl.c index f4418527..91cf937d 100644 --- a/arch/ogl/ogl.c +++ b/arch/ogl/ogl.c @@ -1,4 +1,4 @@ -/* $Id: ogl.c,v 1.17 2004-05-19 03:41:58 btb Exp $ */ +/* $Id: ogl.c,v 1.18 2004-05-20 03:31:32 btb Exp $ */ /* * * Graphics support functions for OpenGL. @@ -15,6 +15,7 @@ #include #include #endif +#include "internal.h" #if defined(__APPLE__) && defined(__MACH__) #include #include @@ -25,7 +26,6 @@ #include #include -#include "internal.h" #include "3d.h" #include "piggy.h" #include "../../3d/globvars.h" @@ -86,6 +86,7 @@ int ogl_arb_multitexture_ok=0; #ifdef GL_SGIS_multitexture int ogl_sgis_multitexture_ok=0; #endif +int ogl_nv_texture_env_combine4_ok = 0; int sphereh=0; int cross_lh[2]={0,0}; @@ -124,7 +125,8 @@ void ogl_init_texture(ogl_texture* t){ t->handle=0; t->internalformat=ogl_rgba_format; t->format=GL_RGBA; - t->wrapstate=-1; + t->wrapstate[0] = -1; + t->wrapstate[1] = -1; t->w=t->h=0; ogl_init_texture_stats(t); } @@ -152,7 +154,8 @@ void ogl_smash_texture_list_internal(void){ glDeleteTextures( 1, &ogl_texture_list[i].handle ); ogl_texture_list[i].handle=0; } - ogl_texture_list[i].wrapstate=-1; + ogl_texture_list[i].wrapstate[0] = -1; + ogl_texture_list[i].wrapstate[1] = -1; } } void ogl_vivify_texture_list_internal(void){ @@ -251,11 +254,13 @@ void ogl_bindbmtex(grs_bitmap *bm){ // } } //gltexture MUST be bound first -void ogl_texwrap(ogl_texture *gltexture,int state){ - if (gltexture->wrapstate!=state || gltexture->numrend<1){ +void ogl_texwrap(ogl_texture *gltexture,int state) +{ + if (gltexture->wrapstate[active_texture_unit] != state || gltexture->numrend < 1) + { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, state); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, state); - gltexture->wrapstate=state; + gltexture->wrapstate[active_texture_unit] = state; } } @@ -674,50 +679,132 @@ bool g3_draw_tmap(int nv,g3s_point **pointlist,g3s_uvl *uvl_list,grs_bitmap *bm) } return 0; } -bool g3_draw_tmap_2(int nv,g3s_point **pointlist,g3s_uvl *uvl_list,grs_bitmap *bmbot,grs_bitmap *bm,int orient) -{ -#if (defined(GL_ARB_multitexture) || defined(GL_SGIS_multitexture)) - if (ogl_arb_multitexture_ok || ogl_sgis_multitexture_ok){ - int c; - float l,u1,v1; - r_tpolyc+=2; - /* if (bm->bm_w !=64||bm->bm_h!=64) - printf("g3_draw_tmap w %i h %i\n",bm->bm_w,bm->bm_h);*/ - if (ogl_arb_multitexture_ok){ +int active_texture_unit = 0; + +void ogl_setActiveTexture(int t) +{ + if (ogl_arb_multitexture_ok) + { #ifdef GL_ARB_multitexture + if (t == 0) glActiveTextureARB(GL_TEXTURE0_ARB); + else + glActiveTextureARB(GL_TEXTURE1_ARB); #endif - }else if (ogl_sgis_multitexture_ok){ + } + else if (ogl_sgis_multitexture_ok) + { #ifdef GL_SGIS_multitexture + if (t == 0) glSelectTextureSGIS(GL_TEXTURE0_SGIS); + else + glSelectTextureSGIS(GL_TEXTURE1_SGIS); #endif - } - ogl_bindbmtex(bmbot); - OGL_ENABLE(TEXTURE_2D); - glEnable(GL_TEXTURE_2D); - ogl_texwrap(bmbot->gltexture,GL_REPEAT); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + active_texture_unit = t; +} - if (ogl_arb_multitexture_ok){ +void ogl_MultiTexCoord2f(int t, float u, float v) +{ + if (ogl_arb_multitexture_ok) + { #ifdef GL_ARB_multitexture - glActiveTextureARB(GL_TEXTURE1_ARB); + if (t == 0) + glMultiTexCoord2fARB(GL_TEXTURE0_ARB, u, v); + else + glMultiTexCoord2fARB(GL_TEXTURE1_ARB, u, v); #endif - }else if (ogl_sgis_multitexture_ok){ + } + else if (ogl_sgis_multitexture_ok) + { #ifdef GL_SGIS_multitexture - glSelectTextureSGIS(GL_TEXTURE1_SGIS); + if (t == 0) + glMultiTexCoord2fSGIS(GL_TEXTURE0_SGIS, u, v); + else + glMultiTexCoord2fSGIS(GL_TEXTURE1_SGIS, u, v); #endif - } - ogl_bindbmtex(bm); -// OGL_ENABLE(TEXTURE_2D); + } +} + +bool g3_draw_tmap_2(int nv, g3s_point **pointlist, g3s_uvl *uvl_list, grs_bitmap *bmbot, grs_bitmap *bm, int orient) +{ +#if (defined(GL_NV_texture_env_combine4) && (defined(GL_ARB_multitexture) || defined(GL_SGIS_multitexture))) + if (ogl_nv_texture_env_combine4_ok && (ogl_arb_multitexture_ok || ogl_sgis_multitexture_ok)) + { + int c; + float l, u1, v1; + + if (tmap_drawer_ptr != draw_tmap) + Error("WTFF\n"); + + r_tpolyc+=2; + + //ogl_setActiveTexture(0); + OGL_ENABLE(TEXTURE_2D); + ogl_bindbmtex(bmbot); + ogl_texwrap(bmbot->gltexture, GL_REPEAT); + // GL_MODULATE is fine for texture 0 + + ogl_setActiveTexture(1); glEnable(GL_TEXTURE_2D); + ogl_bindbmtex(bm); ogl_texwrap(bm->gltexture,GL_REPEAT); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + // GL_DECAL works sorta ok but the top texture is fullbright. + //glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); + + // http://oss.sgi.com/projects/ogl-sample/registry/NV/texture_env_combine4.txt + // only GL_NV_texture_env_combine4 lets us do what we need: + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV); + + // multiply top texture by color(vertex lighting) and add bottom texture(where alpha says to) + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_ADD); + + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PRIMARY_COLOR_EXT); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_EXT, GL_TEXTURE); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE3_RGB_NV, GL_PREVIOUS_EXT); + + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_COLOR); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_EXT, GL_ONE_MINUS_SRC_ALPHA); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND3_RGB_NV, GL_SRC_COLOR); + + // add up alpha channels + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_ADD); + + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, GL_ZERO); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA_EXT, GL_PREVIOUS_EXT); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE3_ALPHA_NV, GL_ZERO); + + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_EXT, GL_SRC_ALPHA); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_EXT, GL_ONE_MINUS_SRC_ALPHA); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA_EXT, GL_SRC_ALPHA); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND3_ALPHA_NV, GL_ONE_MINUS_SRC_ALPHA); + + // GL_ARB_texture_env_combine comes close, but doesn't quite make it. + //glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); + + //// this gives effect like GL_DECAL: + //glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_INTERPOLATE); + //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); + + + // this properly shades the top texture, but the bottom texture doesn't get through. + //glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE); + //glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PRIMARY_COLOR_ARB); + //glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE); + + + // add up alpha + //glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_ADD); + //glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE); + //glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_PREVIOUS_ARB); + glBegin(GL_TRIANGLE_FAN); for (c=0;cbm_flags&BM_FLAG_NO_LIGHTING){ l=1.0; }else{ - //l=f2fl(uvl_list[c].l)+gr_palette_gamma/63.0; l=f2fl(uvl_list[c].l); } glColor3f(l,l,l); -// glTexCoord2f(f2glf(uvl_list[c].u),f2glf(uvl_list[c].v)); - if (ogl_arb_multitexture_ok){ -#ifdef GL_ARB_multitexture - glMultiTexCoord2fARB(GL_TEXTURE0_ARB,f2glf(uvl_list[c].u),f2glf(uvl_list[c].v)); -#endif - }else if (ogl_sgis_multitexture_ok){ -#ifdef GL_SGIS_multitexture - glMultiTexCoord2fSGIS(GL_TEXTURE0_SGIS,f2glf(uvl_list[c].u),f2glf(uvl_list[c].v)); -#endif - } - if (ogl_arb_multitexture_ok){ -#ifdef GL_ARB_multitexture - glMultiTexCoord2fARB(GL_TEXTURE1_ARB,u1,v1); -#endif - }else if (ogl_sgis_multitexture_ok){ -#ifdef GL_SGIS_multitexture - glMultiTexCoord2fSGIS(GL_TEXTURE1_SGIS,u1,v1); -#endif - } + ogl_MultiTexCoord2f(0, f2glf(uvl_list[c].u), f2glf(uvl_list[c].v)); + ogl_MultiTexCoord2f(1, u1, v1); //glVertex3f(f2glf(pointlist[c]->p3_vec.x),f2glf(pointlist[c]->p3_vec.y),f2glf(pointlist[c]->p3_vec.z)); //glVertex3f(f2glf(pointlist[c]->p3_vec.x),f2glf(pointlist[c]->p3_vec.y),f2glf(pointlist[c]->p3_vec.z)); glVertex3f(f2glf(pointlist[c]->p3_vec.x),f2glf(pointlist[c]->p3_vec.y),-f2glf(pointlist[c]->p3_vec.z)); } glEnd(); -/* if (ogl_arb_multitexture_ok){ -#ifdef GL_ARB_multitexture - glActiveTextureARB(GL_TEXTURE1_ARB); -#endif - }else if (ogl_sgis_multitexture_ok){ -#ifdef GL_SGIS_multitexture - glSelectTextureSGIS(GL_TEXTURE1_SGIS); -#endif - } -// OGL_ENABLE(TEXTURE_2D);*/ + //ogl_setActiveTexture(1); // still the active texture + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glDisable(GL_TEXTURE_2D); - if (ogl_arb_multitexture_ok){ -#ifdef GL_ARB_multitexture - glActiveTextureARB(GL_TEXTURE0_ARB); -#endif - }else if (ogl_sgis_multitexture_ok){ -#ifdef GL_SGIS_multitexture - glSelectTextureSGIS(GL_TEXTURE0_SGIS); -#endif - } - }else + ogl_setActiveTexture(0); + } + else #endif { int c; diff --git a/include/loadgl.h b/include/loadgl.h index 7af6b1bc..abdf39c9 100644 --- a/include/loadgl.h +++ b/include/loadgl.h @@ -1,7 +1,7 @@ -/* $ Id: $ */ +/* $Id: loadgl.h,v 1.7 2004-05-20 03:31:34 btb Exp $ */ /* * - * dynamic opengl loading - curtousy (sp) of Jeff Slutter + * dynamic opengl loading - courtesy of Jeff Slutter * * */ @@ -24,12 +24,14 @@ #define GL_ARB_multitexture 1 #define GL_TEXTURE0_ARB 0x84C0 #define GL_TEXTURE1_ARB 0x84C1 +#define GL_MAX_TEXTURE_UNITS_ARB 0x84E2 #endif #ifndef GL_SGIS_multitexture #define GL_SGIS_multitexture 1 #define GL_TEXTURE0_SGIS 0x835F #define GL_TEXTURE1_SGIS 0x8360 +#define GL_MAX_TEXTURES_SGIS 0x835D #endif #ifdef _cplusplus diff --git a/include/ogl_init.h b/include/ogl_init.h index 16aa268b..bcf60a70 100644 --- a/include/ogl_init.h +++ b/include/ogl_init.h @@ -21,14 +21,13 @@ #include "loadgl.h" int ogl_init_load_library(void); #else +#define GL_GLEXT_LEGACY +#undef GL_ARB_multitexture #if defined(__APPLE__) && defined(__MACH__) #include #else #include #endif -//######hack, since multi texture support is not working -#undef GL_ARB_multitexture -#undef GL_SGIS_multitexture #endif #ifndef GL_VERSION_1_1 @@ -52,7 +51,7 @@ typedef struct _ogl_texture { int bytes; GLfloat u,v; GLfloat prio; - int wrapstate; + int wrapstate[2]; fix lastrend; unsigned long numrend; char wantmip; @@ -69,10 +68,43 @@ extern int ogl_rgba2_ok; extern int ogl_readpixels_ok; extern int ogl_gettexlevelparam_ok; +#ifndef EXT_texture_env_combine +#define EXT_texture_env_combine 1 +#define GL_COMBINE_RGB_EXT 0x8571 +#define GL_COMBINE_ALPHA_EXT 0x8572 +#define GL_PRIMARY_COLOR_EXT 0x8577 +#define GL_PREVIOUS_EXT 0x8578 +#define GL_SOURCE0_RGB_EXT 0x8580 +#define GL_SOURCE1_RGB_EXT 0x8581 +#define GL_SOURCE2_RGB_EXT 0x8582 +#define GL_SOURCE0_ALPHA_EXT 0x8588 +#define GL_SOURCE1_ALPHA_EXT 0x8589 +#define GL_SOURCE2_ALPHA_EXT 0x858A +#define GL_OPERAND0_RGB_EXT 0x8590 +#define GL_OPERAND1_RGB_EXT 0x8591 +#define GL_OPERAND2_RGB_EXT 0x8592 +#define GL_OPERAND0_ALPHA_EXT 0x8598 +#define GL_OPERAND1_ALPHA_EXT 0x8599 +#define GL_OPERAND2_ALPHA_EXT 0x859A +#endif + +#ifndef GL_NV_texture_env_combine4 +#define GL_NV_texture_env_combine4 1 +#define GL_COMBINE4_NV 0x8503 +#define GL_SOURCE3_RGB_NV 0x8583 +#define GL_SOURCE3_ALPHA_NV 0x858B +#define GL_OPERAND3_RGB_NV 0x8593 +#define GL_OPERAND3_ALPHA_NV 0x859B +#endif +extern int ogl_nv_texture_env_combine4_ok; + extern int gl_initialized; extern int GL_texmagfilt,GL_texminfilt,GL_needmipmaps; extern int gl_reticle; +extern int active_texture_unit; +void ogl_setActiveTexture(int t); + int ogl_check_mode(int x, int y); // check if mode is valid int ogl_init_window(int x, int y);//create a window/switch modes/etc void ogl_destroy_window(void);//destroy window/etc -- 2.39.2