diff --git a/CMakeLists.txt b/CMakeLists.txt index ef973dd..a7fd395 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -100,11 +100,11 @@ function(add_shader FILE) endif() package(${JSON}) endfunction() -add_shader(hud.frag src/hud.inc) +add_shader(hud.frag src/hud.inc shaders/font.hlsl) add_shader(hud.vert src/hud.inc) add_shader(opaque.frag shaders/shader.hlsl src/voxel.inc) add_shader(opaque.vert shaders/shader.hlsl src/voxel.inc) -add_shader(raycast.frag shaders/shader.hlsl src/voxel.inc) +add_shader(raycast.frag) add_shader(raycast.vert shaders/shader.hlsl src/voxel.inc) add_shader(sky.frag shaders/shader.hlsl src/voxel.inc) add_shader(sky.vert shaders/shader.hlsl src/voxel.inc) diff --git a/README.md b/README.md index 8599f03..0d3bd2e 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # Blocks -![](image.png) +![](doc/image2.png) +![](doc/image1.jpg) Tiny Minecraft clone in C and HLSL using the new SDL3 GPU API @@ -87,9 +88,3 @@ To build locally, add [SDL_shadercross](https://github.com/libsdl-org/SDL_shader - Left side of the screen to move - Right side of the screen to look -- `Blue` to jump -- `Purple` to toggle fly -- `Red` to break a block -- `Green` to place a block -- `Grey` to change blocks -- `Yellow` to sprint diff --git a/doc/image1.jpg b/doc/image1.jpg new file mode 100644 index 0000000..444ee33 Binary files /dev/null and b/doc/image1.jpg differ diff --git a/image.png b/doc/image2.png similarity index 100% rename from image.png rename to doc/image2.png diff --git a/shaders/bin/hud.frag.msl b/shaders/bin/hud.frag.msl index de69520..1c2c8dc 100644 --- a/shaders/bin/hud.frag.msl +++ b/shaders/bin/hud.frag.msl @@ -49,7 +49,9 @@ struct type_UniformBuffer uint Block; }; -constant spvUnsafeArray _62 = spvUnsafeArray({ float3(0.449999988079071044921875, 0.85000002384185791015625, 0.5), float3(0.949999988079071044921875, 0.449999988079071044921875, 0.449999988079071044921875), float3(0.449999988079071044921875, 0.75, 0.949999988079071044921875), float3(0.949999988079071044921875, 0.800000011920928955078125, 0.4000000059604644775390625), float3(0.7200000286102294921875, 0.7400000095367431640625, 0.7799999713897705078125), float3(0.75, 0.550000011920928955078125, 0.949999988079071044921875) }); +constant spvUnsafeArray _332 = spvUnsafeArray({ uint2(0u), uint2(406600728u, 1572888u), uint2(13878u, 0u), uint2(914306614u, 3552895u), uint2(503528972u, 794416u), uint2(406020864u, 6514188u), uint2(1847342620u, 7222075u), uint2(198150u, 0u), uint2(101059608u, 1575942u), uint2(404229126u, 396312u), uint2(4282148352u, 26172u), uint2(1057754112u, 3084u), uint2(0u, 101452800u), uint2(1056964608u, 0u), uint2(0u, 789504u), uint2(202911840u, 66310u), uint2(2071159614u, 4089711u), uint2(202116620u, 4131852u), uint2(472920862u, 4141830u), uint2(472920862u, 1979184u), uint2(859192376u, 7876735u), uint2(807338815u, 1979184u), uint2(520291868u, 1979187u), uint2(405812031u, 789516u), uint2(506671902u, 1979187u), uint2(1043542814u, 923696u), uint2(789504u), uint2(789504u, 101452800u), uint2(50727960u, 1575942u), uint2(4128768u, 16128u), uint2(806882310u, 396312u), uint2(405811998u, 786444u), uint2(2071683902u, 1966971u), uint2(858988044u, 3355455u), uint2(1046898239u, 4154982u), uint2(50554428u, 3958275u), uint2(1717974559u, 2045542u), uint2(504776319u, 8341014u), uint2(504776319u, 984598u), uint2(50554428u, 8152691u), uint2(1060320051u, 3355443u), uint2(202116126u, 1969164u), uint2(808464504u, 1979187u), uint2(506881639u, 6776374u), uint2(101058063u, 8349254u), uint2(2139060067u, 6513515u), uint2(2070898531u, 6513523u), uint2(1667446300u, 1848931u), uint2(1046898239u, 984582u), uint2(858993438u, 3677755u), uint2(1046898239u, 6776374u), uint2(235352862u, 1979192u), uint2(202124607u, 1969164u), uint2(858993459u, 4141875u), uint2(858993459u, 794163u), uint2(1801675619u, 6518655u), uint2(473326435u, 6501916u), uint2(506671923u, 1969164u), uint2(405889919u, 8349260u), uint2(101058078u, 1967622u), uint2(403441155u, 4218928u), uint2(404232222u, 1972248u), uint2(1664490504u, 0u), uint2(0u, 4278190080u), uint2(1575948u, 0u), uint2(807272448u, 7222078u), uint2(1040582151u, 3892838u), uint2(857604096u, 1979139u), uint2(1043345464u, 7222067u), uint2(857604096u, 1966911u), uint2(252065308u, 984582u), uint2(862846976u, 523255347u), uint2(1849034247u, 6776422u), uint2(202244108u, 1969164u), uint2(808452144u, 506671920u), uint2(912655879u, 6764062u), uint2(202116110u, 1969164u), uint2(2134048768u, 6515583u), uint2(857669632u, 3355443u), uint2(857604096u, 1979187u), uint2(1715142656u, 252067430u), uint2(862846976u, 2016427571u), uint2(1849360384u, 984678u), uint2(54394880u, 2043934u), uint2(205392904u, 1584140u), uint2(858980352u, 7222067u), uint2(858980352u, 794163u), uint2(1801650176u, 3571583u), uint2(912457728u, 6501916u), uint2(858980352u, 523255347u), uint2(423559168u, 4138508u), uint2(118230072u, 3673100u), uint2(1579032u), uint2(940313607u, 461836u), uint2(15214u, 0u), uint2(0u) }); +constant spvUnsafeArray _333 = spvUnsafeArray({ 5u, 5u, 4u, 6u, 1u, 3u, 1u }); +constant spvUnsafeArray _334 = spvUnsafeArray({ uint2(1128352848u, 69u), uint2(1095062082u, 75u), uint2(1347245386u, 0u), uint2(1230131283u, 21582u), uint2(62u, 0u), uint2(5852230u, 0u), uint2(60u, 0u) }); struct main0_out { @@ -65,44 +67,115 @@ struct main0_in fragment main0_out main0(main0_in in [[stage_in]], constant type_UniformBuffer& UniformBuffer [[buffer(0)]], texture2d_array atlasTexture [[texture(0)]], sampler atlasSampler [[sampler(0)]]) { main0_out out = {}; - float4 _113; + float4 _450; do { - bool _73; + bool _346; if (in.in_var_TEXCOORD1 != 0u) { - _73 = in.in_var_TEXCOORD1 == 1u; + _346 = in.in_var_TEXCOORD1 == 1u; } else { - _73 = true; + _346 = true; } - if (_73) + if (_346) { - _113 = float4(1.0); + _450 = float4(1.0); break; } if (in.in_var_TEXCOORD1 == 2u) { - float3 _86 = float3(in.in_var_TEXCOORD0, float(UniformBuffer.Block)); - float4 _88 = atlasTexture.sample(atlasSampler, _86.xy, uint(rint(_86.z))); - if (_88.w <= 0.001000000047497451305389404296875) + float3 _359 = float3(in.in_var_TEXCOORD0, float(UniformBuffer.Block)); + float4 _361 = atlasTexture.sample(atlasSampler, _359.xy, uint(rint(_359.z))); + if (_361.w <= 0.001000000047497451305389404296875) { discard_fragment(); } - _113 = _88; + _450 = _361; break; } - float _94 = length(in.in_var_TEXCOORD0 - float2(0.5)); - float _95 = fwidth(_94); - if (_94 > 0.5) + float2 _366 = in.in_var_TEXCOORD0 - float2(0.5); + float _367 = length(_366); + float _368 = fwidth(_367); + if (_367 > 0.5) { discard_fragment(); } - _113 = float4(_62[in.in_var_TEXCOORD1 - 3u], mix(0.119999997317790985107421875, 0.75, smoothstep(0.4650000035762786865234375 - _95, 0.4650000035762786865234375, _94)) * (1.0 - smoothstep(0.5 - _95, 0.5, _94))); - break; + uint _377 = in.in_var_TEXCOORD1 - 3u; + bool _443; + do + { + float2 _386 = float2(float(_333[_377] * 8u), 8.0); + float2 _389 = (_366 * 60.0) + (_386 * 0.5); + bool _397; + if (!any(_389 < float2(0.0))) + { + _397 = any(_389 >= _386); + } + else + { + _397 = true; + } + if (_397) + { + _443 = false; + break; + } + uint2 _400 = uint2(_389); + uint _401 = _400.x; + uint _402 = _401 / 8u; + uint _409; + if (_402 < 4u) + { + _409 = _334[_377].x; + } + else + { + _409 = _334[_377].y; + } + uint _414 = (_409 >> (((_402 & 3u) * 8u) & 31u)) & 255u; + bool _419; + if (_414 >= 32u) + { + _419 = _414 > 127u; + } + else + { + _419 = true; + } + if (_419) + { + _443 = false; + break; + } + uint _422 = _414 - 32u; + uint _425 = _400.y; + uint _432; + if (_425 < 4u) + { + _432 = _332[_422].x; + } + else + { + _432 = _332[_422].y; + } + _443 = ((((_432 >> (((_425 & 3u) * 8u) & 31u)) & 255u) >> ((_401 % 8u) & 31u)) & 1u) != 0u; + break; + } while(false); + if (_443) + { + _450 = float4(0.86000001430511474609375, 0.87999999523162841796875, 0.920000016689300537109375, 0.949999988079071044921875); + break; + } + else + { + _450 = float4(0.86000001430511474609375, 0.87999999523162841796875, 0.920000016689300537109375, mix(0.119999997317790985107421875, 0.75, smoothstep(0.4650000035762786865234375 - _368, 0.4650000035762786865234375, _367)) * (1.0 - smoothstep(0.5 - _368, 0.5, _367))); + break; + } + break; // unreachable workaround } while(false); - out.out_var_SV_Target0 = _113; + out.out_var_SV_Target0 = _450; return out; } diff --git a/shaders/bin/hud.frag.spv b/shaders/bin/hud.frag.spv index f46e6b3..8ecb25f 100644 Binary files a/shaders/bin/hud.frag.spv and b/shaders/bin/hud.frag.spv differ diff --git a/shaders/bin/hud.vert.msl b/shaders/bin/hud.vert.msl index a91cbfd..90c3e0b 100644 --- a/shaders/bin/hud.vert.msl +++ b/shaders/bin/hud.vert.msl @@ -52,8 +52,8 @@ struct type_UniformBuffer int4 Safe; }; -constant spvUnsafeArray _63 = spvUnsafeArray({ float2(0.0), float2(1.0, 0.0), float2(0.0, 1.0), float2(0.0, 1.0), float2(1.0, 0.0), float2(1.0) }); -constant spvUnsafeArray _64 = spvUnsafeArray({ float2(100.0), float2(210.0, 100.0), float2(100.0, 210.0), float2(210.0), float2(100.0), float2(100.0, 210.0) }); +constant spvUnsafeArray _68 = spvUnsafeArray({ float2(0.0), float2(1.0, 0.0), float2(0.0, 1.0), float2(0.0, 1.0), float2(1.0, 0.0), float2(1.0) }); +constant spvUnsafeArray _69 = spvUnsafeArray({ float2(100.0), float2(210.0, 100.0), float2(100.0, 210.0), float2(210.0), float2(100.0, 320.0), float2(100.0, 210.0), float2(100.0, 320.0) }); struct main0_out { @@ -65,87 +65,82 @@ struct main0_out vertex main0_out main0(constant type_UniformBuffer& UniformBuffer [[buffer(0)]], uint gl_VertexIndex [[vertex_id]], uint gl_InstanceIndex [[instance_id]]) { main0_out out = {}; - float2 _75 = float2(UniformBuffer.Viewport); - float4 _78 = float4(UniformBuffer.Safe); - float _80 = _75.x * 0.0007812500116415321826934814453125; - float _82 = _75.y * 0.001388888922519981861114501953125; - float _84 = (_80 > _82) ? _80 : _82; - bool _89; + float2 _79 = float2(UniformBuffer.Viewport); + float4 _82 = float4(UniformBuffer.Safe); + float _84 = _79.x * 0.0007812500116415321826934814453125; + float _86 = _79.y * 0.001388888922519981861114501953125; + float _88 = (_84 > _86) ? _84 : _86; + bool _93; if (gl_InstanceIndex != 0u) { - _89 = gl_InstanceIndex == 1u; + _93 = gl_InstanceIndex == 1u; } else { - _89 = true; + _93 = true; } - float2 _171; - float2 _172; - if (_89) + float2 _156; + float2 _157; + if (_93) { - float2 _164 = _75 * 0.5; - float2 _168 = select(float2(2.0, 8.0), float2(8.0, 2.0), bool2(gl_InstanceIndex == 0u)) * _84; - _171 = _164 + _168; - _172 = _164 - _168; + float2 _97 = _79 * 0.5; + float2 _101 = select(float2(2.0, 8.0), float2(8.0, 2.0), bool2(gl_InstanceIndex == 0u)) * _88; + _156 = _97 + _101; + _157 = _97 - _101; } else { - float2 _162; - float2 _163; + float2 _154; + float2 _155; if (gl_InstanceIndex == 2u) { - float2 _160; - float2 _161; - if (UniformBuffer.Touch != 0) - { - float2 _155 = float2(_78.x + (_64[4u].x * _84), _78.y + (_64[4u].y * _84)); - float2 _157 = float2(27.0000019073486328125 * _84); - _160 = _155 + _157; - _161 = _155 - _157; - } - else - { - float2 _141 = _78.xy + float2(10.0 * _84); - _160 = _141 + float2(50.0 * _84); - _161 = _141; - } - _162 = _160; - _163 = _161; + float2 _111 = _82.xy + float2(10.0 * _88); + _154 = _111 + float2(50.0 * _88); + _155 = _111; } else { - float2 _130; - float2 _131; + float2 _152; + float2 _153; if (UniformBuffer.Touch == 0) { - _130 = float2(0.0); - _131 = float2(0.0); + _152 = float2(0.0); + _153 = float2(0.0); } else { - uint _103 = gl_InstanceIndex - 3u; - float _120; - if (_103 >= 4u) + uint _121 = gl_InstanceIndex - 3u; + bool _128; + if (_121 != 5u) + { + _128 = _121 == 6u; + } + else + { + _128 = true; + } + float _142; + if (_128) { - _120 = _78.x + (_64[_103].x * _84); + _142 = _82.x + (_69[_121].x * _88); } else { - _120 = (_78.x + _78.z) - (_64[_103].x * _84); + _142 = (_82.x + _82.z) - (_69[_121].x * _88); } - float2 _125 = float2(_120, _78.y + (_64[_103].y * _84)); - float2 _127 = float2(45.0 * _84); - _130 = _125 + _127; - _131 = _125 - _127; + float2 _147 = float2(_142, _82.y + (_69[_121].y * _88)); + float2 _149 = float2(45.0 * _88); + _152 = _147 + _149; + _153 = _147 - _149; } - _162 = _130; - _163 = _131; + _154 = _152; + _155 = _153; } - _171 = _162; - _172 = _163; + _156 = _154; + _157 = _155; } - out.gl_Position = float4(((mix(_172, _171, _63[gl_VertexIndex]) / _75) * 2.0) - float2(1.0), 0.0, 1.0); - out.out_var_TEXCOORD0 = float2(_63[gl_VertexIndex].x, 1.0 - _63[gl_VertexIndex].y); + out.gl_Position = float4(((mix(_157, _156, _68[gl_VertexIndex]) / _79) * 2.0) - float2(1.0), 0.0, 1.0); + out.out_var_TEXCOORD0 = float2(_68[gl_VertexIndex].x, 1.0 - _68[gl_VertexIndex].y); out.out_var_TEXCOORD1 = gl_InstanceIndex; return out; } diff --git a/shaders/bin/hud.vert.spv b/shaders/bin/hud.vert.spv index ff3c8aa..5c6824b 100644 Binary files a/shaders/bin/hud.vert.spv and b/shaders/bin/hud.vert.spv differ diff --git a/shaders/font.hlsl b/shaders/font.hlsl new file mode 100644 index 0000000..7ca25fb --- /dev/null +++ b/shaders/font.hlsl @@ -0,0 +1,136 @@ +#ifndef FONT_HLSL +#define FONT_HLSL + +static const uint kFontExtent = 8; +static const uint kFontFirst = 32; +static const uint kFontLast = 127; + +// https://github.com/dhepper/font8x8 +static const uint2 kFont[96] = +{ + uint2(0x00000000u, 0x00000000u), // space + uint2(0x183C3C18u, 0x00180018u), // ! + uint2(0x00003636u, 0x00000000u), // " + uint2(0x367F3636u, 0x0036367Fu), // # + uint2(0x1E033E0Cu, 0x000C1F30u), // $ + uint2(0x18336300u, 0x0063660Cu), // % + uint2(0x6E1C361Cu, 0x006E333Bu), // & + uint2(0x00030606u, 0x00000000u), // ' + uint2(0x06060C18u, 0x00180C06u), // ( + uint2(0x18180C06u, 0x00060C18u), // ) + uint2(0xFF3C6600u, 0x0000663Cu), // * + uint2(0x3F0C0C00u, 0x00000C0Cu), // + + uint2(0x00000000u, 0x060C0C00u), // , + uint2(0x3F000000u, 0x00000000u), // - + uint2(0x00000000u, 0x000C0C00u), // . + uint2(0x0C183060u, 0x00010306u), // / + uint2(0x7B73633Eu, 0x003E676Fu), // 0 + uint2(0x0C0C0E0Cu, 0x003F0C0Cu), // 1 + uint2(0x1C30331Eu, 0x003F3306u), // 2 + uint2(0x1C30331Eu, 0x001E3330u), // 3 + uint2(0x33363C38u, 0x0078307Fu), // 4 + uint2(0x301F033Fu, 0x001E3330u), // 5 + uint2(0x1F03061Cu, 0x001E3333u), // 6 + uint2(0x1830333Fu, 0x000C0C0Cu), // 7 + uint2(0x1E33331Eu, 0x001E3333u), // 8 + uint2(0x3E33331Eu, 0x000E1830u), // 9 + uint2(0x000C0C00u, 0x000C0C00u), // : + uint2(0x000C0C00u, 0x060C0C00u), // ; + uint2(0x03060C18u, 0x00180C06u), // < + uint2(0x003F0000u, 0x00003F00u), // = + uint2(0x30180C06u, 0x00060C18u), // > + uint2(0x1830331Eu, 0x000C000Cu), // ? + uint2(0x7B7B633Eu, 0x001E037Bu), // @ + uint2(0x33331E0Cu, 0x0033333Fu), // A + uint2(0x3E66663Fu, 0x003F6666u), // B + uint2(0x0303663Cu, 0x003C6603u), // C + uint2(0x6666361Fu, 0x001F3666u), // D + uint2(0x1E16467Fu, 0x007F4616u), // E + uint2(0x1E16467Fu, 0x000F0616u), // F + uint2(0x0303663Cu, 0x007C6673u), // G + uint2(0x3F333333u, 0x00333333u), // H + uint2(0x0C0C0C1Eu, 0x001E0C0Cu), // I + uint2(0x30303078u, 0x001E3333u), // J + uint2(0x1E366667u, 0x00676636u), // K + uint2(0x0606060Fu, 0x007F6646u), // L + uint2(0x7F7F7763u, 0x0063636Bu), // M + uint2(0x7B6F6763u, 0x00636373u), // N + uint2(0x6363361Cu, 0x001C3663u), // O + uint2(0x3E66663Fu, 0x000F0606u), // P + uint2(0x3333331Eu, 0x00381E3Bu), // Q + uint2(0x3E66663Fu, 0x00676636u), // R + uint2(0x0E07331Eu, 0x001E3338u), // S + uint2(0x0C0C2D3Fu, 0x001E0C0Cu), // T + uint2(0x33333333u, 0x003F3333u), // U + uint2(0x33333333u, 0x000C1E33u), // V + uint2(0x6B636363u, 0x0063777Fu), // W + uint2(0x1C366363u, 0x0063361Cu), // X + uint2(0x1E333333u, 0x001E0C0Cu), // Y + uint2(0x1831637Fu, 0x007F664Cu), // Z + uint2(0x0606061Eu, 0x001E0606u), // [ + uint2(0x180C0603u, 0x00406030u), // backslash + uint2(0x1818181Eu, 0x001E1818u), // ] + uint2(0x63361C08u, 0x00000000u), // ^ + uint2(0x00000000u, 0xFF000000u), // _ + uint2(0x00180C0Cu, 0x00000000u), // ` + uint2(0x301E0000u, 0x006E333Eu), // a + uint2(0x3E060607u, 0x003B6666u), // b + uint2(0x331E0000u, 0x001E3303u), // c + uint2(0x3E303038u, 0x006E3333u), // d + uint2(0x331E0000u, 0x001E033Fu), // e + uint2(0x0F06361Cu, 0x000F0606u), // f + uint2(0x336E0000u, 0x1F303E33u), // g + uint2(0x6E360607u, 0x00676666u), // h + uint2(0x0C0E000Cu, 0x001E0C0Cu), // i + uint2(0x30300030u, 0x1E333330u), // j + uint2(0x36660607u, 0x0067361Eu), // k + uint2(0x0C0C0C0Eu, 0x001E0C0Cu), // l + uint2(0x7F330000u, 0x00636B7Fu), // m + uint2(0x331F0000u, 0x00333333u), // n + uint2(0x331E0000u, 0x001E3333u), // o + uint2(0x663B0000u, 0x0F063E66u), // p + uint2(0x336E0000u, 0x78303E33u), // q + uint2(0x6E3B0000u, 0x000F0666u), // r + uint2(0x033E0000u, 0x001F301Eu), // s + uint2(0x0C3E0C08u, 0x00182C0Cu), // t + uint2(0x33330000u, 0x006E3333u), // u + uint2(0x33330000u, 0x000C1E33u), // v + uint2(0x6B630000u, 0x00367F7Fu), // w + uint2(0x36630000u, 0x0063361Cu), // x + uint2(0x33330000u, 0x1F303E33u), // y + uint2(0x193F0000u, 0x003F260Cu), // z + uint2(0x070C0C38u, 0x00380C0Cu), // { + uint2(0x00181818u, 0x00181818u), // | + uint2(0x380C0C07u, 0x00070C0Cu), // } + uint2(0x00003B6Eu, 0x00000000u), // ~ + uint2(0x00000000u, 0x00000000u), // delete +}; + +// text: 1-8 characters +// length: number of characters +// texels: width of the quad in bitmap pixels +// texcoord: pixel position in the quad with centered text (0 to 1) +bool GetGlyph(uint2 text, uint length, float texels, float2 texcoord) +{ + float2 extent = float2(length * kFontExtent, kFontExtent); + float2 position = (texcoord - 0.5f) * texels + extent * 0.5f; + if (any(position < 0.0f) || any(position >= extent)) + { + return false; + } + uint2 texel = uint2(position); + uint index = texel.x / kFontExtent; + uint word = index < 4 ? text.x : text.y; + uint character = (word >> ((index & 3) * 8)) & 0xFF; + if (character < kFontFirst || character > kFontLast) + { + return false; + } + uint2 glyph = kFont[character - kFontFirst]; + uint rows = texel.y < 4 ? glyph.x : glyph.y; + uint row = (rows >> ((texel.y & 3) * 8)) & 0xFF; + uint column = texel.x % kFontExtent; + return ((row >> column) & 1) != 0; +} + +#endif diff --git a/shaders/hud.frag b/shaders/hud.frag index 77d2ca2..bb868af 100644 --- a/shaders/hud.frag +++ b/shaders/hud.frag @@ -1,5 +1,6 @@ // TODO: https://github.com/libsdl-org/SDL_shadercross/issues/211 #include "../src/hud.inc" +#include "font.hlsl" Texture2DArray atlasTexture : register(t0, space2); SamplerState atlasSampler : register(s0, space2); @@ -20,14 +21,20 @@ static const float kRadius = 0.5f; static const float kEdge = 0.035f; static const float kFillAlpha = 0.12f; static const float kEdgeAlpha = 0.75f; -static const float3 kColors[HUD_BUTTON_COUNT] = +static const float kTextAlpha = 0.95f; +static const float kTextWidth = 0.80f; +static const float3 kColor = float3(0.86f, 0.88f, 0.92f); +static const uint kLabelLongest = 6; +static const uint kLabelLengths[HUD_BUTTON_COUNT] = {5, 5, 4, 6, 1, 3, 1}; +static const uint2 kLabels[HUD_BUTTON_COUNT] = { - float3(0.45f, 0.85f, 0.50f), - float3(0.95f, 0.45f, 0.45f), - float3(0.45f, 0.75f, 0.95f), - float3(0.95f, 0.80f, 0.40f), - float3(0.72f, 0.74f, 0.78f), - float3(0.75f, 0.55f, 0.95f), + uint2(0x43414C50u, 0x00000045u), // PLACE + uint2(0x41455242u, 0x0000004Bu), // BREAK + uint2(0x504D554Au, 0x00000000u), // JUMP + uint2(0x49525053u, 0x0000544Eu), // SPRINT + uint2(0x0000003Eu, 0x00000000u), // > + uint2(0x00594C46u, 0x00000000u), // FLY + uint2(0x0000003Cu, 0x00000000u), // < }; float4 main(Input input) : SV_Target0 @@ -53,6 +60,14 @@ float4 main(Input input) : SV_Target0 } float mask = 1.0f - smoothstep(kRadius - width, kRadius, distance); float edge = smoothstep(kRadius - kEdge - width, kRadius - kEdge, distance); - float3 color = kColors[input.Instance - HUD_INSTANCE_BUTTON]; - return float4(color, lerp(kFillAlpha, kEdgeAlpha, edge) * mask); + uint index = input.Instance - HUD_INSTANCE_BUTTON; + float texels = kLabelLongest * kFontExtent / kTextWidth; + if (GetGlyph(kLabels[index], kLabelLengths[index], texels, input.Texcoord)) + { + return float4(kColor, kTextAlpha); + } + else + { + return float4(kColor, lerp(kFillAlpha, kEdgeAlpha, edge) * mask); + } } diff --git a/shaders/hud.vert b/shaders/hud.vert index fd84f62..dbba670 100644 --- a/shaders/hud.vert +++ b/shaders/hud.vert @@ -38,8 +38,9 @@ static const float2 kButtons[HUD_BUTTON_COUNT] = float2(HUD_BUTTON_BREAK_X, HUD_BUTTON_BREAK_Y), float2(HUD_BUTTON_JUMP_X, HUD_BUTTON_JUMP_Y), float2(HUD_BUTTON_SPRINT_X, HUD_BUTTON_SPRINT_Y), - float2(HUD_BUTTON_BLOCK_X, HUD_BUTTON_BLOCK_Y), + float2(HUD_BUTTON_BLOCK_NEXT_X, HUD_BUTTON_BLOCK_NEXT_Y), float2(HUD_BUTTON_CONTROLLER_X, HUD_BUTTON_CONTROLLER_Y), + float2(HUD_BUTTON_BLOCK_PREV_X, HUD_BUTTON_BLOCK_PREV_Y), }; static float2 GetCenter(uint index, float4 safe, float scale) @@ -69,18 +70,8 @@ Output main(Input input) } else if (input.InstanceID == HUD_INSTANCE_BLOCK) { - if (Touch) - { - float2 center = GetCenter(HUD_BUTTON_BLOCK, safe, scale); - float extent = HUD_BUTTON_RADIUS * HUD_BLOCK_SCALE * scale; - minimum = center - extent; - maximum = center + extent; - } - else - { - minimum = safe.xy + HUD_BLOCK_MARGIN * scale; - maximum = minimum + HUD_BLOCK_SIZE * scale; - } + minimum = safe.xy + HUD_BLOCK_MARGIN * scale; + maximum = minimum + HUD_BLOCK_SIZE * scale; } else if (!Touch) { diff --git a/shaders/opaque.frag b/shaders/opaque.frag index 45a9578..86eb683 100644 --- a/shaders/opaque.frag +++ b/shaders/opaque.frag @@ -53,7 +53,7 @@ Output main(Input input) } float3 albedo = color.rgb; float3 normal = GetNormal(input.Voxel); - float3 light = GetLight(lightBuffer, LightCount, input.WorldPosition.xyz, normal, material); + float3 light = GetLight(lightBuffer, LightCount, input.WorldPosition.xyz, normal); float3 ambient = Ambient.xyz; float sunlight = GetSunlight(Sun.xyz, Sun.w, normal, block); float3 sky = GetSky(input.WorldPosition.xyz - PlayerPosition, SkyTop.xyz, SkyHorizon.xyz); diff --git a/shaders/shader.hlsl b/shaders/shader.hlsl index 68b1e16..105c64d 100644 --- a/shaders/shader.hlsl +++ b/shaders/shader.hlsl @@ -111,7 +111,7 @@ float3 GetSky(float3 position, float3 top, float3 horizon) return lerp(horizon, top, (atan2(position.y, length(position.xz)) + kPi / 2.0f) / kPi); } -float3 GetLight(StructuredBuffer lights, uint count, float3 position, float3 normal, Material material) +float3 GetLight(StructuredBuffer lights, uint count, float3 position, float3 normal) { static const float3 kOffset = float3(0.0f, 0.5f, 0.0f); static const float kMinAngle = 0.25f; diff --git a/shaders/transparent.frag b/shaders/transparent.frag index 67d122d..81a8690 100644 --- a/shaders/transparent.frag +++ b/shaders/transparent.frag @@ -43,7 +43,7 @@ float4 main(Input input) : SV_Target0 float4 position = input.WorldPosition; float3 albedo = color.rgb; float3 normal = GetNormal(input.Voxel); - float3 light = GetLight(lightBuffer, LightCount, position.xyz, normal, material); + float3 light = GetLight(lightBuffer, LightCount, position.xyz, normal); float3 ambient = Ambient.xyz; float sunlight = GetSunlight(Sun.xyz, Sun.w, normal, block); float3 sky = GetSky(input.WorldPosition.xyz - PlayerPosition, SkyTop.xyz, SkyHorizon.xyz); diff --git a/src/hud.inc b/src/hud.inc index be1704d..e9373b0 100644 --- a/src/hud.inc +++ b/src/hud.inc @@ -9,18 +9,19 @@ #define HUD_CROSSHAIR_HEIGHT 2.0f #define HUD_BLOCK_MARGIN 10.0f #define HUD_BLOCK_SIZE 50.0f -#define HUD_BLOCK_SCALE 0.6f -#define HUD_BUTTON_CENTER_X(x, w, i, o, s) ((i) >= HUD_BUTTON_BLOCK ? (x) + (o) * (s) : (x) + (w) - (o) * (s)) +#define HUD_BUTTON_LEFT(i) ((i) == HUD_BUTTON_CONTROLLER || (i) == HUD_BUTTON_BLOCK_PREV) +#define HUD_BUTTON_CENTER_X(x, w, i, o, s) (HUD_BUTTON_LEFT(i) ? (x) + (o) * (s) : (x) + (w) - (o) * (s)) #define HUD_BUTTON_CENTER_Y(y, o, s) ((y) + (o) * (s)) #define HUD_STICK_RADIUS 120.0f #define HUD_BUTTON_RADIUS 45.0f -#define HUD_BUTTON_COUNT 6 +#define HUD_BUTTON_COUNT 7 #define HUD_BUTTON_PLACE 0 #define HUD_BUTTON_BREAK 1 #define HUD_BUTTON_JUMP 2 #define HUD_BUTTON_SPRINT 3 -#define HUD_BUTTON_BLOCK 4 +#define HUD_BUTTON_BLOCK_NEXT 4 #define HUD_BUTTON_CONTROLLER 5 +#define HUD_BUTTON_BLOCK_PREV 6 #define HUD_BUTTON_PLACE_X 100.0f #define HUD_BUTTON_PLACE_Y 100.0f #define HUD_BUTTON_BREAK_X 210.0f @@ -29,10 +30,12 @@ #define HUD_BUTTON_JUMP_Y 210.0f #define HUD_BUTTON_SPRINT_X 210.0f #define HUD_BUTTON_SPRINT_Y 210.0f -#define HUD_BUTTON_BLOCK_X 100.0f -#define HUD_BUTTON_BLOCK_Y 100.0f +#define HUD_BUTTON_BLOCK_NEXT_X 100.0f +#define HUD_BUTTON_BLOCK_NEXT_Y 320.0f #define HUD_BUTTON_CONTROLLER_X 100.0f #define HUD_BUTTON_CONTROLLER_Y 210.0f +#define HUD_BUTTON_BLOCK_PREV_X 100.0f +#define HUD_BUTTON_BLOCK_PREV_Y 320.0f #define HUD_INSTANCE_CROSSHAIR_X 0 #define HUD_INSTANCE_CROSSHAIR_Y 1 #define HUD_INSTANCE_BLOCK 2 diff --git a/src/input.c b/src/input.c index e84f6df..c3a7751 100644 --- a/src/input.c +++ b/src/input.c @@ -9,8 +9,9 @@ static const float BUTTONS[HUD_BUTTON_COUNT][2] = {HUD_BUTTON_BREAK_X, HUD_BUTTON_BREAK_Y}, {HUD_BUTTON_JUMP_X, HUD_BUTTON_JUMP_Y}, {HUD_BUTTON_SPRINT_X, HUD_BUTTON_SPRINT_Y}, - {HUD_BUTTON_BLOCK_X, HUD_BUTTON_BLOCK_Y}, + {HUD_BUTTON_BLOCK_NEXT_X, HUD_BUTTON_BLOCK_NEXT_Y}, {HUD_BUTTON_CONTROLLER_X, HUD_BUTTON_CONTROLLER_Y}, + {HUD_BUTTON_BLOCK_PREV_X, HUD_BUTTON_BLOCK_PREV_Y}, }; static const float GAMEPAD_DEADZONE = 0.2f; @@ -85,7 +86,21 @@ static float GetTouch(const SDL_Event* event, float touch[2], float viewport[2]) viewport[1] = height; touch[0] = event->tfinger.x * viewport[0]; touch[1] = viewport[1] - event->tfinger.y * viewport[1]; - return HUD_SCALE(viewport[0], viewport[1]); + float scale = HUD_SCALE(viewport[0], viewport[1]); + return scale; +} + +static float GetStick(SDL_GamepadAxis axis) +{ + float value = SDL_GetGamepadAxis(gamepad, axis) / (float) SDL_JOYSTICK_AXIS_MAX; + if (SDL_fabsf(value) > GAMEPAD_DEADZONE) + { + return (value - SDL_copysignf(GAMEPAD_DEADZONE, value)) / (1.0f - GAMEPAD_DEADZONE); + } + else + { + return 0.0f; + } } static void SetDevice(InputDevice in_device) @@ -214,7 +229,8 @@ SDL_AppResult Input_Event(const SDL_Event* event) buttons[index] = event->tfinger.fingerID; place_block |= index == HUD_BUTTON_PLACE; break_block |= index == HUD_BUTTON_BREAK; - change_block += index == HUD_BUTTON_BLOCK; + change_block += index == HUD_BUTTON_BLOCK_NEXT; + change_block -= index == HUD_BUTTON_BLOCK_PREV; toggle_controller |= index == HUD_BUTTON_CONTROLLER; } else if (touch[0] < viewport[0] * 0.5f) @@ -345,20 +361,6 @@ SDL_AppResult Input_Event(const SDL_Event* event) return SDL_APP_CONTINUE; } -static float GetStick(SDL_GamepadAxis axis) -{ - float value = SDL_GetGamepadAxis(gamepad, axis) / (float) SDL_JOYSTICK_AXIS_MAX; - value = SDL_max(value, -1.0f); - if (SDL_fabsf(value) > GAMEPAD_DEADZONE) - { - return (value - SDL_copysignf(GAMEPAD_DEADZONE, value)) / (1.0f - GAMEPAD_DEADZONE); - } - else - { - return 0.0f; - } -} - void Input_Update(float dt) { SDL_zeroa(rotation);