mirror of
https://github.com/XProger/OpenLara.git
synced 2025-08-16 10:04:28 +02:00
#23 fix sky reflections
This commit is contained in:
53
src/cache.h
53
src/cache.h
@@ -773,11 +773,6 @@ struct WaterCache {
|
|||||||
item.init(game);
|
item.init(game);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!count) {
|
|
||||||
visible = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// render mirror reflection
|
// render mirror reflection
|
||||||
Core::setTarget(reflect, CLEAR_ALL);
|
Core::setTarget(reflect, CLEAR_ALL);
|
||||||
Camera *camera = (Camera*)game->getCamera();
|
Camera *camera = (Camera*)game->getCamera();
|
||||||
@@ -787,25 +782,49 @@ struct WaterCache {
|
|||||||
mat4 mView = Core::mView;
|
mat4 mView = Core::mView;
|
||||||
mat4 mViewInv = Core::mViewInv;
|
mat4 mViewInv = Core::mViewInv;
|
||||||
|
|
||||||
|
// merge visible rooms for all items
|
||||||
|
int roomsList[256];
|
||||||
|
int roomsCount = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < level->roomsCount; i++)
|
||||||
|
level->rooms[i].flags.visible = false;
|
||||||
|
|
||||||
|
bool underwater = level->rooms[camera->getRoomIndex()].flags.water;
|
||||||
|
vec4 reflectPlane;
|
||||||
|
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
Item &item = items[i];
|
Item &item = items[i];
|
||||||
if (!item.visible) continue;
|
if (!item.visible) continue;
|
||||||
|
|
||||||
vec3 p = item.pos;
|
reflectPlane = vec4(0, 1, 0, -item.pos.y);
|
||||||
vec3 n = vec3(0, 1, 0);
|
|
||||||
|
|
||||||
vec4 reflectPlane = vec4(n.x, n.y, n.z, -n.dot(p));
|
|
||||||
bool underwater = level->rooms[camera->getRoomIndex()].flags.water;
|
|
||||||
|
|
||||||
//bool underwater = camera->eye.pos.y > item.pos.y;
|
|
||||||
|
|
||||||
camera->reflectPlane = &reflectPlane;
|
camera->reflectPlane = &reflectPlane;
|
||||||
camera->setup(true);
|
camera->setup(true);
|
||||||
|
|
||||||
float sign = underwater ? -1.0f : 1.0f;
|
game->getVisibleRooms(roomsList, roomsCount, TR::NO_ROOM, underwater ? item.from : item.to, vec4(-1.0f, -1.0f, 1.0f, 1.0f), false);
|
||||||
game->setClipParams(sign, item.pos.y * sign);
|
|
||||||
game->renderView(underwater ? item.from : item.to, false, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (roomsCount) {
|
||||||
|
// select optimal water plane
|
||||||
|
float waterLevel = -INF;
|
||||||
|
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
Item &item = items[i];
|
||||||
|
if (!item.visible) continue;
|
||||||
|
|
||||||
|
if (item.pos.y > waterLevel)
|
||||||
|
waterLevel = item.pos.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
reflectPlane = vec4(0, 1, 0, -waterLevel);
|
||||||
|
camera->reflectPlane = &reflectPlane;
|
||||||
|
camera->setup(true);
|
||||||
|
|
||||||
|
// render reflections frame
|
||||||
|
float sign = underwater ? -1.0f : 1.0f;
|
||||||
|
game->setClipParams(sign, waterLevel * sign);
|
||||||
|
game->renderView(TR::NO_ROOM, false, false, roomsCount, roomsList);
|
||||||
|
}
|
||||||
|
|
||||||
Core::invalidateTarget(false, true);
|
Core::invalidateTarget(false, true);
|
||||||
game->setClipParams(1.0f, NO_CLIP_PLANE);
|
game->setClipParams(1.0f, NO_CLIP_PLANE);
|
||||||
|
|
||||||
@@ -831,7 +850,7 @@ struct WaterCache {
|
|||||||
|
|
||||||
int w, h;
|
int w, h;
|
||||||
getTargetSize(w, h);
|
getTargetSize(w, h);
|
||||||
Core::active.shader->setParam(uParam, vec4(float(w) / refract->width, float(h) / refract->height, 0.05f, 0.02f));
|
Core::active.shader->setParam(uParam, vec4(float(w) / refract->width, float(h) / refract->height, 0.05f, 0.03f));
|
||||||
|
|
||||||
float sx = item.size.x * DETAIL / (item.data[0]->width / 2);
|
float sx = item.size.x * DETAIL / (item.data[0]->width / 2);
|
||||||
float sz = item.size.z * DETAIL / (item.data[0]->height / 2);
|
float sz = item.size.z * DETAIL / (item.data[0]->height / 2);
|
||||||
|
@@ -71,9 +71,10 @@ struct IGame {
|
|||||||
virtual void setShader(Core::Pass pass, Shader::Type type, bool underwater = false, bool alphaTest = false) {}
|
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 setRoomParams(int roomIndex, Shader::Type type, float diffuse, float ambient, float specular, float alpha, bool alphaTest = false) {}
|
||||||
virtual void setupBinding() {}
|
virtual void setupBinding() {}
|
||||||
|
virtual void getVisibleRooms(int *roomsList, int &roomsCount, int from, int to, const vec4 &viewPort, bool water, int count = 0) {}
|
||||||
virtual void renderEnvironment(int roomIndex, const vec3 &pos, Texture **targets, int stride = 0, Core::Pass pass = Core::passAmbient) {}
|
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 renderCompose(int roomIndex) {}
|
||||||
virtual void renderView(int roomIndex, bool water, bool showUI) {}
|
virtual void renderView(int roomIndex, bool water, bool showUI, int roomsCount = 0, int *roomsList = NULL) {}
|
||||||
virtual void renderGame(bool showUI) {}
|
virtual void renderGame(bool showUI) {}
|
||||||
virtual void setEffect(Controller *controller, TR::Effect::Type effect) {}
|
virtual void setEffect(Controller *controller, TR::Effect::Type effect) {}
|
||||||
|
|
||||||
|
63
src/level.h
63
src/level.h
@@ -1756,7 +1756,7 @@ struct Level : IGame {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void getVisibleRooms(int *roomsList, int &roomsCount, int from, int to, const vec4 &viewPort, bool water, int count = 0) {
|
virtual void getVisibleRooms(int *roomsList, int &roomsCount, int from, int to, const vec4 &viewPort, bool water, int count = 0) {
|
||||||
if (count > 16) {
|
if (count > 16) {
|
||||||
//ASSERT(false);
|
//ASSERT(false);
|
||||||
return;
|
return;
|
||||||
@@ -1781,48 +1781,51 @@ struct Level : IGame {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void renderView(int roomIndex, bool water, bool showUI) {
|
virtual void renderView(int roomIndex, bool water, bool showUI, int roomsCount = 0, int *roomsList = NULL) {
|
||||||
PROFILE_MARKER("VIEW");
|
PROFILE_MARKER("VIEW");
|
||||||
if (water && waterCache) {
|
|
||||||
|
if (water && waterCache)
|
||||||
waterCache->reset();
|
waterCache->reset();
|
||||||
}
|
|
||||||
|
|
||||||
int roomsList[256];
|
int rList[256];
|
||||||
int roomsCount = 0;
|
|
||||||
|
|
||||||
if (level.isCutsceneLevel()) { // render all rooms except flipped
|
if (!roomsList) {
|
||||||
for (int i = 0; i < level.roomsCount; i++)
|
roomsList = rList;
|
||||||
level.rooms[i].flags.visible = true;
|
|
||||||
|
|
||||||
for (int i = 0; i < level.roomsCount; i++) {
|
// mark all rooms as invisible
|
||||||
int flipIndex = level.rooms[i].alternateRoom;
|
|
||||||
if (flipIndex > 0)
|
|
||||||
level.rooms[flipIndex].flags.visible = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < level.roomsCount; i++)
|
|
||||||
if (level.rooms[i].flags.visible) {
|
|
||||||
roomsList[roomsCount++] = i;
|
|
||||||
if (Core::pass == Core::passCompose && water && waterCache) {
|
|
||||||
TR::Room &r = level.rooms[i];
|
|
||||||
for (int j = 0; j < r.portalsCount; j++) {
|
|
||||||
int to = r.portals[j].roomIndex;
|
|
||||||
if (level.rooms[to].flags.visible && (level.rooms[to].flags.water ^ r.flags.water))
|
|
||||||
waterCache->setVisible(i, to);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
for (int i = 0; i < level.roomsCount; i++)
|
for (int i = 0; i < level.roomsCount; i++)
|
||||||
level.rooms[i].flags.visible = false;
|
level.rooms[i].flags.visible = false;
|
||||||
|
|
||||||
|
if (level.isCutsceneLevel()) { // render all rooms except flipped
|
||||||
|
// hide alternative rooms from getVisibleRooms
|
||||||
|
for (int i = 0; i < level.roomsCount; i++) {
|
||||||
|
int flipIndex = level.rooms[i].alternateRoom;
|
||||||
|
if (flipIndex > -1)
|
||||||
|
level.rooms[flipIndex].flags.visible = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get room list through portals (it will change room visible flag)
|
||||||
|
getVisibleRooms(roomsList, roomsCount, TR::NO_ROOM, roomIndex, vec4(-1.0f, -1.0f, 1.0f, 1.0f), water);
|
||||||
|
|
||||||
|
// add other non-alternative rooms
|
||||||
|
for (int i = 0; i < level.roomsCount; i++)
|
||||||
|
if (!level.rooms[i].flags.visible)
|
||||||
|
roomsList[roomsCount++] = i;
|
||||||
|
|
||||||
|
// refresh visible flag
|
||||||
|
for (int i = 0; i < level.roomsCount; i++)
|
||||||
|
level.rooms[i].flags.visible = false;
|
||||||
|
|
||||||
|
for (int i = 0; i < roomsCount; i++)
|
||||||
|
level.rooms[roomsList[i]].flags.visible = true;
|
||||||
|
} else
|
||||||
getVisibleRooms(roomsList, roomsCount, TR::NO_ROOM, roomIndex, vec4(-1.0f, -1.0f, 1.0f, 1.0f), water);
|
getVisibleRooms(roomsList, roomsCount, TR::NO_ROOM, roomIndex, vec4(-1.0f, -1.0f, 1.0f, 1.0f), water);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (water && waterCache) {
|
if (water && waterCache) {
|
||||||
for (int i = 0; i < roomsCount; i++)
|
for (int i = 0; i < roomsCount; i++)
|
||||||
waterCache->setVisible(roomsList[i]);
|
waterCache->setVisible(roomsList[i]);
|
||||||
|
|
||||||
waterCache->renderReflect();
|
waterCache->renderReflect();
|
||||||
|
|
||||||
Core::Pass pass = Core::pass;
|
Core::Pass pass = Core::pass;
|
||||||
@@ -1830,7 +1833,7 @@ struct Level : IGame {
|
|||||||
Core::pass = pass;
|
Core::pass = pass;
|
||||||
}
|
}
|
||||||
|
|
||||||
// clear visibility flag for rooms
|
// clear entity rendered flag (used for blob shadows)
|
||||||
if (Core::pass != Core::passAmbient)
|
if (Core::pass != Core::passAmbient)
|
||||||
for (int i = 0; i < level.entitiesCount; i++) {
|
for (int i = 0; i < level.entitiesCount; i++) {
|
||||||
Controller *controller = (Controller*)level.entities[i].controller;
|
Controller *controller = (Controller*)level.entities[i].controller;
|
||||||
|
@@ -84,7 +84,7 @@ struct Texture {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
Texture(int width, int height, Format format, uint32 opt = 0, void *data = NULL) : opt(opt) {
|
Texture(int width, int height, Format format, uint32 opt = 0, void *data = NULL) : opt(opt) {
|
||||||
LOG("create texture %d x %d (%d)\n", width, height, format);
|
// LOG("create texture %d x %d (%d)\n", width, height, format);
|
||||||
|
|
||||||
#ifndef _PSP
|
#ifndef _PSP
|
||||||
#ifdef SPLIT_BY_TILE
|
#ifdef SPLIT_BY_TILE
|
||||||
|
Reference in New Issue
Block a user