diff --git a/polymer/build/include/baselayer.h b/polymer/build/include/baselayer.h index 292bf02d1..8a6410ad0 100644 --- a/polymer/build/include/baselayer.h +++ b/polymer/build/include/baselayer.h @@ -46,6 +46,8 @@ struct glinfo { char shadow; char fbos; char rect; + char multitex; + char envcombine; }; extern struct glinfo glinfo; #endif diff --git a/polymer/build/include/build.h b/polymer/build/include/build.h index cb7ada6ad..217686e28 100644 --- a/polymer/build/include/build.h +++ b/polymer/build/include/build.h @@ -36,6 +36,9 @@ extern "C" { #define MAXSPRITESONSCREEN 4096 #define MAXUNIQHUDID 256 //Extra slots so HUD models can store animation state without messing game sprites +#define RESERVEDPALS 1 +#define DETAILPAL MAXPALOOKUPS - 1 + #define CLIPMASK0 (((1L)<<16)+1L) #define CLIPMASK1 (((256L)<<16)+64L) @@ -492,6 +495,7 @@ extern long glwidescreen, glprojectionhacks; void gltexapplyprops (void); extern long r_depthpeeling, r_peelscount; +extern long r_detailmapping; #endif void hicinit(void); diff --git a/polymer/build/include/glbuild.h b/polymer/build/include/glbuild.h index 806c55641..6ede0c4a6 100644 --- a/polymer/build/include/glbuild.h +++ b/polymer/build/include/glbuild.h @@ -146,6 +146,8 @@ extern void (APIENTRY * bglDeleteProgramsARB)(GLsizei n, const GLuint *programs) // Multitexturing extern void (APIENTRY * bglActiveTextureARB)(GLenum texture); +extern void (APIENTRY * bglMultiTexCoord2dARB)(GLenum target, GLdouble s, GLdouble t ); +extern void (APIENTRY * bglMultiTexCoord2fARB)(GLenum target, GLfloat s, GLfloat t ); // Frame Buffer Objects extern void (APIENTRY * bglGenFramebuffersEXT)(GLsizei n, GLuint *framebuffers); diff --git a/polymer/build/src/baselayer.c b/polymer/build/src/baselayer.c index 9f7ba4fcc..d7e4bd6f8 100644 --- a/polymer/build/src/baselayer.c +++ b/polymer/build/src/baselayer.c @@ -26,6 +26,8 @@ struct glinfo glinfo = { 0, // shadow comparison 0, // Frame Buffer Objects 0, // rectangle textures + 0, // multitexturing + 0, // env_combine }; #endif diff --git a/polymer/build/src/defs.c b/polymer/build/src/defs.c index cc23f2b66..b31862331 100644 --- a/polymer/build/src/defs.c +++ b/polymer/build/src/defs.c @@ -42,6 +42,7 @@ enum { T_FPS, T_FLAGS, T_PAL, + T_DETAIL, T_HUD, T_XADD, T_YADD, @@ -184,11 +185,12 @@ static tokenlist tinttokens[] = { }; static tokenlist texturetokens[] = { - { "pal", T_PAL }, + { "pal", T_PAL }, + { "detail", T_DETAIL }, }; static tokenlist texturetokens_pal[] = { { "file", T_FILE },{ "name", T_FILE }, - { "alphacut", T_ALPHACUT }, + { "alphacut", T_ALPHACUT }, { "detailscale", T_ALPHACUT }, { "scale", T_ALPHACUT }, { "nocompress",T_NOCOMPRESS }, }; @@ -1106,7 +1108,7 @@ static int defsparser(scriptfile *script) } if ((unsigned)tile > (unsigned)MAXTILES) break; // message is printed later - if ((unsigned)pal > (unsigned)MAXPALOOKUPS) { + if ((unsigned)pal > ((unsigned)MAXPALOOKUPS - RESERVEDPALS)) { initprintf("Error: missing or invalid 'palette number' for texture definition near " "line %s:%d\n", script->filename, scriptfile_getlinum(script,paltokptr)); break; @@ -1123,6 +1125,40 @@ static int defsparser(scriptfile *script) hicsetsubsttex(tile,pal,fn,alphacut,flags); } break; + case T_DETAIL: { + char *detailtokptr = script->ltextptr, *detailend; + int i; + char *fn = NULL; + double detailscale = 1.0; + char flags = 0; + + if (scriptfile_getbraces(script,&detailend)) break; + while (script->textptr < detailend) { + switch (getatoken(script,texturetokens_pal,sizeof(texturetokens_pal)/sizeof(tokenlist))) { + case T_FILE: + scriptfile_getstring(script,&fn); break; + case T_ALPHACUT: + scriptfile_getdouble(script,&detailscale); break; + case T_NOCOMPRESS: + flags |= 1; break; + default: + break; + } + } + + if ((unsigned)tile > (unsigned)MAXTILES) break; // message is printed later + if (!fn) { + initprintf("Error: missing 'file name' for texture definition near line %s:%d\n", + script->filename, scriptfile_getlinum(script,detailtokptr)); + break; + } + if ((i = kopen4load(fn,0)) < 0) { + initprintf("Error: file '%s' does not exist\n",fn); + break; + } else kclose(i); + + hicsetsubsttex(tile,DETAILPAL,fn,detailscale,flags); + } break; default: break; } diff --git a/polymer/build/src/glbuild.c b/polymer/build/src/glbuild.c index 8593b9e13..925134466 100644 --- a/polymer/build/src/glbuild.c +++ b/polymer/build/src/glbuild.c @@ -123,6 +123,8 @@ void (APIENTRY * bglDeleteProgramsARB)(GLsizei n, const GLuint *programs); // Multitexturing void (APIENTRY * bglActiveTextureARB)(GLenum texture); +void (APIENTRY * bglMultiTexCoord2dARB)(GLenum target, GLdouble s, GLdouble t ); +void (APIENTRY * bglMultiTexCoord2fARB)(GLenum target, GLfloat s, GLfloat t ); // Frame Buffer Objects void (APIENTRY * bglGenFramebuffersEXT)(GLsizei n, GLuint *framebuffers); @@ -335,7 +337,9 @@ int loadglextensions(void) bglDeleteProgramsARB= GETPROCEXTSOFT("glDeleteProgramsARB"); // Multitexturing - bglActiveTextureARB = GETPROCEXTSOFT("glActiveTextureARB"); + bglActiveTextureARB = GETPROCEXTSOFT("glActiveTextureARB"); + bglMultiTexCoord2dARB = GETPROCEXTSOFT("glMultiTexCoord2dARB"); + bglMultiTexCoord2fARB = GETPROCEXTSOFT("glMultiTexCoord2fARB"); // Frame Buffer Objects bglGenFramebuffersEXT = GETPROCEXTSOFT("glGenFramebuffersEXT"); @@ -465,7 +469,9 @@ int unloadgldriver(void) bglDeleteProgramsARB= NULL; // Multitexturing - bglActiveTextureARB = NULL; + bglActiveTextureARB = NULL; + bglMultiTexCoord2dARB = NULL; + bglMultiTexCoord2fARB = NULL; // Frame Buffer Objects bglGenFramebuffersEXT = NULL; diff --git a/polymer/build/src/polymost.c b/polymer/build/src/polymost.c index 409b04223..dbcd18c1a 100644 --- a/polymer/build/src/polymost.c +++ b/polymer/build/src/polymost.c @@ -149,6 +149,9 @@ GLuint *peels; // peels identifiers GLuint *peelfbos; // peels FBOs identifiers GLuint peelprogram[2]; // ARBfp peeling fragment program +// Bleh +long r_detailmapping = 0; + float fogresult, ofogresult; void fogcalc (const signed char *shade, const char *vis) @@ -686,9 +689,15 @@ void polymost_glinit() bglEnable(GL_MULTISAMPLE_ARB); } - if (!glinfo.arbfp || !glinfo.depthtex || !glinfo.shadow || !glinfo.fbos || !glinfo.rect) + if (r_depthpeeling && (!glinfo.arbfp || !glinfo.depthtex || !glinfo.shadow || !glinfo.fbos || !glinfo.rect || !glinfo.multitex)) { - OSD_Printf("Your OpenGL implementation doesn't support depth peeling. Disabling...\n"); + OSD_Printf("Your OpenGL implementation doesn't support depth peeling. Disabling...\n"); + r_depthpeeling = 0; + } + + if (r_detailmapping && (!glinfo.multitex)) + { + OSD_Printf("Your OpenGL implementation doesn't support detail mapping. Disabling...\n"); r_depthpeeling = 0; } @@ -1513,7 +1522,7 @@ void drawpoly (double *dpx, double *dpy, long n, long method) long xx, yy, xi, d0, u0, v0, d1, u1, v1, xmodnice = 0, ymulnice = 0, dorot; char dacol = 0, *walptr, *palptr = NULL, *vidp, *vide; #ifdef USE_OPENGL - pthtyp *pth; + pthtyp *pth, *detailpth; #endif // backup of the n for possible redrawing of fullbright long n_ = n, method_ = method; @@ -1613,6 +1622,46 @@ void drawpoly (double *dpx, double *dpy, long n, long method) bglBindTexture(GL_TEXTURE_2D, pth ? pth->glpic : 0); + detailpth = NULL; + if (r_detailmapping && !r_depthpeeling && indrawroomsandmasks && !drawingskybox && hicfindsubst(globalpicnum, DETAILPAL, 0)) + detailpth = gltexcache(globalpicnum,DETAILPAL,method&(~3)); + + if (detailpth && (detailpth->hicr->palnum == DETAILPAL)) + { + bglActiveTextureARB(GL_TEXTURE1_ARB); + + bglEnable(GL_TEXTURE_2D); + bglBindTexture(GL_TEXTURE_2D, detailpth ? detailpth->glpic : 0); + + bglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); + bglTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE); + + bglTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS_ARB); + bglTexEnvf(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR); + + bglTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE); + bglTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR); + + bglTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE); + bglTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PREVIOUS_ARB); + bglTexEnvf(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA); + + bglTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 2.0f); + + bglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT); + bglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT); + + + f = detailpth ? (1.0f / detailpth->hicr->alphacut) : 1.0; + + bglMatrixMode(GL_TEXTURE); + bglLoadIdentity(); + bglScalef(f, f, 1.0f); + bglMatrixMode(GL_MODELVIEW); + } + else + detailpth = NULL; + if (pth && (pth->flags & 2)) { hackscx = pth->scalex; @@ -1807,7 +1856,14 @@ void drawpoly (double *dpx, double *dpy, long n, long method) dp = ox*ngdx + oy*ngdy + ngdo; up = ox*ngux + oy*nguy + nguo; vp = ox*ngvx + oy*ngvy + ngvo; - r = 1.0/dp; bglTexCoord2d((up*r-du0+uoffs)*ox2,vp*r*oy2); + r = 1.0/dp; + if (detailpth) + { + bglMultiTexCoord2dARB(GL_TEXTURE0_ARB, (up*r-du0+uoffs)*ox2,vp*r*oy2); + bglMultiTexCoord2dARB(GL_TEXTURE1_ARB, (up*r-du0+uoffs)*ox2,vp*r*oy2); + } + else + bglTexCoord2d((up*r-du0+uoffs)*ox2,vp*r*oy2); bglVertex3d((ox-ghalfx)*r*grhalfxdown10x,(ghoriz-oy)*r*grhalfxdown10,r*(1.0/1024.0)); } bglEnd(); @@ -1819,7 +1875,13 @@ void drawpoly (double *dpx, double *dpy, long n, long method) bglBegin(GL_TRIANGLE_FAN); for (i=0;iname, "r_detailmapping")) { + if (showval) { OSD_Printf("r_detailmapping is %d\n", r_detailmapping); } + else { + if (!glinfo.multitex) + { + OSD_Printf("Your OpenGL implementation doesn't support detail mapping.\n"); + r_depthpeeling = 0; + return OSDCMD_OK; + } + r_detailmapping = (val != 0); + } + return OSDCMD_OK; + } else if (!Bstrcasecmp(parm->name, "glpolygonmode")) { if (showval) { OSD_Printf("glpolygonmode is %d\n", glpolygonmode); } else glpolygonmode = val; @@ -5242,6 +5322,7 @@ void polymost_initosdfuncs(void) OSD_RegisterFunction("r_depthpeeling","r_depthpeeling: enable/disable order-independant transparency",osdcmd_polymostvars); OSD_RegisterFunction("r_peelscount","r_peelscount: sets the number of depth layers for depth peeling",osdcmd_polymostvars); OSD_RegisterFunction("r_curpeel","r_curpeel: allows to display one depth layer at a time (for development purposes)",osdcmd_polymostvars); + OSD_RegisterFunction("r_detailmapping","r_detailmapping: shut your fucking face uncle fucker",osdcmd_polymostvars); #endif OSD_RegisterFunction("usemodels","usemodels: enable/disable model rendering in >8-bit mode",osdcmd_polymostvars); OSD_RegisterFunction("usehightile","usehightile: enable/disable hightile texture rendering in >8-bit mode",osdcmd_polymostvars); diff --git a/polymer/build/src/sdlayer.c b/polymer/build/src/sdlayer.c index f1318695f..23c07ea07 100644 --- a/polymer/build/src/sdlayer.c +++ b/polymer/build/src/sdlayer.c @@ -1070,6 +1070,14 @@ int setvideomode(int x, int y, int c, int fs) { glinfo.rect = 1; } + else if (!Bstrcmp((char *)p2, "GL_ARB_multitexture")) + { + glinfo.multitex = 1; + } + else if (!Bstrcmp((char *)p2, "GL_ARB_texture_env_combine")) + { + glinfo.envcombine = 1; + } } Bfree(p); } diff --git a/polymer/build/src/winlayer.c b/polymer/build/src/winlayer.c index ec8d943f1..77b9f3cbd 100644 --- a/polymer/build/src/winlayer.c +++ b/polymer/build/src/winlayer.c @@ -2894,6 +2894,14 @@ static int SetupOpenGL(int width, int height, int bitspp) !Bstrcmp((char *)p2, "GL_EXT_texture_rectangle")) { glinfo.rect = 1; } + else if (!Bstrcmp((char *)p2, "GL_ARB_multitexture")) + { + glinfo.multitex = 1; + } + else if (!Bstrcmp((char *)p2, "GL_ARB_texture_env_combine")) + { + glinfo.envcombine = 1; + } } Bfree(p); } diff --git a/polymer/eduke32/source/config.c b/polymer/eduke32/source/config.c index dd63abf75..6af39887c 100644 --- a/polymer/eduke32/source/config.c +++ b/polymer/eduke32/source/config.c @@ -642,6 +642,8 @@ int32 CONFIG_ReadSetup(void) SCRIPT_GetNumber(scripthandle, "Screen Setup", "GLDepthPeeling", &r_depthpeeling); SCRIPT_GetNumber(scripthandle, "Screen Setup", "GLPeelsCount", &r_peelscount); + SCRIPT_GetNumber(scripthandle, "Screen Setup", "GLDetailMapping", &r_detailmapping); + dummy = usemodels; SCRIPT_GetNumber(scripthandle, "Screen Setup", "UseModels",&dummy); usemodels = dummy != 0; @@ -787,8 +789,11 @@ void CONFIG_WriteSetup(void) SCRIPT_PutNumber(scripthandle, "Screen Setup", "GLUseTextureCacheCompression", glusetexcachecompression,false,false); SCRIPT_PutNumber(scripthandle, "Screen Setup", "GLUseTextureCompr",glusetexcompr,false,false); SCRIPT_PutNumber(scripthandle, "Screen Setup", "GLWidescreen",glwidescreen,false,false); + SCRIPT_PutNumber(scripthandle, "Screen Setup", "GLDepthPeeling",r_depthpeeling,false,false); SCRIPT_PutNumber(scripthandle, "Screen Setup", "GLPeelsCount",r_peelscount,false,false); + + SCRIPT_PutNumber(scripthandle, "Screen Setup", "GLDetailMapping", &r_detailmapping,false,false); #endif #ifdef RENDERTYPEWIN SCRIPT_PutNumber(scripthandle, "Screen Setup", "MaxRefreshFreq",maxrefreshfreq,false,false);