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:
16
src/cache.h
16
src/cache.h
@@ -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();
|
||||
|
||||
|
18
src/core.h
18
src/core.h
@@ -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;
|
||||
|
||||
|
@@ -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);
|
||||
|
18
src/level.h
18
src/level.h
@@ -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);
|
||||
|
@@ -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;
|
||||
|
Reference in New Issue
Block a user