1
0
mirror of https://github.com/XProger/OpenLara.git synced 2025-08-17 18:36:43 +02:00

add upsample filter for backgrounds; add texture content update

This commit is contained in:
XProger
2018-07-03 01:36:39 +03:00
parent 3dbbab4c3b
commit cd62dba110
9 changed files with 58 additions and 18 deletions

View File

@@ -98,7 +98,7 @@ struct ShaderCache {
} }
void prepareFilter(int fx) { 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_DOWNSAMPLE, fx, RS_COLOR_WRITE);
compile(Core::passFilter, Shader::FILTER_GRAYSCALE, fx, RS_COLOR_WRITE); compile(Core::passFilter, Shader::FILTER_GRAYSCALE, fx, RS_COLOR_WRITE);
compile(Core::passFilter, Shader::FILTER_BLUR, fx, RS_COLOR_WRITE); compile(Core::passFilter, Shader::FILTER_BLUR, fx, RS_COLOR_WRITE);
@@ -160,7 +160,7 @@ struct ShaderCache {
break; break;
} }
case Core::passWater : def[defCount++] = SD_WATER_DROP + type; 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; case Core::passGUI : break;
default : ASSERT(false); default : ASSERT(false);
} }

View File

@@ -453,7 +453,7 @@ struct MeshRange {
E( WATER_MASK ) \ E( WATER_MASK ) \
E( WATER_COMPOSE ) \ E( WATER_COMPOSE ) \
/* filter types */ \ /* filter types */ \
E( FILTER_DEFAULT ) \ E( FILTER_UPSCALE ) \
E( FILTER_DOWNSAMPLE ) \ E( FILTER_DOWNSAMPLE ) \
E( FILTER_GRAYSCALE ) \ E( FILTER_GRAYSCALE ) \
E( FILTER_BLUR ) \ E( FILTER_BLUR ) \
@@ -587,6 +587,7 @@ namespace Core {
#include "texture.h" #include "texture.h"
#include "shader.h" #include "shader.h"
//#include "video.h"
namespace Core { namespace Core {

View File

@@ -271,6 +271,13 @@ namespace GAPI {
if (tex2D) tex2D->GenerateMipSubLevels(); 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) { void bind(int sampler) {
if (opt & OPT_PROXY) return; if (opt & OPT_PROXY) return;
ASSERT(tex2D || texCube); ASSERT(tex2D || texCube);

View File

@@ -613,6 +613,11 @@ namespace GAPI {
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 4); //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) { void bind(int sampler) {
if (opt & OPT_PROXY) return; if (opt & OPT_PROXY) return;
ASSERT(ID); ASSERT(ID);

View File

@@ -47,11 +47,7 @@ namespace GAPI {
if (data) { if (data) {
memory = new uint8[width * height * 4]; memory = new uint8[width * height * 4];
#ifdef TEX_SWIZZLE update(data);
swizzle(memory, (uint8*)data, width * 4, height);
#else
memcpy(memory, data, width * height * 4);
#endif
} else } else
memory = NULL; memory = NULL;
} }
@@ -88,6 +84,14 @@ namespace GAPI {
#endif #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) { void bind(int sampler) {
if (!this || (opt & OPT_PROXY)) return; if (!this || (opt & OPT_PROXY)) return;
ASSERT(memory); ASSERT(memory);

View File

@@ -1307,11 +1307,13 @@ struct Inventory {
} }
} }
void renderTitleBG() { void renderTitleBG(float sx = 1.0f, float sy = 1.0f) {
float aspectSrc, aspectDst, aspectImg, ax, ay; float aspectSrc, aspectDst, aspectImg, ax, ay;
if (background[0]) { 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); aspectDst = float(Core::width) / float(Core::height);
ax = background[0]->origWidth / float(background[0]->width); ax = background[0]->origWidth / float(background[0]->width);
ay = background[0]->origHeight / float(background[0]->height); ay = background[0]->origHeight / float(background[0]->height);
@@ -1404,8 +1406,6 @@ struct Inventory {
vertices[10].texCoord = vertices[10].texCoord =
vertices[11].texCoord = short4(0, 0, 0, 0); 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]) { if (Core::settings.detail.stereo == Core::Settings::STEREO_VR || !background[0]) {
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
vertices[i].light.x = vertices[i].light.y = vertices[i].light.z = 0; vertices[i].light.x = vertices[i].light.y = vertices[i].light.z = 0;
@@ -1413,6 +1413,8 @@ struct Inventory {
} else } else
background[0]->bind(sDiffuse); 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)); game->getMesh()->renderBuffer(indices, COUNT(indices), vertices, COUNT(vertices));
} }
@@ -1432,12 +1434,14 @@ struct Inventory {
vertices[2].texCoord = short4(32767, 0, 0, 0); vertices[2].texCoord = short4(32767, 0, 0, 0);
vertices[3].texCoord = short4( 0, 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]) { if (Core::settings.detail.stereo == Core::Settings::STEREO_VR || !background[0]) {
Core::blackTex->bind(sDiffuse); // black background Core::blackTex->bind(sDiffuse); // black background
} else } else
background[0]->bind(sDiffuse); // blured grayscale image 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); Core::setBlendMode(phaseRing < 1.0f ? bmAlpha : bmNone);
game->getMesh()->renderBuffer(indices, COUNT(indices), vertices, COUNT(vertices)); game->getMesh()->renderBuffer(indices, COUNT(indices), vertices, COUNT(vertices));
} }

View File

@@ -8,7 +8,7 @@ struct Shader : GAPI::Shader {
enum Type { enum Type {
DEFAULT = 0, DEFAULT = 0,
/* shader */ SPRITE = 0, FLASH = 1, ROOM = 2, ENTITY = 3, MIRROR = 4, /* 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, /* water */ WATER_DROP = 0, WATER_STEP = 1, WATER_CAUSTICS = 2, WATER_MASK = 3, WATER_COMPOSE = 4,
MAX = 6 MAX = 6
}; };

View File

@@ -67,6 +67,16 @@ uniform vec4 uParam;
} }
#endif #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() { vec4 filter() {
#ifdef FILTER_DOWNSAMPLE #ifdef FILTER_DOWNSAMPLE
return downsample(); return downsample();
@@ -84,7 +94,7 @@ uniform vec4 uParam;
return equirectangular(); return equirectangular();
#endif #endif
return texture2D(sDiffuse, vTexCoord) * vColor; return upscale();
} }
void main() { void main() {

View File

@@ -61,6 +61,15 @@ float4 blur(float2 uv) { // uParam (dirX, dirY, 1 / textureSize, unused)
return color; 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 { float4 main(VS_OUTPUT In) : COLOR0 {
if (FILTER_DOWNSAMPLE) if (FILTER_DOWNSAMPLE)
@@ -69,9 +78,9 @@ float4 main(VS_OUTPUT In) : COLOR0 {
if (FILTER_GRAYSCALE) if (FILTER_GRAYSCALE)
return grayscale(In.texCoord.xy); return grayscale(In.texCoord.xy);
if (FILTER_BLUR) if (FILTER_BLUR)
return blur(In.texCoord.xy); rreturn blur(In.texCoord.xy);
return (tex2D(sDiffuse, In.texCoord.xy) * In.diffuse).bgra; return upscale(In.texCoord.xy) * In.diffuse;
} }
#endif #endif