mirror of
https://github.com/XProger/OpenLara.git
synced 2025-08-11 15:45:05 +02:00
#23 test planar water refraction, reflection and caustics
This commit is contained in:
10
src/camera.h
10
src/camera.h
@@ -21,7 +21,9 @@ struct Camera : Controller {
|
|||||||
int actTargetEntity, actCamera;
|
int actTargetEntity, actCamera;
|
||||||
bool cutscene;
|
bool cutscene;
|
||||||
|
|
||||||
Camera(TR::Level *level, Lara *owner) : Controller(level, owner ? owner->entity : 0), owner(owner), frustum(new Frustum()), timer(0.0f), actTargetEntity(-1), actCamera(-1) {
|
vec4 *reflectPlane;
|
||||||
|
|
||||||
|
Camera(TR::Level *level, Lara *owner) : Controller(level, owner ? owner->entity : 0), owner(owner), frustum(new Frustum()), timer(0.0f), actTargetEntity(-1), actCamera(-1), reflectPlane(NULL) {
|
||||||
fov = 65.0f;
|
fov = 65.0f;
|
||||||
znear = 16;
|
znear = 16;
|
||||||
zfar = 32.0f * 1024.0f;
|
zfar = 32.0f * 1024.0f;
|
||||||
@@ -205,7 +207,11 @@ struct Camera : Controller {
|
|||||||
|
|
||||||
virtual void setup(bool calcMatrices) {
|
virtual void setup(bool calcMatrices) {
|
||||||
if (calcMatrices) {
|
if (calcMatrices) {
|
||||||
Core::mViewInv = mViewInv;
|
if (reflectPlane)
|
||||||
|
Core::mViewInv = mat4(*reflectPlane) * mViewInv;
|
||||||
|
else
|
||||||
|
Core::mViewInv = mViewInv;
|
||||||
|
|
||||||
Core::mView = Core::mViewInv.inverse();
|
Core::mView = Core::mViewInv.inverse();
|
||||||
Core::mProj = mat4(fov, (float)Core::width / (float)Core::height, znear, zfar);
|
Core::mProj = mat4(fov, (float)Core::width / (float)Core::height, znear, zfar);
|
||||||
// TODO: camera shake
|
// TODO: camera shake
|
||||||
|
@@ -32,6 +32,14 @@
|
|||||||
#include <html5.h>
|
#include <html5.h>
|
||||||
#include <GLES3/gl3.h>
|
#include <GLES3/gl3.h>
|
||||||
#include <GLES3/gl2ext.h>
|
#include <GLES3/gl2ext.h>
|
||||||
|
|
||||||
|
#undef GL_RGBA32F
|
||||||
|
#undef GL_RGBA16F
|
||||||
|
#undef GL_HALF_FLOAT
|
||||||
|
|
||||||
|
#define GL_RGBA32F GL_RGBA
|
||||||
|
#define GL_RGBA16F GL_RGBA
|
||||||
|
#define GL_HALF_FLOAT GL_HALF_FLOAT_OES
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
17
src/lara.h
17
src/lara.h
@@ -229,7 +229,14 @@ struct Lara : Character {
|
|||||||
arms[i].rot = quat(0, 0, 0, 1);
|
arms[i].rot = quat(0, 0, 0, 1);
|
||||||
arms[i].rotAbs = quat(0, 0, 0, 1);
|
arms[i].rotAbs = quat(0, 0, 0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pos = vec3(40448, 3584, 60928);
|
||||||
|
angle = vec3(0.0f, PI * 0.5f, 0.0f);
|
||||||
|
getEntity().room = 14;
|
||||||
|
stand = STAND_ONWATER;
|
||||||
|
animation.setAnim(ANIM_TO_ONWATER);
|
||||||
|
updateEntity();
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
/*
|
/*
|
||||||
// gym
|
// gym
|
||||||
@@ -242,7 +249,7 @@ struct Lara : Character {
|
|||||||
angle = vec3(0.0f, PI * 0.5f, 0.0f);
|
angle = vec3(0.0f, PI * 0.5f, 0.0f);
|
||||||
getEntity().room = 14;
|
getEntity().room = 14;
|
||||||
stand = STAND_ONWATER;
|
stand = STAND_ONWATER;
|
||||||
animation.setAnim(ANIM_TO_ONWATER);
|
animation.setAnim(ANIM_TO_ONWATER);
|
||||||
/*
|
/*
|
||||||
// level 2 (pool)
|
// level 2 (pool)
|
||||||
pos = vec3(70067, -256, 29104);
|
pos = vec3(70067, -256, 29104);
|
||||||
@@ -930,9 +937,9 @@ struct Lara : Character {
|
|||||||
int h = int(pos.y - infoDst.floor);
|
int h = int(pos.y - infoDst.floor);
|
||||||
|
|
||||||
if (h > 0 && h <= 256 && (state == STATE_SURF_TREAD || animation.setState(STATE_SURF_TREAD)) && animation.setState(STATE_STOP)) { // possibility check
|
if (h > 0 && h <= 256 && (state == STATE_SURF_TREAD || animation.setState(STATE_SURF_TREAD)) && animation.setState(STATE_STOP)) { // possibility check
|
||||||
alignToWall();
|
alignToWall(-96.0f);
|
||||||
dst.y -= pos.y - infoDst.floor;
|
pos.y = infoDst.floor;
|
||||||
pos = dst; // set new position
|
//pos = dst; // set new position
|
||||||
|
|
||||||
specular = LARA_WET_SPECULAR;
|
specular = LARA_WET_SPECULAR;
|
||||||
|
|
||||||
|
197
src/level.h
197
src/level.h
@@ -35,18 +35,22 @@ struct Level {
|
|||||||
TR::Level level;
|
TR::Level level;
|
||||||
Shader *shaders[shMAX];
|
Shader *shaders[shMAX];
|
||||||
Texture *atlas;
|
Texture *atlas;
|
||||||
|
Texture *cube;
|
||||||
MeshBuilder *mesh;
|
MeshBuilder *mesh;
|
||||||
|
|
||||||
Lara *lara;
|
Lara *lara;
|
||||||
Camera *camera;
|
Camera *camera;
|
||||||
Texture *shadow;
|
Texture *shadow;
|
||||||
|
|
||||||
#ifdef _DEBUG
|
|
||||||
Texture *water[2];
|
Texture *water[2];
|
||||||
Texture *waterCube;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
float time;
|
Texture *waterRefract;
|
||||||
|
Texture *waterReflect;
|
||||||
|
Texture *waterCaustics;
|
||||||
|
|
||||||
|
float time;
|
||||||
|
float clipHeight;
|
||||||
|
float clipSign;
|
||||||
|
|
||||||
struct AmbientCache {
|
struct AmbientCache {
|
||||||
Level *level;
|
Level *level;
|
||||||
@@ -345,12 +349,16 @@ struct Level {
|
|||||||
|
|
||||||
delete shadow;
|
delete shadow;
|
||||||
delete ambientCache;
|
delete ambientCache;
|
||||||
#ifdef _DEBUG
|
|
||||||
delete water[0];
|
delete water[0];
|
||||||
delete water[1];
|
delete water[1];
|
||||||
delete waterCube;
|
|
||||||
#endif
|
delete waterRefract;
|
||||||
|
delete waterReflect;
|
||||||
|
delete waterCaustics;
|
||||||
|
|
||||||
delete atlas;
|
delete atlas;
|
||||||
|
delete cube;
|
||||||
delete mesh;
|
delete mesh;
|
||||||
|
|
||||||
delete camera;
|
delete camera;
|
||||||
@@ -359,19 +367,12 @@ struct Level {
|
|||||||
void initTextures() {
|
void initTextures() {
|
||||||
shadow = new Texture(1024, 1024, Texture::SHADOW, false);
|
shadow = new Texture(1024, 1024, Texture::SHADOW, false);
|
||||||
|
|
||||||
float *ddd = NULL;//new float[4 * 256 * 256];
|
water[0] = new Texture(256, 256, Texture::RGBA_HALF, false);
|
||||||
// memset(ddd, 0, sizeof(float) * 4 * 256 * 256);
|
water[1] = new Texture(256, 256, Texture::RGBA_HALF, false);
|
||||||
// for (int i = 0; i < 512 * 512 * 2; i += 2)
|
|
||||||
// ddd[i] = randf();
|
|
||||||
// ddd[(128 * 256 + 128) * 4] = 50.0f;
|
|
||||||
// ddd[(192 * 256 + 192) * 4] = 100.0f;
|
|
||||||
// ddd[(64 * 256 + 128) * 4] = 20.0f;
|
|
||||||
|
|
||||||
#ifdef _DEBUG
|
waterRefract = new Texture(1024, 1024, Texture::RGBA, false);
|
||||||
water[0] = new Texture(256, 256, Texture::RGBA_FLOAT, false, ddd);
|
waterReflect = new Texture(1024, 1024, Texture::RGBA, false);
|
||||||
water[1] = new Texture(256, 256, Texture::RGBA_FLOAT, false, ddd);
|
waterCaustics = new Texture(1024, 1024, Texture::RGBA, false);
|
||||||
#endif
|
|
||||||
delete[] ddd;
|
|
||||||
|
|
||||||
if (!level.tilesCount) {
|
if (!level.tilesCount) {
|
||||||
atlas = NULL;
|
atlas = NULL;
|
||||||
@@ -406,6 +407,9 @@ struct Level {
|
|||||||
atlas = new Texture(1024, 1024, Texture::RGBA, false, data);
|
atlas = new Texture(1024, 1024, Texture::RGBA, false, data);
|
||||||
PROFILE_LABEL(TEXTURE, atlas->ID, "atlas");
|
PROFILE_LABEL(TEXTURE, atlas->ID, "atlas");
|
||||||
|
|
||||||
|
uint32 whitePix = 0xFFFFFFFF;
|
||||||
|
cube = new Texture(1, 1, Texture::RGBA, true, &whitePix);
|
||||||
|
|
||||||
delete[] data;
|
delete[] data;
|
||||||
delete[] level.tiles;
|
delete[] level.tiles;
|
||||||
level.tiles = NULL;
|
level.tiles = NULL;
|
||||||
@@ -483,11 +487,6 @@ struct Level {
|
|||||||
renderEnvironment(c->getRoomIndex(), c->pos - vec3(0, 512, 0), &c->environment);
|
renderEnvironment(c->getRoomIndex(), c->pos - vec3(0, 512, 0), &c->environment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _DEBUG
|
|
||||||
waterCube = new Texture(512, 512, Texture::RGBA, true);
|
|
||||||
renderEnvironment(14, vec3(40448, 3584, 60928), &waterCube);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef LEVEL_EDITOR
|
#ifdef LEVEL_EDITOR
|
||||||
@@ -566,6 +565,10 @@ struct Level {
|
|||||||
Core::active.shader->setParam(uCaustics, 0);
|
Core::active.shader->setParam(uCaustics, 0);
|
||||||
}
|
}
|
||||||
Core::active.shader->setParam(uColor, Core::color);
|
Core::active.shader->setParam(uColor, Core::color);
|
||||||
|
|
||||||
|
waterCaustics->bind(sReflect);
|
||||||
|
vec4 roomSize = vec4(room.info.x, room.info.z, room.info.x + room.xSectors * 1024, room.info.z + room.zSectors * 1024);
|
||||||
|
Core::active.shader->setParam(uRoomSize, roomSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderRoom(int roomIndex, int from = -1) {
|
void renderRoom(int roomIndex, int from = -1) {
|
||||||
@@ -735,6 +738,7 @@ struct Level {
|
|||||||
camera->setup(Core::pass == Core::passCompose);
|
camera->setup(Core::pass == Core::passCompose);
|
||||||
|
|
||||||
atlas->bind(sDiffuse);
|
atlas->bind(sDiffuse);
|
||||||
|
cube->bind(sEnvironment);
|
||||||
|
|
||||||
if (!Core::support.VAO)
|
if (!Core::support.VAO)
|
||||||
mesh->bind();
|
mesh->bind();
|
||||||
@@ -746,7 +750,7 @@ struct Level {
|
|||||||
sh->setParam(uLightProj, Core::mLightProj);
|
sh->setParam(uLightProj, Core::mLightProj);
|
||||||
sh->setParam(uViewInv, Core::mViewInv);
|
sh->setParam(uViewInv, Core::mViewInv);
|
||||||
sh->setParam(uViewPos, Core::viewPos);
|
sh->setParam(uViewPos, Core::viewPos);
|
||||||
sh->setParam(uParam, vec4(time, 0.0f, 0.0f, 0.0f));
|
sh->setParam(uParam, vec4(time, 0.0f, clipSign, clipHeight));
|
||||||
sh->setParam(uLightsCount, 3);
|
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);
|
||||||
@@ -884,41 +888,105 @@ struct Level {
|
|||||||
|
|
||||||
Core::setBlending(bmAlpha);
|
Core::setBlending(bmAlpha);
|
||||||
Core::clear(vec4(0.0f));
|
Core::clear(vec4(0.0f));
|
||||||
Core::setViewport(0, 0, Core::width, Core::height);
|
|
||||||
shadow->bind(sShadow);
|
shadow->bind(sShadow);
|
||||||
renderScene(roomIndex);
|
renderScene(roomIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void renderWater() {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void render() {
|
void render() {
|
||||||
|
clipHeight = 1000000.0f;
|
||||||
|
clipSign = 1.0f;
|
||||||
Core::resetStates();
|
Core::resetStates();
|
||||||
|
|
||||||
ambientCache->precessQueue();
|
ambientCache->precessQueue();
|
||||||
renderShadows(lara->getRoomIndex());
|
renderShadows(lara->getRoomIndex());
|
||||||
|
Core::setViewport(0, 0, Core::width, Core::height);
|
||||||
renderCompose(camera->getRoomIndex());
|
renderCompose(camera->getRoomIndex());
|
||||||
|
|
||||||
#ifdef _DEBUG
|
|
||||||
|
Core::setViewport(0, 0, waterRefract->width, waterRefract->height);
|
||||||
|
|
||||||
|
bool underwater = level.rooms[camera->getRoomIndex()].flags.water;
|
||||||
|
|
||||||
|
Core::setTarget(waterRefract);
|
||||||
|
renderCompose(camera->getRoomIndex());
|
||||||
|
|
||||||
|
setPassShader(Core::passWater);
|
||||||
|
atlas->bind(sNormal);
|
||||||
|
atlas->bind(sReflect);
|
||||||
|
|
||||||
|
Core::active.shader->setParam(uType, Shader::WATER_MASK);
|
||||||
|
Core::active.shader->setParam(uViewProj, Core::mViewProj);
|
||||||
|
Core::setBlending(bmNone);
|
||||||
|
Core::setCulling(cfNone);
|
||||||
|
glColorMask(false, false, false, true);
|
||||||
|
mesh->renderQuad();
|
||||||
|
glColorMask(true, true, true, true);
|
||||||
|
|
||||||
|
Core::setTarget(waterReflect);
|
||||||
|
vec3 p = vec3(40448, 3584, 60928);
|
||||||
|
vec3 n = vec3(0, 1, 0);
|
||||||
|
|
||||||
|
vec4 reflectPlane = vec4(n.x, n.y, n.z, -n.dot(p));
|
||||||
|
|
||||||
|
camera->reflectPlane = &reflectPlane;
|
||||||
|
Core::setCulling(cfBack);
|
||||||
|
clipSign = underwater ? -1.0f : 1.0f;
|
||||||
|
clipHeight = 3584.0 * clipSign;
|
||||||
|
renderCompose(underwater ? 13 : lara->getRoomIndex());
|
||||||
|
clipHeight = 1000000.0f;
|
||||||
|
clipSign = 1.0f;
|
||||||
|
Core::setCulling(cfFront);
|
||||||
|
camera->reflectPlane = NULL;
|
||||||
|
|
||||||
|
Core::setTarget(NULL);
|
||||||
|
Core::setViewport(0, 0, Core::width, Core::height);
|
||||||
|
|
||||||
|
camera->setup(true);
|
||||||
|
|
||||||
|
// Core::mViewInv = camera->mViewInv;
|
||||||
|
// Core::mView = Core::mViewInv.inverse();
|
||||||
|
|
||||||
|
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
Core::setViewport(0, 0, water[0]->width, water[0]->height);
|
Core::setViewport(0, 0, water[0]->width, water[0]->height);
|
||||||
setPassShader(Core::passWater);
|
setPassShader(Core::passWater);
|
||||||
|
|
||||||
static vec3 lastPos = vec3(0.0);
|
static vec3 lastPos = vec3(0.0);
|
||||||
bool flag = (lara->pos - lastPos).length() > 16.0f;
|
vec3 head = lara->animation.getJoints(lara->getMatrix(), 14).pos;
|
||||||
bool flag2 = lara->animation.frameIndex == 20;//isFrameActive(22) || lara->animation.isFrameActive(21);
|
bool flag = (head - lastPos).length() > 16.0f;
|
||||||
|
bool fall = (lara->animation.index == Lara::ANIM_WATER_FALL || lara->animation.index == 152) && lara->animation.frameIndex == 0;
|
||||||
|
bool flag2 = lara->animation.frameIndex == 20 || fall;
|
||||||
|
flag &= lara->stand == Lara::STAND_ONWATER || fall;
|
||||||
|
flag2 &= lara->stand == Lara::STAND_ONWATER || fall;
|
||||||
|
|
||||||
if (Input::down[ikU] || flag || flag2) {
|
if (Input::down[ikU] || flag || flag2) {
|
||||||
vec2 p(randf(), randf());
|
vec2 p(randf(), randf());
|
||||||
if (flag || flag2) {
|
if (flag || flag2) {
|
||||||
vec3 c(40448, 0.0, 60928);
|
vec3 c(40448, 0.0, 60928);
|
||||||
p.x = (lara->pos.x - c.x) / 5120.0f + 0.5;
|
p.x = (head.x - c.x) / 5120.0f + 0.5;
|
||||||
p.y = (lara->pos.z - c.z) / 5120.0f + 0.5;
|
p.y = (head.z - c.z) / 5120.0f + 0.5;
|
||||||
lastPos = lara->pos;
|
lastPos = head;
|
||||||
}
|
}
|
||||||
|
float radius = (flag2 ? 1.0f : randf() + 0.2f);
|
||||||
|
float strength = flag2 ? 0.01f : randf() * 0.03f;
|
||||||
|
|
||||||
|
if (fall) {
|
||||||
|
radius = 1.5f;
|
||||||
|
strength = 0.05f;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
water[0]->bind(sDiffuse);
|
water[0]->bind(sDiffuse);
|
||||||
Core::setTarget(water[1]);
|
Core::setTarget(water[1]);
|
||||||
Core::active.shader->setParam(uType, Shader::WATER_DROP);
|
Core::active.shader->setParam(uType, Shader::WATER_DROP);
|
||||||
Core::active.shader->setParam(uParam, vec4(p.x, p.y, 128.0f / 5120.0f * (flag2 ? 1.0f : randf() + 0.2f), flag2 ? 0.001f : randf() * 0.05f));
|
Core::active.shader->setParam(uParam, vec4(p.x, p.y, 128.0f / 5120.0f * radius, strength));
|
||||||
mesh->renderQuad();
|
mesh->renderQuad();
|
||||||
swap(water[0], water[1]);
|
swap(water[0], water[1]);
|
||||||
Input::down[ikU] = false;
|
Input::down[ikU] = false;
|
||||||
@@ -938,15 +1006,18 @@ struct Level {
|
|||||||
Core::active.shader->setParam(uType, Shader::WATER_NORMAL);
|
Core::active.shader->setParam(uType, Shader::WATER_NORMAL);
|
||||||
mesh->renderQuad();
|
mesh->renderQuad();
|
||||||
swap(water[0], water[1]);
|
swap(water[0], water[1]);
|
||||||
|
|
||||||
|
Core::setViewport(0, 0, waterCaustics->width, waterCaustics->height);
|
||||||
|
|
||||||
|
water[0]->bind(sDiffuse);
|
||||||
|
Core::setTarget(waterCaustics);
|
||||||
|
Core::active.shader->setParam(uType, Shader::WATER_CAUSTICS);
|
||||||
|
mesh->renderQuad();
|
||||||
|
swap(water[0], water[1]);
|
||||||
|
|
||||||
|
|
||||||
Core::setTarget(NULL);
|
Core::setTarget(NULL);
|
||||||
|
|
||||||
/*
|
|
||||||
waterCube->bind(sEnvironment);
|
|
||||||
Core::setViewport(Core::width - water[0]->width - 16, Core::height - water[0]->height - 16, water[0]->width, water[0]->height);
|
|
||||||
water[0]->bind(sDiffuse);
|
|
||||||
Core::active.shader->setParam(uType, Shader::WATER_TEST);
|
|
||||||
mesh->renderQuad();
|
|
||||||
*/
|
|
||||||
Core::setViewport(0, 0, Core::width, Core::height);
|
Core::setViewport(0, 0, Core::width, Core::height);
|
||||||
|
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
@@ -961,17 +1032,20 @@ struct Level {
|
|||||||
Core::lightColor[0] = vec4(lum, lum, lum, float(light.radius) * float(light.radius));
|
Core::lightColor[0] = vec4(lum, lum, lum, float(light.radius) * float(light.radius));
|
||||||
}
|
}
|
||||||
|
|
||||||
Core::active.shader->setParam(uType, Shader::WATER_TEST);
|
Core::active.shader->setParam(uType, Shader::WATER_COMPOSE);
|
||||||
Core::active.shader->setParam(uViewProj, Core::mViewProj);
|
Core::active.shader->setParam(uViewProj, Core::mViewProj);
|
||||||
Core::active.shader->setParam(uViewPos, Core::viewPos);
|
Core::active.shader->setParam(uViewPos, Core::viewPos);
|
||||||
Core::active.shader->setParam(uLightPos, Core::lightPos[0], 1);
|
Core::active.shader->setParam(uLightPos, Core::lightPos[0], 1);
|
||||||
Core::active.shader->setParam(uLightColor, Core::lightColor[0], 1);
|
Core::active.shader->setParam(uLightColor, Core::lightColor[0], 1);
|
||||||
|
|
||||||
water[0]->bind(sDiffuse);
|
waterRefract->bind(sDiffuse);
|
||||||
waterCube->bind(sEnvironment);
|
waterReflect->bind(sReflect);
|
||||||
|
water[0]->bind(sNormal);
|
||||||
|
Core::setCulling(cfNone);
|
||||||
mesh->renderQuad();
|
mesh->renderQuad();
|
||||||
|
Core::setCulling(cfFront);
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
|
||||||
static int modelIndex = 0;
|
static int modelIndex = 0;
|
||||||
static bool lastStateK = false;
|
static bool lastStateK = false;
|
||||||
@@ -998,6 +1072,39 @@ struct Level {
|
|||||||
// renderModel(level.models[modelIndex], level.entities[4]);
|
// renderModel(level.models[modelIndex], level.entities[4]);
|
||||||
|
|
||||||
Debug::begin();
|
Debug::begin();
|
||||||
|
|
||||||
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
glPushMatrix();
|
||||||
|
glLoadIdentity();
|
||||||
|
glMatrixMode(GL_PROJECTION);
|
||||||
|
glPushMatrix();
|
||||||
|
glLoadIdentity();
|
||||||
|
glOrtho(0, Core::width, 0, Core::height, 0, 1);
|
||||||
|
|
||||||
|
|
||||||
|
waterCaustics->bind(sDiffuse);
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
glDisable(GL_CULL_FACE);
|
||||||
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
|
glColor3f(1, 1, 1);
|
||||||
|
glBegin(GL_QUADS);
|
||||||
|
glTexCoord2f(0, 0); glVertex2f(0, 0);
|
||||||
|
glTexCoord2f(1, 0); glVertex2f(256, 0);
|
||||||
|
glTexCoord2f(1, 1); glVertex2f(256, 256);
|
||||||
|
glTexCoord2f(0, 1); glVertex2f(0, 256);
|
||||||
|
glEnd();
|
||||||
|
|
||||||
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
glEnable(GL_CULL_FACE);
|
||||||
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
|
glMatrixMode(GL_PROJECTION);
|
||||||
|
glPopMatrix();
|
||||||
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
glPopMatrix();
|
||||||
|
|
||||||
|
|
||||||
// Debug::Level::rooms(level, lara->pos, lara->getEntity().room);
|
// Debug::Level::rooms(level, lara->pos, lara->getEntity().room);
|
||||||
// Debug::Level::lights(level, lara->getRoomIndex());
|
// Debug::Level::lights(level, lara->getRoomIndex());
|
||||||
// Debug::Level::sectors(level, lara->getRoomIndex(), (int)lara->pos.y);
|
// Debug::Level::sectors(level, lara->getRoomIndex(), (int)lara->pos.y);
|
||||||
@@ -1099,7 +1206,7 @@ struct Level {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
//Debug::Level::info(level, lara->getEntity(), lara->animation);
|
// Debug::Level::info(level, lara->getEntity(), lara->animation);
|
||||||
|
|
||||||
|
|
||||||
Debug::end();
|
Debug::end();
|
||||||
|
@@ -120,7 +120,8 @@ struct Mesh {
|
|||||||
float intensityf(int lighting) {
|
float intensityf(int lighting) {
|
||||||
if (lighting < 0) return 1.0f;
|
if (lighting < 0) return 1.0f;
|
||||||
float lum = 1.0f - (lighting >> 5) / 255.0f;
|
float lum = 1.0f - (lighting >> 5) / 255.0f;
|
||||||
return powf(lum, 2.2f); // gamma to linear space
|
//return powf(lum, 2.2f); // gamma to linear space
|
||||||
|
return lum * lum;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 intensity(int lighting) {
|
uint8 intensity(int lighting) {
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
R"====(
|
R"====(
|
||||||
varying vec2 vTexCoord;
|
varying vec4 vTexCoord; // xy - atlas coords, zw - caustics coords
|
||||||
|
|
||||||
#ifndef PASS_SHADOW
|
#ifndef PASS_SHADOW
|
||||||
#ifndef PASS_AMBIENT
|
#ifndef PASS_AMBIENT
|
||||||
@@ -37,6 +37,7 @@ uniform int uType;
|
|||||||
uniform vec3 uViewPos;
|
uniform vec3 uViewPos;
|
||||||
uniform vec2 uAnimTexRanges[MAX_RANGES];
|
uniform vec2 uAnimTexRanges[MAX_RANGES];
|
||||||
uniform vec2 uAnimTexOffsets[MAX_OFFSETS];
|
uniform vec2 uAnimTexOffsets[MAX_OFFSETS];
|
||||||
|
uniform vec4 uRoomSize; // xy - minXZ, zw - maxXZ
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
attribute vec4 aCoord;
|
attribute vec4 aCoord;
|
||||||
@@ -75,15 +76,20 @@ uniform int uType;
|
|||||||
float f = fract((aTexCoord.w + uParam.x * 4.0 - range.x) / range.y) * range.y;
|
float f = fract((aTexCoord.w + uParam.x * 4.0 - range.x) / range.y) * range.y;
|
||||||
vec2 offset = uAnimTexOffsets[int(range.x + f)]; // texCoord offset from first frame
|
vec2 offset = uAnimTexOffsets[int(range.x + f)]; // texCoord offset from first frame
|
||||||
|
|
||||||
vTexCoord = (aTexCoord.xy + offset) * TEXCOORD_SCALE; // first frame + offset * isAnimated
|
vTexCoord.xy = (aTexCoord.xy + offset) * TEXCOORD_SCALE; // first frame + offset * isAnimated
|
||||||
vNormal = vec4(mulQuat(rBasisRot, aNormal.xyz), aNormal.w);
|
vNormal = vec4(mulQuat(rBasisRot, aNormal.xyz), aNormal.w);
|
||||||
|
|
||||||
|
if (aTexCoord.z > 0.0)
|
||||||
|
coord.w = -1.0;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
coord.xyz += uViewInv[0].xyz * aTexCoord.z - uViewInv[1].xyz * aTexCoord.w;
|
coord.xyz += uViewInv[0].xyz * aTexCoord.z - uViewInv[1].xyz * aTexCoord.w;
|
||||||
vTexCoord = aTexCoord.xy * TEXCOORD_SCALE;
|
vTexCoord.xy = aTexCoord.xy * TEXCOORD_SCALE;
|
||||||
vNormal = vec4(uViewPos.xyz - coord.xyz, 0.0);
|
vNormal = vec4(uViewPos.xyz - coord.xyz, 0.0);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
vTexCoord = aTexCoord.xy * TEXCOORD_SCALE;
|
vTexCoord.xy = aTexCoord.xy * TEXCOORD_SCALE;
|
||||||
|
vTexCoord.zw = vec2(0.0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef PASS_SHADOW
|
#ifndef PASS_SHADOW
|
||||||
@@ -95,6 +101,7 @@ uniform int uType;
|
|||||||
float sum = coord.x + coord.y + coord.z;
|
float sum = coord.x + coord.y + coord.z;
|
||||||
vColor.xyz *= abs(sin(sum / 512.0 + uParam.x)) * 1.5 + 0.5; // color dodge
|
vColor.xyz *= abs(sin(sum / 512.0 + uParam.x)) * 1.5 + 0.5; // color dodge
|
||||||
}
|
}
|
||||||
|
vTexCoord.zw = smoothstep(uRoomSize.xy, uRoomSize.zw, coord.xz);
|
||||||
|
|
||||||
vViewVec = uViewPos - coord.xyz;
|
vViewVec = uViewPos - coord.xyz;
|
||||||
vLightProj = uLightProj * coord;
|
vLightProj = uLightProj * coord;
|
||||||
@@ -106,6 +113,7 @@ uniform int uType;
|
|||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
uniform sampler2D sDiffuse;
|
uniform sampler2D sDiffuse;
|
||||||
|
uniform sampler2D sReflect;
|
||||||
uniform vec4 uColor;
|
uniform vec4 uColor;
|
||||||
#ifdef PASS_COMPOSE
|
#ifdef PASS_COMPOSE
|
||||||
uniform samplerCube sEnvironment;
|
uniform samplerCube sEnvironment;
|
||||||
@@ -218,6 +226,10 @@ uniform int uType;
|
|||||||
sqr.z * mix(uAmbient[5], uAmbient[4], pos.z);
|
sqr.z * mix(uAmbient[5], uAmbient[4], pos.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float calcCaustics(vec3 n) {
|
||||||
|
return texture2D(sReflect, vTexCoord.zw).r * (float(uCaustics) * max(0.0, -n.y));
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
/*
|
/*
|
||||||
float getLuminance(vec3 color) {
|
float getLuminance(vec3 color) {
|
||||||
@@ -228,17 +240,24 @@ uniform int uType;
|
|||||||
const vec2 size = vec2(2.0, 0.0);
|
const vec2 size = vec2(2.0, 0.0);
|
||||||
const vec3 off = vec3(-1, 0, 1) / 1024.0;
|
const vec3 off = vec3(-1, 0, 1) / 1024.0;
|
||||||
|
|
||||||
float s01 = getLuminance(texture2D(sDiffuse, vTexCoord + off.xy).xyz);
|
float s01 = getLuminance(texture2D(sDiffuse, vTexCoord.xy + off.xy).xyz);
|
||||||
float s21 = getLuminance(texture2D(sDiffuse, vTexCoord + off.zy).xyz);
|
float s21 = getLuminance(texture2D(sDiffuse, vTexCoord.xy + off.zy).xyz);
|
||||||
float s10 = getLuminance(texture2D(sDiffuse, vTexCoord + off.yx).xyz);
|
float s10 = getLuminance(texture2D(sDiffuse, vTexCoord.xy + off.yx).xyz);
|
||||||
float s12 = getLuminance(texture2D(sDiffuse, vTexCoord + off.yz).xyz);
|
float s12 = getLuminance(texture2D(sDiffuse, vTexCoord.xy + off.yz).xyz);
|
||||||
vec3 va = vec3(size.xy * 0.25, s21-s01);
|
vec3 va = vec3(size.xy * 0.25, s21-s01);
|
||||||
vec3 vb = vec3(size.yx * 0.25, s12-s10);
|
vec3 vb = vec3(size.yx * 0.25, s12-s10);
|
||||||
return normalize(cross(va, vb));
|
return normalize(cross(va, vb));
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
void main() {
|
void main() {
|
||||||
vec4 color = texture2D(sDiffuse, vTexCoord);
|
#ifndef PASS_SHADOW
|
||||||
|
#ifndef PASS_AMBIENT
|
||||||
|
if (vCoord.y * uParam.z > uParam.w)
|
||||||
|
discard;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
vec4 color = texture2D(sDiffuse, vTexCoord.xy);
|
||||||
if (color.w < 0.6)
|
if (color.w < 0.6)
|
||||||
discard;
|
discard;
|
||||||
|
|
||||||
@@ -269,7 +288,6 @@ uniform int uType;
|
|||||||
vec3 viewVec = normalize(vViewVec);
|
vec3 viewVec = normalize(vViewVec);
|
||||||
vec3 light = vec3(0.0);
|
vec3 light = vec3(0.0);
|
||||||
|
|
||||||
|
|
||||||
for (int i = 1; i < MAX_LIGHTS; i++) // additional lights
|
for (int i = 1; i < MAX_LIGHTS; i++) // additional lights
|
||||||
light += calcLight(normal, uLightPos[i], uLightColor[i]);
|
light += calcLight(normal, uLightPos[i], uLightColor[i]);
|
||||||
|
|
||||||
@@ -282,6 +300,7 @@ uniform int uType;
|
|||||||
float rShadow = dot(normal, uLightPos[0].xyz - vCoord) > 0.0 ? getShadow(vLightProj) : 1.0;
|
float rShadow = dot(normal, uLightPos[0].xyz - vCoord) > 0.0 ? getShadow(vLightProj) : 1.0;
|
||||||
//light += calcLight(normal, uLightPos[0], uLightColor[0]);
|
//light += calcLight(normal, uLightPos[0], uLightColor[0]);
|
||||||
light += mix(min(uColor.w, vColor.w), vColor.w, rShadow);
|
light += mix(min(uColor.w, vColor.w), vColor.w, rShadow);
|
||||||
|
light += calcCaustics(normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (uType == TYPE_ENTITY) {
|
if (uType == TYPE_ENTITY) {
|
||||||
@@ -289,6 +308,7 @@ uniform int uType;
|
|||||||
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);
|
color.xyz += calcSpecular(normal, viewVec, uLightPos[0], uLightColor[0], uColor.w * rShadow + 0.03);
|
||||||
|
light += calcCaustics(normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (uType == TYPE_MIRROR) {
|
if (uType == TYPE_MIRROR) {
|
||||||
|
14
src/shader.h
14
src/shader.h
@@ -4,12 +4,12 @@
|
|||||||
#include "core.h"
|
#include "core.h"
|
||||||
|
|
||||||
enum AttribType { aCoord, aTexCoord, aNormal, aColor, aMAX };
|
enum AttribType { aCoord, aTexCoord, aNormal, aColor, aMAX };
|
||||||
enum SamplerType { sDiffuse, sShadow, sEnvironment, sMAX };
|
enum SamplerType { sDiffuse, sNormal, sReflect, sShadow, sEnvironment, sMAX };
|
||||||
enum UniformType { uType, uCaustics, uParam, uViewProj, uViewInv, uBasis, uLightProj, uColor, uAmbient, uViewPos, uLightsCount, uLightPos, uLightColor, uAnimTexRanges, uAnimTexOffsets, uMAX };
|
enum UniformType { uType, uCaustics, uParam, uViewProj, uViewInv, uBasis, uLightProj, uColor, uAmbient, uViewPos, uLightsCount, uLightPos, uLightColor, uAnimTexRanges, uAnimTexOffsets, uRoomSize, 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", "sNormal", "sReflect", "sShadow", "sEnvironment" };
|
||||||
const char *UniformName[uMAX] = { "uType", "uCaustics", "uParam", "uViewProj", "uViewInv", "uBasis", "uLightProj", "uColor", "uAmbient", "uViewPos", "uLightsCount", "uLightPos", "uLightColor", "uAnimTexRanges", "uAnimTexOffsets" };
|
const char *UniformName[uMAX] = { "uType", "uCaustics", "uParam", "uViewProj", "uViewInv", "uBasis", "uLightProj", "uColor", "uAmbient", "uViewPos", "uLightsCount", "uLightPos", "uLightColor", "uAnimTexRanges", "uAnimTexOffsets", "uRoomSize" };
|
||||||
|
|
||||||
struct Shader {
|
struct Shader {
|
||||||
GLuint ID;
|
GLuint ID;
|
||||||
@@ -18,14 +18,12 @@ struct Shader {
|
|||||||
enum : GLint {
|
enum : GLint {
|
||||||
/* shader */ SPRITE = 0, FLASH = 1, ROOM = 2, ENTITY = 3, MIRROR = 4,
|
/* shader */ SPRITE = 0, FLASH = 1, ROOM = 2, ENTITY = 3, MIRROR = 4,
|
||||||
/* filter */ FILTER_DOWNSAMPLE = 0,
|
/* filter */ FILTER_DOWNSAMPLE = 0,
|
||||||
/* water */ WATER_DROP = 0, WATER_STEP = 1, WATER_NORMAL = 2, WATER_TEST = 3
|
/* water */ WATER_DROP = 0, WATER_STEP = 1, WATER_NORMAL = 2, WATER_CAUSTICS = 3, WATER_MASK = 4, WATER_COMPOSE = 5,
|
||||||
};
|
};
|
||||||
|
|
||||||
Shader(const char *text, const char *defines = "") {
|
Shader(const char *text, const char *defines = "") {
|
||||||
#ifdef MOBILE
|
#ifdef MOBILE
|
||||||
#define GLSL_DEFINE "#define MOBILE\n"\
|
#define GLSL_DEFINE "precision highp int;\nprecision highp float;\n"
|
||||||
"precision highp int;\n"\
|
|
||||||
"precision highp float;\n"
|
|
||||||
#else
|
#else
|
||||||
#define GLSL_DEFINE "#version 120\n"
|
#define GLSL_DEFINE "#version 120\n"
|
||||||
#endif
|
#endif
|
||||||
|
@@ -4,7 +4,7 @@
|
|||||||
#include "core.h"
|
#include "core.h"
|
||||||
|
|
||||||
struct Texture {
|
struct Texture {
|
||||||
enum Format : uint32 { RGBA, RGBA_FLOAT, RGBA_HALF, DEPTH, SHADOW, MAX };
|
enum Format : uint32 { RGBA, RGBA_FLOAT, RGBA_HALF, RED, DEPTH, SHADOW, MAX };
|
||||||
|
|
||||||
GLuint ID;
|
GLuint ID;
|
||||||
int width, height;
|
int width, height;
|
||||||
@@ -64,6 +64,7 @@ struct Texture {
|
|||||||
{ GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE }, // RGBA
|
{ GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE }, // RGBA
|
||||||
{ GL_RGBA32F, GL_RGBA, GL_FLOAT }, // RGBA_FLOAT
|
{ GL_RGBA32F, GL_RGBA, GL_FLOAT }, // RGBA_FLOAT
|
||||||
{ GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT }, // RGBA_HALF
|
{ GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT }, // RGBA_HALF
|
||||||
|
{ GL_RED, GL_RED, GL_UNSIGNED_BYTE }, // RED
|
||||||
{ GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT }, // DEPTH
|
{ GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT }, // DEPTH
|
||||||
{ GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT }, // SHADOW
|
{ GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT }, // SHADOW
|
||||||
};
|
};
|
||||||
|
13
src/utils.h
13
src/utils.h
@@ -337,6 +337,19 @@ struct mat4 {
|
|||||||
this->offset = vec4(from, 1.0f);
|
this->offset = vec4(from, 1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mat4(const vec4 &reflectPlane) {
|
||||||
|
float a = reflectPlane.x,
|
||||||
|
b = reflectPlane.y,
|
||||||
|
c = reflectPlane.z,
|
||||||
|
d = reflectPlane.w;
|
||||||
|
|
||||||
|
right = vec4(1 - 2*a*a, - 2*b*a, - 2*c*a, 0);
|
||||||
|
up = vec4( - 2*a*b, 1 - 2*b*b, - 2*c*b, 0);
|
||||||
|
dir = vec4( - 2*a*c, - 2*b*c, 1 - 2*c*c, 0);
|
||||||
|
offset = vec4( - 2*a*d, - 2*b*d, - 2*c*d, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void identity() {
|
void identity() {
|
||||||
e10 = e20 = e30 = e01 = e21 = e31 = e02 = e12 = e32 = e03 = e13 = e23 = 0.0f;
|
e10 = e20 = e30 = e01 = e21 = e31 = e02 = e12 = e32 = e03 = e13 = e23 = 0.0f;
|
||||||
e00 = e11 = e22 = e33 = 1.0f;
|
e00 = e11 = e22 = e33 = 1.0f;
|
||||||
|
Reference in New Issue
Block a user