diff --git a/src/cache.h b/src/cache.h index ceca791..a1ace88 100644 --- a/src/cache.h +++ b/src/cache.h @@ -556,8 +556,8 @@ struct WaterCache { int *mf = new int[4 * w * 64 * h * 64]; memset(mf, 0, sizeof(int) * 4 * w * 64 * h * 64); - data[0] = new Texture(w * 64, h * 64, FMT_RGBA_HALF, OPT_TARGET | OPT_VERTEX, mf); - data[1] = new Texture(w * 64, h * 64, FMT_RGBA_HALF, OPT_TARGET | OPT_VERTEX); + data[0] = new Texture(w * 64, h * 64, FMT_RG_HALF, OPT_TARGET | OPT_VERTEX, mf); + data[1] = new Texture(w * 64, h * 64, FMT_RG_HALF, OPT_TARGET | OPT_VERTEX); delete[] mf; caustics = Core::settings.detail.water > Core::Settings::MEDIUM ? new Texture(512, 512, FMT_RGBA, OPT_TARGET) : NULL; @@ -761,7 +761,7 @@ struct WaterCache { float sx = item.size.x * DETAIL / (item.data[0]->width / 2); float sz = item.size.z * DETAIL / (item.data[0]->height / 2); - Core::active.shader->setParam(uTexParam, vec4(0.0f, 0.0f, sx, sz)); + Core::active.shader->setParam(uTexParam, vec4(1.0f / item.data[0]->width, 1.0f / item.data[0]->height, sx, sz)); Core::whiteTex->bind(sReflect); item.data[0]->bind(sNormal); @@ -989,7 +989,7 @@ struct WaterCache { float sx = item.size.x * DETAIL / (item.data[0]->width / 2); float sz = item.size.z * DETAIL / (item.data[0]->height / 2); - Core::active.shader->setParam(uTexParam, vec4(0.0f, 0.0f, sx, sz)); + Core::active.shader->setParam(uTexParam, vec4(1.0f / item.data[0]->width, 1.0f / item.data[0]->height, sx, sz)); Core::active.shader->setParam(uRoomSize, vec4(1.0f / item.mask->origWidth, 1.0f / item.mask->origHeight, float(item.mask->origWidth) / item.mask->width, float(item.mask->origHeight) / item.mask->height)); refract->bind(sDiffuse); diff --git a/src/core.h b/src/core.h index 10aad11..6920886 100644 --- a/src/core.h +++ b/src/core.h @@ -376,8 +376,8 @@ enum TexFormat { FMT_RGBA, FMT_RGB16, FMT_RGBA16, - FMT_RGBA_FLOAT, - FMT_RGBA_HALF, + FMT_RG_FLOAT, + FMT_RG_HALF, FMT_DEPTH, FMT_SHADOW, FMT_MAX, diff --git a/src/gapi_gl.h b/src/gapi_gl.h index d703680..3370559 100644 --- a/src/gapi_gl.h +++ b/src/gapi_gl.h @@ -3,7 +3,9 @@ #include "core.h" -//#define _DEBUG_SHADERS +#if defined(_DEBUG) || defined(PROFILE) + //#define _DEBUG_SHADERS +#endif #ifdef _OS_WIN #include @@ -20,6 +22,9 @@ #define GL_TEXTURE_COMPARE_FUNC 0x884D #define GL_COMPARE_REF_TO_TEXTURE 0x884E + #define GL_RG 0x8227 + #define GL_RG16F 0x822F + #define GL_RG32F 0x8230 #define GL_RGBA16F 0x881A #define GL_RGBA32F 0x8814 #define GL_HALF_FLOAT 0x140B @@ -53,10 +58,12 @@ #define GL_TEXTURE_COMPARE_FUNC 0x884D #define GL_COMPARE_REF_TO_TEXTURE 0x884E + #undef GL_RG #undef GL_RGBA32F #undef GL_RGBA16F #undef GL_HALF_FLOAT + #define GL_RG GL_RGBA #define GL_RGBA32F GL_RGBA #define GL_RGBA16F GL_RGBA #define GL_HALF_FLOAT GL_HALF_FLOAT_OES @@ -101,10 +108,17 @@ #define GL_CLAMP_TO_BORDER 0x812D #define GL_TEXTURE_BORDER_COLOR 0x1004 + // TODO: WTF? + #undef GL_RG #undef GL_RGBA32F #undef GL_RGBA16F + #undef GL_RG32F + #undef GL_RG16F #undef GL_HALF_FLOAT + #define RG GL_RGBA + #define GL_RG16F GL_RGBA + #define GL_RG32F GL_RGBA #define GL_RGBA32F GL_RGBA #define GL_RGBA16F GL_RGBA #define GL_HALF_FLOAT GL_HALF_FLOAT_OES @@ -120,6 +134,9 @@ #include #include + #define GL_RG 0x8227 + #define GL_RG16F 0x822F + #define GL_RG32F 0x8230 #define GL_RGBA16F 0x881A #define GL_RGBA32F 0x8814 #define GL_HALF_FLOAT 0x140B @@ -676,39 +693,43 @@ namespace GAPI { { GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE }, // RGBA { GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5 }, // RGB16 { GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1 }, // RGBA16 - { GL_RGBA32F, GL_RGBA, GL_FLOAT }, // RGBA_FLOAT - { GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT }, // RGBA_HALF + { GL_RG32F, GL_RG, GL_FLOAT }, // RG_FLOAT + { GL_RG16F, GL_RG, GL_HALF_FLOAT }, // RG_HALF { GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT }, // DEPTH { GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT }, // SHADOW }; FormatDesc desc = formats[fmt]; + if ((fmt == FMT_RG_FLOAT || fmt == FMT_RG_HALF) && !Core::support.texRG) { + desc.ifmt = (fmt == FMT_RG_FLOAT) ? GL_RGBA32F : GL_RGBA16F; + desc.fmt = GL_RGBA; + } + #ifdef _OS_WEB // fucking firefox! - if (fmt == FMT_RGBA_FLOAT) { + if (fmt == FMT_RG_FLOAT) { if (Core::support.texFloat) { desc.ifmt = GL_RGBA; desc.type = GL_FLOAT; } } - if (fmt == FMT_RGBA_HALF) { + if (fmt == FMT_RG_HALF) { if (Core::support.texHalf) { desc.ifmt = GL_RGBA; desc.type = GL_HALF_FLOAT_OES; } } #else - if ((fmt == FMT_RGBA_FLOAT && !Core::support.colorFloat) || (fmt == FMT_RGBA_HALF && !Core::support.colorHalf)) { + if ((fmt == FMT_RG_FLOAT && !Core::support.colorFloat) || (fmt == FMT_RG_HALF && !Core::support.colorHalf)) { desc.ifmt = GL_RGBA; #ifdef _GAPI_GLES - if (fmt == FMT_RGBA_HALF) + if (fmt == FMT_RG_HALF) desc.type = GL_HALF_FLOAT_OES; #endif } #endif - void *pix = data; if (data && !Core::support.texNPOT && (width != origWidth || height != origHeight)) pix = NULL; diff --git a/src/shaders/water.glsl b/src/shaders/water.glsl index 5b4e329..96fefec 100644 --- a/src/shaders/water.glsl +++ b/src/shaders/water.glsl @@ -35,6 +35,12 @@ uniform vec4 uRoomSize; uniform sampler2D sNormal; +vec3 calcNormal(vec2 tc, float base) { + float dx = texture2D(sNormal, vec2(tc.x + uTexParam.x, tc.y)).x - base; + float dz = texture2D(sNormal, vec2(tc.x, tc.y + uTexParam.y)).x - base; + return normalize( vec3(dx, 64.0 / (1024.0 * 8.0), dz) ); +} + #ifdef VERTEX attribute vec4 aCoord; @@ -63,8 +69,9 @@ uniform sampler2D sNormal; #ifdef WATER_CAUSTICS vec3 rCoord = vec3(coord.x, coord.y, 0.0) * uPosScale[1].xzy; - vec4 info = texture2D(sNormal, (rCoord.xy * 0.5 + 0.5) * uTexParam.zw); - vec3 normal = vec3(info.z, info.w, sqrt(1.0 - dot(info.zw, info.zw))); + vec2 tc = (rCoord.xy * 0.5 + 0.5) * uTexParam.zw; + vec4 info = texture2D(sNormal, tc); + vec3 normal = calcNormal(tc, info.x).xzy; vec3 light = vec3(0.0, 0.0, 1.0); vec3 refOld = refract(-light, vec3(0.0, 0.0, 1.0), 0.75); @@ -103,13 +110,13 @@ uniform sampler2D sNormal; } vec4 drop() { - vec4 v = texture2D(sNormal, vTexCoord); + vec2 v = texture2D(sNormal, vTexCoord).xy; float drop = max(0.0, 1.0 - length(uParam.xy - vTexCoord / uTexParam.xy) / uParam.z); drop = 0.5 - cos(drop * PI) * 0.5; v.x += drop * uParam.w; - return v; + return vec4(v, 0.0, 0.0); } #ifdef WATER_SIMULATE @@ -119,16 +126,13 @@ uniform sampler2D sNormal; if (texture2D(sMask, vMaskCoord).a < 0.5) return vec4(0.0); - vec4 v = texture2D(sNormal, tc); // height, speed, normal.xz + vec2 v = texture2D(sNormal, tc).xy; // height, speed vec3 d = vec3(uTexParam.xy, 0.0); vec4 f = vec4(texture2D(sNormal, tc + d.xz).x, texture2D(sNormal, tc + d.zy).x, texture2D(sNormal, tc - d.xz).x, texture2D(sNormal, tc - d.zy).x); float average = dot(f, vec4(0.25)); - // normal - v.zw = normalize( vec3(f.x - f.z, 64.0 / (1024.0 * 4.0), f.y - f.w) ).xz; - // integrate const float vel = 1.4; const float vis = 0.995; @@ -137,7 +141,7 @@ uniform sampler2D sNormal; float noise = texture2D(sDiffuse, tc + uParam.zw * 0.5).x; v.x += v.y + (noise * 2.0 - 1.0) * 0.00025; - return v; + return vec4(v.xy, 0.0, 0.0); } #endif @@ -206,9 +210,11 @@ uniform sampler2D sNormal; vec4 compose() { vec3 viewVec = normalize(vViewVec); - vec4 value = texture2D(sNormal, vTexCoord); - vec3 normal = vec3(value.z, sqrt(1.0 - dot(value.zw, value.zw)) * sign(viewVec.y), value.w); - vec2 dudv = (uViewProj * vec4(normal.x, 0.0, normal.z, 0.0)).xy; + vec2 value = texture2D(sNormal, vTexCoord).xy; + vec3 normal = calcNormal(vTexCoord, value.x); + normal.y *= sign(viewVec.y); + + vec2 dudv = (uViewProj * vec4(normal.x, 0.0, normal.z, 0.0)).xy; vec3 rv = reflect(-viewVec, normal); vec3 lv = normalize(vLightVec); diff --git a/src/texture.h b/src/texture.h index fec1134..d5bb6fb 100644 --- a/src/texture.h +++ b/src/texture.h @@ -92,14 +92,14 @@ struct Texture : GAPI::Texture { filter = false; } - if (format == FMT_RGBA_HALF) { + if (format == FMT_RG_HALF) { if (Core::support.texHalf) filter = filter && Core::support.texHalfLinear; else - format = FMT_RGBA_FLOAT; + format = FMT_RG_FLOAT; } - if (format == FMT_RGBA_FLOAT) { + if (format == FMT_RG_FLOAT) { if (Core::support.texFloat) filter = filter && Core::support.texFloatLinear; else