mirror of
https://github.com/XProger/OpenLara.git
synced 2025-08-11 15:45:05 +02:00
15
src/core.h
15
src/core.h
@@ -139,9 +139,9 @@ namespace Core {
|
|||||||
vec4 lightColor[MAX_LIGHTS];
|
vec4 lightColor[MAX_LIGHTS];
|
||||||
vec4 color;
|
vec4 color;
|
||||||
|
|
||||||
enum { passOpaque, passShadow } pass;
|
enum Pass { passCompose, passShadow, passAmbient } pass;
|
||||||
|
|
||||||
GLuint RT;
|
GLuint RT, RB;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
Shader *shader;
|
Shader *shader;
|
||||||
@@ -246,6 +246,10 @@ namespace Core {
|
|||||||
// support.depthTexture = support.shadowSampler = false; // depth textures is not supported in Safari browser in fact :(
|
// support.depthTexture = support.shadowSampler = false; // depth textures is not supported in Safari browser in fact :(
|
||||||
|
|
||||||
glGenFramebuffers(1, &RT);
|
glGenFramebuffers(1, &RT);
|
||||||
|
glGenRenderbuffers(1, &RB);
|
||||||
|
glBindRenderbuffer(GL_RENDERBUFFER, RB);
|
||||||
|
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, 64, 64);
|
||||||
|
glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
||||||
|
|
||||||
Sound::init();
|
Sound::init();
|
||||||
|
|
||||||
@@ -258,6 +262,11 @@ namespace Core {
|
|||||||
Sound::free();
|
Sound::free();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void resetStates() {
|
||||||
|
memset(&active, 0, sizeof(active));
|
||||||
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
}
|
||||||
|
|
||||||
void clear(const vec4 &color) {
|
void clear(const vec4 &color) {
|
||||||
glClearColor(color.x, color.y, color.z, color.w);
|
glClearColor(color.x, color.y, color.z, color.w);
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||||
@@ -316,6 +325,8 @@ namespace Core {
|
|||||||
glBindFramebuffer(GL_FRAMEBUFFER, RT);
|
glBindFramebuffer(GL_FRAMEBUFFER, RT);
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, target->depth ? GL_DEPTH_ATTACHMENT : GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, target->ID, 0);
|
glFramebufferTexture2D(GL_FRAMEBUFFER, target->depth ? GL_DEPTH_ATTACHMENT : GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, target->ID, 0);
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, target->depth ? GL_COLOR_ATTACHMENT0 : GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, target->dummy ? target->dummy->ID : 0, 0);
|
glFramebufferTexture2D(GL_FRAMEBUFFER, target->depth ? GL_COLOR_ATTACHMENT0 : GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, target->dummy ? target->dummy->ID : 0, 0);
|
||||||
|
if (!target->depth)
|
||||||
|
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, RB);
|
||||||
|
|
||||||
bool mask = !target->depth;
|
bool mask = !target->depth;
|
||||||
glColorMask(mask, mask, mask, mask);
|
glColorMask(mask, mask, mask, mask);
|
||||||
|
38
src/lara.h
38
src/lara.h
@@ -1559,20 +1559,42 @@ struct Lara : Character {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void move() {
|
void move() {
|
||||||
|
TR::Entity &e = getEntity();
|
||||||
|
TR::Level::FloorInfo info;
|
||||||
|
|
||||||
|
float f, c;
|
||||||
|
bool canPassGap = true;
|
||||||
|
/*
|
||||||
|
if (velocity != 0.0f) {
|
||||||
|
vec3 dir = velocity.normal() * 128.0f;
|
||||||
|
vec3 p = pos + dir;
|
||||||
|
level->getFloorInfo(e.room, (int)p.x, (int)p.y, (int)p.z, info);
|
||||||
|
if (info.floor < p.y - (256 + 128) || info.ceiling > p.y - 768) { // wall
|
||||||
|
vec3 axis = dir.axisXZ();
|
||||||
|
vec3 normal = (p - vec3(int(p.x / 1024.0f) * 1024.0f + 512.0f, p.y, int(p.z / 1024.0f) * 1024.0f + 512.0f)).axisXZ();
|
||||||
|
LOG("%f %f = %f %f = %f\n", axis.x, axis.z, normal.x, normal.z, abs(axis.dot(normal)));
|
||||||
|
if (abs(axis.dot(normal)) > EPS) {
|
||||||
|
canPassGap = false;
|
||||||
|
} else {
|
||||||
|
updateEntity();
|
||||||
|
checkRoom();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
vec3 offset = velocity * Core::deltaTime * 30.0f;
|
vec3 offset = velocity * Core::deltaTime * 30.0f;
|
||||||
|
|
||||||
vec3 p = pos;
|
vec3 p = pos;
|
||||||
pos = pos + offset;
|
pos = pos + offset;
|
||||||
|
|
||||||
TR::Entity &e = getEntity();
|
if (canPassGap) {
|
||||||
TR::Level::FloorInfo info;
|
level->getFloorInfo(e.room, (int)pos.x, (int)pos.y, (int)pos.z, info);
|
||||||
level->getFloorInfo(e.room, (int)pos.x, (int)pos.y, (int)pos.z, info);
|
canPassGap = (info.floor - info.ceiling) >= (stand == STAND_GROUND ? 768 : 512);
|
||||||
|
}
|
||||||
// get frame to get height
|
|
||||||
bool canPassGap = (info.floor - info.ceiling) >= (stand == STAND_GROUND ? 768 : 512);
|
|
||||||
float f = info.floor - pos.y;
|
|
||||||
float c = pos.y - info.ceiling;
|
|
||||||
|
|
||||||
|
f = info.floor - pos.y;
|
||||||
|
c = pos.y - info.ceiling;
|
||||||
/*
|
/*
|
||||||
TR::Animation *anim = animation;
|
TR::Animation *anim = animation;
|
||||||
Box eBox = Box(pos - vec3(128.0f, 0.0f, 128.0f), pos + vec3(128.0, getHeight(), 128.0f)); // getBoundingBox();
|
Box eBox = Box(pos - vec3(128.0f, 0.0f, 128.0f), pos + vec3(128.0, getHeight(), 128.0f)); // getBoundingBox();
|
||||||
|
176
src/level.h
176
src/level.h
@@ -22,7 +22,7 @@ const char GUI[] =
|
|||||||
;
|
;
|
||||||
|
|
||||||
struct Level {
|
struct Level {
|
||||||
enum { shDefault, shShadow, shGUI, shMAX };
|
enum { shCompose, shShadow, shAmbient, shGUI, shMAX };
|
||||||
|
|
||||||
TR::Level level;
|
TR::Level level;
|
||||||
Shader *shaders[shMAX];
|
Shader *shaders[shMAX];
|
||||||
@@ -32,6 +32,7 @@ struct Level {
|
|||||||
Lara *lara;
|
Lara *lara;
|
||||||
Camera *camera;
|
Camera *camera;
|
||||||
Texture *shadow;
|
Texture *shadow;
|
||||||
|
Texture *ambient[4]; // 64, 16, 4, 1
|
||||||
|
|
||||||
float time;
|
float time;
|
||||||
|
|
||||||
@@ -42,6 +43,8 @@ struct Level {
|
|||||||
mesh = new MeshBuilder(level);
|
mesh = new MeshBuilder(level);
|
||||||
|
|
||||||
shadow = new Texture(1024, 1024, true);
|
shadow = new Texture(1024, 1024, true);
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
ambient[i] = new Texture(64 >> (i << 1), 64 >> (i << 1), false);
|
||||||
|
|
||||||
initAtlas();
|
initAtlas();
|
||||||
initShaders();
|
initShaders();
|
||||||
@@ -154,6 +157,9 @@ struct Level {
|
|||||||
delete shaders[i];
|
delete shaders[i];
|
||||||
|
|
||||||
delete shadow;
|
delete shadow;
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
delete ambient[i];
|
||||||
|
|
||||||
delete atlas;
|
delete atlas;
|
||||||
delete mesh;
|
delete mesh;
|
||||||
|
|
||||||
@@ -214,11 +220,12 @@ struct Level {
|
|||||||
else
|
else
|
||||||
strcat(ext, "#define SHADOW_COLOR\n");
|
strcat(ext, "#define SHADOW_COLOR\n");
|
||||||
|
|
||||||
sprintf(def, "%s#define MAX_LIGHTS %d\n#define MAX_RANGES %d\n#define MAX_OFFSETS %d\n#define MAX_SHADOW_DIST %d.0\n", ext, MAX_LIGHTS, mesh->animTexRangesCount, mesh->animTexOffsetsCount, MAX_SHADOW_DIST);
|
sprintf(def, "%s#define PASS_COMPOSE\n#define MAX_LIGHTS %d\n#define MAX_RANGES %d\n#define MAX_OFFSETS %d\n#define MAX_SHADOW_DIST %d.0\n", ext, MAX_LIGHTS, mesh->animTexRangesCount, mesh->animTexOffsetsCount, MAX_SHADOW_DIST);
|
||||||
shaders[shDefault] = new Shader(SHADER, def);
|
shaders[shCompose] = new Shader(SHADER, def);
|
||||||
sprintf(def, "%s#define PASS_SHADOW\n", ext);
|
sprintf(def, "%s#define PASS_SHADOW\n", ext);
|
||||||
shaders[shShadow] = new Shader(SHADER, def);
|
shaders[shShadow] = new Shader(SHADER, def);
|
||||||
sprintf(ext, "%s#define SPRITE\n", def);
|
sprintf(def, "%s#define PASS_AMBIENT\n", ext);
|
||||||
|
shaders[shAmbient] = new Shader(SHADER, def);
|
||||||
shaders[shGUI] = new Shader(GUI, "");
|
shaders[shGUI] = new Shader(GUI, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -323,13 +330,10 @@ struct Level {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void setRoomShader(const TR::Room &room, float intensity) {
|
void setRoomParams(const TR::Room &room, float intensity) {
|
||||||
if (Core::pass == Core::passShadow) {
|
if (Core::pass == Core::passShadow)
|
||||||
shaders[shShadow]->bind();
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
shaders[shDefault]->bind();
|
|
||||||
if (room.flags.water) {
|
if (room.flags.water) {
|
||||||
Core::color = vec4(0.6f, 0.9f, 0.9f, intensity);
|
Core::color = vec4(0.6f, 0.9f, 0.9f, intensity);
|
||||||
Core::active.shader->setParam(uCaustics, 1);
|
Core::active.shader->setParam(uCaustics, 1);
|
||||||
@@ -347,7 +351,7 @@ struct Level {
|
|||||||
TR::Room &room = level.rooms[roomIndex];
|
TR::Room &room = level.rooms[roomIndex];
|
||||||
vec3 offset = vec3(float(room.info.x), 0.0f, float(room.info.z));
|
vec3 offset = vec3(float(room.info.x), 0.0f, float(room.info.z));
|
||||||
|
|
||||||
setRoomShader(room, intensityf(room.ambient));
|
setRoomParams(room, intensityf(room.ambient));
|
||||||
Shader *sh = Core::active.shader;
|
Shader *sh = Core::active.shader;
|
||||||
|
|
||||||
Core::lightColor[0] = vec4(0, 0, 0, 1);
|
Core::lightColor[0] = vec4(0, 0, 0, 1);
|
||||||
@@ -396,7 +400,7 @@ struct Level {
|
|||||||
sh->setParam(uModel, Core::mModel);
|
sh->setParam(uModel, Core::mModel);
|
||||||
|
|
||||||
// render room geometry
|
// render room geometry
|
||||||
if (Core::pass == Core::passOpaque) {
|
if (Core::pass == Core::passCompose || Core::pass == Core::passAmbient) {
|
||||||
mesh->renderRoomGeometry(roomIndex);
|
mesh->renderRoomGeometry(roomIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -493,7 +497,7 @@ struct Level {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
int16 lum = entity.intensity == -1 ? room.ambient : entity.intensity;
|
int16 lum = entity.intensity == -1 ? room.ambient : entity.intensity;
|
||||||
setRoomShader(room, intensityf(lum));
|
setRoomParams(room, intensityf(lum));
|
||||||
|
|
||||||
if (entity.modelIndex > 0) { // model
|
if (entity.modelIndex > 0) { // model
|
||||||
getLight(((Controller*)entity.controller)->pos, entity.room);
|
getLight(((Controller*)entity.controller)->pos, entity.room);
|
||||||
@@ -512,7 +516,6 @@ struct Level {
|
|||||||
((Controller*)entity.controller)->render(camera->frustum, mesh);
|
((Controller*)entity.controller)->render(camera->frustum, mesh);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void update() {
|
void update() {
|
||||||
time += Core::deltaTime;
|
time += Core::deltaTime;
|
||||||
|
|
||||||
@@ -529,7 +532,7 @@ struct Level {
|
|||||||
void setup() {
|
void setup() {
|
||||||
PROFILE_MARKER("SETUP");
|
PROFILE_MARKER("SETUP");
|
||||||
|
|
||||||
camera->setup(Core::pass != Core::passShadow);;
|
camera->setup(Core::pass == Core::passCompose);
|
||||||
|
|
||||||
atlas->bind(0);
|
atlas->bind(0);
|
||||||
|
|
||||||
@@ -537,19 +540,16 @@ struct Level {
|
|||||||
mesh->bind();
|
mesh->bind();
|
||||||
|
|
||||||
// set frame constants for all shaders
|
// set frame constants for all shaders
|
||||||
Core::active.shader = NULL;
|
Shader *sh = Core::active.shader;
|
||||||
for (int i = 0; i < shMAX; i++) {
|
sh->bind();
|
||||||
shaders[i]->bind();
|
sh->setParam(uViewProj, Core::mViewProj);
|
||||||
shaders[i]->setParam(uViewProj, Core::mViewProj);
|
sh->setParam(uLightProj, Core::mLightProj);
|
||||||
shaders[i]->setParam(uLightProj, Core::mLightProj);
|
sh->setParam(uViewInv, Core::mViewInv);
|
||||||
shaders[i]->setParam(uViewInv, Core::mViewInv);
|
sh->setParam(uViewPos, Core::viewPos);
|
||||||
shaders[i]->setParam(uViewPos, Core::viewPos);
|
sh->setParam(uTime, time);
|
||||||
shaders[i]->setParam(uTime, time);
|
sh->setParam(uLightTarget, lara->pos);
|
||||||
shaders[i]->setParam(uLightTarget, lara->pos);
|
sh->setParam(uAnimTexRanges, mesh->animTexRanges[0], mesh->animTexRangesCount);
|
||||||
shaders[i]->setParam(uAnimTexRanges, mesh->animTexRanges[0], mesh->animTexRangesCount);
|
sh->setParam(uAnimTexOffsets, mesh->animTexOffsets[0], mesh->animTexOffsetsCount);
|
||||||
shaders[i]->setParam(uAnimTexOffsets, mesh->animTexOffsets[0], mesh->animTexOffsetsCount);
|
|
||||||
}
|
|
||||||
glEnable(GL_DEPTH_TEST);
|
|
||||||
|
|
||||||
Core::mModel.identity();
|
Core::mModel.identity();
|
||||||
|
|
||||||
@@ -562,32 +562,50 @@ struct Level {
|
|||||||
room.meshes[j].flags.rendered = false; // clear visible flag for room static meshes
|
room.meshes[j].flags.rendered = false; // clear visible flag for room static meshes
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < level.entitiesCount; i++)
|
if (Core::pass != Core::passAmbient)
|
||||||
level.entities[i].flags.rendered = false;
|
for (int i = 0; i < level.entitiesCount; i++)
|
||||||
|
level.entities[i].flags.rendered = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderRooms() {
|
void renderRooms(int roomIndex) {
|
||||||
PROFILE_MARKER("ROOMS");
|
PROFILE_MARKER("ROOMS");
|
||||||
#ifdef LEVEL_EDITOR
|
#ifdef LEVEL_EDITOR
|
||||||
for (int i = 0; i < level.roomsCount; i++)
|
for (int i = 0; i < level.roomsCount; i++)
|
||||||
renderRoom(i);
|
renderRoom(i);
|
||||||
#else
|
#else
|
||||||
renderRoom(camera->getRoomIndex());
|
renderRoom(roomIndex);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderEntities() {
|
void renderEntities() {
|
||||||
PROFILE_MARKER("ENTITIES");
|
PROFILE_MARKER("ENTITIES");
|
||||||
shaders[Core::pass == Core::passShadow ? shShadow : shDefault]->bind();
|
|
||||||
for (int i = 0; i < level.entitiesCount; i++)
|
for (int i = 0; i < level.entitiesCount; i++)
|
||||||
renderEntity(level.entities[i]);
|
renderEntity(level.entities[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderScene() {
|
void renderScene(int roomIndex) {
|
||||||
PROFILE_MARKER("SCENE");
|
PROFILE_MARKER("SCENE");
|
||||||
setup();
|
setup();
|
||||||
renderRooms();
|
renderRooms(roomIndex);
|
||||||
renderEntities();
|
if (Core::pass != Core::passAmbient)
|
||||||
|
renderEntities();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setupCubeCamera(const vec3 &pos, int face) {
|
||||||
|
vec3 up = vec3(0, 1, 0);
|
||||||
|
vec3 dir;
|
||||||
|
switch (face) {
|
||||||
|
case 0 : dir = vec3( 1, 0, 0); break;
|
||||||
|
case 1 : dir = vec3(-1, 0, 0); break;
|
||||||
|
case 2 : dir = vec3( 0, 1, 0); up = vec3(1, 0, 0); break;
|
||||||
|
case 3 : dir = vec3( 0, -1, 0); up = vec3(1, 0, 0); break;
|
||||||
|
case 4 : dir = vec3( 0, 0, 1); break;
|
||||||
|
case 5 : dir = vec3( 0, 0, -1); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Core::mViewInv = mat4(pos, pos + dir, up);
|
||||||
|
Core::mView = Core::mViewInv.inverse();
|
||||||
|
Core::mProj = mat4(90, 1.0f, camera->znear, camera->zfar);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool setupLightCamera() {
|
bool setupLightCamera() {
|
||||||
@@ -600,48 +618,76 @@ struct Level {
|
|||||||
|
|
||||||
TR::Room::Light &light = level.rooms[room].lights[idx];
|
TR::Room::Light &light = level.rooms[room].lights[idx];
|
||||||
vec3 shadowLightPos = vec3(float(light.x), float(light.y), float(light.z));
|
vec3 shadowLightPos = vec3(float(light.x), float(light.y), float(light.z));
|
||||||
Core::mView = mat4(shadowLightPos, pos - vec3(0, 256, 0), vec3(0, -1, 0)).inverse();
|
Core::mViewInv = mat4(shadowLightPos, pos - vec3(0, 256, 0), vec3(0, -1, 0));
|
||||||
Core::mProj = mat4(120, 1.0f, camera->znear, camera->zfar);
|
Core::mView = Core::mViewInv.inverse();
|
||||||
|
Core::mProj = mat4(120, 1.0f, camera->znear, camera->zfar);
|
||||||
Core::mViewProj = Core::mProj * Core::mView;
|
|
||||||
|
|
||||||
mat4 bias;
|
mat4 bias;
|
||||||
bias.identity();
|
bias.identity();
|
||||||
bias.e03 = bias.e13 = bias.e23 = bias.e00 = bias.e11 = bias.e22 = 0.5f;
|
bias.e03 = bias.e13 = bias.e23 = bias.e00 = bias.e11 = bias.e22 = 0.5f;
|
||||||
Core::mLightProj = bias * Core::mProj * Core::mView; // * ( * ) ?
|
Core::mLightProj = bias * Core::mProj * Core::mView;
|
||||||
|
|
||||||
Shader *sh = shaders[shShadow];
|
|
||||||
sh->bind();
|
|
||||||
sh->setParam(uViewProj, Core::mViewProj);
|
|
||||||
sh->setParam(uLightProj, Core::mLightProj);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderShadows() {
|
void setPassShader(Core::Pass pass) {
|
||||||
if (!setupLightCamera()) return;
|
Core::pass = pass;
|
||||||
|
Shader *sh = NULL;
|
||||||
|
switch (pass) {
|
||||||
|
case Core::passCompose : sh = shaders[shCompose]; break;
|
||||||
|
case Core::passShadow : sh = shaders[shShadow]; break;
|
||||||
|
case Core::passAmbient : sh = shaders[shAmbient]; break;
|
||||||
|
}
|
||||||
|
ASSERT(sh);
|
||||||
|
sh->bind();
|
||||||
|
}
|
||||||
|
|
||||||
|
void renderAmbient(int roomIndex, const vec3 &pos, vec3 *cube) {
|
||||||
|
PROFILE_MARKER("PASS_AMBIENT");
|
||||||
|
setupCubeCamera(pos, 4);
|
||||||
|
|
||||||
|
setPassShader(Core::passAmbient);
|
||||||
|
Core::setBlending(bmAlpha);
|
||||||
|
Core::setTarget(ambient[0]);
|
||||||
|
Core::setViewport(0, 0, ambient[0]->width, ambient[0]->height);
|
||||||
|
Core::clear(vec4(0, 0, 0, 1));
|
||||||
|
renderScene(roomIndex);
|
||||||
|
Core::setTarget(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void renderShadows(int roomIndex) {
|
||||||
PROFILE_MARKER("PASS_SHADOW");
|
PROFILE_MARKER("PASS_SHADOW");
|
||||||
|
if (!setupLightCamera()) return;
|
||||||
Texture::unbind(sShadow);
|
Texture::unbind(sShadow);
|
||||||
Core::pass = Core::passShadow;
|
setPassShader(Core::passShadow);
|
||||||
Core::setBlending(bmNone);
|
Core::setBlending(bmNone);
|
||||||
Core::setTarget(shadow);
|
Core::setTarget(shadow);
|
||||||
Core::setViewport(0, 0, shadow->width, shadow->height);
|
Core::setViewport(0, 0, shadow->width, shadow->height);
|
||||||
Core::clear(vec4(1.0));
|
Core::clear(vec4(1.0));
|
||||||
Core::setCulling(cfBack);
|
Core::setCulling(cfBack);
|
||||||
renderScene();
|
renderScene(roomIndex);
|
||||||
Core::setCulling(cfFront);
|
Core::setCulling(cfFront);
|
||||||
Core::setTarget(NULL);
|
Core::setTarget(NULL);
|
||||||
shadow->bind(sShadow);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void render() {
|
void renderCompose(int roomIndex) {
|
||||||
renderShadows();
|
PROFILE_MARKER("PASS_COMPOSE");
|
||||||
|
setPassShader(Core::passCompose);
|
||||||
Core::pass = Core::passOpaque;
|
|
||||||
Core::setBlending(bmAlpha);
|
Core::setBlending(bmAlpha);
|
||||||
Core::clear(vec4(0.0f));
|
Core::clear(vec4(0.0f));
|
||||||
Core::setViewport(0, 0, Core::width, Core::height);
|
Core::setViewport(0, 0, Core::width, Core::height);
|
||||||
renderScene();
|
shadow->bind(sShadow);
|
||||||
|
renderScene(roomIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void render() {
|
||||||
|
Core::resetStates();
|
||||||
|
|
||||||
|
vec3 cube[6];
|
||||||
|
// renderAmbient(lara->getRoomIndex(), lara->pos - vec3(0, 512, 0), cube);
|
||||||
|
renderShadows(lara->getRoomIndex());
|
||||||
|
renderCompose(camera->getRoomIndex());
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
static int modelIndex = 0;
|
static int modelIndex = 0;
|
||||||
@@ -673,29 +719,29 @@ struct Level {
|
|||||||
|
|
||||||
Debug::begin();
|
Debug::begin();
|
||||||
// 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);
|
||||||
// Debug::Level::portals(level);
|
// Debug::Level::portals(level);
|
||||||
// Debug::Level::meshes(level);
|
// Debug::Level::meshes(level);
|
||||||
// Debug::Level::entities(level);
|
// Debug::Level::entities(level);
|
||||||
/*
|
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
glColor3f(1, 1, 1);
|
glColor3f(1, 1, 1);
|
||||||
glTranslatef(lara->pos.x, lara->pos.y, lara->pos.z);
|
glTranslatef(lara->pos.x, lara->pos.y, lara->pos.z);
|
||||||
Texture::unbind(sShadow);
|
Texture::unbind(sShadow);
|
||||||
shadow->bind(sDiffuse);
|
ambient[0]->bind(sDiffuse);
|
||||||
glEnable(GL_TEXTURE_2D);
|
glEnable(GL_TEXTURE_2D);
|
||||||
glDisable(GL_CULL_FACE);
|
glDisable(GL_CULL_FACE);
|
||||||
glBegin(GL_QUADS);
|
glBegin(GL_QUADS);
|
||||||
glTexCoord2f(0, 0); glVertex3f( 0, 0, 0);
|
glTexCoord2f(1, 1); glVertex3f( 0, 0, 0);
|
||||||
glTexCoord2f(1, 0); glVertex3f(1024, 0, 0);
|
glTexCoord2f(0, 1); glVertex3f(1024, 0, 0);
|
||||||
glTexCoord2f(1, 1); glVertex3f(1024, -1024, 0);
|
glTexCoord2f(0, 0); glVertex3f(1024, -1024, 0);
|
||||||
glTexCoord2f(0, 1); glVertex3f( 0, -1024, 0);
|
glTexCoord2f(1, 0); glVertex3f( 0, -1024, 0);
|
||||||
glEnd();
|
glEnd();
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
glDisable(GL_CULL_FACE);
|
glDisable(GL_CULL_FACE);
|
||||||
glDisable(GL_TEXTURE_2D);
|
glDisable(GL_TEXTURE_2D);
|
||||||
*/
|
|
||||||
/*
|
/*
|
||||||
shaders[shGUI]->bind();
|
shaders[shGUI]->bind();
|
||||||
Core::mViewProj = mat4(0, (float)Core::width, (float)Core::height, 0, 0, 1);
|
Core::mViewProj = mat4(0, (float)Core::width, (float)Core::height, 0, 0, 1);
|
||||||
|
127
src/shader.glsl
127
src/shader.glsl
@@ -2,12 +2,14 @@ R"====(
|
|||||||
varying vec2 vTexCoord;
|
varying vec2 vTexCoord;
|
||||||
|
|
||||||
#ifndef PASS_SHADOW
|
#ifndef PASS_SHADOW
|
||||||
varying vec3 vCoord;
|
#ifndef PASS_AMBIENT
|
||||||
varying vec4 vNormal;
|
varying vec3 vCoord;
|
||||||
varying vec3 vViewVec;
|
varying vec4 vNormal;
|
||||||
|
varying vec3 vViewVec;
|
||||||
|
varying vec4 vLightProj;
|
||||||
|
varying float vLightTargetDist;
|
||||||
|
#endif
|
||||||
varying vec4 vColor;
|
varying vec4 vColor;
|
||||||
varying vec4 vLightProj;
|
|
||||||
varying float vLightTargetDist;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define TYPE_SPRITE 0
|
#define TYPE_SPRITE 0
|
||||||
@@ -16,26 +18,34 @@ varying vec2 vTexCoord;
|
|||||||
#define TYPE_FLASH 3
|
#define TYPE_FLASH 3
|
||||||
|
|
||||||
uniform int uType;
|
uniform int uType;
|
||||||
uniform int uCaustics;
|
|
||||||
uniform float uTime;
|
#ifdef PASS_COMPOSE
|
||||||
|
uniform int uCaustics;
|
||||||
|
uniform float uTime;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef VERTEX
|
#ifdef VERTEX
|
||||||
uniform mat4 uViewProj;
|
uniform mat4 uViewProj;
|
||||||
uniform mat4 uModel;
|
uniform mat4 uModel;
|
||||||
uniform mat4 uViewInv;
|
|
||||||
uniform mat4 uLightProj;
|
|
||||||
uniform vec3 uLightTarget;
|
|
||||||
|
|
||||||
#ifndef PASS_SHADOW
|
#ifndef PASS_AMBIENT
|
||||||
|
uniform mat4 uViewInv;
|
||||||
|
uniform mat4 uLightProj;
|
||||||
|
uniform vec3 uLightTarget;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef PASS_COMPOSE
|
||||||
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];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
attribute vec4 aCoord;
|
attribute vec4 aCoord;
|
||||||
attribute vec4 aTexCoord;
|
attribute vec4 aTexCoord;
|
||||||
attribute vec4 aNormal;
|
|
||||||
|
#ifndef PASS_AMBIENT
|
||||||
|
attribute vec4 aNormal;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef PASS_SHADOW
|
#ifndef PASS_SHADOW
|
||||||
attribute vec4 aColor;
|
attribute vec4 aColor;
|
||||||
@@ -45,32 +55,31 @@ uniform float uTime;
|
|||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec4 coord = uModel * vec4(aCoord.xyz, 1.0);
|
vec4 coord = uModel * vec4(aCoord.xyz, 1.0);
|
||||||
|
|
||||||
|
|
||||||
if (uType != TYPE_SPRITE) {
|
#ifdef PASS_COMPOSE
|
||||||
#ifndef PASS_SHADOW
|
if (uType != TYPE_SPRITE) {
|
||||||
// animated texture coordinates
|
// animated texture coordinates
|
||||||
vec2 range = uAnimTexRanges[int(aTexCoord.z)]; // x - start index, y - count
|
vec2 range = uAnimTexRanges[int(aTexCoord.z)]; // x - start index, y - count
|
||||||
|
|
||||||
float f = fract((aTexCoord.w + uTime * 4.0 - range.x) / range.y) * range.y;
|
float f = fract((aTexCoord.w + uTime * 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 = (aTexCoord.xy + offset) * TEXCOORD_SCALE; // first frame + offset * isAnimated
|
||||||
vNormal = vec4((uModel * vec4(aNormal.xyz, 0.0)).xyz, aNormal.w);
|
vNormal = vec4((uModel * vec4(aNormal.xyz, 0.0)).xyz, aNormal.w);
|
||||||
#else
|
} else {
|
||||||
vTexCoord = aTexCoord.xy * TEXCOORD_SCALE;
|
coord.xyz += uViewInv[0].xyz * aTexCoord.z - uViewInv[1].xyz * aTexCoord.w;
|
||||||
#endif
|
vTexCoord = aTexCoord.xy * TEXCOORD_SCALE;
|
||||||
} else {
|
vNormal = vec4(uViewPos.xyz - coord.xyz, 0.0);
|
||||||
coord.xyz += uViewInv[0].xyz * aTexCoord.z - uViewInv[1].xyz * aTexCoord.w;
|
}
|
||||||
#ifndef PASS_SHADOW
|
#else
|
||||||
vTexCoord = aTexCoord.xy * TEXCOORD_SCALE;
|
vTexCoord = aTexCoord.xy * TEXCOORD_SCALE;
|
||||||
vNormal = vec4(uViewPos.xyz - coord.xyz, 0.0);
|
#endif
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef PASS_SHADOW
|
#ifndef PASS_SHADOW
|
||||||
vColor = aColor;
|
vColor = aColor;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef PASS_COMPOSE
|
||||||
if (uCaustics != 0) {
|
if (uCaustics != 0) {
|
||||||
float sum = coord.x + coord.y + coord.z;
|
float sum = coord.x + coord.y + coord.z;
|
||||||
vColor.xyz *= abs(sin(sum / 512.0 + uTime)) * 1.5 + 0.5; // color dodge
|
vColor.xyz *= abs(sin(sum / 512.0 + uTime)) * 1.5 + 0.5; // color dodge
|
||||||
@@ -91,7 +100,7 @@ uniform float uTime;
|
|||||||
#else
|
#else
|
||||||
uniform sampler2D sDiffuse;
|
uniform sampler2D sDiffuse;
|
||||||
uniform vec4 uColor;
|
uniform vec4 uColor;
|
||||||
#ifndef PASS_SHADOW
|
#ifdef PASS_COMPOSE
|
||||||
uniform vec3 uLightPos[MAX_LIGHTS];
|
uniform vec3 uLightPos[MAX_LIGHTS];
|
||||||
uniform vec4 uLightColor[MAX_LIGHTS];
|
uniform vec4 uLightColor[MAX_LIGHTS];
|
||||||
#endif
|
#endif
|
||||||
@@ -106,7 +115,9 @@ uniform float uTime;
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#else
|
#endif
|
||||||
|
|
||||||
|
#ifdef PASS_COMPOSE
|
||||||
#ifdef AMBIENT_CUBE
|
#ifdef AMBIENT_CUBE
|
||||||
uniform vec3 uAmbientCube[6];
|
uniform vec3 uAmbientCube[6];
|
||||||
|
|
||||||
@@ -180,7 +191,7 @@ uniform float uTime;
|
|||||||
poissonDisk[13] = vec2( -0.81409955, 0.91437590 );
|
poissonDisk[13] = vec2( -0.81409955, 0.91437590 );
|
||||||
poissonDisk[14] = vec2( 0.19984126, 0.78641367 );
|
poissonDisk[14] = vec2( 0.19984126, 0.78641367 );
|
||||||
poissonDisk[15] = vec2( 0.14383161, -0.14100790 );
|
poissonDisk[15] = vec2( 0.14383161, -0.14100790 );
|
||||||
//return SHADOW(p);
|
|
||||||
float rShadow = 0.0;
|
float rShadow = 0.0;
|
||||||
for (int i = 0; i < 16; i += 1)
|
for (int i = 0; i < 16; i += 1)
|
||||||
rShadow += SHADOW(p + vec3(poissonDisk[i] * 1.5, 0.0) * (1.0 / 1024.0));
|
rShadow += SHADOW(p + vec3(poissonDisk[i] * 1.5, 0.0) * (1.0 / 1024.0));
|
||||||
@@ -215,34 +226,38 @@ uniform float uTime;
|
|||||||
|
|
||||||
color.xyz = pow(abs(color.xyz), vec3(2.2)); // to linear space
|
color.xyz = pow(abs(color.xyz), vec3(2.2)); // to linear space
|
||||||
|
|
||||||
// calc point lights
|
#ifdef PASS_AMBIENT
|
||||||
if (uType != TYPE_FLASH) {
|
color.xyz *= vColor.w;
|
||||||
vec3 normal = normalize(vNormal.xyz);
|
#else
|
||||||
vec3 viewVec = normalize(vViewVec);
|
// calc point lights
|
||||||
vec3 light = vec3(0.0);
|
if (uType != TYPE_FLASH) {
|
||||||
|
vec3 normal = normalize(vNormal.xyz);
|
||||||
|
vec3 viewVec = normalize(vViewVec);
|
||||||
|
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]);
|
||||||
|
|
||||||
// apply lighting
|
// apply lighting
|
||||||
if (uType == TYPE_SPRITE) {
|
if (uType == TYPE_SPRITE) {
|
||||||
light += vColor.w * uColor.w;
|
light += vColor.w * uColor.w;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uType == TYPE_ROOM) {
|
||||||
|
light += mix(min(uColor.w, vColor.w), vColor.w, getShadow(vLightProj));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uType == TYPE_ENTITY) {
|
||||||
|
float shadow = getShadow(vLightProj);
|
||||||
|
vec3 lum = calcLight(normal, uLightPos[0], uLightColor[0]) * shadow + uColor.w;
|
||||||
|
light += lum;
|
||||||
|
light *= dot(normal, viewVec) * 0.2 + 0.8; // apply backlight
|
||||||
|
}
|
||||||
|
color.xyz *= light;
|
||||||
|
} else {
|
||||||
|
color.w = uColor.w;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
if (uType == TYPE_ROOM) {
|
|
||||||
light += mix(min(uColor.w, vColor.w), vColor.w, getShadow(vLightProj));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (uType == TYPE_ENTITY) {
|
|
||||||
float shadow = getShadow(vLightProj);
|
|
||||||
vec3 lum = calcLight(normal, uLightPos[0], uLightColor[0]) * shadow + uColor.w;
|
|
||||||
light += lum;
|
|
||||||
light *= dot(normal, viewVec) * 0.2 + 0.8; // apply backlight
|
|
||||||
}
|
|
||||||
color.xyz *= light;
|
|
||||||
} else {
|
|
||||||
color.w = uColor.w;
|
|
||||||
}
|
|
||||||
|
|
||||||
color.xyz = pow(abs(color.xyz), vec3(1.0/2.2)); // back to gamma space
|
color.xyz = pow(abs(color.xyz), vec3(1.0/2.2)); // back to gamma space
|
||||||
|
|
||||||
|
@@ -133,6 +133,7 @@ struct vec3 {
|
|||||||
float length2() const { return dot(*this); }
|
float length2() const { return dot(*this); }
|
||||||
float length() const { return sqrtf(length2()); }
|
float length() const { return sqrtf(length2()); }
|
||||||
vec3 normal() const { float s = length(); return s == 0.0f ? (*this) : (*this)*(1.0f/s); }
|
vec3 normal() const { float s = length(); return s == 0.0f ? (*this) : (*this)*(1.0f/s); }
|
||||||
|
vec3 axisXZ() const { return (fabsf(x) > fabsf(z)) ? vec3(sign(x), 0, 0) : vec3(0, 0, sign(z)); }
|
||||||
|
|
||||||
vec3 lerp(const vec3 &v, const float t) const {
|
vec3 lerp(const vec3 &v, const float t) const {
|
||||||
if (t <= 0.0f) return *this;
|
if (t <= 0.0f) return *this;
|
||||||
|
Reference in New Issue
Block a user