From cd62dba11096b782c69adcdb9e463bdf85f223e9 Mon Sep 17 00:00:00 2001 From: XProger Date: Tue, 3 Jul 2018 01:36:39 +0300 Subject: [PATCH] add upsample filter for backgrounds; add texture content update --- src/cache.h | 4 ++-- src/core.h | 3 ++- src/gapi_d3d9.h | 7 +++++++ src/gapi_gl.h | 5 +++++ src/gapi_gu.h | 14 +++++++++----- src/inventory.h | 14 +++++++++----- src/shader.h | 2 +- src/shaders/filter.glsl | 12 +++++++++++- src/shaders/filter.hlsl | 15 ++++++++++++--- 9 files changed, 58 insertions(+), 18 deletions(-) diff --git a/src/cache.h b/src/cache.h index d9ab0da..8d9b3e1 100644 --- a/src/cache.h +++ b/src/cache.h @@ -98,7 +98,7 @@ struct ShaderCache { } void prepareFilter(int fx) { - compile(Core::passFilter, Shader::DEFAULT, fx, RS_COLOR_WRITE); + compile(Core::passFilter, Shader::FILTER_UPSCALE, fx, RS_COLOR_WRITE); compile(Core::passFilter, Shader::FILTER_DOWNSAMPLE, fx, RS_COLOR_WRITE); compile(Core::passFilter, Shader::FILTER_GRAYSCALE, fx, RS_COLOR_WRITE); compile(Core::passFilter, Shader::FILTER_BLUR, fx, RS_COLOR_WRITE); @@ -160,7 +160,7 @@ struct ShaderCache { break; } case Core::passWater : def[defCount++] = SD_WATER_DROP + type; break; - case Core::passFilter : def[defCount++] = SD_FILTER_DEFAULT + type; break; + case Core::passFilter : def[defCount++] = SD_FILTER_UPSCALE + type; break; case Core::passGUI : break; default : ASSERT(false); } diff --git a/src/core.h b/src/core.h index 4910cf8..3dbcd85 100644 --- a/src/core.h +++ b/src/core.h @@ -453,7 +453,7 @@ struct MeshRange { E( WATER_MASK ) \ E( WATER_COMPOSE ) \ /* filter types */ \ - E( FILTER_DEFAULT ) \ + E( FILTER_UPSCALE ) \ E( FILTER_DOWNSAMPLE ) \ E( FILTER_GRAYSCALE ) \ E( FILTER_BLUR ) \ @@ -587,6 +587,7 @@ namespace Core { #include "texture.h" #include "shader.h" +//#include "video.h" namespace Core { diff --git a/src/gapi_d3d9.h b/src/gapi_d3d9.h index a00b17d..bfe8650 100644 --- a/src/gapi_d3d9.h +++ b/src/gapi_d3d9.h @@ -271,6 +271,13 @@ namespace GAPI { if (tex2D) tex2D->GenerateMipSubLevels(); } + void update(void *data) { + D3DLOCKED_RECT rect; + D3DCHECK(tex2D->LockRect(0, &rect, NULL, 0)); + memcpy(rect.pBits, data, width * height * 4); + D3DCHECK(tex2D->UnlockRect(0)); + } + void bind(int sampler) { if (opt & OPT_PROXY) return; ASSERT(tex2D || texCube); diff --git a/src/gapi_gl.h b/src/gapi_gl.h index 53c4643..9a0615c 100644 --- a/src/gapi_gl.h +++ b/src/gapi_gl.h @@ -613,6 +613,11 @@ namespace GAPI { //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 4); } + void update(void *data) { + bind(0); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, origWidth, origHeight, GL_RGBA, GL_UNSIGNED_BYTE, data); + } + void bind(int sampler) { if (opt & OPT_PROXY) return; ASSERT(ID); diff --git a/src/gapi_gu.h b/src/gapi_gu.h index 890fc24..6dfdad5 100644 --- a/src/gapi_gu.h +++ b/src/gapi_gu.h @@ -47,11 +47,7 @@ namespace GAPI { if (data) { memory = new uint8[width * height * 4]; - #ifdef TEX_SWIZZLE - swizzle(memory, (uint8*)data, width * 4, height); - #else - memcpy(memory, data, width * height * 4); - #endif + update(data); } else memory = NULL; } @@ -88,6 +84,14 @@ namespace GAPI { #endif } + void update(void *data) { + #ifdef TEX_SWIZZLE + swizzle(memory, (uint8*)data, width * 4, height); + #else + memcpy(memory, data, width * height * 4); + #endif + } + void bind(int sampler) { if (!this || (opt & OPT_PROXY)) return; ASSERT(memory); diff --git a/src/inventory.h b/src/inventory.h index 0359641..e1ff1fe 100644 --- a/src/inventory.h +++ b/src/inventory.h @@ -1307,11 +1307,13 @@ struct Inventory { } } - void renderTitleBG() { + void renderTitleBG(float sx = 1.0f, float sy = 1.0f) { float aspectSrc, aspectDst, aspectImg, ax, ay; if (background[0]) { - aspectSrc = float(background[0]->origWidth) / float(background[0]->origHeight); + float ox = sx * background[0]->origWidth; + float oy = sy * background[0]->origHeight; + aspectSrc = ox / oy; aspectDst = float(Core::width) / float(Core::height); ax = background[0]->origWidth / float(background[0]->width); ay = background[0]->origHeight / float(background[0]->height); @@ -1404,8 +1406,6 @@ struct Inventory { vertices[10].texCoord = vertices[11].texCoord = short4(0, 0, 0, 0); - game->setShader(Core::passFilter, Shader::DEFAULT, false, false); - if (Core::settings.detail.stereo == Core::Settings::STEREO_VR || !background[0]) { for (int i = 0; i < 4; i++) vertices[i].light.x = vertices[i].light.y = vertices[i].light.z = 0; @@ -1413,6 +1413,8 @@ struct Inventory { } else background[0]->bind(sDiffuse); + game->setShader(Core::passFilter, Shader::FILTER_UPSCALE, false, false); + Core::active.shader->setParam(uParam, vec4(float(Core::active.textures[sDiffuse]->width), float(Core::active.textures[sDiffuse]->height), 0.0f, 0.0f)); game->getMesh()->renderBuffer(indices, COUNT(indices), vertices, COUNT(vertices)); } @@ -1432,12 +1434,14 @@ struct Inventory { vertices[2].texCoord = short4(32767, 0, 0, 0); vertices[3].texCoord = short4( 0, 0, 0, 0); - game->setShader(Core::passFilter, Shader::DEFAULT, false, false); if (Core::settings.detail.stereo == Core::Settings::STEREO_VR || !background[0]) { Core::blackTex->bind(sDiffuse); // black background } else background[0]->bind(sDiffuse); // blured grayscale image + game->setShader(Core::passFilter, Shader::FILTER_UPSCALE, false, false); + Core::active.shader->setParam(uParam, vec4(float(Core::active.textures[sDiffuse]->width), float(Core::active.textures[sDiffuse]->height), 0.0f, 0.0f)); + Core::setBlendMode(phaseRing < 1.0f ? bmAlpha : bmNone); game->getMesh()->renderBuffer(indices, COUNT(indices), vertices, COUNT(vertices)); } diff --git a/src/shader.h b/src/shader.h index 2a08be7..4274a60 100644 --- a/src/shader.h +++ b/src/shader.h @@ -8,7 +8,7 @@ struct Shader : GAPI::Shader { enum Type { DEFAULT = 0, /* shader */ SPRITE = 0, FLASH = 1, ROOM = 2, ENTITY = 3, MIRROR = 4, - /* filter */ FILTER_DOWNSAMPLE = 1, FILTER_GRAYSCALE = 2, FILTER_BLUR = 3, FILTER_EQUIRECTANGULAR = 4, + /* filter */ FILTER_UPSCALE = 0, FILTER_DOWNSAMPLE = 1, FILTER_GRAYSCALE = 2, FILTER_BLUR = 3, FILTER_EQUIRECTANGULAR = 4, /* water */ WATER_DROP = 0, WATER_STEP = 1, WATER_CAUSTICS = 2, WATER_MASK = 3, WATER_COMPOSE = 4, MAX = 6 }; diff --git a/src/shaders/filter.glsl b/src/shaders/filter.glsl index ebb1e62..0376918 100644 --- a/src/shaders/filter.glsl +++ b/src/shaders/filter.glsl @@ -67,6 +67,16 @@ uniform vec4 uParam; } #endif + + vec4 upscale() { // https://www.shadertoy.com/view/XsfGDn + vec2 uv = vTexCoord * uParam.xy + 0.5; + vec2 iuv = floor(uv); + vec2 fuv = fract(uv); + uv = iuv + fuv * fuv * (3.0 - 2.0 * fuv); + uv = (uv - 0.5) / uParam.xy; + return texture2D(sDiffuse, uv) * vColor; + } + vec4 filter() { #ifdef FILTER_DOWNSAMPLE return downsample(); @@ -84,7 +94,7 @@ uniform vec4 uParam; return equirectangular(); #endif - return texture2D(sDiffuse, vTexCoord) * vColor; + return upscale(); } void main() { diff --git a/src/shaders/filter.hlsl b/src/shaders/filter.hlsl index fe38570..f2c7de0 100644 --- a/src/shaders/filter.hlsl +++ b/src/shaders/filter.hlsl @@ -61,6 +61,15 @@ float4 blur(float2 uv) { // uParam (dirX, dirY, 1 / textureSize, unused) return color; } +float4 upscale(float2 uv) { + uv *= uParam.xy + 0.5; + float2 iuv = floor(uv); + float2 fuv = frac(uv); + uv = iuv + fuv * fuv * (3.0 - 2.0 * fuv); + uv = (uv - 0.5) / uParam.xy; + return tex2D(sDiffuse, uv).bgra; +} + float4 main(VS_OUTPUT In) : COLOR0 { if (FILTER_DOWNSAMPLE) @@ -69,9 +78,9 @@ float4 main(VS_OUTPUT In) : COLOR0 { if (FILTER_GRAYSCALE) return grayscale(In.texCoord.xy); - if (FILTER_BLUR) - return blur(In.texCoord.xy); + if (FILTER_BLUR) + rreturn blur(In.texCoord.xy); - return (tex2D(sDiffuse, In.texCoord.xy) * In.diffuse).bgra; + return upscale(In.texCoord.xy) * In.diffuse; } #endif \ No newline at end of file