From ad259150b3d5b8b81cb006023031d95ca0b40adf Mon Sep 17 00:00:00 2001 From: XProger <xproger@list.ru> Date: Sun, 26 May 2019 02:27:19 +0300 Subject: [PATCH] fix 3DS build, fix autostereoscopy display support --- src/cache.h | 2 +- src/core.h | 6 ++- src/gapi/c3d.h | 23 +++-------- src/gapi/gl.h | 12 +++++- src/inventory.h | 36 ++++++++++------- src/level.h | 10 ++++- src/mesh.h | 56 +++++++++++++------------- src/platform/3ds/compose.v.pica | 41 +++++-------------- src/platform/3ds/filter_upscale.v.pica | 18 +++++---- src/platform/3ds/gui.v.pica | 29 +++++-------- src/shaders/gui.glsl | 10 ++--- src/ui.h | 43 +++++++++----------- src/utils.h | 55 ++++++++++++++++++++----- 13 files changed, 180 insertions(+), 161 deletions(-) diff --git a/src/cache.h b/src/cache.h index 131ec4a..ae80334 100644 --- a/src/cache.h +++ b/src/cache.h @@ -286,7 +286,7 @@ struct AmbientCache { mat4 mProj, mView; mView.identity(); - mProj.identity(); + mProj = GAPI::ortho(-1, +1, -1, +1, 0, 1); mProj.scale(vec3(1.0f / 32767.0f)); Core::setViewProj(mView, mProj); game->setShader(Core::passFilter, Shader::FILTER_DOWNSAMPLE); diff --git a/src/core.h b/src/core.h index c9f72cd..daa87e2 100644 --- a/src/core.h +++ b/src/core.h @@ -122,7 +122,11 @@ #include "utils.h" // muse be equal with base shader -#define SHADOW_TEX_SIZE 2048 +#ifdef __OS_3DS + #define SHADOW_TEX_SIZE 512 +#else + #define SHADOW_TEX_SIZE 2048 +#endif extern void* osMutexInit (); extern void osMutexFree (void *obj); diff --git a/src/gapi/c3d.h b/src/gapi/c3d.h index a7faed7..fc1d424 100644 --- a/src/gapi/c3d.h +++ b/src/gapi/c3d.h @@ -143,8 +143,7 @@ namespace GAPI { cbCount[uType] = count * 4; ASSERT(count == 1); - mat4 m = value.transpose(); - memcpy(cbMem + bindings[uType], &m, sizeof(m)); + memcpy(cbMem + bindings[uType], &value, sizeof(value)); } }; @@ -477,26 +476,14 @@ namespace GAPI { mat4 ortho(float l, float r, float b, float t, float znear, float zfar) { mat4 m; - Mtx_OrthoTilt((C3D_Mtx*)&m, l, r, b, t, znear, zfar, false); - - mat4 res; - res.e00 = m.e30; res.e10 = m.e31; res.e20 = m.e32; res.e30 = m.e33; - res.e01 = m.e20; res.e11 = m.e21; res.e21 = m.e22; res.e31 = m.e23; - res.e02 = m.e10; res.e12 = m.e11; res.e22 = m.e12; res.e32 = m.e13; - res.e03 = m.e00; res.e13 = m.e01; res.e23 = m.e02; res.e33 = m.e03; - return res; + m.ortho(mat4::PROJ_NEG_ZERO, l, r, b, t, znear, zfar, true); + return m; } mat4 perspective(float fov, float aspect, float znear, float zfar, float eye) { mat4 m; - Mtx_PerspTilt((C3D_Mtx*)&m, fov * DEG2RAD, aspect, znear, zfar, false); - - mat4 res; - res.e00 = m.e30; res.e10 = m.e31; res.e20 = m.e32; res.e30 = m.e33; - res.e01 = m.e20; res.e11 = m.e21; res.e21 = m.e22; res.e31 = m.e23; - res.e02 = m.e10; res.e12 = m.e11; res.e22 = m.e12; res.e32 = m.e13; - res.e03 = m.e00; res.e13 = m.e01; res.e23 = m.e02; res.e33 = m.e03; - return res; + m.perspective(mat4::PROJ_NEG_ZERO, fov, aspect, znear, zfar, eye, true); + return m; } bool beginFrame() { diff --git a/src/gapi/gl.h b/src/gapi/gl.h index 729297f..2a78fcd 100644 --- a/src/gapi/gl.h +++ b/src/gapi/gl.h @@ -430,6 +430,7 @@ namespace GAPI { typedef ::Vertex Vertex; int cullMode, blendMode; + bool depthWrite; char GLSL_HEADER_VERT[512]; char GLSL_HEADER_FRAG[512]; @@ -1454,7 +1455,15 @@ namespace GAPI { void clear(bool color, bool depth) { uint32 mask = (color ? GL_COLOR_BUFFER_BIT : 0) | (depth ? GL_DEPTH_BUFFER_BIT : 0); - if (mask) glClear(mask); + if (mask) { + if (depth && !depthWrite) { + glDepthMask(GL_TRUE); + glClear(mask); + glDepthMask(GL_FALSE); + } else { + glClear(mask); + } + } } void setClearColor(const vec4 &color) { @@ -1474,6 +1483,7 @@ namespace GAPI { } void setDepthWrite(bool enable) { + depthWrite = enable; glDepthMask(enable ? GL_TRUE : GL_FALSE); } diff --git a/src/inventory.h b/src/inventory.h index 98fc448..153f03f 100644 --- a/src/inventory.h +++ b/src/inventory.h @@ -1401,6 +1401,10 @@ struct Inventory { return; #endif + #ifdef _OS_3DS + return; + #endif + game->renderGame(false, true); Core::setDepthTest(false); @@ -1417,7 +1421,7 @@ struct Inventory { mat4 mProj, mView; mView.identity(); - mProj.identity(); + mProj = GAPI::ortho(-1, +1, -1, +1, 0, 1); mProj.scale(vec3(1.0f / 32767.0f)); Core::setViewProj(mView, mProj); @@ -1716,20 +1720,20 @@ struct Inventory { Index indices[10 * 3] = { 0,1,2, 0,2,3, 8,9,5, 8,5,4, 9,10,6, 9,6,5, 10,11,7, 10,7,6, 11,8,4, 11,4,7 }; Vertex vertices[4 * 3]; - vertices[ 0].coord = short4(-size.x, size.y, 0, 0); - vertices[ 1].coord = short4( size.x, size.y, 0, 0); - vertices[ 2].coord = short4( size.x, -size.y, 0, 0); - vertices[ 3].coord = short4(-size.x, -size.y, 0, 0); + vertices[ 0].coord = short4(-size.x, size.y, 0, 1); + vertices[ 1].coord = short4( size.x, size.y, 0, 1); + vertices[ 2].coord = short4( size.x, -size.y, 0, 1); + vertices[ 3].coord = short4(-size.x, -size.y, 0, 1); vertices[ 4].coord = vertices[0].coord; vertices[ 5].coord = vertices[1].coord; vertices[ 6].coord = vertices[2].coord; vertices[ 7].coord = vertices[3].coord; - vertices[ 8].coord = short4(-o_frame, o_frame, 0, 0); - vertices[ 9].coord = short4( o_frame, o_frame, 0, 0); - vertices[10].coord = short4( o_frame, -o_frame, 0, 0); - vertices[11].coord = short4(-o_frame, -o_frame, 0, 0); + vertices[ 8].coord = short4(-o_frame, o_frame, 0, 1); + vertices[ 9].coord = short4( o_frame, o_frame, 0, 1); + vertices[10].coord = short4( o_frame, -o_frame, 0, 1); + vertices[11].coord = short4(-o_frame, -o_frame, 0, 1); vertices[ 0].light = vertices[ 1].light = @@ -1770,7 +1774,7 @@ struct Inventory { mat4 mProj, mView; mView.identity(); - mProj.identity(); + mProj = GAPI::ortho(-1, +1, -1, +1, 0, 1); mProj.scale(vec3(1.0f / max(size.x, size.y))); mProj.translate(vec3(eye, 0.0f, 0.0f)); Core::setViewProj(mView, mProj); @@ -1783,10 +1787,10 @@ struct Inventory { void renderGameBG(int view) { Index indices[6] = { 0, 1, 2, 0, 2, 3 }; Vertex vertices[4]; - vertices[0].coord = short4(-32767, 32767, 0, 0); - vertices[1].coord = short4( 32767, 32767, 0, 0); - vertices[2].coord = short4( 32767, -32767, 0, 0); - vertices[3].coord = short4(-32767, -32767, 0, 0); + vertices[0].coord = short4(-32767, 32767, 0, 1); + vertices[1].coord = short4( 32767, 32767, 0, 1); + vertices[2].coord = short4( 32767, -32767, 0, 1); + vertices[3].coord = short4(-32767, -32767, 0, 1); vertices[0].light = vertices[1].light = vertices[2].light = @@ -1821,7 +1825,7 @@ struct Inventory { mat4 mProj, mView; mView.identity(); - mProj.identity(); + mProj = GAPI::ortho(-1, +1, -1, +1, 0, 1); mProj.scale(vec3(1.0f / 32767.0f)); Core::setViewProj(mView, mProj); @@ -1837,6 +1841,7 @@ struct Inventory { return; Core::setDepthTest(false); + Core::setDepthWrite(false); uint8 alpha; if (!isActive() && titleTimer > 0.0f && titleTimer < 1.0f) @@ -1863,6 +1868,7 @@ struct Inventory { Core::setBlendMode(bmPremult); Core::setDepthTest(true); + Core::setDepthWrite(true); } void setupCamera(float aspect, bool ui = false) { diff --git a/src/level.h b/src/level.h index ff75eed..bbc819b 100644 --- a/src/level.h +++ b/src/level.h @@ -3000,7 +3000,7 @@ struct Level : IGame { int texIndex = eye <= 0 ? 0 : 1; #ifdef _OS_3DS - Core::eye *= osGet3DSliderState() / 3.0f; + Core::eye *= osGet3DSliderState(); GAPI::curTarget = GAPI::defTarget[texIndex]; @@ -3081,9 +3081,12 @@ struct Level : IGame { if (Core::settings.detail.stereo == Core::Settings::STEREO_ANAGLYPH && !invBG) { mat4 mProj, mView; mView.identity(); - mProj.identity(); + mProj = GAPI::ortho(-1, +1, -1, +1, 0, 1); mProj.scale(vec3(1.0f / 32767.0f)); Core::setViewProj(mView, mProj); +\ + Core::setDepthTest(false); + Core::setDepthWrite(false); Core::setTarget(NULL, NULL, RT_STORE_COLOR); setShader(Core::passFilter, Shader::FILTER_ANAGLYPH, false, false); @@ -3091,6 +3094,9 @@ struct Level : IGame { Core::eyeTex[1]->bind(sNormal); Core::setDepthTest(false); mesh->renderQuad(); + + Core::setDepthTest(true); + Core::setDepthWrite(true); } } diff --git a/src/mesh.h b/src/mesh.h index 5eabba5..9ecad6f 100644 --- a/src/mesh.h +++ b/src/mesh.h @@ -1208,17 +1208,17 @@ struct MeshBuilder { #ifndef MERGE_SPRITES if (!expand) { vec3 pos = vec3(float(x), float(y), float(z)); - quad[0].coord = coordTransform(pos, vec3( float(sprite.l), float(-sprite.t), 0 )); - quad[1].coord = coordTransform(pos, vec3( float(sprite.r), float(-sprite.t), 0 )); - quad[2].coord = coordTransform(pos, vec3( float(sprite.r), float(-sprite.b), 0 )); - quad[3].coord = coordTransform(pos, vec3( float(sprite.l), float(-sprite.b), 0 )); + quad[0].coord = coordTransform(pos, vec3( float(sprite.l), float(-sprite.t), 1 )); + quad[1].coord = coordTransform(pos, vec3( float(sprite.r), float(-sprite.t), 1 )); + quad[2].coord = coordTransform(pos, vec3( float(sprite.r), float(-sprite.b), 1 )); + quad[3].coord = coordTransform(pos, vec3( float(sprite.l), float(-sprite.b), 1 )); } else #endif { - quad[0].coord = short4( x0, y0, z, 0 ); - quad[1].coord = short4( x1, y0, z, 0 ); - quad[2].coord = short4( x1, y1, z, 0 ); - quad[3].coord = short4( x0, y1, z, 0 ); + quad[0].coord = short4( x0, y0, z, 1 ); + quad[1].coord = short4( x1, y0, z, 1 ); + quad[2].coord = short4( x1, y1, z, 1 ); + quad[3].coord = short4( x0, y1, z, 1 ); } quad[0].normal = quad[1].normal = quad[2].normal = quad[3].normal = short4( 0, 0, 0, 0 ); @@ -1250,10 +1250,10 @@ struct MeshBuilder { int16 maxX = int16(size.x) + minX; int16 maxY = int16(size.y) + minY; - vertices[vCount + 0].coord = short4( minX, minY, 0, 0 ); - vertices[vCount + 1].coord = short4( maxX, minY, 0, 0 ); - vertices[vCount + 2].coord = short4( maxX, maxY, 0, 0 ); - vertices[vCount + 3].coord = short4( minX, maxY, 0, 0 ); + vertices[vCount + 0].coord = short4( minX, minY, 0, 1 ); + vertices[vCount + 1].coord = short4( maxX, minY, 0, 1 ); + vertices[vCount + 2].coord = short4( maxX, maxY, 0, 1 ); + vertices[vCount + 3].coord = short4( minX, maxY, 0, 1 ); for (int i = 0; i < 4; i++) { Vertex &v = vertices[vCount + i]; @@ -1286,15 +1286,15 @@ struct MeshBuilder { int16 maxX = int16(size.x) + minX; int16 maxY = int16(size.y) + minY; - vertices[vCount + 0].coord = short4( minX, minY, 0, 0 ); - vertices[vCount + 1].coord = short4( maxX, minY, 0, 0 ); - vertices[vCount + 2].coord = short4( maxX, int16(minY + 1), 0, 0 ); - vertices[vCount + 3].coord = short4( minX, int16(minY + 1), 0, 0 ); + vertices[vCount + 0].coord = short4( minX, minY, 0, 1 ); + vertices[vCount + 1].coord = short4( maxX, minY, 0, 1 ); + vertices[vCount + 2].coord = short4( maxX, int16(minY + 1), 0, 1 ); + vertices[vCount + 3].coord = short4( minX, int16(minY + 1), 0, 1 ); - vertices[vCount + 4].coord = short4( minX, minY, 0, 0 ); - vertices[vCount + 5].coord = short4( int16(minX + 1), minY, 0, 0 ); - vertices[vCount + 6].coord = short4( int16(minX + 1), maxY, 0, 0 ); - vertices[vCount + 7].coord = short4( minX, maxY, 0, 0 ); + vertices[vCount + 4].coord = short4( minX, minY, 0, 1 ); + vertices[vCount + 5].coord = short4( int16(minX + 1), minY, 0, 1 ); + vertices[vCount + 6].coord = short4( int16(minX + 1), maxY, 0, 1 ); + vertices[vCount + 7].coord = short4( minX, maxY, 0, 1 ); for (int i = 0; i < 8; i++) { Vertex &v = vertices[vCount + i]; @@ -1306,15 +1306,15 @@ struct MeshBuilder { addQuad(indices, iCount, vCount, 0, vertices, NULL, false, false); vCount += 4; addQuad(indices, iCount, vCount, 0, vertices, NULL, false, false); vCount += 4; - vertices[vCount + 0].coord = short4( minX, int16(maxY - 1), 0, 0 ); - vertices[vCount + 1].coord = short4( maxX, int16(maxY - 1), 0, 0 ); - vertices[vCount + 2].coord = short4( maxX, maxY, 0, 0 ); - vertices[vCount + 3].coord = short4( minX, maxY, 0, 0 ); + vertices[vCount + 0].coord = short4( minX, int16(maxY - 1), 0, 1 ); + vertices[vCount + 1].coord = short4( maxX, int16(maxY - 1), 0, 1 ); + vertices[vCount + 2].coord = short4( maxX, maxY, 0, 1 ); + vertices[vCount + 3].coord = short4( minX, maxY, 0, 1 ); - vertices[vCount + 4].coord = short4( int16(maxX - 1), minY, 0, 0 ); - vertices[vCount + 5].coord = short4( maxX, minY, 0, 0 ); - vertices[vCount + 6].coord = short4( maxX, maxY, 0, 0 ); - vertices[vCount + 7].coord = short4( int16(maxX - 1), maxY, 0, 0 ); + vertices[vCount + 4].coord = short4( int16(maxX - 1), minY, 0, 1 ); + vertices[vCount + 5].coord = short4( maxX, minY, 0, 1 ); + vertices[vCount + 6].coord = short4( maxX, maxY, 0, 1 ); + vertices[vCount + 7].coord = short4( int16(maxX - 1), maxY, 0, 1 ); for (int i = 0; i < 8; i++) { Vertex &v = vertices[vCount + i]; diff --git a/src/platform/3ds/compose.v.pica b/src/platform/3ds/compose.v.pica index 41a2d3d..a4a157c 100644 --- a/src/platform/3ds/compose.v.pica +++ b/src/platform/3ds/compose.v.pica @@ -20,19 +20,8 @@ .proc main ; mulQuat - ;mul r0.xyz, uBasis[0], aCoord.zxy - ;mad r0.xyz, aCoord, uBasis[0].zxy, -r0 - ;mad r0.xyz, aCoord.yzx, uBasis[0].w, r0 - ;mul r1.xyz, uBasis[0].zxy, r0 - ;mad r0.xyz, r0.yzx, uBasis[0].yzx, -r1 - ;mad r0.xyz, r0, const0.x, aCoord - ;add r0.xyz, uBasis[1], r0 - ;mov r0.w, uBasis[1].w - mul r0.x, const0.xxxx, aCoord.wwww - - ;frc r0.x, v0.w - ;add r0.x, -r0.x, v0.w + mova a0.x, r0.x mul r0.xyz, uBasis[a0.x], aCoord.zxyw mad r0.xyz, aCoord, uBasis[a0.x].zxyw, -r0 @@ -44,24 +33,16 @@ mov r0.w, uBasis[a0.x + 1].w ; uViewProj * coord - dp4 vPosition.x, uViewProj[0], r0 - dp4 vPosition.y, uViewProj[1], r0 - dp4 vPosition.z, uViewProj[2], r0 - dp4 vPosition.w, uViewProj[3], r0 - - mul r2, const1.xxxx, aTexCoord.xyzw - mov vTexCoord, r2 - - mov r3, aColor - mul r3, const1.yyyy, r3.xyzw - - mov r4, aLight - mul r4, const1.yyyy, r4.xyzw - + mul r1, uViewProj[0], r0.xxxx + mad r1, r0.yyyy, uViewProj[1], r1 + mad r1, r0.zzzz, uViewProj[2], r1 + mad vPosition, r0.wwww, uViewProj[3], r1 + + mul vTexCoord, const1.xxxx, aTexCoord.xyzw + + mul r3, const1.yyyy, aColor + mul r4, const1.yyyy, aLight mul vColor, r3, r4 - ;mov vColor, r3 - ;mov vColor.xyz, r2.xyz - ;mov vColor.w, const0.yyyy - + end .end diff --git a/src/platform/3ds/filter_upscale.v.pica b/src/platform/3ds/filter_upscale.v.pica index d8e05e7..be68a1f 100644 --- a/src/platform/3ds/filter_upscale.v.pica +++ b/src/platform/3ds/filter_upscale.v.pica @@ -1,5 +1,8 @@ ; constants -.constf const0(1.0, 3.05185094e-005, 0.00392156886, -0.5) +.constf const0(3.05185094e-005, 0.00392156886, 0.0, 0.0) + +; uniforms +.fvec uViewProj[4] ; in .alias aCoord v0 @@ -12,13 +15,14 @@ .out vColor color .proc main - mul r0.xyzw, const0.yyyy, aCoord.yxzw - mov r0.w, const0.xxxx - mov r0.y, -r0.y - mov vPosition, r0 +; uViewProj * coord + mov r0, uViewProj[3] + mad r1, aCoord.xxxx, uViewProj[0], r0 + mad r1, aCoord.yyyy, uViewProj[1], r1 + mad vPosition, aCoord.zzzz, uViewProj[2], r1 - mul vTexCoord, const0.yyyy, aTexCoord - mul vColor, const0.zzzz, aLight + mul vTexCoord, const0.xxxx, aTexCoord + mul vColor, const0.yyyy, aLight end .end diff --git a/src/platform/3ds/gui.v.pica b/src/platform/3ds/gui.v.pica index 3a68fe7..409a127 100644 --- a/src/platform/3ds/gui.v.pica +++ b/src/platform/3ds/gui.v.pica @@ -1,6 +1,5 @@ ; constants -.constf const0(2.0, 1.0, 0.5, 0.25) -.constf const1(3.05185094e-005, 0.00392156886, 0.00784313725, 0.0) +.constf const0(3.05185094e-005, 0.00392156886, 1.0, 0.0) ; uniforms .fvec uViewProj[4] @@ -8,9 +7,7 @@ ; in .alias aCoord v0 -.alias aNormal v1 .alias aTexCoord v2 -.alias aColor v3 .alias aLight v4 ; out @@ -19,21 +16,15 @@ .out vColor color .proc main - mov r0.xyz, aCoord - mov r0.w, const0.yyyy - ; uViewProj * coord - dp4 vPosition.x, uViewProj[0], r0 - dp4 vPosition.y, uViewProj[1], r0 - dp4 vPosition.z, uViewProj[2], r0 - dp4 vPosition.w, uViewProj[3], r0 - - mul r2, const1.xxxx, aTexCoord.xyzw - mov vTexCoord, r2 - - mov r3, aLight - mul r3, const1.yyyy, r3.xyzw - mul vColor, uMaterial, r3 - + mov r0, uViewProj[3] + mad r1, aCoord.xxxx, uViewProj[0], r0 + mad r1, aCoord.yyyy, uViewProj[1], r1 + mad vPosition, aCoord.zzzz, uViewProj[2], r1 + + mul vTexCoord, const0.xxxx, aTexCoord + mul r2, const0.yyyy, aLight + mul vColor, uMaterial, r2 + end .end diff --git a/src/shaders/gui.glsl b/src/shaders/gui.glsl index c800a0f..54ef398 100644 --- a/src/shaders/gui.glsl +++ b/src/shaders/gui.glsl @@ -11,15 +11,15 @@ varying vec4 vColor; attribute vec4 aLight; void main() { - vTexCoord = aTexCoord.xy; - vColor = aLight * uMaterial; - gl_Position = uViewProj * vec4(aCoord.xyz, 1.0); + vTexCoord = aTexCoord.xy; + vColor = aLight * uMaterial; + gl_Position = uViewProj * aCoord; } #else - uniform sampler2D sDiffuse; + uniform sampler2D sDiffuse; void main() { fragColor = texture2D(sDiffuse, vTexCoord) * vColor; } #endif -)====" \ No newline at end of file +)====" diff --git a/src/ui.h b/src/ui.h index 3d565ee..060a282 100644 --- a/src/ui.h +++ b/src/ui.h @@ -105,8 +105,14 @@ namespace UI { void patchGlyphs(TR::Level &level) { UI::advGlyphsStart = level.spriteTexturesCount; - TR::TextureInfo ruSprites[RU_GLYPH_COUNT]; - for (int i = 0; i < COUNT(ruSprites); i++) { + // init new sprites array with additional sprites + TR::TextureInfo *newSprites = new TR::TextureInfo[level.spriteTexturesCount + RU_GLYPH_COUNT + JA_GLYPH_COUNT + GR_GLYPH_COUNT]; + + // copy original sprites + memcpy(newSprites, level.spriteTextures, sizeof(TR::TextureInfo) * level.spriteTexturesCount); + // append russian glyphs + TR::TextureInfo *ruSprites = newSprites + level.spriteTexturesCount; + for (int i = 0; i < RU_GLYPH_COUNT; i++) { int idx = 110 + i; // mapped index int w = char_width[idx]; int h = upperCase(idx) ? 13 : 9; @@ -119,34 +125,21 @@ namespace UI { ruSprites[i] = TR::TextureInfo(TR::TEX_TYPE_SPRITE, 0, -h + o, w, o, (i % 16) * 16, (i / 16) * 16 + (16 - h), w, h); } - - TR::TextureInfo jaSprites[JA_GLYPH_COUNT]; - for (int i = 0; i < COUNT(jaSprites); i++) { + // append japanese glyphs + TR::TextureInfo *jaSprites = newSprites + level.spriteTexturesCount + RU_GLYPH_COUNT; + for (int i = 0; i < JA_GLYPH_COUNT; i++) { jaSprites[i] = TR::TextureInfo(TR::TEX_TYPE_SPRITE, 0, -16, 16, 0, (i % 16) * 16, ((i % 256) / 16) * 16, 16, 16); } - - TR::TextureInfo grSprites[GR_GLYPH_COUNT]; - for (int i = 0; i < COUNT(grSprites); i++) { + // append greek glyphs + TR::TextureInfo *grSprites = newSprites + level.spriteTexturesCount + RU_GLYPH_COUNT + JA_GLYPH_COUNT; + for (int i = 0; i < GR_GLYPH_COUNT; i++) { grSprites[i] = TR::TextureInfo(TR::TEX_TYPE_SPRITE, 0, -16 + GR_GLYPH_BASE - 1, GR_GLYPH_WIDTH[i], 0 + GR_GLYPH_BASE - 1, (i % 16) * 16, ((i % 256) / 16) * 16, GR_GLYPH_WIDTH[i], 16); } - // init new sprites array with additional sprites - TR::TextureInfo *newSprites = new TR::TextureInfo[level.spriteTexturesCount + COUNT(ruSprites) + COUNT(jaSprites) + COUNT(grSprites)]; - // copy original sprites - memcpy(newSprites, level.spriteTextures, sizeof(TR::TextureInfo) * level.spriteTexturesCount); - // append russian glyphs - memcpy(newSprites + level.spriteTexturesCount, ruSprites, sizeof(TR::TextureInfo) * COUNT(ruSprites)); - level.spriteTexturesCount += COUNT(ruSprites); - // append japanese glyphs - memcpy(newSprites + level.spriteTexturesCount, jaSprites, sizeof(TR::TextureInfo) * COUNT(jaSprites)); - level.spriteTexturesCount += COUNT(jaSprites); - // append greek glyphs - memcpy(newSprites + level.spriteTexturesCount, grSprites, sizeof(TR::TextureInfo) * COUNT(grSprites)); - level.spriteTexturesCount += COUNT(grSprites); + level.spriteTexturesCount += RU_GLYPH_COUNT + JA_GLYPH_COUNT + GR_GLYPH_COUNT; delete[] level.spriteTextures; - level.spriteTextures = newSprites; - TR::gSpriteTextures = level.spriteTextures; + TR::gSpriteTextures = level.spriteTextures = newSprites; TR::gSpriteTexturesCount = level.spriteTexturesCount; } @@ -276,6 +269,7 @@ namespace UI { ensureLanguage(Core::settings.audio.language); Core::setDepthTest(false); + Core::setDepthWrite(false); Core::setBlendMode(bmPremult); Core::setCullMode(cmNone); game->setupBinding(); @@ -298,6 +292,7 @@ namespace UI { Core::setCullMode(cmFront); Core::setBlendMode(bmNone); Core::setDepthTest(true); + Core::setDepthWrite(true); } enum ShadeType { @@ -802,6 +797,7 @@ namespace UI { Basis joints[MAX_SPHERES]; Core::setDepthTest(true); + Core::setDepthWrite(true); for (int i = 0; i < pickups.length; i++) { const PickupItem &item = pickups[i]; @@ -836,6 +832,7 @@ namespace UI { } Core::setDepthTest(false); + Core::setDepthWrite(false); Core::setViewProj(mView, Core::mProj); game->setShader(Core::passGUI, Shader::DEFAULT); diff --git a/src/utils.h b/src/utils.h index 38d6b77..712062e 100644 --- a/src/utils.h +++ b/src/utils.h @@ -615,6 +615,7 @@ struct mat4 { enum ProjRange { PROJ_NEG_POS, + PROJ_NEG_ZERO, PROJ_ZERO_POS, }; @@ -646,30 +647,49 @@ struct mat4 { e33 = 1.0f; } - void ortho(ProjRange range, float l, float r, float b, float t, float znear, float zfar) { + void ortho(ProjRange range, float l, float r, float b, float t, float znear, float zfar, bool rotate90 = false) { identity(); - e00 = 2.0f / (r - l); - e11 = 2.0f / (t - b); - e22 = 2.0f / (znear - zfar); + if (rotate90) { + e00 = e11 = 0.0f; + e01 = 2.0f / (r - l); + e10 = 2.0f / (b - t); + } else { + e00 = 2.0f / (r - l); + e11 = 2.0f / (t - b); + } + e03 = (l + r) / (l - r); e13 = (t + b) / (b - t); switch (range) { case PROJ_NEG_POS : - e23 = (zfar + znear) / (znear - zfar); + e22 = 2.0f / (znear - zfar); + e23 = (znear + zfar) / (znear - zfar); + break; + case PROJ_NEG_ZERO : + e22 = 1.0f / (znear - zfar); + e23 = (znear + zfar) / (znear - zfar) * 0.5f - 0.5f; break; case PROJ_ZERO_POS : + e22 = 2.0f / (znear - zfar); e23 = znear / (znear - zfar); break; } } - void frustum(ProjRange range, float l, float r, float b, float t, float znear, float zfar) { + void frustum(ProjRange range, float l, float r, float b, float t, float znear, float zfar, bool rotate90 = false) { identity(); - e00 = 2.0f * znear / (r - l); - e11 = 2.0f * znear / (t - b); + if (rotate90) { + e00 = e11 = 0.0f; + e01 = 2.0f * znear / (r - l); + e10 = 2.0f * znear / (b - t); + } else { + e00 = 2.0f * znear / (r - l); + e11 = 2.0f * znear / (t - b); + } + e02 = (r + l) / (r - l); e12 = (t + b) / (t - b); e32 = -1.0f; @@ -680,6 +700,10 @@ struct mat4 { e22 = (znear + zfar) / (znear - zfar); e23 = 2.0f * zfar * znear / (znear - zfar); break; + case PROJ_NEG_ZERO : + e22 = znear / (znear - zfar); + e23 = zfar * znear / (znear - zfar); + break; case PROJ_ZERO_POS : e22 = zfar / (znear - zfar); e23 = znear * e22; @@ -687,18 +711,27 @@ struct mat4 { } } - void perspective(ProjRange range, float fov, float aspect, float znear, float zfar, float eye = 0.0f) { + void perspective(ProjRange range, float fov, float aspect, float znear, float zfar, float eye = 0.0f, bool rotate90 = false) { float y = tanf(fov * 0.5f * DEG2RAD) * znear; float x = y; + float eyeX, eyeY; + if (rotate90) { + eyeX = 0.0f; + eyeY = -eye; + aspect = 1.0f / aspect; + } else { + eyeX = eye; + eyeY = 0.0f; + } + if (aspect >= 1.0f) { x = y * aspect; } else { - x = y; y /= aspect; } - frustum(range, -x - eye, x - eye, -y, y, znear, zfar); + frustum(range, -x - eyeX, x - eyeX, -y - eyeY, y - eyeY, znear, zfar, rotate90); } mat4(const vec3 &from, const vec3 &at, const vec3 &up) {