1
0
mirror of https://github.com/XProger/OpenLara.git synced 2025-08-14 09:04:31 +02:00

#15 clear RT before render for TBR

This commit is contained in:
XProger
2018-04-15 04:45:35 +03:00
parent 67d89d1e1d
commit 0f8b3ff84f
5 changed files with 65 additions and 43 deletions

View File

@@ -288,6 +288,8 @@ struct AmbientCache {
float(max((s.floor - 2) * 256, (s.floor + s.ceiling) * 256 / 2)),
float((sector % r.zSectors) * 1024 + 512 + r.info.z));
Core::setClearColor(vec4(0, 0, 0, 1));
// first pass - render environment from position (room geometry & static meshes)
game->renderEnvironment(room, pos, textures, 4);
@@ -304,7 +306,7 @@ struct AmbientCache {
for (int j = 0; j < 6; j++) {
Texture *src = textures[j * 4 + i - 1];
Texture *dst = textures[j * 4 + i];
Core::setRenderTarget(dst, RT_CLEAR_COLOR | RT_CLEAR_DEPTH | RT_STORE_COLOR);
Core::setTarget(dst, RT_STORE_COLOR);
src->bind(sDiffuse);
game->getMesh()->renderQuad();
}
@@ -312,11 +314,12 @@ struct AmbientCache {
// get result color from 1x1 textures
for (int j = 0; j < 6; j++) {
Core::setRenderTarget(textures[j * 4 + 3], RT_STORE_COLOR);
Core::setTarget(textures[j * 4 + 3], RT_LOAD_COLOR);
colors[j] = Core::copyPixel(0, 0).xyz();
}
Core::setDepthTest(true);
Core::setClearColor(vec4(0, 0, 0, 0));
}
void processQueue() {
@@ -628,7 +631,7 @@ struct WaterCache {
Core::active.shader->setParam(uParam, vec4(p.x, p.z, drop.radius * DETAIL, -drop.strength));
item.data[0]->bind(sDiffuse);
Core::setRenderTarget(item.data[1], RT_STORE_COLOR);
Core::setTarget(item.data[1], RT_STORE_COLOR);
Core::setViewport(0, 0, int(item.size.x * DETAIL * 2.0f + 0.5f), int(item.size.z * DETAIL * 2.0f + 0.5f));
game->getMesh()->renderQuad();
swap(item.data[0], item.data[1]);
@@ -636,7 +639,6 @@ struct WaterCache {
}
void step(Item &item) {
item.timer = SIMULATE_TIMESTEP;
if (item.timer < SIMULATE_TIMESTEP) return;
game->setShader(Core::passWater, Shader::WATER_STEP);
@@ -646,7 +648,7 @@ struct WaterCache {
while (item.timer >= SIMULATE_TIMESTEP) {
// water step
item.data[0]->bind(sDiffuse);
Core::setRenderTarget(item.data[1], RT_STORE_COLOR);
Core::setTarget(item.data[1], RT_STORE_COLOR);
Core::setViewport(0, 0, int(item.size.x * DETAIL * 2.0f + 0.5f), int(item.size.z * DETAIL * 2.0f + 0.5f));
game->getMesh()->renderQuad();
swap(item.data[0], item.data[1]);
@@ -665,7 +667,7 @@ struct WaterCache {
Core::whiteTex->bind(sReflect);
item.data[0]->bind(sNormal);
Core::setRenderTarget(item.caustics, RT_STORE_COLOR);
Core::setTarget(item.caustics, RT_STORE_COLOR);
game->getMesh()->renderPlane();
#ifdef BLUR_CAUSTICS
// v blur
@@ -765,7 +767,7 @@ struct WaterCache {
}
// render mirror reflection
Core::setRenderTarget(reflect, RT_CLEAR_COLOR | RT_CLEAR_DEPTH | RT_STORE_COLOR);
Core::setTarget(reflect, RT_CLEAR_COLOR | RT_CLEAR_DEPTH | RT_STORE_COLOR);
Camera *camera = (Camera*)game->getCamera();
game->setupBinding();

View File

@@ -22,6 +22,8 @@
#undef OS_PTHREAD_MT
#elif ANDROID
#define MOBILE
#define RENDER_TBR
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include <dlfcn.h>
@@ -57,6 +59,8 @@
extern void osToggleVR(bool enable);
#elif __RPI__
#define MOBILE
#define RENDER_TBR
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include <EGL/egl.h>
@@ -101,6 +105,8 @@
#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
#define MOBILE
#define RENDER_TBR
#include <OpenGLES/ES2/gl.h>
#include <OpenGLES/ES2/glext.h>
#include <OpenGLES/ES3/glext.h>
@@ -1237,6 +1243,8 @@ namespace Core {
sceGuDrawBufferList(GU_PSM_5650, target->offset, target->width);
*/
#else
bool depth = false;
Core::stats.rt++;
if (!target) { // may be a null
glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO);
@@ -1245,7 +1253,8 @@ namespace Core {
if (target->opt & Texture::CUBEMAP)
texTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X + face;
bool depth = target->format == Texture::DEPTH || target->format == Texture::SHADOW;
depth = target->format == Texture::DEPTH || target->format == Texture::SHADOW;
int rtIndex = cacheRenderTarget(depth, target->width, target->height);
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
@@ -1254,6 +1263,11 @@ namespace Core {
}
#endif
#ifdef RENDER_TBR
if (!(reqTarget.op & RT_LOAD_COLOR) && !depth) reqTarget.op |= RT_CLEAR_COLOR;
if (!(reqTarget.op & RT_LOAD_DEPTH) && depth) reqTarget.op |= RT_CLEAR_DEPTH;
#endif
active.target = target;
active.targetOp = reqTarget.op;
active.targetFace = face;
@@ -1454,7 +1468,7 @@ namespace Core {
renderState &= ~RS_DEPTH_TEST;
}
void setRenderTarget(Texture *target, int op, int face = 0) {
void setTarget(Texture *target, int op, int face = 0) {
if (!target)
target = defaultTarget;

View File

@@ -1121,21 +1121,21 @@ struct Inventory {
//
#else
// vertical blur
Core::setRenderTarget(background[1], RT_STORE_COLOR);
Core::setTarget(background[1], RT_STORE_COLOR);
game->setShader(Core::passFilter, Shader::FILTER_BLUR, false, false);
Core::active.shader->setParam(uParam, vec4(0, 1, 1.0f / INVENTORY_BG_SIZE, 0));;
background[0]->bind(sDiffuse);
game->getMesh()->renderQuad();
// horizontal blur
Core::setRenderTarget(background[0], RT_STORE_COLOR);
Core::setTarget(background[0], RT_STORE_COLOR);
game->setShader(Core::passFilter, Shader::FILTER_BLUR, false, false);
Core::active.shader->setParam(uParam, vec4(1, 0, 1.0f / INVENTORY_BG_SIZE, 0));;
background[1]->bind(sDiffuse);
game->getMesh()->renderQuad();
// grayscale
Core::setRenderTarget(background[1], RT_STORE_COLOR);
Core::setTarget(background[1], RT_STORE_COLOR);
game->setShader(Core::passFilter, Shader::FILTER_GRAYSCALE, false, false);
Core::active.shader->setParam(uParam, vec4(1, 0, 0, 0));
background[0]->bind(sDiffuse);

View File

@@ -414,18 +414,22 @@ struct Level : IGame {
virtual void renderEnvironment(int roomIndex, const vec3 &pos, Texture **targets, int stride = 0, Core::Pass pass = Core::passAmbient) {
PROFILE_MARKER("ENVIRONMENT");
Core::eye = 0.0f;
setupBinding();
float tmpEye = Core::eye;
Core::Pass tmpPass = Core::pass;
// first pass render level into cube faces
Core::eye = 0.0f;
// render level into cube faces or texture images
for (int i = 0; i < 6; i++) {
setupCubeCamera(pos, i);
Core::pass = pass;
Texture *target = (targets[0]->opt & Texture::CUBEMAP) ? targets[0] : targets[i * stride];
Core::setRenderTarget(target, RT_CLEAR_COLOR | RT_CLEAR_DEPTH | RT_STORE_COLOR, i);
Core::setTarget(target, RT_CLEAR_COLOR | RT_CLEAR_DEPTH | RT_STORE_COLOR, i);
renderView(roomIndex, false, false);
}
Core::pass = tmpPass;
Core::eye = tmpEye;
}
virtual void setEffect(Controller *controller, TR::Effect::Type effect) {
@@ -1869,7 +1873,7 @@ struct Level : IGame {
}
if (water) {
Core::setRenderTarget(NULL, RT_CLEAR_COLOR | RT_CLEAR_DEPTH | RT_STORE_COLOR); // render to back buffer
Core::setTarget(NULL, RT_CLEAR_COLOR | RT_CLEAR_DEPTH | RT_STORE_COLOR); // render to back buffer
setupBinding();
}
@@ -2041,7 +2045,7 @@ struct Level : IGame {
bool colorShadow = shadow->format == Texture::RGBA ? true : false;
if (colorShadow)
Core::setClearColor(vec4(1.0f));
Core::setRenderTarget(shadow, RT_CLEAR_DEPTH | (colorShadow ? (RT_CLEAR_COLOR | RT_STORE_COLOR) : RT_STORE_DEPTH));
Core::setTarget(shadow, RT_CLEAR_DEPTH | (colorShadow ? (RT_CLEAR_COLOR | RT_STORE_COLOR) : RT_STORE_DEPTH));
Core::validateRenderState();
Core::setCulling(cfBack);
@@ -2478,7 +2482,7 @@ struct Level : IGame {
}
void renderInventory() {
Core::setRenderTarget(NULL, RT_CLEAR_DEPTH | RT_STORE_COLOR);
Core::setTarget(NULL, RT_CLEAR_DEPTH | RT_STORE_COLOR);
if (!(level.isTitle() || inventory.titleTimer > 0.0f))
inventory.renderBackground();
@@ -2501,7 +2505,7 @@ struct Level : IGame {
lastTitle = title;
if (isEnded) {
Core::setRenderTarget(NULL, RT_CLEAR_COLOR);
Core::setTarget(NULL, RT_CLEAR_COLOR);
UI::begin();
UI::updateAspect(float(Core::width) / float(Core::height));
UI::textOut(vec2(0, 480 - 16), STR_LOADING, UI::aCenter, UI::width);

View File

@@ -4,18 +4,17 @@ R"====(
precision highp float;
#endif
#ifdef OPT_CONTACT
#if defined(PASS_COMPOSE) && !defined(TYPE_FLASH)
varying vec3 vCoord;
#endif
varying vec4 vTexCoord; // xy - atlas coords, zw - trapezoidal correction
#ifdef OPT_CAUSTICS
varying vec2 vCausticsCoord; // - xy caustics texture coord
uniform vec4 uRoomSize; // xy - minXZ, zw - maxXZ
#endif
uniform mat4 uLightProj;
uniform mat4 uLightProj[SHADOW_OBJ_MAX];
uniform mat4 uViewProj;
uniform vec3 uViewPos;
uniform vec4 uParam; // x - time, y - water height, z - clip plane sign, w - clip plane height
@@ -32,7 +31,6 @@ uniform vec4 uMaterial; // x - diffuse, y - ambient, z - specular, w - alpha
#ifndef TYPE_FLASH
#ifdef PASS_COMPOSE
varying vec4 vLightProj;
varying vec4 vLightVec; // xyz - dir, w - fog factor
#ifdef OPT_SHADOW
@@ -131,7 +129,7 @@ uniform vec4 uMaterial; // x - diffuse, y - ambient, z - specular, w - alpha
vLightVec.w = clamp(1.0 / exp(fog), 0.0, 1.0);
#endif
#ifdef OPT_CONTACT
#if defined(PASS_COMPOSE) && !defined(TYPE_FLASH)
vCoord = coord.xyz;
#endif
return coord;
@@ -227,10 +225,6 @@ uniform vec4 uMaterial; // x - diffuse, y - ambient, z - specular, w - alpha
#if defined(PASS_COMPOSE) && !defined(TYPE_SPRITE)
vTexCoord.xy *= vTexCoord.zw;
#endif
#ifdef OPT_CAUSTICS
vCausticsCoord.xy = clamp((coord.xz - uRoomSize.xy) / (uRoomSize.zw - uRoomSize.xy), vec2(0.0), vec2(1.0));
#endif
}
void main() {
@@ -239,10 +233,6 @@ uniform vec4 uMaterial; // x - diffuse, y - ambient, z - specular, w - alpha
#ifndef PASS_SHADOW
_diffuse();
_lighting(coord.xyz);
#if defined(PASS_COMPOSE) && !defined(TYPE_FLASH)
vLightProj = uLightProj * coord;
#endif
#endif
_uv(coord.xyz);
@@ -293,8 +283,6 @@ uniform vec4 uMaterial; // x - diffuse, y - ambient, z - specular, w - alpha
}
#endif
#define SHADOW_TEXEL (2.0 / SHADOW_TEX_SIZE)
float random(vec3 seed, float freq) {
float dt = dot(floor(seed * freq), vec3(53.1215, 21.1352, 9.1322));
return fract(sin(dt) * 2105.2354);
@@ -308,8 +296,18 @@ uniform vec4 uMaterial; // x - diffuse, y - ambient, z - specular, w - alpha
return vec3(v.x * sc.y + v.y * sc.x, v.x * -sc.x + v.y * sc.y, 0.0);
}
float getShadow(vec4 lightProj) {
float getShadow(vec4 lightProj, vec2 tileOffset) {
vec3 p = lightProj.xyz / lightProj.w;
float vis =
#ifdef TYPE_ROOM
min(dot(vNormal.xyz, vLightVec.xyz), lightProj.w);
#else
lightProj.w;
#endif
vis = min(min(p.x, p.y), vis);
if (vis <= 0.0 || max(p.x, p.y) > 1.0) return 1.0;
p.xy = p.xy * vec2(0.25, 0.5) + tileOffset;
float rShadow = SHADOW(SHADOW_TEXEL * vec3(-0.93289, -0.03146, 0.0) + p) +
SHADOW(SHADOW_TEXEL * vec3( 0.81628, -0.05965, 0.0) + p) +
@@ -337,13 +335,17 @@ uniform vec4 uMaterial; // x - diffuse, y - ambient, z - specular, w - alpha
return rShadow + (1.0 - rShadow) * fade;
}
float getShadow() {
#ifdef TYPE_ROOM
float vis = min(dot(vNormal.xyz, vLightVec.xyz), vLightProj.w);
#else
float vis = vLightProj.w;
#endif
return vis > 0.0 ? getShadow(vLightProj) : 1.0;
float getShadow() { // hardcoded for 4x2 shadow atlas
vec4 c = vec4(vCoord, 1.0);
return min(min(min(min(min(min(min(
getShadow(uLightProj[0] * c, vec2(0.00, 0.0)),
getShadow(uLightProj[1] * c, vec2(0.25, 0.0))),
getShadow(uLightProj[2] * c, vec2(0.50, 0.0))),
getShadow(uLightProj[3] * c, vec2(0.75, 0.0))),
getShadow(uLightProj[4] * c, vec2(0.00, 0.5))),
getShadow(uLightProj[5] * c, vec2(0.25, 0.5))),
getShadow(uLightProj[6] * c, vec2(0.50, 0.5))),
getShadow(uLightProj[7] * c, vec2(0.75, 0.5)));
}
#endif
@@ -351,7 +353,7 @@ uniform vec4 uMaterial; // x - diffuse, y - ambient, z - specular, w - alpha
uniform sampler2D sReflect;
float calcCaustics(vec3 n) {
vec2 cc = vCausticsCoord.xy;
vec2 cc = clamp((vCoord.xz - uRoomSize.xy) / (uRoomSize.zw - uRoomSize.xy), vec2(0.0), vec2(1.0));
vec2 border = vec2(256.0) / (uRoomSize.zw - uRoomSize.xy);
vec2 fade = smoothstep(vec2(0.0), border, cc) * (1.0 - smoothstep(vec2(1.0) - border, vec2(1.0), cc));
return texture2D(sReflect, cc).x * max(0.0, -n.y) * fade.x * fade.y;