diff --git a/planet/Graphics.ocg/LandscapeShader.c b/planet/Graphics.ocg/LandscapeShader.c index 12ff99f07..a25267b2b 100644 --- a/planet/Graphics.ocg/LandscapeShader.c +++ b/planet/Graphics.ocg/LandscapeShader.c @@ -20,7 +20,7 @@ uniform int materialDepth; // Expected parameters for the scaler const vec2 scalerStepX = vec2(1.0 / 8.0, 0.0); const vec2 scalerStepY = vec2(0.0, 1.0 / 32.0); -const vec2 scalerOffset = vec2(0.0, 0.0) + scalerStepX / 3.0 + scalerStepY / 3.0; +const vec2 scalerOffset = scalerStepX / 3.0 + scalerStepY / 3.0; const vec2 scalerPixel = vec2(scalerStepX.x, scalerStepY.y) / 3.0; #ifdef NO_TEXTURE_LOD_IN_FRAGMENT @@ -61,6 +61,7 @@ void main() // find scaler coordinate vec2 scalerCoo = scalerOffset + mod(pixelCoo, vec2(1.0, 1.0)) * scalerPixel; +#ifdef SCALER_IN_GPU if(texture2D(landscapeTex[0], centerCoo - fullStepX - fullStepY).r == lpx.r) scalerCoo += scalerStepX; if(texture2D(landscapeTex[0], centerCoo - fullStepY).r == lpx.r) @@ -80,6 +81,13 @@ void main() if(texture2D(landscapeTex[0], centerCoo + fullStepX + fullStepY).r == lpx.r) scalerCoo += 16.0 * scalerStepY; +#else + + scalerCoo.x += px.a * 255.0 / 8.0; + scalerCoo.y += floor(lpx.a * 255.0 / 8.0) / 32.0; + +#endif + // Note: scalerCoo will jump around a lot, causing some GPUs to apparantly get confused with // the level-of-detail calculation. We therefore try to disable LOD. vec4 spx = texture2DLod(scalerTex, scalerCoo, 0.0); @@ -90,9 +98,9 @@ void main() // Get material pixels float mi = queryMatMap(f2i(lpx.r)); - vec4 mpx = texture3D(materialTex, vec3(gl_TexCoord[0].st * resolution / vec2(512.0, 512.0) * vec2(3.0, 3.0), mi)); + vec4 mpx = texture3D(materialTex, vec3(gl_TexCoord[0].st * resolution / vec2(512.0, 512.0) * vec2(4.0, 4.0), mi)); float omi = queryMatMap(f2i(lopx.r)); - vec4 ompx = texture3D(materialTex, vec3(gl_TexCoord[0].st * resolution / vec2(512.0, 512.0) * vec2(3.0, 3.0), omi)); + vec4 ompx = texture3D(materialTex, vec3(gl_TexCoord[0].st * resolution / vec2(512.0, 512.0) * vec2(4.0, 4.0), omi)); // Brightness float ambientBright = 1.0, shadeBright = 0.8; diff --git a/src/game/landscape/C4LandscapeRender.cpp b/src/game/landscape/C4LandscapeRender.cpp index 1a5ed3351..fc6f51fe6 100644 --- a/src/game/landscape/C4LandscapeRender.cpp +++ b/src/game/landscape/C4LandscapeRender.cpp @@ -36,6 +36,7 @@ const char *C4LR_ShaderWorkarounds[] = { "", "#define NO_TEXTURE_LOD_IN_FRAGMENT\n", "#define BROKEN_ARRAYS_WORKAROUND\n", + "#define SCALER_IN_GPU\n", }; const int C4LR_ShaderWorkaroundCount = sizeof(C4LR_ShaderWorkarounds) / sizeof(*C4LR_ShaderWorkarounds); @@ -369,7 +370,9 @@ void C4LandscapeRenderGL::Update(C4Rect To, C4Landscape *pSource) for(x = 0; x < To.Wdt; x++) { // Biases + int iPix = pSource->_GetPix(To.x+x, To.y+y); int iPlac = pSource->_GetPlacement(To.x+x, To.y+y); + int iMat = pSource->_GetMat(To.x+x, To.y+y); int iHBias = Max(0, iPlac * (C4LR_BiasDistanceY-1) - iRight) - Max(0, iPlac * (C4LR_BiasDistanceY-1) - iLeft); int iVBias = Max(0, iPlac * (C4LR_BiasDistanceY-1) - pDown[x]) - @@ -381,13 +384,37 @@ void C4LandscapeRenderGL::Update(C4Rect To, C4Landscape *pSource) int iHBiasScaled = BoundBy(iHBias * 127 / iMaxPlacDiff / C4LR_BiasDistanceX + 128, 0, 255); int iVBiasScaled = BoundBy(iVBias * 127 / iMaxPlacDiff / C4LR_BiasDistanceY + 128, 0, 255); + // Get scaler + int iScaler = 0; + if(To.y+y > 0) { + if(To.x+x > 0 && pSource->_GetMat(To.x+x-1, To.y+y-1) == iMat) + iScaler += 1; + if(pSource->_GetMat(To.x+x, To.y+y-1) == iMat) + iScaler += 2; + if(To.x+x < iWidth-1 && pSource->_GetMat(To.x+x+1, To.y+y-1) == iMat) + iScaler += 4; + } + if(To.x+x > 0 && pSource->_GetMat(To.x+x-1, To.y+y) == iMat) + iScaler += 8; + if(To.x+x < iWidth-1 && pSource->_GetMat(To.x+x+1, To.y+y) == iMat) + iScaler += 16; + if(To.y+y < iHeight-1) { + if(To.x+x > 0 && pSource->_GetMat(To.x+x-1, To.y+y+1) == iMat) + iScaler += 32; + if(pSource->_GetMat(To.x+x, To.y+y+1) == iMat) + iScaler += 64; + if(To.x+x < iWidth-1 && pSource->_GetMat(To.x+x+1, To.y+y+1) == iMat) + iScaler += 128; + } + // Collect data to save per pixel unsigned char data[C4LR_SurfaceCount * 4]; memset(data, 0, sizeof(data)); - data[C4LR_Material] = pSource->_GetPix(To.x+x, To.y+y); + data[C4LR_Material] = iPix; data[C4LR_BiasX] = iHBiasScaled; data[C4LR_BiasY] = iVBiasScaled; + data[C4LR_Scaler] = iScaler; for(int i = 0; i < C4LR_SurfaceCount; i++) TexRefs[i]->SetPix4(To.x+x, To.y+y, @@ -754,6 +781,8 @@ void C4LandscapeRenderGL::Draw(const C4TargetFacet &cgo) { ALLOC_UNIT(hUniforms[C4LRU_ScalerTex], GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, fctScaler.Surface->ppTex[0]->texName); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); } diff --git a/src/game/landscape/C4LandscapeRender.h b/src/game/landscape/C4LandscapeRender.h index cab238bfb..6b914110f 100644 --- a/src/game/landscape/C4LandscapeRender.h +++ b/src/game/landscape/C4LandscapeRender.h @@ -10,6 +10,7 @@ enum C4LR_Byte { C4LR_Material, C4LR_BiasX, C4LR_BiasY, + C4LR_Scaler, C4LR_ByteCount };