diff --git a/bin/OpenLara.exe b/bin/OpenLara.exe index e7da36d..fe9329e 100644 Binary files a/bin/OpenLara.exe and b/bin/OpenLara.exe differ diff --git a/src/controller.h b/src/controller.h index f088d63..4632b02 100644 --- a/src/controller.h +++ b/src/controller.h @@ -26,6 +26,7 @@ struct Controller { int frameIndex; vec3 ambient[6]; + float specular; struct MeshLayer { uint32 model; @@ -50,6 +51,7 @@ struct Controller { TR::Model *m = getModel(); joints = m ? new mat4[m->mCount] : NULL; frameIndex = -1; + specular = 0.0f; } virtual ~Controller() { diff --git a/src/core.h b/src/core.h index 1017ee9..903be28 100644 --- a/src/core.h +++ b/src/core.h @@ -103,6 +103,7 @@ #endif #define MAX_LIGHTS 3 +#define MAX_CACHED_LIGHTS 3 #define MAX_RENDER_BUFFERS 11 struct Shader; diff --git a/src/filter.glsl b/src/filter.glsl index f7f8aa2..e79d144 100644 --- a/src/filter.glsl +++ b/src/filter.glsl @@ -29,10 +29,8 @@ uniform int uType; p.xyz *= p.w; color += p; } - color.xyz /= color.w; - color.w = 1.0; - return color; + return vec4(color.xyz / color.w, 1.0); } vec4 filter() { diff --git a/src/lara.h b/src/lara.h index c25ec1c..2fe0aa6 100644 --- a/src/lara.h +++ b/src/lara.h @@ -23,6 +23,9 @@ #define LARA_HANG_OFFSET 735.0f +#define LARA_WET_SPECULAR 0.5f +#define LARA_WET_TIMER (LARA_WET_SPECULAR / 16.0f) // 4 sec + #define PICKUP_FRAME_GROUND 40 #define PICKUP_FRAME_UNDERWATER 16 #define PUZZLE_FRAME 80 @@ -889,6 +892,8 @@ struct Lara : Character { alignToWall(); dst.y -= pos.y - infoDst.floor; pos = dst; // set new position + + specular = LARA_WET_SPECULAR; getEntity().room = infoCur.roomAbove; updateEntity(); @@ -1441,6 +1446,11 @@ struct Lara : Character { virtual void updateAnimation(bool commands) { Controller::updateAnimation(commands); updateWeapon(); + if (stand == STAND_UNDERWATER) + specular = 0.0f; + else + if (specular > 0.0f) + specular = max(0.0f, specular - LARA_WET_TIMER * Core::deltaTime); } virtual void updateVelocity() { diff --git a/src/level.h b/src/level.h index e571e1b..6816b0e 100644 --- a/src/level.h +++ b/src/level.h @@ -176,6 +176,46 @@ struct Level { } } *ambientCache; + /* + struct LightCache { + + struct Item { + int room; + int index; + float intensity; + } items[MAX_CACHED_LIGHTS]; + + void updateLightCache(const TR::Level &level, const vec3 &pos, int room) { + // update intensity + for (int i = 0; i < MAX_CACHED_LIGHTS; i++) { + Item &item = items[i]; + if (c.intensity < 0.0f) continue; + TR::Room::Light &light = level.rooms[c.room].lights[i]; + c.intensity = max(0.0f, 1.0f - (pos - vec3(float(light.x), float(light.y), float(light.z))).length2() / ((float)light.radius * (float)light.radius)); + } + + // check for new lights + int index = getLightIndex(pos, room); + + if (index >= 0 && (items[0].room != room || items[0].index != index)) [ + TR::Room::Light &light = level.rooms[room].lights[index]; + float intensity = max(0.0f, 1.0f - (lara->pos - vec3(float(light.x), float(light.y), float(light.z))).length2() / ((float)light.radius * (float)light.radius)); + + int i = 0; + while (i < MAX_CACHED_LIGHTS && lightCache[i].intensity > intensity) // get sorted place + i++; + if (i < MAX_CACHED_LIGHTS) { // insert light + for (int j = MAX_CACHED_LIGHTS - 1; j > i; j--) + lightCache[j] = lightCache[j - 1]; + lightCache[i].room = room; + lightCache[i].index = index; + lightCache[i].intensity = intensity; + } + + } + } + } lightCache; + */ Level(const char *name, bool demo, bool home) : level(name, demo), lara(NULL), time(0.0f) { #ifdef _DEBUG Debug::init(); @@ -613,21 +653,23 @@ struct Level { void renderEntity(const TR::Entity &entity) { //if (entity.room != lara->getRoomIndex()) return; - if (entity.type == TR::Entity::NONE) return; + if (entity.type == TR::Entity::NONE || !entity.modelIndex) return; if (Core::pass == Core::passShadow && !TR::castShadow(entity.type)) return; ASSERT(entity.controller); + bool isModel = entity.modelIndex > 0; + + Controller *controller = (Controller*)entity.controller; + TR::Room &room = level.rooms[entity.room]; if (!room.flags.rendered || entity.flags.invisible || entity.flags.rendered) return; - int16 lum = entity.intensity == -1 ? room.ambient : entity.intensity; - setRoomParams(room, intensityf(lum)); + int16 lum = entity.intensity == -1 ? room.ambient : entity.intensity; + setRoomParams(room, isModel ? controller->specular : intensityf(lum)); - Controller *controller = (Controller*)entity.controller; - - if (entity.modelIndex > 0) { // model + if (isModel) { // model vec3 pos = controller->pos; AmbientCache::Cube cube; if (Core::frameIndex != controller->frameIndex) { @@ -638,9 +680,7 @@ struct Level { getLight(pos, entity.room); Core::active.shader->setParam(uType, Shader::ENTITY); Core::active.shader->setParam(uAmbient, controller->ambient[0], 6); - } - - if (entity.modelIndex < 0) { // sprite + } else { // sprite Core::active.shader->setParam(uType, Shader::SPRITE); Core::lightPos[0] = vec3(0); Core::lightColor[0] = vec4(0, 0, 0, 1); @@ -684,6 +724,7 @@ struct Level { sh->setParam(uViewInv, Core::mViewInv); sh->setParam(uViewPos, Core::viewPos); sh->setParam(uTime, time); + sh->setParam(uLightsCount, 3); sh->setParam(uAnimTexRanges, mesh->animTexRanges[0], mesh->animTexRangesCount); sh->setParam(uAnimTexOffsets, mesh->animTexOffsets[0], mesh->animTexOffsetsCount); @@ -743,7 +784,7 @@ struct Level { Core::mView = Core::mViewInv.inverse(); Core::mProj = mat4(90, 1.0f, camera->znear, camera->zfar); } - + bool setupLightCamera() { vec3 pos = (lara->animation.getJoints(lara->getMatrix(), 0, false, NULL)).getPos(); diff --git a/src/platform/web/build.bat b/src/platform/web/build.bat index f065120..d71d279 100644 --- a/src/platform/web/build.bat +++ b/src/platform/web/build.bat @@ -3,7 +3,7 @@ cls set SRC=main.cpp set PROJ=OpenLara set FLAGS=-O3 -Wno-deprecated-register --llvm-opts 2 -fmax-type-align=2 -std=c++11 -I../../ -set PRELOAD=./GYM.PSX +set PRELOAD=./LEVEL2.PSX echo. call em++ %SRC% %FLAGS% -o %PROJ%.js --preload-file %PRELOAD% gzip.exe -9 -f %PROJ%.data %PROJ%.js %PROJ%.js.mem \ No newline at end of file diff --git a/src/platform/web/index.html b/src/platform/web/index.html index b952e8e..3c468c9 100644 --- a/src/platform/web/index.html +++ b/src/platform/web/index.html @@ -102,5 +102,7 @@ }; + + \ No newline at end of file diff --git a/src/shader.glsl b/src/shader.glsl index e6a8ff2..bf278db 100644 --- a/src/shader.glsl +++ b/src/shader.glsl @@ -99,6 +99,7 @@ uniform int uType; uniform vec4 uColor; #ifdef PASS_COMPOSE uniform samplerCube sEnvironment; + uniform int uLightsCount; uniform vec3 uLightPos[MAX_LIGHTS]; uniform vec4 uLightColor[MAX_LIGHTS]; uniform vec3 uAmbient[6]; @@ -192,6 +193,13 @@ uniform int uType; return color.xyz * (lum * att); } + vec3 calcSpecular(vec3 normal, vec3 viewVec, vec3 pos, vec4 color, float intensity) { + vec3 rv = reflect(-viewVec, normal); + vec3 lv = normalize(pos - vCoord.xyz); + float spec = pow(max(0.0, dot(rv, lv)), 8.0) * intensity; + return vec3(spec); + } + vec3 calcAmbient(vec3 n) { vec3 sqr = n * n; vec3 pos = step(0.0, n); @@ -242,7 +250,8 @@ uniform int uType; if (uType == TYPE_ENTITY) { vec3 rAmbient = pow(abs(calcAmbient(normal)), vec3(2.2)); float rShadow = getShadow(vLightProj); - light += calcLight(normal, uLightPos[0], uLightColor[0]) * rShadow + rAmbient; + light += calcLight(normal, uLightPos[0], uLightColor[0]) * rShadow + rAmbient; + color.xyz += calcSpecular(normal, viewVec, uLightPos[0], uLightColor[0], uColor.w * rShadow + 0.03); } if (uType == TYPE_MIRROR) { diff --git a/src/shader.h b/src/shader.h index 66311b2..2152fbf 100644 --- a/src/shader.h +++ b/src/shader.h @@ -5,11 +5,11 @@ enum AttribType { aCoord, aTexCoord, aNormal, aColor, aMAX }; enum SamplerType { sDiffuse, sShadow, sEnvironment, sMAX }; -enum UniformType { uType, uCaustics, uTime, uViewProj, uViewInv, uModel, uLightProj, uColor, uAmbient, uViewPos, uLightPos, uLightColor, uAnimTexRanges, uAnimTexOffsets, uMAX }; +enum UniformType { uType, uCaustics, uTime, uViewProj, uViewInv, uModel, uLightProj, uColor, uAmbient, uViewPos, uLightsCount, uLightPos, uLightColor, uAnimTexRanges, uAnimTexOffsets, uMAX }; const char *AttribName[aMAX] = { "aCoord", "aTexCoord", "aNormal", "aColor" }; const char *SamplerName[sMAX] = { "sDiffuse", "sShadow", "sEnvironment" }; -const char *UniformName[uMAX] = { "uType", "uCaustics", "uTime", "uViewProj", "uViewInv", "uModel", "uLightProj", "uColor", "uAmbient", "uViewPos", "uLightPos", "uLightColor", "uAnimTexRanges", "uAnimTexOffsets" }; +const char *UniformName[uMAX] = { "uType", "uCaustics", "uTime", "uViewProj", "uViewInv", "uModel", "uLightProj", "uColor", "uAmbient", "uViewPos", "uLightsCount", "uLightPos", "uLightColor", "uAnimTexRanges", "uAnimTexOffsets" }; struct Shader { GLuint ID;