From d57056e8a0e0cf06818907cab5ff4e9902fc070f Mon Sep 17 00:00:00 2001 From: XProger Date: Sun, 16 Jul 2017 05:21:48 +0300 Subject: [PATCH] #23 trapezoidal texturing --- src/format.h | 3 +- src/lara.h | 6 +-- src/level.h | 6 +++ src/mesh.h | 114 +++++++++++++++++++++++++++++++--------- src/shader.h | 3 +- src/shaders/gui.glsl | 4 +- src/shaders/shader.glsl | 82 ++++++++++++++++------------- src/utils.h | 19 +++++-- 8 files changed, 163 insertions(+), 74 deletions(-) diff --git a/src/format.h b/src/format.h index 625694a..cd57665 100644 --- a/src/format.h +++ b/src/format.h @@ -412,7 +412,8 @@ namespace TR { struct Vertex { int16 x, y, z; - operator vec3() const { return vec3((float)x, (float)y, (float)z); }; + operator vec3() const { return vec3((float)x, (float)y, (float)z); } + operator short3() const { return *((short3*)this); } }; struct Rectangle { diff --git a/src/lara.h b/src/lara.h index 2f2a92b..d023af4 100644 --- a/src/lara.h +++ b/src/lara.h @@ -425,10 +425,8 @@ struct Lara : Character { if (level->extra.braid > -1) braid = new Braid(this, vec3(-4.0f, 24.0f, -48.0f)); - #ifdef _DEBUG - //reset(14, vec3(40448, 3584, 60928), PI * 0.5f, true); // gym (pool) - + //reset(14, vec3(40448, 3584, 60928), PI * 0.5f, STAND_ONWATER); // gym (pool) //reset(14, vec3(20215, 6656, 52942), PI); // level 1 (bridge) //reset(15, vec3(70067, -256, 29104), -0.68f); // level 2 (pool) //reset(61, vec3(27221, -1024, 29205), PI * 0.5f); // level 2 (blade) @@ -1562,7 +1560,7 @@ struct Lara : Character { if (getRoom().flags.water) { wpnHide(); - if (stand != STAND_UNDERWATER && (state != STATE_FALL && state != STATE_FALL_BACK && state != STATE_SWAN_DIVE && state != STATE_FAST_DIVE)) + if (stand != STAND_UNDERWATER && stand != STAND_ONWATER && (state != STATE_FALL && state != STATE_FALL_BACK && state != STATE_SWAN_DIVE && state != STATE_FAST_DIVE)) animation.setAnim(ANIM_FALL_FORTH); return STAND_UNDERWATER; } diff --git a/src/level.h b/src/level.h index 4253331..59065f0 100644 --- a/src/level.h +++ b/src/level.h @@ -411,6 +411,12 @@ struct Level : IGame { fwrite(data, 1024 * 1024 * 4, 1, f); fclose(f); */ + /* + memset(data, 255, 4 * 1024 * 1024); + for (int i = 0; i < 1024; i++) + for (int j = 0; j < 1024; j++) + data[i * 1024 + j].b = data[i * 1024 + j].g = ((i % 8 == 0) || (j % 8 == 0)) ? 0 : 255; + */ atlas = new Texture(1024, 1024, Texture::RGBA, false, data); PROFILE_LABEL(TEXTURE, atlas->ID, "atlas"); diff --git a/src/mesh.h b/src/mesh.h index e607baf..69fe8a8 100644 --- a/src/mesh.h +++ b/src/mesh.h @@ -13,9 +13,10 @@ typedef unsigned short Index; struct Vertex { - short4 coord; // xyz - position, w - unused - short4 texCoord; // xy - texture coordinates, z - anim tex range index, w - anim tex frame index + short4 coord; // xyz - position, w - joint index (for entities only) short4 normal; // xyz - vertex normalá w - unused + short4 texCoord; // xy - texture coordinates, zw - trapezoid warping + ubyte4 param; // xy - anim tex range and frame index, zw - unused ubyte4 color; // xyz - color, w - intensity }; @@ -29,14 +30,16 @@ struct MeshRange { void setup() const { glEnableVertexAttribArray(aCoord); - glEnableVertexAttribArray(aTexCoord); glEnableVertexAttribArray(aNormal); + glEnableVertexAttribArray(aTexCoord); + glEnableVertexAttribArray(aParam); glEnableVertexAttribArray(aColor); Vertex *v = (Vertex*)NULL + vStart; glVertexAttribPointer(aCoord, 4, GL_SHORT, false, sizeof(Vertex), &v->coord); - glVertexAttribPointer(aTexCoord, 4, GL_SHORT, false, sizeof(Vertex), &v->texCoord); glVertexAttribPointer(aNormal, 4, GL_SHORT, true, sizeof(Vertex), &v->normal); + glVertexAttribPointer(aTexCoord, 4, GL_SHORT, true, sizeof(Vertex), &v->texCoord); + glVertexAttribPointer(aParam, 4, GL_UNSIGNED_BYTE, false, sizeof(Vertex), &v->param); glVertexAttribPointer(aColor, 4, GL_UNSIGNED_BYTE, true, sizeof(Vertex), &v->color); } @@ -234,7 +237,7 @@ struct MeshBuilder { if (Core::settings.detail.water) roomRemoveWaterSurfaces(r, iCount, vCount); - + for (int j = 0; j < r.meshesCount; j++) { TR::Room::Mesh &m = r.meshes[j]; TR::StaticMesh *s = &level.staticMeshes[m.meshIndex]; @@ -402,8 +405,9 @@ struct MeshBuilder { // build shadow blob for (int i = 0; i < 9; i++) { Vertex &v0 = vertices[vCount + i * 2 + 0]; - v0.normal = { 0, -1, 0, 1 }; - v0.texCoord = { 32688, 32688, 0, 0 }; + v0.normal = { 0, -1, 0, 0 }; + v0.texCoord = { 32688, 32688, 32767, 32767 }; + v0.param = { 0, 0, 0, 0 }; v0.color = { 0, 0, 0, 0 }; if (i == 8) { @@ -507,7 +511,8 @@ struct MeshBuilder { Vertex &v = vertices[vCount + i]; v.normal = { 0, 0, 0, 0 }; v.color = { 255, 255, 255, 255 }; - v.texCoord = { 32688, 32688, 0, 0 }; + v.texCoord = { 32688, 32688, 32767, 32767 }; + v.param = { 0, 0, 0, 0 }; } vCount += 4; aCount++; @@ -522,7 +527,8 @@ struct MeshBuilder { v.coord = { short(pos.x), short(pos.y), 0, 0 }; v.normal = { 0, 0, 0, 0 }; v.color = { 255, 255, 255, 255 }; - v.texCoord = { 32688, 32688, 0, 0 }; + v.texCoord = { 32688, 32688, 32767, 32767 }; + v.param = { 0, 0, 0, 0 }; indices[iCount++] = i; indices[iCount++] = (i + 1) % CIRCLE_SEGS; @@ -700,8 +706,11 @@ struct MeshBuilder { if (opaque != (t.attribute == 0)) continue; - - addQuad(indices, iCount, vCount, vStart, vertices, &t); + addQuad(indices, iCount, vCount, vStart, vertices, &t, + d.vertices[f.vertices[0]].vertex, + d.vertices[f.vertices[1]].vertex, + d.vertices[f.vertices[2]].vertex, + d.vertices[f.vertices[3]].vertex); TR::Vertex n; CHECK_ROOM_NORMAL(n); @@ -761,7 +770,11 @@ struct MeshBuilder { TR::Color24 c = textured ? COLOR_WHITE : level.getColor(f.texture); - addQuad(indices, iCount, vCount, vStart, vertices, &t); + addQuad(indices, iCount, vCount, vStart, vertices, &t, + mesh.vertices[f.vertices[0]].coord, + mesh.vertices[f.vertices[1]].coord, + mesh.vertices[f.vertices[2]].coord, + mesh.vertices[f.vertices[3]].coord); for (int k = 0; k < 4; k++) { TR::Mesh::Vertex &v = mesh.vertices[f.vertices[k]]; @@ -808,7 +821,7 @@ struct MeshBuilder { int tx = (tile % 4) * 256; int ty = (tile / 4) * 256; return vec2( (float)(((tx + tex.texCoord[0].x) << 5) + 16), - (float)(((ty + tex.texCoord[0].y) << 5) + 16) ); + (float)(((ty + tex.texCoord[0].y) << 5) + 16) ) * (1.0f / 32767.0f); } void initAnimTextures(TR::Level &level) { @@ -846,7 +859,7 @@ struct MeshBuilder { } } - TR::ObjectTexture* getAnimTexture(TR::ObjectTexture *tex, int &range, int &frame) { + TR::ObjectTexture* getAnimTexture(TR::ObjectTexture *tex, uint8 &range, uint8 &frame) { range = frame = 0; if (!level->animTexturesDataSize) return tex; @@ -869,28 +882,41 @@ struct MeshBuilder { } void addTexCoord(Vertex *vertices, int vCount, TR::ObjectTexture *tex, bool triangle) { - int range, frame; + uint8 range, frame; tex = getAnimTexture(tex, range, frame); int tile = tex->tile.index; int tx = (tile % 4) * 256; int ty = (tile / 4) * 256; + int count = triangle ? 3 : 4; for (int i = 0; i < count; i++) { Vertex &v = vertices[vCount + i]; v.texCoord.x = ((tx + tex->texCoord[i].x) << 5) + 16; v.texCoord.y = ((ty + tex->texCoord[i].y) << 5) + 16; - v.texCoord.z = range; - v.texCoord.w = frame; + v.texCoord.z = 32767; + v.texCoord.w = 32767; + v.param = { range, frame, 0, 0 }; } if (level->version == TR::Level::VER_TR1_PSX && !triangle) swap(vertices[vCount + 2].texCoord, vertices[vCount + 3].texCoord); + /* + short2 uv[4] = { + {0, 0}, {32767, 0}, {32767, 32767}, {0, 32767} + }; + + for (int i = 0; i < count; i++) { + Vertex &v = vertices[vCount + i]; + v.texCoord.x = uv[i].x; + v.texCoord.y = uv[i].y; + } + */ } void addTriangle(Index *indices, int &iCount, int vCount, int vStart, Vertex *vertices, TR::ObjectTexture *tex) { - int vIndex = vCount - vStart; + int vIndex = vCount - vStart; indices[iCount + 0] = vIndex + 0; indices[iCount + 1] = vIndex + 1; @@ -902,7 +928,7 @@ struct MeshBuilder { } void addQuad(Index *indices, int &iCount, int vCount, int vStart, Vertex *vertices, TR::ObjectTexture *tex) { - int vIndex = vCount - vStart; + int vIndex = vCount - vStart; indices[iCount + 0] = vIndex + 0; indices[iCount + 1] = vIndex + 1; @@ -917,6 +943,43 @@ struct MeshBuilder { if (tex) addTexCoord(vertices, vCount, tex, false); } + void addQuad(Index *indices, int &iCount, int &vCount, int vStart, Vertex *vertices, TR::ObjectTexture *tex, + const short3 &c0, const short3 &c1, const short3 &c2, const short3 &c3) { + addQuad(indices, iCount, vCount, vStart, vertices, tex); + + vec3 a = c0 - c1; + vec3 b = c3 - c2; + vec3 c = c0 - c3; + vec3 d = c1 - c2; + + float aL = a.length(); + float bL = b.length(); + float cL = c.length(); + float dL = d.length(); + + float ab = a.dot(b) / (aL * bL); + float cd = c.dot(d) / (cL * dL); + + int16 tx = abs(vertices[vCount + 0].texCoord.x - vertices[vCount + 3].texCoord.x); + int16 ty = abs(vertices[vCount + 0].texCoord.y - vertices[vCount + 3].texCoord.y); + + if (ab > cd) { + int k = (tx > ty) ? 3 : 2; + + if (aL > bL) + vertices[vCount + 2].texCoord[k] = vertices[vCount + 3].texCoord[k] = int16(bL / aL * 32767.0f); + else + vertices[vCount + 0].texCoord[k] = vertices[vCount + 1].texCoord[k] = int16(aL / bL * 32767.0f); + } else { + int k = (tx > ty) ? 2 : 3; + + if (cL > dL) { + vertices[vCount + 1].texCoord[k] = vertices[vCount + 2].texCoord[k] = int16(dL / cL * 32767.0f); + } else + vertices[vCount + 0].texCoord[k] = vertices[vCount + 3].texCoord[k] = int16(cL / dL * 32767.0f); + } + } + void addSprite(Index *indices, Vertex *vertices, int &iCount, int &vCount, int vStart, int16 x, int16 y, int16 z, const TR::SpriteTexture &sprite, uint8 intensity, bool expand = false) { addQuad(indices, iCount, vCount, vStart, NULL, NULL); @@ -939,12 +1002,12 @@ struct MeshBuilder { quad[2].coord = { x1, y1, z, 0 }; quad[3].coord = { x0, y1, 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 = { 255, 255, 255, intensity }; + quad[0].param = quad[1].param = quad[2].param = quad[3].param = { 0, 0, 0, 0 }; - int tx = (sprite.tile % 4) * 256; - int ty = (sprite.tile / 4) * 256; + int tx = (sprite.tile % 4) * 256; + int ty = (sprite.tile / 4) * 256; int16 u0 = (((tx + sprite.texCoord[0].x) << 5)); int16 v0 = (((ty + sprite.texCoord[0].y) << 5)); @@ -992,7 +1055,8 @@ struct MeshBuilder { s = int(s) * 32767 / 1024; t = int(t) * 32767 / 1024; - v.texCoord = { s, t, 0, 0 }; + v.texCoord = { s, t, 32767, 32767 }; + v.param = { 0, 0, 0, 0 }; } vCount += 4; @@ -1018,7 +1082,7 @@ struct MeshBuilder { Vertex &v = vertices[vCount + i]; v.normal = { 0, 0, 0, 0 }; v.color = *((ubyte4*)&color1); - v.texCoord = { 32688, 32688, 0, 0 }; + v.texCoord = { 32688, 32688, 32767, 32767 }; } addQuad(indices, iCount, vCount, 0, vertices, NULL); vCount += 4; @@ -1038,7 +1102,7 @@ struct MeshBuilder { Vertex &v = vertices[vCount + i]; v.normal = { 0, 0, 0, 0 }; v.color = *((ubyte4*)&color2); - v.texCoord = { 32688, 32688, 0, 0 }; + v.texCoord = { 32688, 32688, 32767, 32767 }; } addQuad(indices, iCount, vCount, 0, vertices, NULL); vCount += 4; diff --git a/src/shader.h b/src/shader.h index 1882603..ffeb37a 100644 --- a/src/shader.h +++ b/src/shader.h @@ -5,8 +5,9 @@ #define SHADER_ATTRIBS(E) \ E( aCoord ) \ - E( aTexCoord ) \ E( aNormal ) \ + E( aTexCoord ) \ + E( aParam ) \ E( aColor ) #define SHADER_SAMPLERS(E) \ diff --git a/src/shaders/gui.glsl b/src/shaders/gui.glsl index 4764b7c..5988d58 100644 --- a/src/shaders/gui.glsl +++ b/src/shaders/gui.glsl @@ -16,10 +16,8 @@ varying vec4 vColor; attribute vec4 aTexCoord; attribute vec4 aColor; - #define TEXCOORD_SCALE (1.0 / 32767.0) - void main() { - vTexCoord = aTexCoord.xy * TEXCOORD_SCALE; + vTexCoord = aTexCoord.xy; vColor = aColor * uMaterial; gl_Position = uViewProj * vec4(aCoord.xy * uPosScale.zw + uPosScale.xy, 0.0, 1.0); } diff --git a/src/shaders/shader.glsl b/src/shaders/shader.glsl index 4345cf3..2bbeac9 100644 --- a/src/shaders/shader.glsl +++ b/src/shaders/shader.glsl @@ -4,19 +4,23 @@ R"====( precision highp float; #endif -varying vec4 vTexCoord; // xy - atlas coords, zw - caustics coords +varying vec4 vTexCoord; // xy - atlas coords, zw - trapezoidal correction + +#if defined(OPT_WATER) && defined(UNDERWATER) + varying vec2 vCausticsCoord; // - xy caustics texture coord +#endif #ifndef PASS_SHADOW - varying vec4 vViewVec; // xyz - dir * dist, w - coord.y uniform vec3 uViewPos; + varying vec4 vViewVec; // xyz - dir * dist, w - coord.y varying vec4 vDiffuse; #ifndef TYPE_FLASH #ifdef PASS_COMPOSE - varying vec4 vNormal; // xyz - normal dir, w - fog factor + varying vec3 vNormal; // xyz - normal dir varying vec4 vLightProj; - varying vec3 vLightVec; + varying vec4 vLightVec; // xyz - dir, w - fog factor #ifdef OPT_SHADOW varying vec3 vAmbient; @@ -26,7 +30,7 @@ varying vec4 vTexCoord; // xy - atlas coords, zw - caustics coords uniform vec4 uLightColor[4]; // xyz - color, w - radius * intensity #endif - varying vec4 vLight; // 4 lights intensity + varying vec4 vLight; // 4 lights intensity #if defined(OPT_WATER) && defined(UNDERWATER) uniform vec4 uRoomSize; // xy - minXZ, zw - maxXZ @@ -38,15 +42,15 @@ varying vec4 vTexCoord; // xy - atlas coords, zw - caustics coords vec3 calcAmbient(vec3 n) { vec3 sqr = n * n; vec3 pos = step(0.0, n); - return sqr.x * mix(uAmbient[1], uAmbient[0], pos.x) + - sqr.y * mix(uAmbient[3], uAmbient[2], pos.y) + - sqr.z * mix(uAmbient[5], uAmbient[4], pos.z); + return sqr.x * mix(uAmbient[1], uAmbient[0], pos.x) + + sqr.y * mix(uAmbient[3], uAmbient[2], pos.y) + + sqr.z * mix(uAmbient[5], uAmbient[4], pos.z); } #endif #endif - uniform vec4 uParam; // x - time, y - water height, z - clip plane sign, w - clip plane height - uniform vec4 uMaterial; // x - diffuse, y - ambient, z - specular, w - alpha + uniform vec4 uParam; // x - time, y - water height, z - clip plane sign, w - clip plane height + uniform vec4 uMaterial; // x - diffuse, y - ambient, z - specular, w - alpha #endif #ifdef VERTEX @@ -71,6 +75,7 @@ varying vec4 vTexCoord; // xy - atlas coords, zw - caustics coords attribute vec4 aCoord; attribute vec4 aTexCoord; + attribute vec4 aParam; #ifndef PASS_AMBIENT attribute vec4 aNormal; @@ -80,7 +85,7 @@ varying vec4 vTexCoord; // xy - atlas coords, zw - caustics coords attribute vec4 aColor; #endif - #define TEXCOORD_SCALE (1.0 / 32767.0) + #define TEXCOORD_SCALE 32767.0 vec3 mulQuat(vec4 q, vec3 v) { return v + 2.0 * cross(q.xyz, cross(q.xyz, v) + v * q.w); @@ -103,7 +108,7 @@ varying vec4 vTexCoord; // xy - atlas coords, zw - caustics coords vec4 coord = vec4(mulBasis(rBasisRot, rBasisPos, aCoord.xyz), rBasisPos.w); #ifdef TYPE_SPRITE - coord.xyz += uViewInv[0].xyz * aTexCoord.z - uViewInv[1].xyz * aTexCoord.w; + coord.xyz += (uViewInv[0].xyz * aTexCoord.z - uViewInv[1].xyz * aTexCoord.w) * TEXCOORD_SCALE; #endif #ifndef PASS_SHADOW @@ -129,7 +134,7 @@ varying vec4 vTexCoord; // xy - atlas coords, zw - caustics coords fog = length(vViewVec.xyz); #endif - vNormal.w = clamp(1.0 / exp(fog), 0.0, 1.0); + vLightVec.w = clamp(1.0 / exp(fog), 0.0, 1.0); #endif return coord; @@ -161,22 +166,24 @@ varying vec4 vTexCoord; // xy - atlas coords, zw - caustics coords vec3 lv2 = (uLightPos[2].xyz - coord) * uLightColor[2].w; vec3 lv3 = (uLightPos[3].xyz - coord) * uLightColor[3].w; - vLightVec = lv0; + vLightVec.xyz = lv0; vec4 lum, att; #ifdef TYPE_ENTITY - lum.x = dot(vNormal.xyz, normalize(lv0)); att.x = dot(lv0, lv0); + lum.x = dot(vNormal.xyz, normalize(lv0)); + att.x = dot(lv0, lv0); #else - lum.x = aColor.w; att.x = 0.0; + lum.x = aColor.w; + att.x = 0.0; #ifdef TYPE_SPRITE lum.x *= uMaterial.y; #endif #endif - lum.y = dot(vNormal.xyz, normalize(lv1)); att.y = dot(lv1, lv1); - lum.z = dot(vNormal.xyz, normalize(lv2)); att.z = dot(lv2, lv2); - lum.w = dot(vNormal.xyz, normalize(lv3)); att.w = dot(lv3, lv3); + lum.y = dot(vNormal.xyz, normalize(lv1)); att.y = dot(lv1, lv1); + lum.z = dot(vNormal.xyz, normalize(lv2)); att.z = dot(lv2, lv2); + lum.w = dot(vNormal.xyz, normalize(lv3)); att.w = dot(lv3, lv3); vec4 light = max(vec4(0.0), lum) * max(vec4(0.0), vec4(1.0) - att); #ifdef UNDERWATER @@ -219,20 +226,18 @@ varying vec4 vTexCoord; // xy - atlas coords, zw - caustics coords } void _uv(vec3 coord) { + vTexCoord = aTexCoord; #if defined(PASS_COMPOSE) && !defined(TYPE_SPRITE) // animated texture coordinates - vec2 range = uAnimTexRanges[int(aTexCoord.z)]; // x - start index, y - count - float frame = fract((aTexCoord.w + uParam.x * 4.0 - range.x) / range.y) * range.y; - vec2 offset = uAnimTexOffsets[int(range.x + frame)]; // texCoord offset from first frame - vTexCoord.xy = (aTexCoord.xy + offset) * TEXCOORD_SCALE; - #else - vTexCoord.xy = aTexCoord.xy * TEXCOORD_SCALE; + vec2 range = uAnimTexRanges[int(aParam.x)]; // x - start index, y - count + float frame = fract((aParam.y + uParam.x * 4.0 - range.x) / range.y) * range.y; + vec2 offset = uAnimTexOffsets[int(range.x + frame)]; // texCoord offset from first frame + vTexCoord.xy += offset; + vTexCoord.xy *= vTexCoord.zw; #endif #if defined(OPT_WATER) && defined(UNDERWATER) - vTexCoord.zw = clamp((coord.xz - uRoomSize.xy) / (uRoomSize.zw - uRoomSize.xy), vec2(0.0), vec2(1.0)); - #else - vTexCoord.zw = vec2(1.0); + vCausticsCoord.xy = clamp((coord.xz - uRoomSize.xy) / (uRoomSize.zw - uRoomSize.xy), vec2(0.0), vec2(1.0)); #endif } @@ -346,13 +351,13 @@ varying vec4 vTexCoord; // xy - atlas coords, zw - caustics coords } else rShadow /= 4.0; - float fade = clamp(dot(vLightVec, vLightVec), 0.0, 1.0); + float fade = clamp(dot(vLightVec.xyz, vLightVec.xyz), 0.0, 1.0); return rShadow + (1.0 - rShadow) * fade; } float getShadow() { #ifdef TYPE_ROOM - float vis = min(dot(vNormal.xyz, vLightVec), vLightProj.w); + float vis = min(dot(vNormal.xyz, vLightVec.xyz), vLightProj.w); #else float vis = vLightProj.w; #endif @@ -369,9 +374,10 @@ varying vec4 vTexCoord; // xy - atlas coords, zw - caustics coords #if defined(OPT_WATER) && defined(UNDERWATER) float calcCaustics(vec3 n) { + vec2 cc = vCausticsCoord.xy; vec2 border = vec2(256.0) / (uRoomSize.zw - uRoomSize.xy); - vec2 fade = smoothstep(vec2(0.0), border, vTexCoord.zw) * (1.0 - smoothstep(vec2(1.0) - border, vec2(1.0), vTexCoord.zw)); - return texture2D(sReflect, vTexCoord.zw).g * max(0.0, -n.y) * fade.x * fade.y; + vec2 fade = smoothstep(vec2(0.0), border, cc) * (1.0 - smoothstep(vec2(1.0) - border, vec2(1.0), cc)); + return texture2D(sReflect, cc).g * max(0.0, -n.y) * fade.x * fade.y; } #endif #endif @@ -391,7 +397,11 @@ varying vec4 vTexCoord; // xy - atlas coords, zw - caustics coords color = textureCube(sEnvironment, normalize(rv)); #endif #else - color = texture2D(sDiffuse, vTexCoord.xy); + #if defined(PASS_COMPOSE) && !defined(TYPE_SPRITE) + color = texture2D(sDiffuse, vTexCoord.xy / vTexCoord.zw); + #else + color = texture2D(sDiffuse, vTexCoord.xy); + #endif #endif #ifdef ALPHA_TEST @@ -444,7 +454,7 @@ varying vec4 vTexCoord; // xy - atlas coords, zw - caustics coords #endif #ifdef TYPE_ENTITY - color.xyz += calcSpecular(n, vViewVec.xyz, vLightVec, uLightColor[0], uMaterial.z * rShadow + 0.03); + color.xyz += calcSpecular(n, vViewVec.xyz, vLightVec.xyz, uLightColor[0], uMaterial.z * rShadow + 0.03); #endif #endif @@ -460,9 +470,9 @@ varying vec4 vTexCoord; // xy - atlas coords, zw - caustics coords #if defined(PASS_COMPOSE) && !defined(TYPE_FLASH) #ifdef UNDERWATER - color.xyz = mix(UNDERWATER_COLOR * 0.2, color.xyz, vNormal.w); + color.xyz = mix(UNDERWATER_COLOR * 0.2, color.xyz, vLightVec.w); #else - color.xyz = mix(vec3(0.0), color.xyz, vNormal.w); + color.xyz = mix(vec3(0.0), color.xyz, vLightVec.w); #endif #endif diff --git a/src/utils.h b/src/utils.h index d55b9a7..7aaa4ee 100644 --- a/src/utils.h +++ b/src/utils.h @@ -140,9 +140,9 @@ int nextPow2(uint32 x) { } uint32 fnv32(const char *data, int32 size, uint32 hash = 0x811c9dc5) { - for (int i = 0; i < size; i++) - hash = (hash ^ data[i]) * 0x01000193; - return hash; + for (int i = 0; i < size; i++) + hash = (hash ^ data[i]) * 0x01000193; + return hash; } struct vec2 { @@ -711,12 +711,23 @@ struct short2 { struct short3 { int16 x, y, z; + + short3() {} + short3(int16 x, int16 y, int16 z) : x(x), y(y), z(z) {} + + operator vec3() const { return vec3((float)x, (float)y, (float)z); }; + + short3 operator + (const short3 &v) const { return short3(x + v.x, y + v.y, z + v.z); } + short3 operator - (const short3 &v) const { return short3(x - v.x, y - v.y, z - v.z); } }; struct short4 { int16 x, y, z, w; - operator vec3() const { return vec3((float)x, (float)y, (float)z); }; + operator vec3() const { return vec3((float)x, (float)y, (float)z); }; + operator short3() const { return *((short3*)this); } + + inline int16& operator [] (int index) const { ASSERT(index >= 0 && index <= 3); return ((int16*)this)[index]; } }; quat rotYXZ(const vec3 &a) {