From 44b98ec84bc40f25387cd9f32f07c7e67c265a09 Mon Sep 17 00:00:00 2001 From: XProger Date: Mon, 30 Oct 2017 04:24:59 +0300 Subject: [PATCH] #23 fix dark ambient problem, add equirectangular projection and catsuit tests code --- src/cache.h | 12 ++++++++++-- src/controller.h | 2 +- src/lara.h | 11 +++++++++-- src/level.h | 40 ++++++++++++++++++++++++++++------------ src/shader.h | 4 ++-- src/shaders/filter.glsl | 16 ++++++++++++++++ src/shaders/shader.glsl | 7 +++++-- 7 files changed, 71 insertions(+), 21 deletions(-) diff --git a/src/cache.h b/src/cache.h index a8bc4a6..9227ab2 100644 --- a/src/cache.h +++ b/src/cache.h @@ -173,7 +173,7 @@ struct ShaderCache { break; } case Core::passFilter : { - static const char *typeNames[] = { "DEFAULT", "DOWNSAMPLE", "GRAYSCALE", "BLUR", "MIXER" }; + static const char *typeNames[] = { "DEFAULT", "DOWNSAMPLE", "GRAYSCALE", "BLUR", "MIXER", "EQUIRECTANGULAR" }; src = FILTER; typ = typeNames[type]; sprintf(def, "%s#define PASS_%s\n#define FILTER_%s\n", ext, passNames[pass], typ); @@ -729,6 +729,10 @@ struct WaterCache { Camera *camera = (Camera*)game->getCamera(); game->setupBinding(); + mat4 mProj = Core::mProj; + mat4 mView = Core::mView; + mat4 mViewInv = Core::mViewInv; + for (int i = 0; i < count; i++) { Item &item = items[i]; if (!item.visible) continue; @@ -751,8 +755,12 @@ struct WaterCache { Core::invalidateTarget(false, true); game->setClipParams(1.0f, NO_CLIP_PLANE); + Core::mProj = mProj; + Core::mView = mView; + Core::mViewInv = mViewInv; + camera->reflectPlane = NULL; - camera->setup(true); + camera->setup(false); } void render() { diff --git a/src/controller.h b/src/controller.h index 8980642..8a59d7c 100644 --- a/src/controller.h +++ b/src/controller.h @@ -51,7 +51,7 @@ struct IGame { virtual void setShader(Core::Pass pass, Shader::Type type, bool underwater = false, bool alphaTest = false) {} virtual void setRoomParams(int roomIndex, Shader::Type type, float diffuse, float ambient, float specular, float alpha, bool alphaTest = false) {} virtual void setupBinding() {} - virtual void renderEnvironment(int roomIndex, const vec3 &pos, Texture **targets, int stride = 0) {} + virtual void renderEnvironment(int roomIndex, const vec3 &pos, Texture **targets, int stride = 0, Core::Pass pass = Core::passAmbient) {} virtual void renderCompose(int roomIndex) {} virtual void renderView(int roomIndex, bool water) {} virtual void setEffect(Controller *controller, TR::Effect effect) {} diff --git a/src/lara.h b/src/lara.h index 341c717..0cf8f8b 100644 --- a/src/lara.h +++ b/src/lara.h @@ -1373,12 +1373,14 @@ struct Lara : Character { } void bakeEnvironment() { + getEntity().flags.invisible = true; if (!environment) environment = new Texture(256, 256, Texture::RGBA, true, NULL, true, true); Core::beginFrame(); - game->renderEnvironment(getRoomIndex(), pos - vec3(0.0f, 384.0f, 0.0f), &environment); + game->renderEnvironment(getRoomIndex(), pos - vec3(0.0f, 384.0f, 0.0f), &environment, 0, Core::passCompose); environment->generateMipMap(); Core::endFrame(); + getEntity().flags.invisible = false; } virtual void hit(float damage, Controller *enemy = NULL, TR::HitType hitType = TR::HIT_DEFAULT) { @@ -3035,8 +3037,13 @@ struct Lara : Character { Core::setBlending(bmNone); } - if (state == STATE_MIDAS_DEATH) { + if (state == STATE_MIDAS_DEATH /* && Core::pass == Core::passCompose */) { game->setRoomParams(getRoomIndex(), Shader::MIRROR, 1.2f, 1.0f, 0.2f, 1.0f, false); + /* catsuit test + game->setRoomParams(getRoomIndex(), Shader::MIRROR, 0.3f, 0.3f, 0.3f, 1.0f, false); + Core::active.shader->setParam(uLightColor, Core::lightColor[0], MAX_LIGHTS); + Core::active.shader->setParam(uLightPos, Core::lightPos[0], MAX_LIGHTS); + */ environment->bind(sEnvironment); Core::setBlending(bmAlpha); visibleMask ^= 0xFFFFFFFF; diff --git a/src/level.h b/src/level.h index 0b2a192..e0a4226 100644 --- a/src/level.h +++ b/src/level.h @@ -52,6 +52,8 @@ struct Level : IGame { float effectTimer; int effectIdx; + Texture *cube360; + // IGame implementation ======== virtual void loadLevel(TR::LevelID id) { if (isEnded) return; @@ -214,19 +216,21 @@ struct Level : IGame { Core::basis.identity(); } - virtual void renderEnvironment(int roomIndex, const vec3 &pos, Texture **targets, int stride = 0) { + 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(); + Core::Pass tmpPass = Core::pass; // first pass render level into cube faces for (int i = 0; i < 6; i++) { setupCubeCamera(pos, i); - Core::pass = Core::passAmbient; + Core::pass = pass; Texture *target = targets[0]->cube ? targets[0] : targets[i * stride]; Core::setTarget(target, true, i); renderView(roomIndex, false); Core::invalidateTarget(false, true); } + Core::pass = tmpPass; } virtual void setEffect(Controller *controller, TR::Effect effect) { @@ -441,9 +445,12 @@ struct Level : IGame { sndCurrent = sndSoundtrack; effect = TR::Effect::NONE; + cube360 = NULL; } virtual ~Level() { + delete cube360; + #ifdef _DEBUG Debug::free(); #endif @@ -932,8 +939,6 @@ struct Level : IGame { } void updateLighting() { - camera->setup(true); - // update crystal lighting (TODO: make it per-room instead of global) int index = -1; float minDist = 1000000000.f; @@ -1051,10 +1056,7 @@ struct Level : IGame { } void setup() { - PROFILE_MARKER("SETUP"); - camera->setup(Core::pass == Core::passCompose); - setupBinding(); } @@ -1141,9 +1143,6 @@ struct Level : IGame { } } - if (clipPort.x > clipPort.z || clipPort.y > clipPort.w) - return false; - if (clipPort.x > viewPort.z || clipPort.y > viewPort.w || clipPort.z < viewPort.x || clipPort.w < viewPort.y) return false; @@ -1217,8 +1216,6 @@ struct Level : IGame { setupBinding(); } - camera->setup(Core::pass == Core::passCompose); - renderRooms(roomsList, roomsCount); if (Core::pass != Core::passAmbient) @@ -1250,6 +1247,7 @@ struct Level : IGame { Core::mView = Core::mViewInv.inverse(); Core::mProj = mat4(90, 1.0f, camera->znear, camera->zfar); Core::mViewProj = Core::mProj * Core::mView; + Core::viewPos = Core::mViewInv.offset.xyz; } void setupLightCamera() { @@ -1541,6 +1539,22 @@ struct Level : IGame { Core::setTarget(NULL, true); Core::validateRenderState(); } +/* // catsuit test + lara->bakeEnvironment(); + lara->visibleMask = Lara::BODY_HEAD | Lara::BODY_ARM_L3 | Lara::BODY_ARM_R3; +*/ + +/* + // EQUIRECTANGULAR PROJECTION test + if (!cube360) + cube360 = new Texture(1024, 1024, Texture::RGBA, true, NULL, true, false); + renderEnvironment(camera->getRoomIndex(), camera->pos, &cube360, 0, Core::passCompose); + Core::setTarget(NULL, true); + setShader(Core::passFilter, Shader::FILTER_EQUIRECTANGULAR); + cube360->bind(sEnvironment); + mesh->renderQuad(); + return; +*/ if (Core::settings.detail.stereo) { Core::viewportDef = vec4(0.0f, 0.0f, float(Core::width) * 0.5f, float(Core::height)); @@ -1559,6 +1573,8 @@ struct Level : IGame { setup(); renderView(camera->getRoomIndex(), true); } + + // lara->visibleMask = 0xFFFFFFFF; // catsuit test } void renderInventory() { diff --git a/src/shader.h b/src/shader.h index cd12e38..c49d05a 100644 --- a/src/shader.h +++ b/src/shader.h @@ -57,9 +57,9 @@ struct Shader { enum Type : GLint { DEFAULT = 0, /* shader */ SPRITE = 0, FLASH = 1, ROOM = 2, ENTITY = 3, MIRROR = 4, - /* filter */ FILTER_DOWNSAMPLE = 1, FILTER_GRAYSCALE = 2, FILTER_BLUR = 3, FILTER_MIXER = 4, + /* filter */ FILTER_DOWNSAMPLE = 1, FILTER_GRAYSCALE = 2, FILTER_BLUR = 3, FILTER_MIXER = 4, FILTER_EQUIRECTANGULAR = 5, /* water */ WATER_DROP = 0, WATER_STEP = 1, WATER_CAUSTICS = 2, WATER_MASK = 3, WATER_COMPOSE = 4, - MAX = 5 + MAX = 6 }; Shader(const char *source, const char *defines = "") { diff --git a/src/shaders/filter.glsl b/src/shaders/filter.glsl index 8f7add5..a17cfdf 100644 --- a/src/shaders/filter.glsl +++ b/src/shaders/filter.glsl @@ -62,6 +62,18 @@ uniform vec4 uParam; return mix(texture2D(sDiffuse, vTexCoord), texture2D(sNormal, vTexCoord), uParam.x) * uParam.y; } + #ifdef FILTER_EQUIRECTANGULAR + uniform samplerCube sEnvironment; + + #define PI 3.14159265358979323846 + + vec4 equirectangular() { + vec2 a = (vTexCoord - 0.5) * vec2(PI * 2.0, PI); + vec3 v = vec3(sin(a.x) * cos(a.y), -sin(a.y), cos(a.x) * cos(a.y)); + return textureCube(sEnvironment, normalize(v)); + } + #endif + vec4 filter() { #ifdef FILTER_DOWNSAMPLE return downsample(); @@ -79,6 +91,10 @@ uniform vec4 uParam; return mixer(); #endif + #ifdef FILTER_EQUIRECTANGULAR + return equirectangular(); + #endif + return texture2D(sDiffuse, vTexCoord); } diff --git a/src/shaders/shader.glsl b/src/shaders/shader.glsl index a224907..a1a296d 100644 --- a/src/shaders/shader.glsl +++ b/src/shaders/shader.glsl @@ -480,9 +480,12 @@ uniform vec4 uMaterial; // x - diffuse, y - ambient, z - specular, w - alpha color.xyz = mix(vec3(0.0), color.xyz, vLightVec.w); #endif #endif - +/* catsuit test + #elif defined(TYPE_MIRROR) + color.xyz += calcSpecular(normalize(vNormal.xyz), vViewVec.xyz, vLightVec.xyz, uLightColor[0], 0.4); + color.w = 1.0; +*/ #endif - gl_FragColor = color; #endif }