mirror of
https://github.com/XProger/OpenLara.git
synced 2025-07-31 18:30:19 +02:00
#23 specular on wet Lara
This commit is contained in:
BIN
bin/OpenLara.exe
BIN
bin/OpenLara.exe
Binary file not shown.
@@ -26,6 +26,7 @@ struct Controller {
|
|||||||
int frameIndex;
|
int frameIndex;
|
||||||
|
|
||||||
vec3 ambient[6];
|
vec3 ambient[6];
|
||||||
|
float specular;
|
||||||
|
|
||||||
struct MeshLayer {
|
struct MeshLayer {
|
||||||
uint32 model;
|
uint32 model;
|
||||||
@@ -50,6 +51,7 @@ struct Controller {
|
|||||||
TR::Model *m = getModel();
|
TR::Model *m = getModel();
|
||||||
joints = m ? new mat4[m->mCount] : NULL;
|
joints = m ? new mat4[m->mCount] : NULL;
|
||||||
frameIndex = -1;
|
frameIndex = -1;
|
||||||
|
specular = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~Controller() {
|
virtual ~Controller() {
|
||||||
|
@@ -103,6 +103,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define MAX_LIGHTS 3
|
#define MAX_LIGHTS 3
|
||||||
|
#define MAX_CACHED_LIGHTS 3
|
||||||
#define MAX_RENDER_BUFFERS 11
|
#define MAX_RENDER_BUFFERS 11
|
||||||
|
|
||||||
struct Shader;
|
struct Shader;
|
||||||
|
@@ -29,10 +29,8 @@ uniform int uType;
|
|||||||
p.xyz *= p.w;
|
p.xyz *= p.w;
|
||||||
color += p;
|
color += p;
|
||||||
}
|
}
|
||||||
color.xyz /= color.w;
|
|
||||||
color.w = 1.0;
|
|
||||||
|
|
||||||
return color;
|
return vec4(color.xyz / color.w, 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
vec4 filter() {
|
vec4 filter() {
|
||||||
|
10
src/lara.h
10
src/lara.h
@@ -23,6 +23,9 @@
|
|||||||
|
|
||||||
#define LARA_HANG_OFFSET 735.0f
|
#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_GROUND 40
|
||||||
#define PICKUP_FRAME_UNDERWATER 16
|
#define PICKUP_FRAME_UNDERWATER 16
|
||||||
#define PUZZLE_FRAME 80
|
#define PUZZLE_FRAME 80
|
||||||
@@ -889,6 +892,8 @@ struct Lara : Character {
|
|||||||
alignToWall();
|
alignToWall();
|
||||||
dst.y -= pos.y - infoDst.floor;
|
dst.y -= pos.y - infoDst.floor;
|
||||||
pos = dst; // set new position
|
pos = dst; // set new position
|
||||||
|
|
||||||
|
specular = LARA_WET_SPECULAR;
|
||||||
|
|
||||||
getEntity().room = infoCur.roomAbove;
|
getEntity().room = infoCur.roomAbove;
|
||||||
updateEntity();
|
updateEntity();
|
||||||
@@ -1441,6 +1446,11 @@ struct Lara : Character {
|
|||||||
virtual void updateAnimation(bool commands) {
|
virtual void updateAnimation(bool commands) {
|
||||||
Controller::updateAnimation(commands);
|
Controller::updateAnimation(commands);
|
||||||
updateWeapon();
|
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() {
|
virtual void updateVelocity() {
|
||||||
|
61
src/level.h
61
src/level.h
@@ -176,6 +176,46 @@ struct Level {
|
|||||||
}
|
}
|
||||||
} *ambientCache;
|
} *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) {
|
Level(const char *name, bool demo, bool home) : level(name, demo), lara(NULL), time(0.0f) {
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
Debug::init();
|
Debug::init();
|
||||||
@@ -613,21 +653,23 @@ struct Level {
|
|||||||
|
|
||||||
void renderEntity(const TR::Entity &entity) {
|
void renderEntity(const TR::Entity &entity) {
|
||||||
//if (entity.room != lara->getRoomIndex()) return;
|
//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;
|
if (Core::pass == Core::passShadow && !TR::castShadow(entity.type)) return;
|
||||||
|
|
||||||
ASSERT(entity.controller);
|
ASSERT(entity.controller);
|
||||||
|
|
||||||
|
bool isModel = entity.modelIndex > 0;
|
||||||
|
|
||||||
|
Controller *controller = (Controller*)entity.controller;
|
||||||
|
|
||||||
TR::Room &room = level.rooms[entity.room];
|
TR::Room &room = level.rooms[entity.room];
|
||||||
if (!room.flags.rendered || entity.flags.invisible || entity.flags.rendered)
|
if (!room.flags.rendered || entity.flags.invisible || entity.flags.rendered)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int16 lum = entity.intensity == -1 ? room.ambient : entity.intensity;
|
int16 lum = entity.intensity == -1 ? room.ambient : entity.intensity;
|
||||||
setRoomParams(room, intensityf(lum));
|
setRoomParams(room, isModel ? controller->specular : intensityf(lum));
|
||||||
|
|
||||||
Controller *controller = (Controller*)entity.controller;
|
if (isModel) { // model
|
||||||
|
|
||||||
if (entity.modelIndex > 0) { // model
|
|
||||||
vec3 pos = controller->pos;
|
vec3 pos = controller->pos;
|
||||||
AmbientCache::Cube cube;
|
AmbientCache::Cube cube;
|
||||||
if (Core::frameIndex != controller->frameIndex) {
|
if (Core::frameIndex != controller->frameIndex) {
|
||||||
@@ -638,9 +680,7 @@ struct Level {
|
|||||||
getLight(pos, entity.room);
|
getLight(pos, entity.room);
|
||||||
Core::active.shader->setParam(uType, Shader::ENTITY);
|
Core::active.shader->setParam(uType, Shader::ENTITY);
|
||||||
Core::active.shader->setParam(uAmbient, controller->ambient[0], 6);
|
Core::active.shader->setParam(uAmbient, controller->ambient[0], 6);
|
||||||
}
|
} else { // sprite
|
||||||
|
|
||||||
if (entity.modelIndex < 0) { // sprite
|
|
||||||
Core::active.shader->setParam(uType, Shader::SPRITE);
|
Core::active.shader->setParam(uType, Shader::SPRITE);
|
||||||
Core::lightPos[0] = vec3(0);
|
Core::lightPos[0] = vec3(0);
|
||||||
Core::lightColor[0] = vec4(0, 0, 0, 1);
|
Core::lightColor[0] = vec4(0, 0, 0, 1);
|
||||||
@@ -684,6 +724,7 @@ struct Level {
|
|||||||
sh->setParam(uViewInv, Core::mViewInv);
|
sh->setParam(uViewInv, Core::mViewInv);
|
||||||
sh->setParam(uViewPos, Core::viewPos);
|
sh->setParam(uViewPos, Core::viewPos);
|
||||||
sh->setParam(uTime, time);
|
sh->setParam(uTime, time);
|
||||||
|
sh->setParam(uLightsCount, 3);
|
||||||
sh->setParam(uAnimTexRanges, mesh->animTexRanges[0], mesh->animTexRangesCount);
|
sh->setParam(uAnimTexRanges, mesh->animTexRanges[0], mesh->animTexRangesCount);
|
||||||
sh->setParam(uAnimTexOffsets, mesh->animTexOffsets[0], mesh->animTexOffsetsCount);
|
sh->setParam(uAnimTexOffsets, mesh->animTexOffsets[0], mesh->animTexOffsetsCount);
|
||||||
|
|
||||||
@@ -743,7 +784,7 @@ struct Level {
|
|||||||
Core::mView = Core::mViewInv.inverse();
|
Core::mView = Core::mViewInv.inverse();
|
||||||
Core::mProj = mat4(90, 1.0f, camera->znear, camera->zfar);
|
Core::mProj = mat4(90, 1.0f, camera->znear, camera->zfar);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool setupLightCamera() {
|
bool setupLightCamera() {
|
||||||
vec3 pos = (lara->animation.getJoints(lara->getMatrix(), 0, false, NULL)).getPos();
|
vec3 pos = (lara->animation.getJoints(lara->getMatrix(), 0, false, NULL)).getPos();
|
||||||
|
|
||||||
|
@@ -3,7 +3,7 @@ cls
|
|||||||
set SRC=main.cpp
|
set SRC=main.cpp
|
||||||
set PROJ=OpenLara
|
set PROJ=OpenLara
|
||||||
set FLAGS=-O3 -Wno-deprecated-register --llvm-opts 2 -fmax-type-align=2 -std=c++11 -I../../
|
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.
|
echo.
|
||||||
call em++ %SRC% %FLAGS% -o %PROJ%.js --preload-file %PRELOAD%
|
call em++ %SRC% %FLAGS% -o %PROJ%.js --preload-file %PRELOAD%
|
||||||
gzip.exe -9 -f %PROJ%.data %PROJ%.js %PROJ%.js.mem
|
gzip.exe -9 -f %PROJ%.data %PROJ%.js %PROJ%.js.mem
|
@@ -102,5 +102,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<audio autoplay loop><source src="05.ogg" type="audio/ogg"></audio>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
@@ -99,6 +99,7 @@ uniform int uType;
|
|||||||
uniform vec4 uColor;
|
uniform vec4 uColor;
|
||||||
#ifdef PASS_COMPOSE
|
#ifdef PASS_COMPOSE
|
||||||
uniform samplerCube sEnvironment;
|
uniform samplerCube sEnvironment;
|
||||||
|
uniform int uLightsCount;
|
||||||
uniform vec3 uLightPos[MAX_LIGHTS];
|
uniform vec3 uLightPos[MAX_LIGHTS];
|
||||||
uniform vec4 uLightColor[MAX_LIGHTS];
|
uniform vec4 uLightColor[MAX_LIGHTS];
|
||||||
uniform vec3 uAmbient[6];
|
uniform vec3 uAmbient[6];
|
||||||
@@ -192,6 +193,13 @@ uniform int uType;
|
|||||||
return color.xyz * (lum * att);
|
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 calcAmbient(vec3 n) {
|
||||||
vec3 sqr = n * n;
|
vec3 sqr = n * n;
|
||||||
vec3 pos = step(0.0, n);
|
vec3 pos = step(0.0, n);
|
||||||
@@ -242,7 +250,8 @@ uniform int uType;
|
|||||||
if (uType == TYPE_ENTITY) {
|
if (uType == TYPE_ENTITY) {
|
||||||
vec3 rAmbient = pow(abs(calcAmbient(normal)), vec3(2.2));
|
vec3 rAmbient = pow(abs(calcAmbient(normal)), vec3(2.2));
|
||||||
float rShadow = getShadow(vLightProj);
|
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) {
|
if (uType == TYPE_MIRROR) {
|
||||||
|
@@ -5,11 +5,11 @@
|
|||||||
|
|
||||||
enum AttribType { aCoord, aTexCoord, aNormal, aColor, aMAX };
|
enum AttribType { aCoord, aTexCoord, aNormal, aColor, aMAX };
|
||||||
enum SamplerType { sDiffuse, sShadow, sEnvironment, sMAX };
|
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 *AttribName[aMAX] = { "aCoord", "aTexCoord", "aNormal", "aColor" };
|
||||||
const char *SamplerName[sMAX] = { "sDiffuse", "sShadow", "sEnvironment" };
|
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 {
|
struct Shader {
|
||||||
GLuint ID;
|
GLuint ID;
|
||||||
|
Reference in New Issue
Block a user