From 70f150f8207427ba13b6887b70ce2330e2d53a19 Mon Sep 17 00:00:00 2001 From: falsycat Date: Sun, 13 Oct 2019 00:00:00 +0000 Subject: [PATCH] [update] Implemented a glitch effect for TextProgram. --- src/sj/SelectScene.d | 52 +++++++++++++++++++++++++++++++++++++++++--- src/sj/Text.d | 24 ++++++++++++++------ src/sj/TextProgram.d | 41 +++++++++++++++++++++++++++++++--- 3 files changed, 104 insertions(+), 13 deletions(-) diff --git a/src/sj/SelectScene.d b/src/sj/SelectScene.d index aee49fd..edd7311 100644 --- a/src/sj/SelectScene.d +++ b/src/sj/SelectScene.d @@ -3,6 +3,7 @@ module sj.SelectScene; import std.conv, std.math, + std.random, std.variant; import derelict.sfml2.audio; @@ -113,6 +114,13 @@ private abstract class AbstractSceneState { enum LoadingCubeRotationSpeed = vec3(0, PI/5, PI/10); enum LoadingCubeInterval = 0.06; + enum TitleTextSize = 40; + enum TitleTextScale = vec3(-0.002, 0.002, 0.002); + enum TitleTextTranslation = vec3(0, -0.4, 0); + + enum TitleTextRandomTranslationRange = 0.02; + enum TitleTextRandomScaleRange = 0.0003; + this(SelectScene owner) { owner_ = owner; } @@ -212,14 +220,23 @@ private class SongAppearState : AbstractSceneState { const song = owner.songs_[song_index_]; with (owner.text_) { const w = LoadGlyphs(vec2i(256, 64), - song.name.to!dstring, vec2i(40, 0), owner.fonts_.gothic); - matrix.scale = vec3(-0.002, 0.002, 0.002); - matrix.translation = vec3(-w/2*matrix.scale.x, -0.4, 0); + song.name.to!dstring, vec2i(TitleTextSize, 0), owner.fonts_.gothic); + matrix.scale = TitleTextScale; + matrix.translation = TitleTextTranslation + vec3(-w/2*matrix.scale.x, 0, 0); } } override UpdateResult Update(KeyInput input) { const ratio = anime_.Update(); + if (owner.text_.frame++%10 > 7) { + alias RT = TitleTextRandomTranslationRange; + owner.text_.matrix.translation += vec3( + uniform(-RT, RT), uniform(-RT, RT), uniform(-RT, RT)); + alias RS = TitleTextRandomScaleRange; + owner.text_.matrix.scale += vec3( + uniform(-RS, RS), uniform(-RS, RS), 0); + } + with (owner.lobby_) { cube_matrix.rotation += cube_rota_speed_ease_.Calculate(ratio); cube_interval = cube_interval_ease_.Calculate(ratio); @@ -260,10 +277,35 @@ private class SongWaitState : AbstractSceneState { auto song = owner.songs_[song_index_]; song.PlayForPreview(); + + with (owner.text_) { + matrix.scale = TitleTextScale; + matrix.translation = + TitleTextTranslation + vec3(-modelWidth/2*matrix.scale.x, 0, 0); + frame = 0; + } + frame_ = 0; } override UpdateResult Update(KeyInput input) { owner.lobby_.cube_matrix.rotation += CubeRotationSpeed; + if (frame_%10 == 0) with (owner.text_) { + ++frame; + + if (frame_%100 == 0) { + matrix.scale = TitleTextScale; + matrix.translation = + TitleTextTranslation + vec3(-modelWidth/2*matrix.scale.x, 0, 0); + + } else if (frame_%20 == 0) { + alias RT = TitleTextRandomTranslationRange; + matrix.translation += vec3(uniform(-RT, RT), uniform(-RT, RT), uniform(-RT, RT)); + + alias RS = TitleTextRandomScaleRange; + matrix.scale += vec3(uniform(-RS, RS), uniform(-RS, RS), 0); + } + } + if (input.right) { song.StopPlaying(); song_appear_state_.Initialize(++song_index_%owner.songs_.length); @@ -274,6 +316,8 @@ private class SongWaitState : AbstractSceneState { owner.title_scene_.Initialize(); return CreateResult(owner.title_scene_); } + + ++frame_; return CreateResult(this); } @@ -285,4 +329,6 @@ private class SongWaitState : AbstractSceneState { SongAppearState song_appear_state_; size_t song_index_; + + int frame_; } diff --git a/src/sj/Text.d b/src/sj/Text.d index 6ad152c..ff200de 100644 --- a/src/sj/Text.d +++ b/src/sj/Text.d @@ -44,8 +44,8 @@ class Text { gloader.pxHeight = charsz.y; gloader.flags = FT_LOAD_DEFAULT | FT_LOAD_RENDER; - int bmp_width; - float text_width = 0; + model_width_ = 0; + int bmp_width; foreach (c; text) { with (gloader) { character = c; @@ -60,7 +60,7 @@ class Text { const bearing_y = m.horiBearingY*1f / m.height * srcsz.y; const advance = m.horiAdvance *1f / m.width * srcsz.x; - const posleft = text_width + bearing_x; + const posleft = model_width_ + bearing_x; const posright = posleft + srcsz.x; const postop = bearing_y; const posbottom = postop - srcsz.y; @@ -94,8 +94,8 @@ class Text { *vertices_ptr++ = uvright; *vertices_ptr++ = uvbottom; - bmp_width += srcsz.x; - text_width += advance; + bmp_width += srcsz.x; + model_width_ += advance; } texture_.Bind(); @@ -133,7 +133,7 @@ class Text { } index_count_ = indices_ptr - indices_data.entity; - return text_width; + return model_width_; } /// @@ -145,17 +145,25 @@ class Text { void Draw(mat4 proj, mat4 view) { if (index_count_ == 0) return; - program_.Use(proj, view, matrix.Create(), texture_, color); + program_.Use(proj, view, + matrix.Create(), texture_, color, frame, model_width_); vao_.Bind(); indices_.Bind(); gl.DrawElements(GL_TRIANGLE_STRIP, index_count_.to!int, GL_UNSIGNED_SHORT, null); } + /// + @property float modelWidth() const { + return model_width_; + } + /// ModelMatrixFactory!4 matrix; /// vec4 color = vec4(0, 0, 0, 1); + /// + int frame; private: static void CopyRawPixels(in ubyte* src, vec2i srcsz, ubyte* dst, vec2i dstsz, vec2i offset) { @@ -179,4 +187,6 @@ class Text { ElementArrayBufferRef indices_; size_t index_count_; + + float model_width_; } diff --git a/src/sj/TextProgram.d b/src/sj/TextProgram.d index 37b1416..5b02453 100644 --- a/src/sj/TextProgram.d +++ b/src/sj/TextProgram.d @@ -28,10 +28,12 @@ class TextProgram { layout(location = 0) in vec3 vert; layout(location = 1) in vec2 uv; + out vec3 vert_; out vec2 uv_; void main() { - uv_ = uv; + vert_ = vert; + uv_ = uv; gl_Position = P * V * M * vec4(vert, 1); } }; @@ -39,14 +41,44 @@ class TextProgram { enum FragmentShaderSrc = ShaderHeader ~ q{ layout(location = 3) uniform sampler2D tex; layout(location = 4) uniform vec4 color; + layout(location = 5) uniform int frame; + layout(location = 6) uniform float model_width; + in vec3 vert_; in vec2 uv_; out vec4 pixel_; + float choose(int a, int b, float a_big, float b_big) { + float condition = step(float(a), float(b)); + return condition * b_big + (1-condition) * a_big; + } + float choose(float a, float b, float c, float hit, float other) { + float condition = step(a, b) * step(b, c); + return condition * hit + (1-condition) * other; + } + void main() { + float vx = vert_.x / model_width; + vec2 uv = uv_; + + uv.y = choose(15, frame%18, uv.y, + choose(0.1, vx, 0.2, clamp(uv.y, 0, 0.6), uv.y)); + uv.y = choose(8, frame%14, uv.y, + choose(0.1, vx, 0.6, clamp(uv.y, 0, 0.8), uv.y)); + uv.y = choose(21, frame%29, uv.y, + choose(0.2, vx, 0.3, clamp(uv.y, 0.1, 1), uv.y)); + uv.y = choose(20, frame%23, uv.y, + choose(0.4, vx, 0.6, clamp(uv.y, 0.4, 1), uv.y)); + uv.y = choose(5, frame%6, uv.y, + choose(0.5, vx, 0.8, clamp(uv.y, 0, 0.7), uv.y)); + uv.y = choose(15, frame%17, uv.y, + choose(0.6, vx, 0.7, clamp(uv.y, 0.5, 1), uv.y)); + uv.y = choose(7, frame%9, uv.y, + choose(0.6, vx, 0.9, clamp(uv.y, 0.3, 1), uv.y)); + pixel_ = color; - pixel_.a *= texture(tex, uv_).r; + pixel_.a *= texture(tex, uv).r; } }; @@ -89,7 +121,8 @@ class TextProgram { } /// - void Use(mat4 proj, mat4 view, mat4 model, ref Texture2DRef tex, vec4 color) { + void Use(mat4 proj, mat4 view, mat4 model, + ref Texture2DRef tex, vec4 color, int frame, float model_width) { tex.BindToUnit(GL_TEXTURE0); sampler_.Bind(0); @@ -99,6 +132,8 @@ class TextProgram { program_.uniform!2 = model; program_.uniform!3 = 0; program_.uniform!4 = color; + program_.uniform!5 = frame; + program_.uniform!6 = model_width; } private: