From f3c78fb1c533cb34cfbd4f2a0c91f977bc02db8f Mon Sep 17 00:00:00 2001 From: Daniel Gibson Date: Sat, 18 Mar 2017 20:02:31 +0100 Subject: [PATCH] GL3: Theoretically support 4 lightmaps with styles (in shaders) practically those lightmaps must be created and uploaded as textures etc --- src/client/refresh/gl3/gl3_image.c | 8 ++- src/client/refresh/gl3/gl3_light.c | 72 +++------------------------ src/client/refresh/gl3/gl3_lightmap.c | 2 +- src/client/refresh/gl3/gl3_main.c | 2 +- src/client/refresh/gl3/gl3_shaders.c | 48 ++++++++++++++---- src/client/refresh/gl3/gl3_surf.c | 9 ++-- src/client/refresh/gl3/header/local.h | 6 ++- 7 files changed, 62 insertions(+), 85 deletions(-) diff --git a/src/client/refresh/gl3/gl3_image.c b/src/client/refresh/gl3/gl3_image.c index e64bc313..94832a78 100644 --- a/src/client/refresh/gl3/gl3_image.c +++ b/src/client/refresh/gl3/gl3_image.c @@ -145,7 +145,13 @@ GL3_BindLightmap(int lightmapnum) gl3state.currentlightmap = lightmapnum; GL3_SelectTMU(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, gl3state.lightmap_textureIDs[lightmapnum]); + glBindTexture(GL_TEXTURE_2D, gl3state.lightmap_textureIDs[lightmapnum][0]); + GL3_SelectTMU(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_2D, gl3state.lightmap_textureIDs[lightmapnum][1]); + GL3_SelectTMU(GL_TEXTURE3); + glBindTexture(GL_TEXTURE_2D, gl3state.lightmap_textureIDs[lightmapnum][2]); + GL3_SelectTMU(GL_TEXTURE4); + glBindTexture(GL_TEXTURE_2D, gl3state.lightmap_textureIDs[lightmapnum][3]); } /* diff --git a/src/client/refresh/gl3/gl3_light.c b/src/client/refresh/gl3/gl3_light.c index fd5d5735..1f449856 100644 --- a/src/client/refresh/gl3/gl3_light.c +++ b/src/client/refresh/gl3/gl3_light.c @@ -406,7 +406,6 @@ GL3_BuildLightMap(msurface_t *surf, byte *dest, int stride) int i, j, size; byte *lightmap; float scale[4]; - int nummaps; float *bl; if (surf->texinfo->flags & @@ -435,59 +434,14 @@ GL3_BuildLightMap(msurface_t *surf, byte *dest, int stride) goto store; } - /* count the # of maps */ - for (nummaps = 0; nummaps < MAXLIGHTMAPS && surf->styles[nummaps] != 255; - nummaps++) - { - } - - lightmap = surf->samples; - /* add all the lightmaps */ - if (nummaps == 1) - { - int maps; - - for (maps = 0; maps < MAXLIGHTMAPS && surf->styles[maps] != 255; maps++) - { - bl = s_blocklights; - - for (i = 0; i < 3; i++) - { - scale[i] = gl_modulate->value * - gl3_newrefdef.lightstyles[surf->styles[maps]].rgb[i]; - } - - if ((scale[0] == 1.0F) && - (scale[1] == 1.0F) && - (scale[2] == 1.0F)) - { - for (i = 0; i < size; i++, bl += 3) - { - bl[0] = lightmap[i * 3 + 0]; - bl[1] = lightmap[i * 3 + 1]; - bl[2] = lightmap[i * 3 + 2]; - } - } - else - { - for (i = 0; i < size; i++, bl += 3) - { - bl[0] = lightmap[i * 3 + 0] * scale[0]; - bl[1] = lightmap[i * 3 + 1] * scale[1]; - bl[2] = lightmap[i * 3 + 2] * scale[2]; - } - } - - lightmap += size * 3; /* skip to next lightmap */ - } - } - else { int maps; memset(s_blocklights, 0, sizeof(s_blocklights[0]) * size * 3); + lightmap = surf->samples; + for (maps = 0; maps < MAXLIGHTMAPS && surf->styles[maps] != 255; maps++) { bl = s_blocklights; @@ -498,25 +452,11 @@ GL3_BuildLightMap(msurface_t *surf, byte *dest, int stride) gl3_newrefdef.lightstyles[surf->styles[maps]].rgb[i]; } - if ((scale[0] == 1.0F) && - (scale[1] == 1.0F) && - (scale[2] == 1.0F)) + for (i = 0; i < size; i++, bl += 3) { - for (i = 0; i < size; i++, bl += 3) - { - bl[0] += lightmap[i * 3 + 0]; - bl[1] += lightmap[i * 3 + 1]; - bl[2] += lightmap[i * 3 + 2]; - } - } - else - { - for (i = 0; i < size; i++, bl += 3) - { - bl[0] += lightmap[i * 3 + 0] * scale[0]; - bl[1] += lightmap[i * 3 + 1] * scale[1]; - bl[2] += lightmap[i * 3 + 2] * scale[2]; - } + bl[0] += lightmap[i * 3 + 0] * scale[0]; + bl[1] += lightmap[i * 3 + 1] * scale[1]; + bl[2] += lightmap[i * 3 + 2] * scale[2]; } lightmap += size * 3; /* skip to next lightmap */ diff --git a/src/client/refresh/gl3/gl3_lightmap.c b/src/client/refresh/gl3/gl3_lightmap.c index b4e21da6..70f1ebf0 100644 --- a/src/client/refresh/gl3/gl3_lightmap.c +++ b/src/client/refresh/gl3/gl3_lightmap.c @@ -53,8 +53,8 @@ GL3_LM_UploadBlock(qboolean dynamic) texture = gl3_lms.current_lightmap_texture; } - GL3_SelectTMU(GL_TEXTURE1); GL3_BindLightmap(texture); + GL3_SelectTMU(GL_TEXTURE1); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); diff --git a/src/client/refresh/gl3/gl3_main.c b/src/client/refresh/gl3/gl3_main.c index 2dd8e651..af9229c4 100644 --- a/src/client/refresh/gl3/gl3_main.c +++ b/src/client/refresh/gl3/gl3_main.c @@ -515,7 +515,7 @@ GL3_Init(void) } // generate texture handles for all possible lightmaps - glGenTextures(MAX_LIGHTMAPS, gl3state.lightmap_textureIDs); + glGenTextures(MAX_LIGHTMAPS*MAX_LIGHTMAPS_PER_SURFACE, gl3state.lightmap_textureIDs[0]); GL3_SetDefaultState(); diff --git a/src/client/refresh/gl3/gl3_shaders.c b/src/client/refresh/gl3/gl3_shaders.c index 6bf9ec58..fcf0d179 100644 --- a/src/client/refresh/gl3/gl3_shaders.c +++ b/src/client/refresh/gl3/gl3_shaders.c @@ -332,8 +332,6 @@ static const char* vertexSrc3DlmOnly = MULTILINE_STRING( static const char* fragmentSrc3D = MULTILINE_STRING( // it gets attributes and uniforms from fragmentCommon3D - // TODO: will prolly need another version of this without lightmap, - // also shaders for that for flow (and more?) for translucent things that have no lightmap uniform sampler2D tex; @@ -351,11 +349,15 @@ static const char* fragmentSrc3D = MULTILINE_STRING( static const char* fragmentSrc3Dlm = MULTILINE_STRING( // it gets attributes and uniforms from fragmentCommon3D - // TODO: will prolly need another version of this without lightmap, - // also shaders for that for flow (and more?) for translucent things that have no lightmap uniform sampler2D tex; - uniform sampler2D lightmap; + + uniform sampler2D lightmap0; + uniform sampler2D lightmap1; + uniform sampler2D lightmap2; + uniform sampler2D lightmap3; + + uniform vec4 lmScales[4]; in vec2 passLMcoord; @@ -363,12 +365,15 @@ static const char* fragmentSrc3Dlm = MULTILINE_STRING( { vec4 texel = texture(tex, passTexCoord); - // apply intensity texel.rgb *= intensity; // apply lightmap - vec4 lmTex = texture(lightmap, passLMcoord); + vec4 lmTex = texture(lightmap0, passLMcoord) * lmScales[0]; + lmTex += texture(lightmap1, passLMcoord) * lmScales[1]; + lmTex += texture(lightmap2, passLMcoord) * lmScales[2]; + lmTex += texture(lightmap3, passLMcoord) * lmScales[3]; + lmTex.rgb *= overbrightbits; outColor = lmTex*texel; outColor.rgb = pow(outColor.rgb, vec3(gamma)); // apply gamma correction to result @@ -599,6 +604,7 @@ initShader2D(gl3ShaderInfo_t* shaderInfo, const char* vertSrc, const char* fragS //shaderInfo->uniColor = shaderInfo->uniProjMatrix = shaderInfo->uniModelViewMatrix = -1; shaderInfo->shaderProgram = 0; + shaderInfo->uniLmScales = -1; shaders2D[0] = CompileShader(GL_VERTEX_SHADER, vertSrc, NULL); if(shaders2D[0] == 0) return false; @@ -681,6 +687,7 @@ initShader3D(gl3ShaderInfo_t* shaderInfo, const char* vertSrc, const char* fragS { GLuint shaders3D[2] = {0}; GLuint prog = 0; + int i=0; if(shaderInfo->shaderProgram != 0) { @@ -689,6 +696,7 @@ initShader3D(gl3ShaderInfo_t* shaderInfo, const char* vertSrc, const char* fragS } shaderInfo->shaderProgram = 0; + shaderInfo->uniLmScales = -1; shaders3D[0] = CompileShader(GL_VERTEX_SHADER, vertexCommon3D, vertSrc); if(shaders3D[0] == 0) return false; @@ -751,16 +759,34 @@ initShader3D(gl3ShaderInfo_t* shaderInfo, const char* vertSrc, const char* fragS goto err_cleanup; } - // make sure texture is GL_TEXTURE0 and lightmap is GL_TEXTURE1 + // make sure texture is GL_TEXTURE0 GLint texLoc = glGetUniformLocation(prog, "tex"); if(texLoc != -1) { glUniform1i(texLoc, 0); } - GLint lmLoc = glGetUniformLocation(prog, "lightmap"); - if(lmLoc != -1) + + // .. and the 4 lightmap texture use GL_TEXTURE1..4 + for(i=0; i<4; ++i) { - glUniform1i(lmLoc, 1); + char lmName[10] = "lightmapX"; + lmName[8] = '0'+i; + GLint lmLoc = glGetUniformLocation(prog, lmName); + if(lmLoc != -1) + { + glUniform1i(lmLoc, i+1); // lightmap0 belongs to GL_TEXTURE1, lightmap1 to GL_TEXTURE2 etc + } + } + + GLint lmScalesLoc = glGetUniformLocation(prog, "lmScales"); + shaderInfo->uniLmScales = lmScalesLoc; + if(lmScalesLoc != -1) + { + GLfloat scales[4][4] = {0}; + + for(i=0; i<4; ++i) scales[0][i] = 1.0f; + + glUniform4fv(lmScalesLoc, 4, scales[0]); } shaderInfo->shaderProgram = prog; diff --git a/src/client/refresh/gl3/gl3_surf.c b/src/client/refresh/gl3/gl3_surf.c index e63e0171..3ad1f2de 100644 --- a/src/client/refresh/gl3/gl3_surf.c +++ b/src/client/refresh/gl3/gl3_surf.c @@ -305,7 +305,7 @@ BlendLightmaps(void) msurface_t *surf, *newdrawsurf = 0; return; // XXX: remove the whole function - +#if 0 /* don't bother if we're set to fullbright */ if (gl_fullbright->value) { @@ -490,6 +490,7 @@ BlendLightmaps(void) glDisable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDepthMask(1); +#endif // 0 } static void @@ -550,6 +551,8 @@ RenderBrushPoly(msurface_t *fa) // R_TexEnv(GL_REPLACE); TODO! } + // TODO: bind all the lightmaps + GL3_BindLightmap(fa->lightmaptexturenum); if (fa->texinfo->flags & SURF_FLOWING) @@ -594,7 +597,7 @@ RenderBrushPoly(msurface_t *fa) // TODO: 2D texture array für lightmaps? if (is_dynamic) { - if (((fa->styles[maps] >= 32) || + /*if (((fa->styles[maps] >= 32) || (fa->styles[maps] == 0)) && (fa->dlightframe != gl3_framecount)) { @@ -619,7 +622,7 @@ RenderBrushPoly(msurface_t *fa) fa->lightmapchain = gl3_lms.lightmap_surfaces[fa->lightmaptexturenum]; gl3_lms.lightmap_surfaces[fa->lightmaptexturenum] = fa; } - else + else*/ { // dynamic lights: add to dynamic lightmap chain fa->lightmapchain = gl3_lms.lightmap_surfaces[0]; diff --git a/src/client/refresh/gl3/header/local.h b/src/client/refresh/gl3/header/local.h index c34a5c56..a8d35aa4 100644 --- a/src/client/refresh/gl3/header/local.h +++ b/src/client/refresh/gl3/header/local.h @@ -106,6 +106,7 @@ typedef struct typedef struct { GLuint shaderProgram; + GLint uniLmScales; } gl3ShaderInfo_t; typedef struct @@ -144,7 +145,8 @@ enum { BLOCK_WIDTH = 128, BLOCK_HEIGHT = 128, LIGHTMAP_BYTES = 4, - MAX_LIGHTMAPS = 128 + MAX_LIGHTMAPS = 128, + MAX_LIGHTMAPS_PER_SURFACE = MAXLIGHTMAPS // 4 }; typedef struct @@ -160,7 +162,7 @@ typedef struct // "So color textures start at 0, the dynamic lightmap texture is always 1024 and the static lighmap are 1025 up to 1036." // yes, dynamic lightmap is 1024, but I think there can be 127 dynamic lightmaps (MAX_LIGHTMAPS == 128) //int lightmap_textures; - GLuint lightmap_textureIDs[MAX_LIGHTMAPS]; // instead of lightmap_textures+i use lightmap_textureIDs[i] + GLuint lightmap_textureIDs[MAX_LIGHTMAPS][MAX_LIGHTMAPS_PER_SURFACE]; // instead of lightmap_textures+i use lightmap_textureIDs[i] //int currenttextures[2]; GLuint currenttexture; // bound to GL_TEXTURE0