Calculate scaler coordinate in CPU

Uses up another color component, but might be faster for some GPUs?
We will see.
Peter Wortmann 2011-07-24 22:50:52 +01:00
parent 8cb2b8452d
commit 6394061f3d
3 changed files with 42 additions and 4 deletions

View File

@ -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;

View File

@ -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);
}

View File

@ -10,6 +10,7 @@ enum C4LR_Byte {
C4LR_Material,
C4LR_BiasX,
C4LR_BiasY,
C4LR_Scaler,
C4LR_ByteCount
};