From c187fe5fe0c6811edc303e562d4d067a7a4f6720 Mon Sep 17 00:00:00 2001 From: XProger Date: Wed, 11 Jan 2017 11:41:35 +0300 Subject: [PATCH] #23 test planar water refraction, reflection and caustics --- src/camera.h | 10 ++- src/core.h | 8 ++ src/lara.h | 17 +++-- src/level.h | 197 +++++++++++++++++++++++++++++++++++++----------- src/mesh.h | 3 +- src/shader.glsl | 42 ++++++++--- src/shader.h | 14 ++-- src/texture.h | 3 +- src/utils.h | 13 ++++ 9 files changed, 234 insertions(+), 73 deletions(-) diff --git a/src/camera.h b/src/camera.h index 8e63a55..a79d282 100644 --- a/src/camera.h +++ b/src/camera.h @@ -21,7 +21,9 @@ struct Camera : Controller { int actTargetEntity, actCamera; 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; znear = 16; zfar = 32.0f * 1024.0f; @@ -205,7 +207,11 @@ struct Camera : Controller { virtual void setup(bool calcMatrices) { if (calcMatrices) { - Core::mViewInv = mViewInv; + if (reflectPlane) + Core::mViewInv = mat4(*reflectPlane) * mViewInv; + else + Core::mViewInv = mViewInv; + Core::mView = Core::mViewInv.inverse(); Core::mProj = mat4(fov, (float)Core::width / (float)Core::height, znear, zfar); // TODO: camera shake diff --git a/src/core.h b/src/core.h index 0c3cb15..c6ad76a 100644 --- a/src/core.h +++ b/src/core.h @@ -32,6 +32,14 @@ #include #include #include + + #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 #include "utils.h" diff --git a/src/lara.h b/src/lara.h index 53b2737..a60743f 100644 --- a/src/lara.h +++ b/src/lara.h @@ -229,7 +229,14 @@ struct Lara : Character { arms[i].rot = 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 /* // gym @@ -242,7 +249,7 @@ struct Lara : Character { angle = vec3(0.0f, PI * 0.5f, 0.0f); getEntity().room = 14; stand = STAND_ONWATER; - animation.setAnim(ANIM_TO_ONWATER); + animation.setAnim(ANIM_TO_ONWATER); /* // level 2 (pool) pos = vec3(70067, -256, 29104); @@ -930,9 +937,9 @@ struct Lara : Character { 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 - alignToWall(); - dst.y -= pos.y - infoDst.floor; - pos = dst; // set new position + alignToWall(-96.0f); + pos.y = infoDst.floor; + //pos = dst; // set new position specular = LARA_WET_SPECULAR; diff --git a/src/level.h b/src/level.h index f1c6282..502a155 100644 --- a/src/level.h +++ b/src/level.h @@ -35,18 +35,22 @@ struct Level { TR::Level level; Shader *shaders[shMAX]; Texture *atlas; + Texture *cube; MeshBuilder *mesh; Lara *lara; Camera *camera; Texture *shadow; -#ifdef _DEBUG Texture *water[2]; - Texture *waterCube; -#endif - float time; + Texture *waterRefract; + Texture *waterReflect; + Texture *waterCaustics; + + float time; + float clipHeight; + float clipSign; struct AmbientCache { Level *level; @@ -345,12 +349,16 @@ struct Level { delete shadow; delete ambientCache; -#ifdef _DEBUG + delete water[0]; delete water[1]; - delete waterCube; -#endif + + delete waterRefract; + delete waterReflect; + delete waterCaustics; + delete atlas; + delete cube; delete mesh; delete camera; @@ -359,19 +367,12 @@ struct Level { 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; + water[0] = new Texture(256, 256, Texture::RGBA_HALF, false); + water[1] = new Texture(256, 256, Texture::RGBA_HALF, false); - #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; + waterRefract = new Texture(1024, 1024, Texture::RGBA, false); + waterReflect = new Texture(1024, 1024, Texture::RGBA, false); + waterCaustics = new Texture(1024, 1024, Texture::RGBA, false); if (!level.tilesCount) { atlas = NULL; @@ -406,6 +407,9 @@ struct Level { atlas = new Texture(1024, 1024, Texture::RGBA, false, data); PROFILE_LABEL(TEXTURE, atlas->ID, "atlas"); + uint32 whitePix = 0xFFFFFFFF; + cube = new Texture(1, 1, Texture::RGBA, true, &whitePix); + delete[] data; delete[] level.tiles; level.tiles = NULL; @@ -483,11 +487,6 @@ struct Level { 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 @@ -566,6 +565,10 @@ struct Level { Core::active.shader->setParam(uCaustics, 0); } 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) { @@ -735,6 +738,7 @@ struct Level { camera->setup(Core::pass == Core::passCompose); atlas->bind(sDiffuse); + cube->bind(sEnvironment); if (!Core::support.VAO) mesh->bind(); @@ -746,7 +750,7 @@ struct Level { sh->setParam(uLightProj, Core::mLightProj); sh->setParam(uViewInv, Core::mViewInv); 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(uAnimTexRanges, mesh->animTexRanges[0], mesh->animTexRangesCount); sh->setParam(uAnimTexOffsets, mesh->animTexOffsets[0], mesh->animTexOffsetsCount); @@ -884,41 +888,105 @@ struct Level { Core::setBlending(bmAlpha); Core::clear(vec4(0.0f)); - Core::setViewport(0, 0, Core::width, Core::height); shadow->bind(sShadow); renderScene(roomIndex); } + void renderWater() { + + + } + void render() { + clipHeight = 1000000.0f; + clipSign = 1.0f; Core::resetStates(); ambientCache->precessQueue(); renderShadows(lara->getRoomIndex()); + Core::setViewport(0, 0, Core::width, Core::height); 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_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); + vec3 head = lara->animation.getJoints(lara->getMatrix(), 14).pos; + 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) { 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; + p.x = (head.x - c.x) / 5120.0f + 0.5; + p.y = (head.z - c.z) / 5120.0f + 0.5; + 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); 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)); + Core::active.shader->setParam(uParam, vec4(p.x, p.y, 128.0f / 5120.0f * radius, strength)); mesh->renderQuad(); swap(water[0], water[1]); Input::down[ikU] = false; @@ -938,15 +1006,18 @@ struct Level { Core::active.shader->setParam(uType, Shader::WATER_NORMAL); mesh->renderQuad(); 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); -/* - 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); @@ -961,17 +1032,20 @@ struct Level { 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(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); - + waterRefract->bind(sDiffuse); + waterReflect->bind(sReflect); + water[0]->bind(sNormal); + Core::setCulling(cfNone); mesh->renderQuad(); + Core::setCulling(cfFront); + #ifdef _DEBUG static int modelIndex = 0; static bool lastStateK = false; @@ -998,6 +1072,39 @@ struct Level { // renderModel(level.models[modelIndex], level.entities[4]); 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::lights(level, lara->getRoomIndex()); // 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(); diff --git a/src/mesh.h b/src/mesh.h index 8d48175..d08b50c 100644 --- a/src/mesh.h +++ b/src/mesh.h @@ -120,7 +120,8 @@ struct Mesh { float intensityf(int lighting) { if (lighting < 0) return 1.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) { diff --git a/src/shader.glsl b/src/shader.glsl index b910c30..f3194e4 100644 --- a/src/shader.glsl +++ b/src/shader.glsl @@ -1,5 +1,5 @@ R"====( -varying vec2 vTexCoord; +varying vec4 vTexCoord; // xy - atlas coords, zw - caustics coords #ifndef PASS_SHADOW #ifndef PASS_AMBIENT @@ -37,6 +37,7 @@ uniform int uType; uniform vec3 uViewPos; uniform vec2 uAnimTexRanges[MAX_RANGES]; uniform vec2 uAnimTexOffsets[MAX_OFFSETS]; + uniform vec4 uRoomSize; // xy - minXZ, zw - maxXZ #endif 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; vec2 offset = uAnimTexOffsets[int(range.x + f)]; // texCoord offset from first frame - vTexCoord = (aTexCoord.xy + offset) * TEXCOORD_SCALE; // first frame + offset * isAnimated - vNormal = vec4(mulQuat(rBasisRot, aNormal.xyz), aNormal.w); + vTexCoord.xy = (aTexCoord.xy + offset) * TEXCOORD_SCALE; // first frame + offset * isAnimated + vNormal = vec4(mulQuat(rBasisRot, aNormal.xyz), aNormal.w); + + if (aTexCoord.z > 0.0) + coord.w = -1.0; + } else { 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); } #else - vTexCoord = aTexCoord.xy * TEXCOORD_SCALE; + vTexCoord.xy = aTexCoord.xy * TEXCOORD_SCALE; + vTexCoord.zw = vec2(0.0); #endif #ifndef PASS_SHADOW @@ -95,6 +101,7 @@ uniform int uType; float sum = coord.x + coord.y + coord.z; 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; vLightProj = uLightProj * coord; @@ -106,6 +113,7 @@ uniform int uType; } #else uniform sampler2D sDiffuse; + uniform sampler2D sReflect; uniform vec4 uColor; #ifdef PASS_COMPOSE uniform samplerCube sEnvironment; @@ -218,6 +226,10 @@ uniform int uType; 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 /* float getLuminance(vec3 color) { @@ -228,17 +240,24 @@ uniform int uType; const vec2 size = vec2(2.0, 0.0); const vec3 off = vec3(-1, 0, 1) / 1024.0; - float s01 = getLuminance(texture2D(sDiffuse, vTexCoord + off.xy).xyz); - float s21 = getLuminance(texture2D(sDiffuse, vTexCoord + off.zy).xyz); - float s10 = getLuminance(texture2D(sDiffuse, vTexCoord + off.yx).xyz); - float s12 = getLuminance(texture2D(sDiffuse, vTexCoord + off.yz).xyz); + float s01 = getLuminance(texture2D(sDiffuse, vTexCoord.xy + off.xy).xyz); + float s21 = getLuminance(texture2D(sDiffuse, vTexCoord.xy + off.zy).xyz); + float s10 = getLuminance(texture2D(sDiffuse, vTexCoord.xy + off.yx).xyz); + float s12 = getLuminance(texture2D(sDiffuse, vTexCoord.xy + off.yz).xyz); vec3 va = vec3(size.xy * 0.25, s21-s01); vec3 vb = vec3(size.yx * 0.25, s12-s10); return normalize(cross(va, vb)); } */ 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) discard; @@ -269,7 +288,6 @@ uniform int uType; vec3 viewVec = normalize(vViewVec); vec3 light = vec3(0.0); - for (int i = 1; i < MAX_LIGHTS; i++) // additional lights 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; //light += calcLight(normal, uLightPos[0], uLightColor[0]); light += mix(min(uColor.w, vColor.w), vColor.w, rShadow); + light += calcCaustics(normal); } if (uType == TYPE_ENTITY) { @@ -289,6 +308,7 @@ uniform int uType; float rShadow = getShadow(vLightProj); light += calcLight(normal, uLightPos[0], uLightColor[0]) * rShadow + rAmbient; color.xyz += calcSpecular(normal, viewVec, uLightPos[0], uLightColor[0], uColor.w * rShadow + 0.03); + light += calcCaustics(normal); } if (uType == TYPE_MIRROR) { diff --git a/src/shader.h b/src/shader.h index 7db7857..cbb9b92 100644 --- a/src/shader.h +++ b/src/shader.h @@ -4,12 +4,12 @@ #include "core.h" enum AttribType { aCoord, aTexCoord, aNormal, aColor, aMAX }; -enum SamplerType { sDiffuse, sShadow, sEnvironment, sMAX }; -enum UniformType { uType, uCaustics, uParam, uViewProj, uViewInv, uBasis, uLightProj, uColor, uAmbient, uViewPos, uLightsCount, uLightPos, uLightColor, uAnimTexRanges, uAnimTexOffsets, uMAX }; +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, uRoomSize, uMAX }; const char *AttribName[aMAX] = { "aCoord", "aTexCoord", "aNormal", "aColor" }; -const char *SamplerName[sMAX] = { "sDiffuse", "sShadow", "sEnvironment" }; -const char *UniformName[uMAX] = { "uType", "uCaustics", "uParam", "uViewProj", "uViewInv", "uBasis", "uLightProj", "uColor", "uAmbient", "uViewPos", "uLightsCount", "uLightPos", "uLightColor", "uAnimTexRanges", "uAnimTexOffsets" }; +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", "uRoomSize" }; struct Shader { GLuint ID; @@ -18,14 +18,12 @@ struct Shader { 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 + /* 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 = "") { #ifdef MOBILE - #define GLSL_DEFINE "#define MOBILE\n"\ - "precision highp int;\n"\ - "precision highp float;\n" + #define GLSL_DEFINE "precision highp int;\nprecision highp float;\n" #else #define GLSL_DEFINE "#version 120\n" #endif diff --git a/src/texture.h b/src/texture.h index 27ce2d3..cc753f6 100644 --- a/src/texture.h +++ b/src/texture.h @@ -4,7 +4,7 @@ #include "core.h" 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; int width, height; @@ -64,6 +64,7 @@ struct Texture { { 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_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 }, // SHADOW }; diff --git a/src/utils.h b/src/utils.h index e17f0a3..db7fc63 100644 --- a/src/utils.h +++ b/src/utils.h @@ -337,6 +337,19 @@ struct mat4 { 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() { e10 = e20 = e30 = e01 = e21 = e31 = e02 = e12 = e32 = e03 = e13 = e23 = 0.0f; e00 = e11 = e22 = e33 = 1.0f;