mirror of
https://github.com/XProger/OpenLara.git
synced 2025-08-20 03:41:33 +02:00
#23 water surface rendering (parallax-corrected cubemaps)
This commit is contained in:
@@ -111,7 +111,7 @@ struct Camera : Controller {
|
|||||||
if (Input::down[ikS]) v = v - d;
|
if (Input::down[ikS]) v = v - d;
|
||||||
if (Input::down[ikA]) v = v + d.cross(vec3(0, 1, 0));
|
if (Input::down[ikA]) v = v + d.cross(vec3(0, 1, 0));
|
||||||
if (Input::down[ikD]) v = v - d.cross(vec3(0, 1, 0));
|
if (Input::down[ikD]) v = v - d.cross(vec3(0, 1, 0));
|
||||||
pos = pos + v.normal() * (Core::deltaTime * 2048.0f * 10.0f);
|
pos = pos + v.normal() * (Core::deltaTime * 512.0 * 10.0f);
|
||||||
|
|
||||||
mViewInv.identity();
|
mViewInv.identity();
|
||||||
mViewInv.translate(pos);
|
mViewInv.translate(pos);
|
||||||
|
@@ -52,6 +52,7 @@ struct Controller {
|
|||||||
joints = m ? new Basis[m->mCount] : NULL;
|
joints = m ? new Basis[m->mCount] : NULL;
|
||||||
frameIndex = -1;
|
frameIndex = -1;
|
||||||
specular = 0.0f;
|
specular = 0.0f;
|
||||||
|
ambient[0] = ambient[1] = ambient[2] = ambient[3] = ambient[4] = ambient[5] = vec3(intensityf(getRoom().ambient));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~Controller() {
|
virtual ~Controller() {
|
||||||
@@ -338,7 +339,7 @@ struct Controller {
|
|||||||
case TR::Action::CLEAR :
|
case TR::Action::CLEAR :
|
||||||
case TR::Action::CAMERA_FLYBY :
|
case TR::Action::CAMERA_FLYBY :
|
||||||
case TR::Action::CUTSCENE :
|
case TR::Action::CUTSCENE :
|
||||||
LOG("! action is not implemented\n");
|
//LOG("! action is not implemented\n");
|
||||||
actionCommand = next;
|
actionCommand = next;
|
||||||
activateNext();
|
activateNext();
|
||||||
break;
|
break;
|
||||||
@@ -430,7 +431,7 @@ struct Controller {
|
|||||||
mat4 matrix;
|
mat4 matrix;
|
||||||
|
|
||||||
TR::Entity &e = getEntity();
|
TR::Entity &e = getEntity();
|
||||||
if (e.type < TR::Entity::CUT_1 || e.type > TR::Entity::CUT_3) { // TODO: move to ctor
|
if (e.type < TR::Entity::CUT_1 || e.type > TR::Entity::CUT_4) { // TODO: move to ctor
|
||||||
matrix.identity();
|
matrix.identity();
|
||||||
matrix.translate(pos);
|
matrix.translate(pos);
|
||||||
if (angle.y != 0.0f) matrix.rotateY(angle.y - (animation.flip ? PI * animation.delta : 0.0f));
|
if (angle.y != 0.0f) matrix.rotateY(angle.y - (animation.flip ? PI * animation.delta : 0.0f));
|
||||||
|
24
src/core.h
24
src/core.h
@@ -142,7 +142,7 @@ namespace Core {
|
|||||||
vec4 lightColor[MAX_LIGHTS];
|
vec4 lightColor[MAX_LIGHTS];
|
||||||
vec4 color;
|
vec4 color;
|
||||||
|
|
||||||
enum Pass { passCompose, passShadow, passAmbient, passFilter } pass;
|
enum Pass { passCompose, passShadow, passAmbient, passFilter, passWater } pass;
|
||||||
|
|
||||||
GLuint FBO;
|
GLuint FBO;
|
||||||
GLuint renderBuffers[2][MAX_RENDER_BUFFERS];
|
GLuint renderBuffers[2][MAX_RENDER_BUFFERS];
|
||||||
@@ -162,6 +162,8 @@ namespace Core {
|
|||||||
bool depthTexture;
|
bool depthTexture;
|
||||||
bool shadowSampler;
|
bool shadowSampler;
|
||||||
bool VAO;
|
bool VAO;
|
||||||
|
bool texFloat, texFloatLinear;
|
||||||
|
bool texHalf, texHalfLinear;
|
||||||
} support;
|
} support;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -232,9 +234,13 @@ namespace Core {
|
|||||||
#endif
|
#endif
|
||||||
char *ext = (char*)glGetString(GL_EXTENSIONS);
|
char *ext = (char*)glGetString(GL_EXTENSIONS);
|
||||||
//LOG("%s\n", ext);
|
//LOG("%s\n", ext);
|
||||||
support.depthTexture = extSupport(ext, "_depth_texture");
|
support.depthTexture = extSupport(ext, "_depth_texture");
|
||||||
support.shadowSampler = extSupport(ext, "EXT_shadow_samplers") || extSupport(ext, "GL_ARB_shadow");
|
support.shadowSampler = extSupport(ext, "EXT_shadow_samplers") || extSupport(ext, "GL_ARB_shadow");
|
||||||
support.VAO = extSupport(ext, "_vertex_array_object");
|
support.VAO = extSupport(ext, "_vertex_array_object");
|
||||||
|
support.texFloatLinear = extSupport(ext, "GL_ARB_texture_float") || extSupport(ext, "_texture_float_linear");
|
||||||
|
support.texFloat = support.texFloatLinear || extSupport(ext, "_texture_float");
|
||||||
|
support.texHalfLinear = extSupport(ext, "GL_ARB_texture_float") || extSupport(ext, "_texture_half_float_linear");
|
||||||
|
support.texHalf = support.texHalfLinear || extSupport(ext, "_texture_half_float");
|
||||||
|
|
||||||
char *vendor = (char*)glGetString(GL_VENDOR);
|
char *vendor = (char*)glGetString(GL_VENDOR);
|
||||||
LOG("Vendor : %s\n", vendor);
|
LOG("Vendor : %s\n", vendor);
|
||||||
@@ -245,6 +251,9 @@ namespace Core {
|
|||||||
LOG(" depth texture : %s\n", support.depthTexture ? "true" : "false");
|
LOG(" depth texture : %s\n", support.depthTexture ? "true" : "false");
|
||||||
LOG(" shadow sampler : %s\n", support.shadowSampler ? "true" : "false");
|
LOG(" shadow sampler : %s\n", support.shadowSampler ? "true" : "false");
|
||||||
LOG(" vertex arrays : %s\n", support.VAO ? "true" : "false");
|
LOG(" vertex arrays : %s\n", support.VAO ? "true" : "false");
|
||||||
|
LOG(" float textures : float = %s, half = %s\n",
|
||||||
|
support.texFloat ? (support.texFloatLinear ? "linear" : "nearest") : "false",
|
||||||
|
support.texHalf ? (support.texHalfLinear ? "linear" : "nearest") : "false");
|
||||||
LOG("\n");
|
LOG("\n");
|
||||||
|
|
||||||
glGenFramebuffers(1, &FBO);
|
glGenFramebuffers(1, &FBO);
|
||||||
@@ -339,10 +348,11 @@ namespace Core {
|
|||||||
|
|
||||||
ASSERT(target->width == (1 << dummyBuffer) )
|
ASSERT(target->width == (1 << dummyBuffer) )
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
|
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
|
||||||
glFramebufferTexture2D (GL_FRAMEBUFFER, target->depth ? GL_DEPTH_ATTACHMENT : GL_COLOR_ATTACHMENT0, texTarget, target->ID, 0);
|
bool depth = target->format == Texture::DEPTH || target->format == Texture::SHADOW;
|
||||||
glFramebufferRenderbuffer (GL_FRAMEBUFFER, target->depth ? GL_COLOR_ATTACHMENT0 : GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderBuffers[target->depth][dummyBuffer]);
|
glFramebufferTexture2D (GL_FRAMEBUFFER, depth ? GL_DEPTH_ATTACHMENT : GL_COLOR_ATTACHMENT0, texTarget, target->ID, 0);
|
||||||
|
glFramebufferRenderbuffer (GL_FRAMEBUFFER, depth ? GL_COLOR_ATTACHMENT0 : GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderBuffers[depth][dummyBuffer]);
|
||||||
|
|
||||||
if (target->depth)
|
if (depth)
|
||||||
glColorMask(false, false, false, false);
|
glColorMask(false, false, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
R"====(
|
R"====(
|
||||||
varying vec2 vTexCoord;
|
varying vec2 vTexCoord;
|
||||||
|
|
||||||
#define TYPE_DOWNSAMPLE 10
|
#define FILTER_DOWNSAMPLE 0
|
||||||
|
|
||||||
uniform int uType;
|
uniform int uType;
|
||||||
|
|
||||||
@@ -9,16 +9,16 @@ uniform int uType;
|
|||||||
attribute vec4 aCoord;
|
attribute vec4 aCoord;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vTexCoord = aCoord.zw;
|
vTexCoord = aCoord.zw;
|
||||||
gl_Position = vec4(aCoord.xy, 0.0, 1.0);
|
gl_Position = vec4(aCoord.xy, 0.0, 1.0);
|
||||||
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
uniform sampler2D sDiffuse;
|
uniform sampler2D sDiffuse;
|
||||||
|
uniform vec4 uParam; // texture size
|
||||||
uniform float uTime; // texture size
|
|
||||||
|
|
||||||
vec4 downsample() {
|
vec4 downsample() {
|
||||||
float k = 1.0 / uTime;
|
float k = 1.0 / uParam.x;
|
||||||
|
|
||||||
vec4 color = vec4(0.0);
|
vec4 color = vec4(0.0);
|
||||||
for (float y = -1.5; y < 2.0; y++)
|
for (float y = -1.5; y < 2.0; y++)
|
||||||
@@ -34,9 +34,7 @@ uniform int uType;
|
|||||||
}
|
}
|
||||||
|
|
||||||
vec4 filter() {
|
vec4 filter() {
|
||||||
if (uType == TYPE_DOWNSAMPLE) {
|
if (uType == FILTER_DOWNSAMPLE) return downsample();
|
||||||
return downsample();
|
|
||||||
}
|
|
||||||
return vec4(1.0, 0.0, 0.0, 1.0);
|
return vec4(1.0, 0.0, 0.0, 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -415,6 +415,7 @@ namespace TR {
|
|||||||
CUT_1 = 77,
|
CUT_1 = 77,
|
||||||
CUT_2 = 78,
|
CUT_2 = 78,
|
||||||
CUT_3 = 79,
|
CUT_3 = 79,
|
||||||
|
CUT_4 = 79,
|
||||||
|
|
||||||
CRYSTAL = 83, // sprite
|
CRYSTAL = 83, // sprite
|
||||||
WEAPON_PISTOLS = 84, // sprite
|
WEAPON_PISTOLS = 84, // sprite
|
||||||
@@ -1228,10 +1229,15 @@ namespace TR {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define RECALC_ZERO_NORMALS(mesh, face, count)\
|
#define RECALC_ZERO_NORMALS(mesh, face, count)\
|
||||||
|
int fn = -1;\
|
||||||
for (int j = 0; j < count; j++) {\
|
for (int j = 0; j < count; j++) {\
|
||||||
Mesh::Vertex &v = mesh.vertices[face.vertices[j]];\
|
Mesh::Vertex &v = mesh.vertices[face.vertices[j]];\
|
||||||
short4 &n = v.normal;\
|
short4 &n = v.normal;\
|
||||||
if (!(n.x | n.y | n.z)) {\
|
if (!(n.x | n.y | n.z)) {\
|
||||||
|
if (fn > -1) {\
|
||||||
|
n = mesh.vertices[face.vertices[fn]].normal;\
|
||||||
|
continue;\
|
||||||
|
}\
|
||||||
vec3 o(mesh.vertices[face.vertices[0]].coord);\
|
vec3 o(mesh.vertices[face.vertices[0]].coord);\
|
||||||
vec3 a = o - mesh.vertices[face.vertices[1]].coord;\
|
vec3 a = o - mesh.vertices[face.vertices[1]].coord;\
|
||||||
vec3 b = o - mesh.vertices[face.vertices[2]].coord;\
|
vec3 b = o - mesh.vertices[face.vertices[2]].coord;\
|
||||||
@@ -1239,6 +1245,7 @@ namespace TR {
|
|||||||
n.x = (int)o.x;\
|
n.x = (int)o.x;\
|
||||||
n.y = (int)o.y;\
|
n.y = (int)o.y;\
|
||||||
n.z = (int)o.z;\
|
n.z = (int)o.z;\
|
||||||
|
fn = j;\
|
||||||
}\
|
}\
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -236,7 +236,14 @@ struct Lara : Character {
|
|||||||
pos = vec3(43182, 2473, 51556);
|
pos = vec3(43182, 2473, 51556);
|
||||||
angle = vec3(0.0f, PI * 0.5f, 0.0f);
|
angle = vec3(0.0f, PI * 0.5f, 0.0f);
|
||||||
getEntity().room = 12;
|
getEntity().room = 12;
|
||||||
|
*/
|
||||||
|
// gym (pool)
|
||||||
|
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);
|
||||||
|
/*
|
||||||
// level 2 (pool)
|
// level 2 (pool)
|
||||||
pos = vec3(70067, -256, 29104);
|
pos = vec3(70067, -256, 29104);
|
||||||
angle = vec3(0.0f, -0.68f, 0.0f);
|
angle = vec3(0.0f, -0.68f, 0.0f);
|
||||||
|
170
src/level.h
170
src/level.h
@@ -21,22 +21,31 @@ const char FILTER[] =
|
|||||||
#include "filter.glsl"
|
#include "filter.glsl"
|
||||||
;
|
;
|
||||||
|
|
||||||
|
const char WATER[] =
|
||||||
|
#include "water.glsl"
|
||||||
|
;
|
||||||
|
|
||||||
const char GUI[] =
|
const char GUI[] =
|
||||||
#include "gui.glsl"
|
#include "gui.glsl"
|
||||||
;
|
;
|
||||||
|
|
||||||
struct Level {
|
struct Level {
|
||||||
enum { shCompose, shShadow, shAmbient, shFilter, shGUI, shMAX };
|
enum { shCompose, shShadow, shAmbient, shFilter, shWater, shGUI, shMAX };
|
||||||
|
|
||||||
TR::Level level;
|
TR::Level level;
|
||||||
Shader *shaders[shMAX];
|
Shader *shaders[shMAX];
|
||||||
Texture *atlas, *cube;
|
Texture *atlas;
|
||||||
MeshBuilder *mesh;
|
MeshBuilder *mesh;
|
||||||
|
|
||||||
Lara *lara;
|
Lara *lara;
|
||||||
Camera *camera;
|
Camera *camera;
|
||||||
Texture *shadow;
|
Texture *shadow;
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
Texture *water[2];
|
||||||
|
Texture *waterCube;
|
||||||
|
#endif
|
||||||
|
|
||||||
float time;
|
float time;
|
||||||
|
|
||||||
struct AmbientCache {
|
struct AmbientCache {
|
||||||
@@ -74,7 +83,7 @@ struct Level {
|
|||||||
// init downsample textures
|
// init downsample textures
|
||||||
for (int j = 0; j < 6; j++)
|
for (int j = 0; j < 6; j++)
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
textures[j * 4 + i] = new Texture(64 >> (i << 1), 64 >> (i << 1), false, false);
|
textures[j * 4 + i] = new Texture(64 >> (i << 1), 64 >> (i << 1), Texture::RGBA, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
~AmbientCache() {
|
~AmbientCache() {
|
||||||
@@ -111,12 +120,12 @@ struct Level {
|
|||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
// glDisable(GL_CULL_FACE);
|
// glDisable(GL_CULL_FACE);
|
||||||
level->setPassShader(Core::passFilter);
|
level->setPassShader(Core::passFilter);
|
||||||
Core::active.shader->setParam(uType, Shader::DOWNSAMPLE);
|
Core::active.shader->setParam(uType, Shader::FILTER_DOWNSAMPLE);
|
||||||
|
|
||||||
for (int i = 1; i < 4; i++) {
|
for (int i = 1; i < 4; i++) {
|
||||||
int size = 64 >> (i << 1);
|
int size = 64 >> (i << 1);
|
||||||
|
|
||||||
Core::active.shader->setParam(uTime, float(size << 2));
|
Core::active.shader->setParam(uParam, vec4(float(size << 2), 0.0f, 0.0f, 0.0f));
|
||||||
Core::setViewport(0, 0, size, size);
|
Core::setViewport(0, 0, size, size);
|
||||||
|
|
||||||
for (int j = 0; j < 6; j++) {
|
for (int j = 0; j < 6; j++) {
|
||||||
@@ -134,7 +143,7 @@ struct Level {
|
|||||||
|
|
||||||
TR::Color32 color;
|
TR::Color32 color;
|
||||||
glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &color);
|
glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &color);
|
||||||
colors[j] = vec3(color.r / 255.0f, color.g / 255.0f, color.b / 255.0f);
|
colors[j] = vec3(powf(color.r / 255.0f, 2.2f), powf(color.g / 255.0f, 2.2f), powf(color.b / 255.0f, 2.2f)); // to linear space
|
||||||
}
|
}
|
||||||
Core::setTarget(NULL);
|
Core::setTarget(NULL);
|
||||||
|
|
||||||
@@ -166,13 +175,10 @@ struct Level {
|
|||||||
|
|
||||||
int sector = sx * r.zSectors + sz;
|
int sector = sx * r.zSectors + sz;
|
||||||
Cube *a = getAmbient(room, sector);
|
Cube *a = getAmbient(room, sector);
|
||||||
if (a) {
|
if (a)
|
||||||
value = *a;
|
value = *a;
|
||||||
} else {
|
else
|
||||||
value.status = Cube::BLANK;
|
value.status = Cube::BLANK;
|
||||||
value.colors[0] = value.colors[1] = value.colors[2] =
|
|
||||||
value.colors[3] = value.colors[4] = value.colors[5] = vec3(intensityf(r.ambient));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} *ambientCache;
|
} *ambientCache;
|
||||||
|
|
||||||
@@ -222,8 +228,6 @@ struct Level {
|
|||||||
#endif
|
#endif
|
||||||
mesh = new MeshBuilder(level);
|
mesh = new MeshBuilder(level);
|
||||||
|
|
||||||
shadow = new Texture(1024, 1024, true, false);
|
|
||||||
|
|
||||||
initTextures();
|
initTextures();
|
||||||
initShaders();
|
initShaders();
|
||||||
initOverrides();
|
initOverrides();
|
||||||
@@ -341,15 +345,34 @@ struct Level {
|
|||||||
|
|
||||||
delete shadow;
|
delete shadow;
|
||||||
delete ambientCache;
|
delete ambientCache;
|
||||||
|
#ifdef _DEBUG
|
||||||
|
delete water[0];
|
||||||
|
delete water[1];
|
||||||
|
delete waterCube;
|
||||||
|
#endif
|
||||||
delete atlas;
|
delete atlas;
|
||||||
delete cube;
|
|
||||||
delete mesh;
|
delete mesh;
|
||||||
|
|
||||||
delete camera;
|
delete camera;
|
||||||
}
|
}
|
||||||
|
|
||||||
void initTextures() {
|
void initTextures() {
|
||||||
|
shadow = new Texture(1024, 1024, Texture::SHADOW, false);
|
||||||
|
|
||||||
|
float *ddd = NULL;//new float[4 * 256 * 256];
|
||||||
|
// memset(ddd, 0, sizeof(float) * 4 * 256 * 256);
|
||||||
|
// 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
|
||||||
|
water[0] = new Texture(256, 256, Texture::RGBA_FLOAT, false, ddd);
|
||||||
|
water[1] = new Texture(256, 256, Texture::RGBA_FLOAT, false, ddd);
|
||||||
|
#endif
|
||||||
|
delete[] ddd;
|
||||||
|
|
||||||
if (!level.tilesCount) {
|
if (!level.tilesCount) {
|
||||||
atlas = NULL;
|
atlas = NULL;
|
||||||
return;
|
return;
|
||||||
@@ -380,12 +403,9 @@ struct Level {
|
|||||||
fclose(f);
|
fclose(f);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
atlas = new Texture(1024, 1024, false, 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, false, true, &whitePix);
|
|
||||||
|
|
||||||
delete[] data;
|
delete[] data;
|
||||||
delete[] level.tiles;
|
delete[] level.tiles;
|
||||||
level.tiles = NULL;
|
level.tiles = NULL;
|
||||||
@@ -413,6 +433,7 @@ struct Level {
|
|||||||
sprintf(def, "%s#define PASS_AMBIENT\n", ext);
|
sprintf(def, "%s#define PASS_AMBIENT\n", ext);
|
||||||
shaders[shAmbient] = new Shader(SHADER, def);
|
shaders[shAmbient] = new Shader(SHADER, def);
|
||||||
shaders[shFilter] = new Shader(FILTER, "");
|
shaders[shFilter] = new Shader(FILTER, "");
|
||||||
|
shaders[shWater] = new Shader(WATER, "");
|
||||||
shaders[shGUI] = new Shader(GUI, "");
|
shaders[shGUI] = new Shader(GUI, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -462,6 +483,11 @@ 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
|
||||||
@@ -709,7 +735,6 @@ struct Level {
|
|||||||
camera->setup(Core::pass == Core::passCompose);
|
camera->setup(Core::pass == Core::passCompose);
|
||||||
|
|
||||||
atlas->bind(sDiffuse);
|
atlas->bind(sDiffuse);
|
||||||
cube->bind(sEnvironment); // dummy texture binding to prevent "there is no texture bound to the unit 2" warnings
|
|
||||||
|
|
||||||
if (!Core::support.VAO)
|
if (!Core::support.VAO)
|
||||||
mesh->bind();
|
mesh->bind();
|
||||||
@@ -721,7 +746,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(uTime, time);
|
sh->setParam(uParam, vec4(time, 0.0f, 0.0f, 0.0f));
|
||||||
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);
|
||||||
@@ -817,6 +842,7 @@ struct Level {
|
|||||||
case Core::passShadow : sh = shaders[shShadow]; break;
|
case Core::passShadow : sh = shaders[shShadow]; break;
|
||||||
case Core::passAmbient : sh = shaders[shAmbient]; break;
|
case Core::passAmbient : sh = shaders[shAmbient]; break;
|
||||||
case Core::passFilter : sh = shaders[shFilter]; break;
|
case Core::passFilter : sh = shaders[shFilter]; break;
|
||||||
|
case Core::passWater : sh = shaders[shWater]; break;
|
||||||
}
|
}
|
||||||
ASSERT(sh);
|
ASSERT(sh);
|
||||||
sh->bind();
|
sh->bind();
|
||||||
@@ -867,11 +893,86 @@ struct Level {
|
|||||||
Core::resetStates();
|
Core::resetStates();
|
||||||
|
|
||||||
ambientCache->precessQueue();
|
ambientCache->precessQueue();
|
||||||
//renderEnvironment(lara->getRoomIndex(), lara->pos - vec3(0, , ambientCache->textures, 4);
|
|
||||||
renderShadows(lara->getRoomIndex());
|
renderShadows(lara->getRoomIndex());
|
||||||
renderCompose(camera->getRoomIndex());
|
renderCompose(camera->getRoomIndex());
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
|
glDisable(GL_BLEND);
|
||||||
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
Core::setViewport(0, 0, water[0]->width, water[0]->height);
|
||||||
|
setPassShader(Core::passWater);
|
||||||
|
|
||||||
|
static vec3 lastPos = vec3(0.0);
|
||||||
|
bool flag = (lara->pos - lastPos).length() > 16.0f;
|
||||||
|
bool flag2 = lara->animation.frameIndex == 20;//isFrameActive(22) || lara->animation.isFrameActive(21);
|
||||||
|
|
||||||
|
if (Input::down[ikU] || flag || flag2) {
|
||||||
|
vec2 p(randf(), randf());
|
||||||
|
if (flag || flag2) {
|
||||||
|
vec3 c(40448, 0.0, 60928);
|
||||||
|
p.x = (lara->pos.x - c.x) / 5120.0f + 0.5;
|
||||||
|
p.y = (lara->pos.z - c.z) / 5120.0f + 0.5;
|
||||||
|
lastPos = lara->pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
water[0]->bind(sDiffuse);
|
||||||
|
Core::setTarget(water[1]);
|
||||||
|
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));
|
||||||
|
mesh->renderQuad();
|
||||||
|
swap(water[0], water[1]);
|
||||||
|
Input::down[ikU] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Core::active.shader->setParam(uParam, vec4(1.0f / water[0]->width, 1.0f / water[0]->height, Core::deltaTime * 4.0f, 0.0f));
|
||||||
|
|
||||||
|
water[0]->bind(sDiffuse);
|
||||||
|
Core::setTarget(water[1]);
|
||||||
|
Core::active.shader->setParam(uType, Shader::WATER_STEP);
|
||||||
|
mesh->renderQuad();
|
||||||
|
swap(water[0], water[1]);
|
||||||
|
|
||||||
|
water[0]->bind(sDiffuse);
|
||||||
|
Core::setTarget(water[1]);
|
||||||
|
Core::active.shader->setParam(uType, Shader::WATER_NORMAL);
|
||||||
|
mesh->renderQuad();
|
||||||
|
swap(water[0], water[1]);
|
||||||
|
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);
|
||||||
|
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
|
int dx, dz;
|
||||||
|
TR::Room::Sector &s = level.getSector(lara->getRoomIndex(), int(lara->pos.x), int(lara->pos.z), dx, dz);
|
||||||
|
if (s.roomAbove != 0xFF && level.rooms[s.roomAbove].lightsCount) {
|
||||||
|
TR::Room::Light &light = level.rooms[s.roomAbove].lights[0];
|
||||||
|
Core::lightPos[0] = vec3(float(light.x), float(light.y), float(light.z));
|
||||||
|
float lum = intensityf(light.intensity);
|
||||||
|
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(uViewProj, Core::mViewProj);
|
||||||
|
Core::active.shader->setParam(uViewPos, Core::viewPos);
|
||||||
|
Core::active.shader->setParam(uLightPos, Core::lightPos[0], 1);
|
||||||
|
Core::active.shader->setParam(uLightColor, Core::lightColor[0], 1);
|
||||||
|
|
||||||
|
water[0]->bind(sDiffuse);
|
||||||
|
waterCube->bind(sEnvironment);
|
||||||
|
|
||||||
|
mesh->renderQuad();
|
||||||
|
|
||||||
|
|
||||||
static int modelIndex = 0;
|
static int modelIndex = 0;
|
||||||
static bool lastStateK = false;
|
static bool lastStateK = false;
|
||||||
static int lastEntity = -1;
|
static int lastEntity = -1;
|
||||||
@@ -902,13 +1003,12 @@ struct Level {
|
|||||||
// 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);
|
||||||
|
/*
|
||||||
static int dbg_ambient = 0;
|
static int dbg_ambient = 0;
|
||||||
dbg_ambient = int(time * 2) % 4;
|
dbg_ambient = int(time * 2) % 4;
|
||||||
|
|
||||||
shadow->unbind(sShadow);
|
shadow->unbind(sShadow);
|
||||||
cube->unbind(sEnvironment);
|
|
||||||
atlas->bind(sDiffuse);
|
atlas->bind(sDiffuse);
|
||||||
glEnable(GL_TEXTURE_2D);
|
glEnable(GL_TEXTURE_2D);
|
||||||
glDisable(GL_CULL_FACE);
|
glDisable(GL_CULL_FACE);
|
||||||
@@ -938,6 +1038,7 @@ struct Level {
|
|||||||
|
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
glEnable(GL_CULL_FACE);
|
glEnable(GL_CULL_FACE);
|
||||||
glDisable(GL_TEXTURE_2D);
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
|
||||||
@@ -954,27 +1055,27 @@ struct Level {
|
|||||||
|
|
||||||
AmbientCache::Cube &cube = ambientCache->items[ambientCache->offsets[i] + j];
|
AmbientCache::Cube &cube = ambientCache->items[ambientCache->offsets[i] + j];
|
||||||
if (cube.status == AmbientCache::Cube::READY) {
|
if (cube.status == AmbientCache::Cube::READY) {
|
||||||
glColor3fv((GLfloat*)&cube.colors[0]);
|
glColor3f(powf(cube.colors[0].x, 1.0f / 2.2f), powf(cube.colors[0].y, 1.0f / 2.2f), powf(cube.colors[0].z, 1.0f / 2.2f));
|
||||||
glVertex3f(p.x + 0, p.y + 0, p.z + 0);
|
glVertex3f(p.x + 0, p.y + 0, p.z + 0);
|
||||||
glVertex3f(p.x + S, p.y + 0, p.z + 0);
|
glVertex3f(p.x + S, p.y + 0, p.z + 0);
|
||||||
|
|
||||||
glColor3fv((GLfloat*)&cube.colors[1]);
|
glColor3f(powf(cube.colors[1].x, 1.0f / 2.2f), powf(cube.colors[1].y, 1.0f / 2.2f), powf(cube.colors[1].z, 1.0f / 2.2f));
|
||||||
glVertex3f(p.x + 0, p.y + 0, p.z + 0);
|
glVertex3f(p.x + 0, p.y + 0, p.z + 0);
|
||||||
glVertex3f(p.x - S, p.y + 0, p.z + 0);
|
glVertex3f(p.x - S, p.y + 0, p.z + 0);
|
||||||
|
|
||||||
glColor3fv((GLfloat*)&cube.colors[2]);
|
glColor3f(powf(cube.colors[2].x, 1.0f / 2.2f), powf(cube.colors[2].y, 1.0f / 2.2f), powf(cube.colors[2].z, 1.0f / 2.2f));
|
||||||
glVertex3f(p.x + 0, p.y + 0, p.z + 0);
|
glVertex3f(p.x + 0, p.y + 0, p.z + 0);
|
||||||
glVertex3f(p.x + 0, p.y + S, p.z + 0);
|
glVertex3f(p.x + 0, p.y + S, p.z + 0);
|
||||||
|
|
||||||
glColor3fv((GLfloat*)&cube.colors[3]);
|
glColor3f(powf(cube.colors[3].x, 1.0f / 2.2f), powf(cube.colors[3].y, 1.0f / 2.2f), powf(cube.colors[3].z, 1.0f / 2.2f));
|
||||||
glVertex3f(p.x + 0, p.y + 0, p.z + 0);
|
glVertex3f(p.x + 0, p.y + 0, p.z + 0);
|
||||||
glVertex3f(p.x + 0, p.y - S, p.z + 0);
|
glVertex3f(p.x + 0, p.y - S, p.z + 0);
|
||||||
|
|
||||||
glColor3fv((GLfloat*)&cube.colors[4]);
|
glColor3f(powf(cube.colors[4].x, 1.0f / 2.2f), powf(cube.colors[4].y, 1.0f / 2.2f), powf(cube.colors[4].z, 1.0f / 2.2f));
|
||||||
glVertex3f(p.x + 0, p.y + 0, p.z + 0);
|
glVertex3f(p.x + 0, p.y + 0, p.z + 0);
|
||||||
glVertex3f(p.x + 0, p.y + 0, p.z + S);
|
glVertex3f(p.x + 0, p.y + 0, p.z + S);
|
||||||
|
|
||||||
glColor3fv((GLfloat*)&cube.colors[5]);
|
glColor3f(powf(cube.colors[5].x, 1.0f / 2.2f), powf(cube.colors[5].y, 1.0f / 2.2f), powf(cube.colors[5].z, 1.0f / 2.2f));
|
||||||
glVertex3f(p.x + 0, p.y + 0, p.z + 0);
|
glVertex3f(p.x + 0, p.y + 0, p.z + 0);
|
||||||
glVertex3f(p.x + 0, p.y + 0, p.z - S);
|
glVertex3f(p.x + 0, p.y + 0, p.z - S);
|
||||||
}
|
}
|
||||||
@@ -983,7 +1084,7 @@ struct Level {
|
|||||||
glEnd();
|
glEnd();
|
||||||
glLineWidth(1);
|
glLineWidth(1);
|
||||||
|
|
||||||
|
*/
|
||||||
/*
|
/*
|
||||||
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);
|
||||||
@@ -997,7 +1098,10 @@ struct Level {
|
|||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Debug::Level::info(level, lara->getEntity(), lara->animation);
|
|
||||||
|
//Debug::Level::info(level, lara->getEntity(), lara->animation);
|
||||||
|
|
||||||
|
|
||||||
Debug::end();
|
Debug::end();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@@ -120,7 +120,7 @@ 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 lum * lum; // gamma to linear space
|
return powf(lum, 2.2f); // gamma to linear space
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 intensity(int lighting) {
|
uint8 intensity(int lighting) {
|
||||||
|
@@ -214,6 +214,7 @@
|
|||||||
<None Include="..\..\filter.glsl" />
|
<None Include="..\..\filter.glsl" />
|
||||||
<None Include="..\..\gui.glsl" />
|
<None Include="..\..\gui.glsl" />
|
||||||
<None Include="..\..\shader.glsl" />
|
<None Include="..\..\shader.glsl" />
|
||||||
|
<None Include="..\..\water.glsl" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
@@ -20,8 +20,8 @@ varying vec2 vTexCoord;
|
|||||||
uniform int uType;
|
uniform int uType;
|
||||||
|
|
||||||
#ifdef PASS_COMPOSE
|
#ifdef PASS_COMPOSE
|
||||||
uniform int uCaustics;
|
uniform int uCaustics;
|
||||||
uniform float uTime;
|
uniform vec4 uParam;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef VERTEX
|
#ifdef VERTEX
|
||||||
@@ -72,7 +72,7 @@ uniform int uType;
|
|||||||
// 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 + 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 = (aTexCoord.xy + offset) * TEXCOORD_SCALE; // first frame + offset * isAnimated
|
||||||
@@ -93,7 +93,7 @@ uniform int uType;
|
|||||||
#ifdef PASS_COMPOSE
|
#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 + uParam.x)) * 1.5 + 0.5; // color dodge
|
||||||
}
|
}
|
||||||
|
|
||||||
vViewVec = uViewPos - coord.xyz;
|
vViewVec = uViewPos - coord.xyz;
|
||||||
@@ -285,7 +285,7 @@ uniform int uType;
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (uType == TYPE_ENTITY) {
|
if (uType == TYPE_ENTITY) {
|
||||||
vec3 rAmbient = pow(abs(calcAmbient(normal)), vec3(2.2));
|
vec3 rAmbient = calcAmbient(normal);
|
||||||
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);
|
||||||
@@ -298,6 +298,7 @@ uniform int uType;
|
|||||||
}
|
}
|
||||||
|
|
||||||
color.xyz *= light;
|
color.xyz *= light;
|
||||||
|
|
||||||
//color.xyz = normal * 0.5 + 0.5;
|
//color.xyz = normal * 0.5 + 0.5;
|
||||||
} else {
|
} else {
|
||||||
color.w = uColor.w;
|
color.w = uColor.w;
|
||||||
|
10
src/shader.h
10
src/shader.h
@@ -5,17 +5,21 @@
|
|||||||
|
|
||||||
enum AttribType { aCoord, aTexCoord, aNormal, aColor, aMAX };
|
enum AttribType { aCoord, aTexCoord, aNormal, aColor, aMAX };
|
||||||
enum SamplerType { sDiffuse, sShadow, sEnvironment, sMAX };
|
enum SamplerType { sDiffuse, sShadow, sEnvironment, sMAX };
|
||||||
enum UniformType { uType, uCaustics, uTime, 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, 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", "sShadow", "sEnvironment" };
|
||||||
const char *UniformName[uMAX] = { "uType", "uCaustics", "uTime", "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" };
|
||||||
|
|
||||||
struct Shader {
|
struct Shader {
|
||||||
GLuint ID;
|
GLuint ID;
|
||||||
GLint uID[uMAX];
|
GLint uID[uMAX];
|
||||||
|
|
||||||
enum : GLint { SPRITE = 0, FLASH = 1, ROOM = 2, ENTITY = 3, MIRROR = 4, DOWNSAMPLE = 10 };
|
enum : GLint {
|
||||||
|
/* shader */ SPRITE = 0, FLASH = 1, ROOM = 2, ENTITY = 3, MIRROR = 4,
|
||||||
|
/* filter */ FILTER_DOWNSAMPLE = 0,
|
||||||
|
/* water */ WATER_DROP = 0, WATER_STEP = 1, WATER_NORMAL = 2, WATER_TEST = 3
|
||||||
|
};
|
||||||
|
|
||||||
Shader(const char *text, const char *defines = "") {
|
Shader(const char *text, const char *defines = "") {
|
||||||
#ifdef MOBILE
|
#ifdef MOBILE
|
||||||
|
@@ -4,29 +4,52 @@
|
|||||||
#include "core.h"
|
#include "core.h"
|
||||||
|
|
||||||
struct Texture {
|
struct Texture {
|
||||||
|
enum Format : uint32 { RGBA, RGBA_FLOAT, RGBA_HALF, DEPTH, SHADOW, MAX };
|
||||||
|
|
||||||
GLuint ID;
|
GLuint ID;
|
||||||
int width, height;
|
int width, height;
|
||||||
bool depth;
|
Format format;
|
||||||
bool cube;
|
bool cube;
|
||||||
|
|
||||||
Texture(int width, int height, bool depth, bool cube, void *data = NULL) : width(width), height(height), cube(cube) {
|
Texture(int width, int height, Format format, bool cube, void *data = NULL) : width(width), height(height), cube(cube) {
|
||||||
glGenTextures(1, &ID);
|
glGenTextures(1, &ID);
|
||||||
bind(0);
|
bind(0);
|
||||||
|
|
||||||
bool filter = true;
|
bool filter = true;
|
||||||
if (depth && !Core::support.depthTexture)
|
|
||||||
depth = false;
|
|
||||||
this->depth = depth;
|
|
||||||
|
|
||||||
GLenum target = cube ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D;
|
GLenum target = cube ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D;
|
||||||
GLint format = depth ? GL_DEPTH_COMPONENT : GL_RGBA;
|
|
||||||
|
|
||||||
if (depth) {
|
if (format == SHADOW && !Core::support.shadowSampler) {
|
||||||
if (Core::support.shadowSampler) {
|
format = DEPTH;
|
||||||
glTexParameteri(target, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
|
filter = false;
|
||||||
glTexParameteri(target, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
|
}
|
||||||
} else
|
|
||||||
|
if (format == DEPTH) {
|
||||||
|
if (Core::support.depthTexture)
|
||||||
filter = false;
|
filter = false;
|
||||||
|
else
|
||||||
|
format = RGBA;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (format == RGBA_HALF) {
|
||||||
|
if (Core::support.texHalf)
|
||||||
|
filter = Core::support.texHalfLinear;
|
||||||
|
else
|
||||||
|
format = RGBA_FLOAT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (format == RGBA_FLOAT) {
|
||||||
|
if (Core::support.texFloat)
|
||||||
|
filter = Core::support.texFloatLinear;
|
||||||
|
else
|
||||||
|
format = RGBA;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->format = format;
|
||||||
|
|
||||||
|
if (format == SHADOW) {
|
||||||
|
glTexParameteri(target, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
|
||||||
|
glTexParameteri(target, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
@@ -34,8 +57,21 @@ struct Texture {
|
|||||||
glTexParameteri(target, GL_TEXTURE_MAG_FILTER, filter ? GL_LINEAR : GL_NEAREST);
|
glTexParameteri(target, GL_TEXTURE_MAG_FILTER, filter ? GL_LINEAR : GL_NEAREST);
|
||||||
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, filter ? GL_LINEAR : GL_NEAREST);
|
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, filter ? GL_LINEAR : GL_NEAREST);
|
||||||
|
|
||||||
|
struct FormatDesc {
|
||||||
|
GLuint ifmt, fmt;
|
||||||
|
GLenum type;
|
||||||
|
} formats[MAX] = {
|
||||||
|
{ GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE }, // RGBA
|
||||||
|
{ GL_RGBA32F, GL_RGBA, GL_FLOAT }, // RGBA_FLOAT
|
||||||
|
{ GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT }, // RGBA_HALF
|
||||||
|
{ GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT }, // DEPTH
|
||||||
|
{ GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT }, // SHADOW
|
||||||
|
};
|
||||||
|
|
||||||
|
FormatDesc &desc = formats[format];
|
||||||
|
|
||||||
for (int i = 0; i < 6; i++) {
|
for (int i = 0; i < 6; i++) {
|
||||||
glTexImage2D(cube ? (GL_TEXTURE_CUBE_MAP_POSITIVE_X + i) : GL_TEXTURE_2D, 0, format, width, height, 0, format, depth ? GL_UNSIGNED_SHORT : GL_UNSIGNED_BYTE, data);
|
glTexImage2D(cube ? (GL_TEXTURE_CUBE_MAP_POSITIVE_X + i) : GL_TEXTURE_2D, 0, desc.ifmt, width, height, 0, desc.fmt, desc.type, data);
|
||||||
if (!cube) break;
|
if (!cube) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -292,7 +292,7 @@ struct Crystal : Controller {
|
|||||||
Texture *environment;
|
Texture *environment;
|
||||||
|
|
||||||
Crystal(TR::Level *level, int entity) : Controller(level, entity) {
|
Crystal(TR::Level *level, int entity) : Controller(level, entity) {
|
||||||
environment = new Texture(64, 64, false, true);
|
environment = new Texture(64, 64, Texture::RGBA, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~Crystal() {
|
virtual ~Crystal() {
|
||||||
|
Reference in New Issue
Block a user