1
0
mirror of https://github.com/XProger/OpenLara.git synced 2025-08-15 09:34:18 +02:00

#22 refactoring; #23 fix water masks

This commit is contained in:
XProger
2017-11-08 04:44:44 +03:00
parent 1292a88e4f
commit 9336d5a79e
7 changed files with 71 additions and 124 deletions

View File

@@ -414,20 +414,14 @@ struct WaterCache {
for (int x = minX; x < maxX; x++) {
TR::Room::Sector &s = r.sectors[x * r.zSectors + z];
bool hasWater = (s.roomAbove != TR::NO_ROOM && !level->rooms[s.roomAbove].flags.water);
bool hasFlow = false;
bool hasWater = s.roomAbove != TR::NO_ROOM && !level->rooms[s.roomAbove].flags.water;
if (hasWater) {
TR::Level::FloorInfo info;
game->getLara()->getFloorInfo(to, vec3(float(x + r.info.x), float(r.info.yBottom), float(z + r.info.z)), info);
if (info.trigCmdCount && info.trigger == TR::Level::Trigger::ACTIVATE)
for (int i = 0; i < info.trigCmdCount; i++)
if (info.trigCmd[i].action == TR::Action::FLOW) {
hasFlow = true;
break;
}
TR::Room &rt = level->rooms[s.roomAbove];
TR::Room::Sector &st = rt.sectors[x * rt.zSectors + z];
hasWater = s.ceiling > st.ceiling;
}
m[(x - minX) + w * (z - minZ)] = hasWater ? (hasFlow ? 0xF81F : 0xF800) : 0;
m[(x - minX) + w * (z - minZ)] = hasWater ? 0xF800 : 0;
}
size = vec3(float((maxX - minX) * 512), 1.0f, float((maxZ - minZ) * 512)); // half size
@@ -785,8 +779,10 @@ struct WaterCache {
refract->bind(sDiffuse);
reflect->bind(sReflect);
item.mask->bind(sMask);
item.data[0]->bind(sNormal);
Core::setCulling(cfNone);
Core::setBlending(bmAlpha);
#ifdef WATER_USE_GRID
vec3 rPosScale[2] = { item.pos, item.size * vec3(1.0f / PLANE_DETAIL, 512.0f, 1.0f / PLANE_DETAIL) };
Core::active.shader->setParam(uPosScale, rPosScale[0], 2);
@@ -796,6 +792,7 @@ struct WaterCache {
game->getMesh()->renderQuad();
#endif
Core::setCulling(cfFront);
Core::setBlending(bmNone);
}
dropCount = 0;
}

View File

@@ -58,6 +58,7 @@ struct IGame {
virtual void checkTrigger(Controller *controller, bool heavy) {}
virtual Controller* addEntity(TR::Entity::Type type, int room, const vec3 &pos, float angle = 0.0f) { return NULL; }
virtual void removeEntity(Controller *controller) {}
virtual bool invUse(TR::Entity::Type type) { return false; }
virtual void invAdd(TR::Entity::Type type, int count = 1) {}

View File

@@ -2103,29 +2103,6 @@ namespace TR {
return 0;
}
int entityAdd(Entity::Type type, int16 room, const vec3 &pos, float rotation, int16 intensity) {
for (int i = entitiesBaseCount; i < entitiesCount; i++) {
Entity &e = entities[i];
if (!e.controller) {
e.type = type;
e.room = room;
e.x = int(pos.x);
e.y = int(pos.y);
e.z = int(pos.z);
e.rotation = angle(normalizeAngle(rotation));
e.intensity = intensity;
e.flags.value = 0;
e.modelIndex = getModelIndex(e.type);
return i;
}
}
return -1;
}
void entityRemove(int entityIndex) {
entities[entityIndex].controller = NULL;
}
int getNextRoom(int floorIndex) const {
if (!floorIndex) return NO_ROOM;
FloorData *fd = &floors[floorIndex];

View File

@@ -319,30 +319,51 @@ struct Level : IGame {
}
virtual Controller* addEntity(TR::Entity::Type type, int room, const vec3 &pos, float angle) {
int index = level.entityAdd(type, room, pos, angle, -1);
if (index > -1) {
int index;
for (index = level.entitiesBaseCount; index < level.entitiesCount; index++) {
TR::Entity &e = level.entities[index];
if (e.isPickup())
e.intensity = 4096;
else
if (e.isSprite()) {
if (e.type == TR::Entity::LAVA_PARTICLE || e.type == TR::Entity::FLAME)
e.intensity = 0; // emissive
else
e.intensity = 0x1FFF - level.rooms[room].ambient;
}
if (!e.controller) {
e.type = type;
e.room = room;
e.x = int(pos.x);
e.y = int(pos.y);
e.z = int(pos.z);
e.rotation = TR::angle(normalizeAngle(angle));
e.intensity = -1;
e.flags.value = 0;
e.modelIndex = level.getModelIndex(e.type);
break;
}
}
Controller *controller = initController(index);
e.controller = controller;
if (index == level.entitiesCount)
return NULL;
if (e.isEnemy() || e.isSprite()) {
controller->flags.active = TR::ACTIVE;
controller->activate();
TR::Entity &e = level.entities[index];
if (e.isPickup())
e.intensity = 4096;
else
if (e.isSprite()) {
if (e.type == TR::Entity::LAVA_PARTICLE || e.type == TR::Entity::FLAME)
e.intensity = 0; // emissive
else
e.intensity = 0x1FFF - level.rooms[room].ambient;
}
return controller;
Controller *controller = initController(index);
e.controller = controller;
if (e.isEnemy() || e.isSprite()) {
controller->flags.active = TR::ACTIVE;
controller->activate();
}
return NULL;
return controller;
}
virtual void removeEntity(Controller *controller) {
level.entities[controller->entity].controller = NULL;
delete controller;
}
virtual bool invUse(TR::Entity::Type type) {
@@ -618,9 +639,10 @@ struct Level : IGame {
case TR::Entity::RICOCHET : return new Sprite(this, index, true, Sprite::FRAME_RANDOM);
case TR::Entity::CENTAUR_STATUE : return new CentaurStatue(this, index);
case TR::Entity::CABIN : return new Cabin(this, index);
case TR::Entity::TRAP_FLAME_EMITTER : return new TrapFlameEmitter(this, index);
case TR::Entity::LAVA_PARTICLE : return new LavaParticle(this, index);
case TR::Entity::TRAP_LAVA_EMITTER : return new TrapLavaEmitter(this, index);
case TR::Entity::FLAME : return new Flame(this, index);
case TR::Entity::TRAP_FLAME_EMITTER : return new TrapFlameEmitter(this, index);
case TR::Entity::BOAT : return new Boat(this, index);
case TR::Entity::EARTHQUAKE : return new Earthquake(this, index);
case TR::Entity::MUTANT_EGG_SMALL :
@@ -1359,8 +1381,6 @@ struct Level : IGame {
void renderDebug() {
if (level.id == TR::TITLE) return;
// Core::mViewInv = camera->mViewInv;
// Core::mView = Core::mViewInv.inverse();
Core::setViewport(0, 0, Core::width, Core::height);
camera->setup(true);
@@ -1369,39 +1389,6 @@ struct Level : IGame {
Input::down[ikF] = false;
}
/*
static int snd_index = 0;
if (Input::down[ikG]) {
snd_index = (snd_index + 1) % level.soundsInfoCount;
LOG("play sound: %d\n", snd_index);
lara->playSound(snd_index, lara->pos, 0);
Input::down[ikG] = false;
}
static int modelIndex = 0;
static bool lastStateK = false;
static int lastEntity = -1;
if (Input::down[ikM]) {
if (!lastStateK) {
lastStateK = true;
modelIndex = (modelIndex + 1) % level.modelsCount;
// modelIndex = (modelIndex + 1) % level.spriteSequencesCount;
LOG("model: %d %d\n", modelIndex, level.spriteSequences[modelIndex].type);
if (lastEntity > -1) {
delete level.entities[lastEntity].controller;
level.entityRemove(lastEntity);
}
vec3 p = lara->pos + lara->getDir() * 256.0f;
lastEntity = level.entityAdd(level.models[modelIndex].type, lara->getRoomIndex(), p.x, p.y - 512, p.z, lara->getEntity().rotation, -1);
level.entities[lastEntity].controller = new Controller(this, lastEntity);
}
} else
lastStateK = false;
if (lastEntity > -1)
renderEntity(level.entities[lastEntity]);
// renderModel(level.models[modelIndex], level.entities[4]);
*/
Debug::begin();
/*
lara->updateEntity(); // TODO clip angle while rotating

View File

@@ -177,7 +177,7 @@ uniform sampler2D sNormal;
vec3 normal = vec3(value.z, -sqrt(1.0 - dot(value.zw, value.zw)), value.w);
vec2 dudv = (uViewProj * vec4(normal.x, 0.0, normal.z, 0.0)).xy;
vec2 dudv = (uViewProj * vec4(normal.x, 0.0, normal.z, 0.0)).xy;
vec3 viewVec = normalize(vViewVec);
vec3 rv = reflect(-viewVec, normal);
@@ -185,7 +185,7 @@ uniform sampler2D sNormal;
float spec = pow(max(0.0, dot(rv, lv)), 64.0) * 0.5;
vec2 tc = vProjCoord.xy / vProjCoord.w * 0.5 + 0.5;
vec2 tc = vProjCoord.xy / vProjCoord.w * 0.5 + 0.5;
vec4 refrA = texture2D(sDiffuse, uParam.xy * clamp(tc + dudv * uParam.z, 0.0, 0.999) );
vec4 refrB = texture2D(sDiffuse, uParam.xy * tc );
@@ -199,7 +199,7 @@ uniform sampler2D sNormal;
float d = abs((vCoord.y - uViewPos.y) / normalize(vViewVec).y);
d *= step(0.0, uViewPos.y - vCoord.y); // apply fog only when camera is underwater
color.xyz = applyFog(color.xyz, UNDERWATER_COLOR * 0.2, d * WATER_FOG_DIST);
color.w *= texture2D(sMask, vTexCoord).x;
return color;
}

View File

@@ -50,10 +50,8 @@ struct Sprite : Controller {
pos += velocity * (30.0f * Core::deltaTime);
if (remove) {
level->entityRemove(entity);
delete this;
}
if (remove)
game->removeEntity(this);
}
virtual void render(Frustum *frustum, MeshBuilder *mesh, Shader::Type type, bool caustics) {

View File

@@ -82,8 +82,7 @@ struct Dart : Controller {
getFloorInfo(getRoomIndex(), pos, info);
if (pos.y > info.floor || pos.y < info.ceiling || !insideRoom(pos, getRoomIndex())) {
game->addEntity(TR::Entity::RICOCHET, getRoomIndex(), pos - dir * 64.0f); // with wall offset
level->entityRemove(entity);
delete this;
game->removeEntity(this);
}
}
};
@@ -120,24 +119,16 @@ struct TrapDartEmitter : Controller {
struct Flame : Sprite {
static Flame* add(IGame *game, Controller *controller, int jointIndex) {
Flame *flame = NULL;
TR::Level *level = game->getLevel();
int roomIndex = controller->getRoomIndex();
vec3 pos = controller->pos;
int index = level->entityAdd(TR::Entity::FLAME, roomIndex, pos, 0, 0);
if (index > -1) {
flame = new Flame(game, index, jointIndex);
level->entities[index].controller = flame;
}
Flame *flame = (Flame*)game->addEntity(TR::Entity::FLAME, controller->getRoomIndex(), controller->pos);
if (flame)
flame->jointIndex = jointIndex;
return flame;
}
int jointIndex;
float sleep;
Flame(IGame *game, int entity, int jointIndex) : Sprite(game, entity, false, Sprite::FRAME_ANIMATED), jointIndex(jointIndex), sleep(0.0f) {
Flame(IGame *game, int entity) : Sprite(game, entity, false, Sprite::FRAME_ANIMATED), jointIndex(0), sleep(0.0f) {
time = randf() * 3.0f;
activate();
}
@@ -150,8 +141,7 @@ struct Flame : Sprite {
if (jointIndex > -1) {
if (lara->stand == Character::STAND_UNDERWATER) {
level->entityRemove(entity);
delete this;
game->removeEntity(this);
return;
}
@@ -185,10 +175,9 @@ struct TrapFlameEmitter : Controller {
void virtual update() {
if (!isActive()) {
if (flame) {
level->entityRemove(flame->entity);
delete flame;
flame = NULL;
Sound::stop(TR::SND_FLAME);
game->removeEntity(flame);
flame = NULL;
}
return;
}
@@ -231,8 +220,7 @@ struct LavaParticle : Sprite {
if (hit || pos.y > info.floor || pos.y < info.ceiling) {
if (hit || ++bounces > 4) {
level->entityRemove(entity);
delete this;
game->removeEntity(this);
return;
}
intensity = max(0.0f, 1.0f - bounces * 0.25f);
@@ -379,13 +367,15 @@ struct Block : Controller {
// check for trapdoor
int px = int(p.x) / 1024;
int pz = int(p.z) / 1024;
for (int i = 0; i < info.trigCmdCount; i++)
for (int i = 0; i < info.trigCmdCount; i++) {
if (info.trigCmd[i].action == TR::Action::ACTIVATE) {
TR::Entity &e = level->entities[info.trigCmd[i].args];
vec3 objPos = ((Controller*)e.controller)->pos;
if ((e.type == TR::Entity::TRAP_DOOR_1 || e.type == TR::Entity::TRAP_DOOR_2) && px == int(objPos.x) / 1024 && pz == int(objPos.z) / 1024)
return false;
}
} else if (info.trigCmd[i].action == TR::Action::CAMERA_SWITCH)
i++; // skip camera switch delay info
}
// check Laras destination position
if (!push) {
@@ -895,11 +885,8 @@ struct ThorHammer : Controller {
Controller *block;
ThorHammer(IGame *game, int entity) : Controller(game, entity) {
int index = level->entityAdd(TR::Entity::HAMMER_BLOCK, getRoomIndex(), pos, angle.y, -1);
if (index > -1) {
block = new Controller(game, index);
level->entities[index].controller = block;
}
block = game->addEntity(TR::Entity::HAMMER_BLOCK, getRoomIndex(), pos, angle.y);
ASSERT(block);
flags.collision = block->flags.collision = false;
}