1
0
mirror of https://github.com/XProger/OpenLara.git synced 2025-01-17 21:09:00 +01:00

#12 flash lights

This commit is contained in:
XProger 2016-11-16 03:26:41 +03:00
parent 08dc561617
commit 0921c615e3
8 changed files with 170 additions and 101 deletions

Binary file not shown.

View File

@ -688,6 +688,7 @@ struct Controller {
Core::active.shader->setParam(uModel, m);
Core::active.shader->setParam(uColor, vec4(0.0f, 0.0f, 0.0f, 0.5f));
Core::active.shader->setParam(uAmbient, vec3(0.0f));
mesh->renderShadowSpot();
}

View File

@ -83,6 +83,8 @@
#endif
#endif
#define MAX_LIGHTS 3
struct Shader;
struct Texture;
@ -113,8 +115,8 @@ namespace Core {
float deltaTime;
mat4 mView, mProj, mViewProj, mViewInv, mModel;
vec3 viewPos;
vec3 lightPos;
vec4 lightColor;
vec3 lightPos[MAX_LIGHTS];
vec4 lightColor[MAX_LIGHTS];
vec3 ambient;
vec4 color;
@ -185,6 +187,9 @@ namespace Core {
support.VAO = (void*)glBindVertexArray != NULL;
Sound::init();
for (int i = 0; i < MAX_LIGHTS; i++)
lightColor[i] = vec4(0, 0, 0, 1);
}
void free() {

View File

@ -26,6 +26,7 @@
#define DESCENT_SPEED 2048.0f
#define MUZZLE_FLASH_TIME 0.1f
#define FLASH_LIGHT_COLOR vec4(0.8f, 0.7f, 0.3f, 2048 * 2048)
#define TARGET_MAX_DIST (8.0f * 1024.0f)
struct Lara : Controller {
@ -490,12 +491,15 @@ struct Lara : Controller {
for (int i = 0; i < count; i++) {
Arm *arm;
int armIndex;
if (wpnCurrent == Weapon::SHOTGUN) {
if (!rightHand) continue;
arm = &arms[0];
armIndex = 0;
} else {
if (!(i ? leftHand : rightHand)) continue;
arm = &arms[i];
armIndex = i;
}
arm->shotTimer = 0.0f;
@ -523,6 +527,9 @@ struct Lara : Controller {
nearDist = dist;
}
}
Core::lightPos[1 + armIndex] = getJoint(armIndex == 0 ? 10 : 13, false).getPos();
Core::lightColor[1 + armIndex] = FLASH_LIGHT_COLOR;
}
if (hasShot) {
@ -571,6 +578,9 @@ struct Lara : Controller {
for (int i = 0; i < 2; i++){
arms[i].animTime += Core::deltaTime * arms[i].animDir;
arms[i].shotTimer += Core::deltaTime;
float intensity = clamp((0.1f - arms[i].shotTimer) * 20.0f, 0.0f, 1.0f);
Core::lightColor[1 + i] = FLASH_LIGHT_COLOR * vec4(intensity, intensity, intensity, sqrtf(intensity));
}
if (isRifle)

View File

@ -172,11 +172,11 @@ struct Level {
void initShaders() {
char def[255], ext[255];
sprintf(def, "#define MAX_RANGES %d\n#define MAX_OFFSETS %d\n", mesh->animTexRangesCount, mesh->animTexOffsetsCount);
sprintf(def, "#define MAX_LIGHTS %d\n#define MAX_RANGES %d\n#define MAX_OFFSETS %d\n", MAX_LIGHTS, mesh->animTexRangesCount, mesh->animTexOffsetsCount);
shaders[shStatic] = new Shader(SHADER, def);
sprintf(ext, "%s#define CAUSTICS\n", def);
sprintf(ext, "#define MAX_LIGHTS %d\n%s#define CAUSTICS\n", MAX_LIGHTS, def);
shaders[shCaustics] = new Shader(SHADER, ext);
sprintf(ext, "%s#define SPRITE\n", def);
sprintf(ext, "#define MAX_LIGHTS %d\n%s#define SPRITE\n", MAX_LIGHTS, def);
shaders[shSprite] = new Shader(SHADER, ext);
}
@ -238,11 +238,12 @@ struct Level {
sh->bind();
sh->setParam(uColor, Core::color);
sh->setParam(uLightColor, Core::lightColor[0], MAX_LIGHTS);
sh->setParam(uLightPos, Core::lightPos[0], MAX_LIGHTS);
sh->setParam(uAmbient, vec3(0.0f));//Core::ambient);
// room static meshes
{
PROFILE_MARKER("R_MESH");
for (int i = 0; i < room.meshesCount; i++) {
TR::Room::Mesh &rMesh = room.meshes[i];
if (rMesh.flags.rendered) continue; // skip if already rendered
@ -261,11 +262,17 @@ struct Level {
// set light parameters
getLight(offset, roomIndex);
if (rMesh.intensity >= 0) {
Core::ambient = vec3(intensity(rMesh.intensity) / 255.0f);
Core::ambient = vec3(0.0);
sh->setParam(uAmbient, Core::ambient);
}
// render static mesh
mat4 mTemp = Core::mModel;
Core::mModel.translate(offset);
Core::mModel.rotateY(rMesh.rotation);
Core::active.shader->setParam(uModel, Core::mModel);
sh->setParam(uModel, Core::mModel);
mesh->renderMesh(mesh->meshMap[sMesh->mesh]);
Core::mModel = mTemp;
}
@ -275,30 +282,30 @@ struct Level {
if (!room.flags.rendered) { // skip if already rendered
mat4 mTemp = Core::mModel;
{
PROFILE_MARKER("R_GEOM");
room.flags.rendered = true;
room.flags.rendered = true;
Core::lightColor[0] = vec4(0, 0, 0, 1);
Core::ambient = vec3(0.0);
Core::lightColor = vec4(0.0f, 0.0f, 0.0f, 1.0f);
Core::ambient = vec3(1.0f);
sh->setParam(uLightColor, Core::lightColor);
sh->setParam(uAmbient, Core::ambient);
sh->setParam(uLightColor, Core::lightColor[0], MAX_LIGHTS);
sh->setParam(uLightPos, Core::lightPos[0], MAX_LIGHTS);
sh->setParam(uAmbient, Core::ambient);
Core::mModel.translate(offset);
Core::mModel.translate(offset);
// render room geometry
sh->setParam(uModel, Core::mModel);
mesh->renderRoomGeometry(roomIndex);
}
// render room geometry
sh->setParam(uModel, Core::mModel);
mesh->renderRoomGeometry(roomIndex);
// render room sprites
if (mesh->hasRoomSprites(roomIndex)) {
PROFILE_MARKER("R_SPR");
sh = shaders[shSprite];
sh->bind();
sh->setParam(uModel, Core::mModel);
sh->setParam(uColor, Core::color);
sh->setParam(uLightColor, Core::lightColor[0], MAX_LIGHTS);
sh->setParam(uLightPos, Core::lightPos[0], MAX_LIGHTS);
sh->setParam(uAmbient, vec3(0.0f));//Core::ambient);
mesh->renderRoomSprites(roomIndex);
}
@ -353,17 +360,17 @@ struct Level {
if (idx > -1) {
TR::Room::Light &light = level.rooms[room].lights[idx];
float c = level.rooms[room].lights[idx].intensity / 8191.0f;
Core::lightPos = vec3(light.x, light.y, light.z);
Core::lightColor = vec4(c, c, c, (float)light.attenuation * (float)light.attenuation);
Core::lightPos[0] = vec3(light.x, light.y, light.z);
Core::lightColor[0] = vec4(c, c, c, (float)light.attenuation * (float)light.attenuation);
} else {
Core::lightPos = vec3(0);
Core::lightColor = vec4(0, 0, 0, 1);
Core::lightPos[0] = vec3(0);
Core::lightColor[0] = vec4(0, 0, 0, 1);
}
Core::ambient = vec3(1.0f - level.rooms[roomIndex].ambient / 8191.0f);
Core::active.shader->setParam(uAmbient, Core::ambient);
Core::active.shader->setParam(uLightPos, Core::lightPos);
Core::active.shader->setParam(uLightColor, Core::lightColor);
Core::active.shader->setParam(uLightPos, Core::lightPos[0], MAX_LIGHTS);
Core::active.shader->setParam(uLightColor, Core::lightColor[0], MAX_LIGHTS);
}
void renderEntity(const TR::Entity &entity) {

View File

@ -106,6 +106,20 @@ struct Mesh {
n.z = (int)o.z;\
}\
#define CHECK_ROOM_NORMAL(n) \
vec3 o(d.vertices[f.vertices[0]].vertex);\
vec3 a = o - d.vertices[f.vertices[1]].vertex;\
vec3 b = o - d.vertices[f.vertices[2]].vertex;\
o = b.cross(a).normal() * 16300.0f;\
n.x = (int)o.x;\
n.y = (int)o.y;\
n.z = (int)o.z;
uint8 intensity(int lighting) {
float a = 1.0f - (lighting >> 5) / 255.0f;
return int(255 * a * a);
}
struct MeshBuilder {
// rooms
@ -252,13 +266,14 @@ struct MeshBuilder {
addQuad(indices, iCount, vCount, vStart, vertices, &t);
TR::Vertex n;
CHECK_ROOM_NORMAL(n);
for (int k = 0; k < 4; k++) {
TR::Room::Data::Vertex &v = d.vertices[f.vertices[k]];
uint8 a = 255 - (v.lighting >> 5);
vertices[vCount].coord = { v.vertex.x, v.vertex.y, v.vertex.z, 0 };
vertices[vCount].color = { a, a, a, 255 };
vertices[vCount].normal = { 0, 0, 0, 1 };
vertices[vCount].coord = { v.vertex.x, v.vertex.y, v.vertex.z, 0 };
vertices[vCount].color = { 255, 255, 255, intensity(v.lighting) };
vertices[vCount].normal = { n.x, n.y, n.z, 0 };
vCount++;
}
}
@ -269,13 +284,14 @@ struct MeshBuilder {
addTriangle(indices, iCount, vCount, vStart, vertices, &t);
TR::Vertex n;
CHECK_ROOM_NORMAL(n);
for (int k = 0; k < 3; k++) {
auto &v = d.vertices[f.vertices[k]];
uint8 a = 255 - (v.lighting >> 5);
vertices[vCount].coord = { v.vertex.x, v.vertex.y, v.vertex.z, 0 };
vertices[vCount].color = { a, a, a, 255 };
vertices[vCount].normal = { 0, 0, 0, 1 };
vertices[vCount].coord = { v.vertex.x, v.vertex.y, v.vertex.z, 0 };
vertices[vCount].color = { 255, 255, 255, intensity(v.lighting) };
vertices[vCount].normal = { n.x, n.y, n.z, 0 };
vCount++;
}
}
@ -288,8 +304,7 @@ struct MeshBuilder {
TR::Room::Data::Vertex &v = d.vertices[f.vertex];
TR::SpriteTexture &sprite = level.spriteTextures[f.texture];
uint8 intensity = 255 - (v.lighting >> 5);
addSprite(indices, vertices, iCount, vCount, vStart, v.vertex.x, v.vertex.y, v.vertex.z, sprite, intensity);
addSprite(indices, vertices, iCount, vCount, vStart, v.vertex.x, v.vertex.y, v.vertex.z, sprite, intensity(v.lighting));
}
}
@ -335,21 +350,26 @@ struct MeshBuilder {
addQuad(indices, iCount, vCount, vStart, vertices, &t);
short4 normal;
if (!normals) {
TR::Vertex n = { 0, 0, 0 };
CHECK_NORMAL(n);
normal = { n.x, n.y, n.z, 0 };
}
for (int k = 0; k < 4; k++) {
uint16 idx = f.vertices[k];
TR::Vertex &v = mVertices[idx];
TR::Vertex &v = mVertices[f.vertices[k]];
vertices[vCount].coord = { v.x, v.y, v.z, 0 };
if (normals) {
TR::Vertex &n = normals[idx];
TR::Vertex &n = normals[f.vertices[k]];
CHECK_NORMAL(n);
vertices[vCount].normal = { n.x, n.y, n.z, 0 };
vertices[vCount].color = { 255, 255, 255, 255 };
vertices[vCount].color = { 255, 255, 255, 0 };
} else {
uint8 a = 255 - (lights[idx] >> 5);
vertices[vCount].normal = { 0, 0, 0, 1 };
vertices[vCount].color = { a, a, a, 255 };
vertices[vCount].normal = normal;
vertices[vCount].color = { 255, 255, 255, intensity(lights[f.vertices[k]]) };
}
vCount++;
}
@ -363,19 +383,25 @@ struct MeshBuilder {
addTriangle(indices, iCount, vCount, vStart, vertices, &t);
short4 normal;
if (!normals) {
TR::Vertex n = { 0, 0, 0 };
CHECK_NORMAL(n);
normal = { n.x, n.y, n.z, 0 };
}
for (int k = 0; k < 3; k++) {
auto &v = mVertices[f.vertices[k]];
vertices[vCount].coord = { v.x, v.y, v.z, 0 };
vertices[vCount].coord = { v.x, v.y, v.z, 0 };
if (nCount > 0) {
if (normals) {
TR::Vertex &n = normals[f.vertices[k]];
CHECK_NORMAL(n);
vertices[vCount].normal = { n.x, n.y, n.z, 0 };
vertices[vCount].color = { 255, 255, 255, 255 };
vertices[vCount].color = { 255, 255, 255, 0 };
} else {
uint8 a = 255 - (lights[f.vertices[k]] >> 5);
vertices[vCount].normal = { 0, 0, 0, 1 };
vertices[vCount].color = { a, a, a, 255 };
vertices[vCount].normal = normal;
vertices[vCount].color = { 255, 255, 255, intensity(lights[f.vertices[k]]) };
}
vCount++;
}
@ -389,20 +415,26 @@ struct MeshBuilder {
addQuad(indices, iCount, vCount, vStart, vertices, &whiteTileQuad);
short4 normal;
if (!normals) {
TR::Vertex n = { 0, 0, 0 };
CHECK_NORMAL(n);
normal = { n.x, n.y, n.z, 0 };
}
for (int k = 0; k < 4; k++) {
auto &v = mVertices[f.vertices[k]];
vertices[vCount].coord = { v.x, v.y, v.z, 0 };
vertices[vCount].coord = { v.x, v.y, v.z, 0 };
if (nCount > 0) {
if (normals) {
TR::Vertex &n = normals[f.vertices[k]];
CHECK_NORMAL(n);
vertices[vCount].normal = { n.x, n.y, n.z, 0 };
vertices[vCount].color = { c.r, c.g, c.b, 255 };
vertices[vCount].color = { c.r, c.g, c.b, 0 };
} else {
uint8 a = 255 - (lights[f.vertices[k]] >> 5);
vertices[vCount].normal = { 0, 0, 0, 1 };
vertices[vCount].color = { a, a, a, 255 };
vertices[vCount].normal = normal;
vertices[vCount].color = { c.r, c.g, c.b, intensity(lights[f.vertices[k]]) };
}
vCount++;
}
@ -419,17 +451,23 @@ struct MeshBuilder {
for (int k = 0; k < 3; k++) {
auto &v = mVertices[f.vertices[k]];
vertices[vCount].coord = { v.x, v.y, v.z, 0 };
vertices[vCount].coord = { v.x, v.y, v.z, 0 };
if (nCount > 0) {
short4 normal;
if (!normals) {
TR::Vertex n = { 0, 0, 0 };
CHECK_NORMAL(n);
normal = { n.x, n.y, n.z, 0 };
}
if (normals) {
TR::Vertex &n = normals[f.vertices[k]];
CHECK_NORMAL(n);
vertices[vCount].normal = { n.x, n.y, n.z, 0 };
vertices[vCount].color = { c.r, c.g, c.b, 255 };
vertices[vCount].color = { c.r, c.g, c.b, 0 };
} else {
uint8 a = 255 - (lights[f.vertices[k]] >> 5);
vertices[vCount].normal = { 0, 0, 0, 1 };
vertices[vCount].color = { a, a, a, 255 };
vertices[vCount].normal = normal;
vertices[vCount].color = { c.r, c.g, c.b, intensity(lights[f.vertices[k]]) };
}
vCount++;
}
@ -450,8 +488,8 @@ struct MeshBuilder {
// build shadow spot
for (int i = 0; i < 8; i++) {
Vertex &v = vertices[vCount + i];
v.normal = { 0, 0, 0, 1 };
v.color = { 255, 255, 255, 255 };
v.normal = { 0, -1, 0, 0 };
v.color = { 255, 255, 255, 0 };
v.texCoord = { 32688, 32688, 0, 0 };
float a = i * (PI / 4.0f) + (PI / 8.0f);
@ -618,7 +656,7 @@ struct MeshBuilder {
quad[0].coord = quad[1].coord = quad[2].coord = quad[3].coord = { x, y, z, 0 };
quad[0].normal = quad[1].normal = quad[2].normal = quad[3].normal = { 0, 0, 0, 0 };
quad[0].color = quad[1].color = quad[2].color = quad[3].color = { intensity, intensity, intensity, 255 };
quad[0].color = quad[1].color = quad[2].color = quad[3].color = { 255, 255, 255, intensity };
int tx = (sprite.tile % 4) * 256;
int ty = (sprite.tile / 4) * 256;

View File

@ -1,9 +1,7 @@
R"====(
#ifndef SPRITE
varying vec4 vNormal;
varying vec3 vLightVec;
varying vec3 vViewVec;
#endif
varying vec4 vNormal;
varying vec3 vLightVec[MAX_LIGHTS];
varying vec3 vViewVec;
varying vec2 vTexCoord;
varying vec4 vColor;
@ -11,11 +9,10 @@ varying vec4 vColor;
uniform mat4 uViewProj;
uniform mat4 uModel;
uniform mat4 uViewInv;
uniform vec4 uColor;
uniform vec3 uLightPos[MAX_LIGHTS];
uniform vec3 uViewPos;
#ifndef SPRITE
uniform vec3 uViewPos;
uniform vec3 uLightPos;
#ifndef SPRITE
uniform vec2 uAnimTexRanges[MAX_RANGES];
uniform vec2 uAnimTexOffsets[MAX_OFFSETS];
#endif
@ -31,7 +28,7 @@ varying vec4 vColor;
void main() {
vec4 coord = uModel * vec4(aCoord.xyz, 1.0);
vColor = aColor * uColor;
vColor = aColor;
#ifdef CAUSTICS
float sum = coord.x + coord.y + coord.z;
@ -46,49 +43,59 @@ varying vec4 vColor;
vec2 offset = uAnimTexOffsets[int(range.x + f)]; // texCoord offset from first frame
vTexCoord = (aTexCoord.xy + offset) * TEXCOORD_SCALE; // first frame + offset * isAnimated
vViewVec = uViewPos - coord.xyz;
vLightVec = uLightPos - coord.xyz;
vNormal = uModel * aNormal;
#else
vTexCoord = aTexCoord.xy * TEXCOORD_SCALE;
coord.xyz -= uViewInv[0].xyz * aTexCoord.z + uViewInv[1].xyz * aTexCoord.w;
vNormal = vec4(uViewPos.xyz - coord.xyz, 0.0);
#endif
vViewVec = uViewPos - coord.xyz;
for (int i = 0; i < MAX_LIGHTS; i++)
vLightVec[i] = uLightPos[i] - coord.xyz;
gl_Position = uViewProj * coord;
}
#else
uniform sampler2D sDiffuse;
#ifndef SPRITE
uniform vec3 uAmbient;
uniform vec4 uLightColor;
#endif
uniform vec4 uColor;
uniform vec3 uAmbient;
uniform vec4 uLightColor[MAX_LIGHTS];
void main() {
vec4 color = texture2D(sDiffuse, vTexCoord);
if (color.w < 0.6)
discard;
color *= vColor;
#ifndef SPRITE
color.xyz = pow(abs(color.xyz), vec3(2.2));
vec3 normal = normalize(vNormal.xyz);
vec3 lightVec = normalize(vLightVec);
vec3 viewVec = normalize(vViewVec);
float lum = dot(normal, lightVec);
float att = max(0.0, 1.0 - dot(vLightVec, vLightVec) / uLightColor.w);
vec3 light = uLightColor.xyz * max(vNormal.w, lum * att) + uAmbient;
// apply backlight
light *= max(vNormal.w, dot(normal, viewVec) * 0.5 + 0.5);
color.xyz *= light;
color.xyz = pow(abs(color.xyz), vec3(1.0/2.2));
#endif
color *= uColor;
color.xyz *= vColor.xyz;
// fog
color.xyz = pow(abs(color.xyz), vec3(2.2)); // to linear space
// calc point lights
vec3 normal = normalize(vNormal.xyz);
vec3 viewVec = normalize(vViewVec);
vec3 light = uAmbient;
for (int i = 0; i < MAX_LIGHTS; i++) {
vec3 lv = vLightVec[i];
vec4 lc = uLightColor[i];
float lum = max(0.0, dot(normal, normalize(lv)));
float att = max(0.0, 1.0 - dot(lv, lv) / lc.w);
light += lc.xyz * (lum * att);
}
// calc backlight
light *= dot(normal, viewVec) * 0.5 + 0.5;
// apply lighting
color.xyz *= vColor.w + light;
color.xyz = pow(abs(color.xyz), vec3(1.0/2.2)); // back to gamma space
// apply fog
float fog = clamp(1.0 / exp(gl_FragCoord.z / gl_FragCoord.w * 0.000025), 0.0, 1.0);
color = mix(vec4(0.0, 0.0, 0.0, 1.0), color, fog);
gl_FragColor = mix(vec4(0.0, 0.0, 0.0, 1.0), color, fog);
gl_FragColor = color;
}
#endif
)===="

View File

@ -158,6 +158,7 @@ struct vec4 {
vec4(float x, float y, float z, float w) : x(x), y(y), z(z), w(w) {}
vec4(const vec3 &xyz, float w) : x(xyz.x), y(xyz.y), z(xyz.z), w(w) {}
vec4 operator * (const vec4 &v) const { return vec4(x*v.x, y*v.y, z*v.z, w*v.w); }
vec4& operator *= (const vec4 &v) { x*=v.x; y*=v.y; z*=v.z; w*=v.w; return *this; }
};