diff --git a/src/cache.h b/src/cache.h index 9edc9c0..7facf8d 100644 --- a/src/cache.h +++ b/src/cache.h @@ -321,7 +321,7 @@ struct AmbientCache { for (int j = 0; j < 6; j++) { Texture *src = textures[j * 4 + i - 1]; Texture *dst = textures[j * 4 + i]; - Core::setTarget(dst, RT_STORE_COLOR); + Core::setTarget(dst, NULL, RT_STORE_COLOR); src->bind(sDiffuse); game->getMesh()->renderQuad(); } @@ -329,7 +329,7 @@ struct AmbientCache { // get result color from 1x1 textures for (int j = 0; j < 6; j++) { - Core::setTarget(textures[j * 4 + 3], RT_LOAD_COLOR); + Core::setTarget(textures[j * 4 + 3], NULL, RT_LOAD_COLOR); colors[j] = Core::copyPixel(0, 0); } @@ -719,7 +719,7 @@ struct WaterCache { Core::active.shader->setParam(uParam, vec4(p.x, p.z, drop.radius * DETAIL, -drop.strength)); item.data[0]->bind(sDiffuse); - Core::setTarget(item.data[1], RT_STORE_COLOR); + Core::setTarget(item.data[1], NULL, RT_STORE_COLOR); Core::setViewport(0, 0, int(s.x + 0.5f), int(s.y + 0.5f)); game->getMesh()->renderQuad(); swap(item.data[0], item.data[1]); @@ -738,7 +738,7 @@ struct WaterCache { while (item.timer >= SIMULATE_TIMESTEP) { // water step item.data[0]->bind(sDiffuse); - Core::setTarget(item.data[1], RT_STORE_COLOR); + Core::setTarget(item.data[1], NULL, RT_STORE_COLOR); Core::setViewport(0, 0, int(s.x + 0.5f), int(s.y + 0.5f)); game->getMesh()->renderQuad(); swap(item.data[0], item.data[1]); @@ -760,7 +760,7 @@ struct WaterCache { Core::whiteTex->bind(sReflect); item.data[0]->bind(sNormal); - Core::setTarget(item.caustics, RT_CLEAR_COLOR | RT_STORE_COLOR); + Core::setTarget(item.caustics, NULL, RT_CLEAR_COLOR | RT_STORE_COLOR); Core::setViewport(1, 1, item.caustics->width - 2, item.caustics->width - 2); // leave 1px for black border game->getMesh()->renderPlane(); #ifdef BLUR_CAUSTICS @@ -869,9 +869,9 @@ struct WaterCache { x = y = 0; if (screen) { // only for iOS devices - Core::setTarget(refract, RT_LOAD_DEPTH | RT_STORE_COLOR | RT_STORE_DEPTH); + Core::setTarget(refract, NULL, RT_LOAD_DEPTH | RT_STORE_COLOR | RT_STORE_DEPTH); blitTexture(screen); - Core::setTarget(screen, RT_LOAD_COLOR | RT_LOAD_DEPTH | RT_STORE_COLOR); + Core::setTarget(screen, NULL, RT_LOAD_COLOR | RT_LOAD_DEPTH | RT_STORE_COLOR); } else Core::copyTarget(refract, 0, 0, x, y, Core::viewportDef.width, Core::viewportDef.height); // copy framebuffer into refraction texture } @@ -907,7 +907,7 @@ struct WaterCache { } // render mirror reflection - Core::setTarget(reflect, RT_CLEAR_COLOR | RT_CLEAR_DEPTH | RT_STORE_COLOR); + Core::setTarget(reflect, NULL, RT_CLEAR_COLOR | RT_CLEAR_DEPTH | RT_STORE_COLOR); Camera *camera = (Camera*)game->getCamera(); game->setupBinding(); diff --git a/src/core.h b/src/core.h index 31ed08f..8d9405d 100644 --- a/src/core.h +++ b/src/core.h @@ -483,11 +483,12 @@ struct MeshRange { E( WATER_MASK ) \ E( WATER_COMPOSE ) \ /* filter types */ \ - E( FILTER_UPSCALE ) \ - E( FILTER_DOWNSAMPLE ) \ - E( FILTER_GRAYSCALE ) \ - E( FILTER_BLUR ) \ - E( FILTER_EQUIRECTANGULAR ) \ + E( FILTER_UPSCALE ) \ + E( FILTER_DOWNSAMPLE ) \ + E( FILTER_DOWNSAMPLE_DEPTH ) \ + E( FILTER_GRAYSCALE ) \ + E( FILTER_BLUR ) \ + E( FILTER_EQUIRECTANGULAR ) \ /* options */ \ E( UNDERWATER ) \ E( ALPHA_TEST ) \ @@ -939,19 +940,19 @@ namespace Core { renderState &= ~RS_DEPTH_TEST; } - void setTarget(GAPI::Texture *target, int op, int face = 0) { - if (!target) - target = defaultTarget; + void setTarget(GAPI::Texture *color, GAPI::Texture *depth, int op, int face = 0) { + if (!color) + color = defaultTarget; - bool color = !target || (target->fmt != FMT_DEPTH && target->fmt != FMT_SHADOW); - setColorWrite(color, color, color, color); + bool isColor = !color || (color->fmt != FMT_DEPTH && color->fmt != FMT_SHADOW); + setColorWrite(isColor, isColor, isColor, isColor); - if (target == defaultTarget) // backbuffer + if (color == defaultTarget) // backbuffer setViewport(viewportDef); else - setViewport(0, 0, target->origWidth, target->origHeight); + setViewport(0, 0, color->origWidth, color->origHeight); - reqTarget.texture = target; + reqTarget.texture = color; reqTarget.op = op; reqTarget.face = face; renderState |= RS_TARGET; @@ -1016,7 +1017,7 @@ namespace Core { void endFrame() { if (active.target != defaultTarget) { - GAPI::setTarget(NULL, 0); + GAPI::setTarget(NULL, NULL, 0); validateRenderState(); } GAPI::endFrame(); diff --git a/src/inventory.h b/src/inventory.h index c6b9408..cba9eb9 100644 --- a/src/inventory.h +++ b/src/inventory.h @@ -1378,21 +1378,21 @@ struct Inventory { // #else // vertical blur - Core::setTarget(background[1], RT_STORE_COLOR); + Core::setTarget(background[1], NULL, RT_STORE_COLOR); game->setShader(Core::passFilter, Shader::FILTER_BLUR, false, false); Core::active.shader->setParam(uParam, vec4(0, 1.0f / INVENTORY_BG_SIZE, 0, 0)); background[0]->bind(sDiffuse); game->getMesh()->renderQuad(); // horizontal blur - Core::setTarget(background[0], RT_STORE_COLOR); + Core::setTarget(background[0], NULL, RT_STORE_COLOR); game->setShader(Core::passFilter, Shader::FILTER_BLUR, false, false); Core::active.shader->setParam(uParam, vec4(1.0f / INVENTORY_BG_SIZE, 0, 0, 0)); background[1]->bind(sDiffuse); game->getMesh()->renderQuad(); // grayscale - Core::setTarget(background[1], RT_STORE_COLOR); + Core::setTarget(background[1], NULL, RT_STORE_COLOR); game->setShader(Core::passFilter, Shader::FILTER_GRAYSCALE, false, false); Core::active.shader->setParam(uParam, vec4(0.75f, 0.75f, 1.0f, 1.0f)); background[0]->bind(sDiffuse); diff --git a/src/level.h b/src/level.h index 8f0c7df..5934da6 100644 --- a/src/level.h +++ b/src/level.h @@ -577,7 +577,7 @@ struct Level : IGame { setupCubeCamera(pos, i); Core::pass = pass; Texture *target = (targets[0]->opt & OPT_CUBEMAP) ? targets[0] : targets[i * stride]; - Core::setTarget(target, RT_CLEAR_COLOR | RT_CLEAR_DEPTH | RT_STORE_COLOR, i); + Core::setTarget(target, NULL, RT_CLEAR_COLOR | RT_CLEAR_DEPTH | RT_STORE_COLOR, i); renderView(rIndex, false); } @@ -2151,7 +2151,7 @@ struct Level : IGame { Texture *screen = NULL; if (water) { screen = (waterCache && waterCache->visible) ? waterCache->getScreenTex() : NULL; - Core::setTarget(screen, RT_CLEAR_COLOR | RT_CLEAR_DEPTH | RT_STORE_COLOR | (screen ? RT_STORE_DEPTH : 0)); // render to screen texture (FUCK YOU iOS!) or back buffer + Core::setTarget(screen, NULL, RT_CLEAR_COLOR | RT_CLEAR_DEPTH | RT_STORE_COLOR | (screen ? RT_STORE_DEPTH : 0)); // render to screen texture (FUCK YOU iOS!) or back buffer setupBinding(); } @@ -2188,7 +2188,7 @@ struct Level : IGame { Core::Pass pass = Core::pass; if (water && waterCache && waterCache->visible && screen) { - Core::setTarget(NULL, RT_STORE_COLOR); + Core::setTarget(NULL, NULL, RT_STORE_COLOR); waterCache->blitTexture(screen); } @@ -2358,7 +2358,7 @@ struct Level : IGame { bool colorShadow = shadow->fmt == FMT_RGBA ? true : false; if (colorShadow) Core::setClearColor(vec4(1.0f)); - Core::setTarget(shadow, RT_CLEAR_DEPTH | (colorShadow ? (RT_CLEAR_COLOR | RT_STORE_COLOR) : RT_STORE_DEPTH)); + Core::setTarget(shadow, NULL, RT_CLEAR_DEPTH | (colorShadow ? (RT_CLEAR_COLOR | RT_STORE_COLOR) : RT_STORE_DEPTH)); //Core::setCullMode(cmBack); Core::validateRenderState(); @@ -2848,7 +2848,7 @@ struct Level : IGame { } void renderInventory() { - Core::setTarget(NULL, RT_CLEAR_DEPTH | RT_STORE_COLOR); + Core::setTarget(NULL, NULL, RT_CLEAR_DEPTH | RT_STORE_COLOR); Core::resetLights(); @@ -2877,7 +2877,7 @@ struct Level : IGame { needRedrawTitleBG = false; if (isEnded) { - Core::setTarget(NULL, RT_CLEAR_COLOR | RT_STORE_COLOR); + Core::setTarget(NULL, NULL, RT_CLEAR_COLOR | RT_STORE_COLOR); UI::begin(); UI::updateAspect(float(Core::width) / float(Core::height)); UI::textOut(vec2(0, 480 - 16), STR_LOADING, UI::aCenter, UI::width); diff --git a/src/shader.h b/src/shader.h index 26a7046..085766d 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, ROOM, ENTITY, MIRROR, - /* filter */ FILTER_UPSCALE = 0, FILTER_DOWNSAMPLE, FILTER_GRAYSCALE, FILTER_BLUR, FILTER_EQUIRECTANGULAR, + /* filter */ FILTER_UPSCALE = 0, FILTER_DOWNSAMPLE, FILTER_DOWNSAMPLE_DEPTH, FILTER_GRAYSCALE, FILTER_BLUR, FILTER_EQUIRECTANGULAR, /* water */ WATER_DROP = 0, WATER_SIMULATE, WATER_CAUSTICS, WATER_RAYS, WATER_MASK, WATER_COMPOSE, MAX = 6 }; diff --git a/src/shaders/common.hlsl b/src/shaders/common.hlsl index 7352304..959443c 100644 --- a/src/shaders/common.hlsl +++ b/src/shaders/common.hlsl @@ -58,18 +58,12 @@ float4 uPosScale[2] : register( c92 ); FLAGS_TYPE uFlags[4] : register( FLAGS_REG ); float4 uContacts[MAX_CONTACTS] : register( c98 ); - -#define TYPE_SPRITE uFlags[0].x -#define TYPE_FLASH uFlags[0].y -#define TYPE_ROOM uFlags[0].z -#define TYPE_ENTITY uFlags[0].w -#define TYPE_MIRROR uFlags[1].x - #define FILTER_DEFAULT uFlags[0].x #define FILTER_DOWNSAMPLE uFlags[0].y -#define FILTER_GRAYSCALE uFlags[0].z -#define FILTER_BLUR uFlags[0].w -#define FILTER_EQUIRECTANGULAR uFlags[1].x +#define FILTER_DOWNSAMPLE_DEPTH uFlags[0].z +#define FILTER_GRAYSCALE uFlags[0].w +#define FILTER_BLUR uFlags[1].x +#define FILTER_EQUIRECTANGULAR uFlags[1].y #define WATER_DROP uFlags[0].x #define WATER_SIMULATE uFlags[0].y @@ -79,6 +73,11 @@ float4 uContacts[MAX_CONTACTS] : register( c98 ); #define WATER_COMPOSE uFlags[1].y // options for compose, shadow, ambient passes +#define TYPE_SPRITE uFlags[0].x +#define TYPE_FLASH uFlags[0].y +#define TYPE_ROOM uFlags[0].z +#define TYPE_ENTITY uFlags[0].w +#define TYPE_MIRROR uFlags[1].x #define UNDERWATER uFlags[1].y #define ALPHA_TEST uFlags[1].z #define CLIP_PLANE uFlags[1].w diff --git a/src/shaders/filter.glsl b/src/shaders/filter.glsl index b648846..491f7be 100644 --- a/src/shaders/filter.glsl +++ b/src/shaders/filter.glsl @@ -36,6 +36,19 @@ uniform vec4 uParam; return vec4(color.xyz / color.w, 1.0); } + #ifdef FILTER_DOWNSAMPLE_DEPTH + vec4 downsampleDepth() { + vec2 t = vTexCoord.xy; + vec3 o = vec3(uParam.x, uParam.y, 0.0); + float d0 = texture2D(sDiffuse, t + o.zz).x; + float d1 = texture2D(sDiffuse, t + o.xz).x; + float d2 = texture2D(sDiffuse, t + o.zy).x; + float d3 = texture2D(sDiffuse, t + o.xy).x; + gl_FragDepth = max(max(d0, d1), max(d2, d3)); + return vec4(0.0); + } + #endif + vec4 grayscale() { // uParam (factor, unused, unused, unused) vec4 color = texture2D(sDiffuse, vTexCoord); vec3 gray = vec3(dot(color, vec4(0.299, 0.587, 0.114, 0.0))); @@ -81,6 +94,10 @@ uniform vec4 uParam; return downsample(); #endif + #ifdef FILTER_DOWNSAMPLE_DEPTH + return downsampleDepth(); + #endif + #ifdef FILTER_GRAYSCALE return grayscale(); #endif