[update] Implemented showing a title logo in TitleScene.

This commit is contained in:
falsycat 2019-10-12 00:00:00 +00:00
parent e3e149f451
commit 3f05669fbd
6 changed files with 154 additions and 21 deletions

View File

@ -3,6 +3,8 @@
"targetPath": ".bin", "targetPath": ".bin",
"stringImportPaths": ["res"],
"dependencies": { "dependencies": {
"sjplayer": {"path": "sjplayer"}, "sjplayer": {"path": "sjplayer"},

BIN
res/images/title.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

View File

@ -17,7 +17,7 @@ class Game : AbstractGame {
lobby_ = new LobbyWorld(programs_); lobby_ = new LobbyWorld(programs_);
title_ = new TitleScene(lobby_); title_ = new TitleScene(lobby_, programs_);
title_.SetupSceneDependency(title_); // TODO: specify proper next scene title_.SetupSceneDependency(title_); // TODO: specify proper next scene
super(title_); super(title_);
@ -29,6 +29,7 @@ class Game : AbstractGame {
lobby_.destroy(); lobby_.destroy();
programs_.destroy(); programs_.destroy();
fonts_.destroy();
} }
private: private:

View File

@ -8,15 +8,27 @@ import gl4d;
import sj.AbstractScene, import sj.AbstractScene,
sj.KeyInput, sj.KeyInput,
sj.LobbyWorld, sj.LobbyWorld,
sj.SceneInterface; sj.ProgramSet,
sj.SceneInterface,
sj.TitleTextProgram;
/// ///
class TitleScene : AbstractScene { class TitleScene : AbstractScene {
public: public:
/// ///
this(LobbyWorld lobby) { enum TitleMatrix = {
auto m = mat4.identity;
m.scale(0.8, 0.1, 0.1);
m.translate(0, -0.3, 0);
return m;
}();
///
this(LobbyWorld lobby, ProgramSet program) {
lobby_ = lobby; lobby_ = lobby;
SetupLobby(lobby); SetupLobby(lobby);
title_ = program.Get!TitleTextProgram;
} }
/// ///
@ -25,29 +37,35 @@ class TitleScene : AbstractScene {
} }
override void Update(KeyInput input) { override void Update(KeyInput input) {
lobby_.cube_matrix.rotation += vec3(PI/300, PI/300, PI/300); lobby_.cube_matrix.rotation += vec3(PI/600, PI/600, PI/600);
} }
override void Draw() { override void Draw() {
lobby_.Draw(); lobby_.Draw();
title_.Draw(lobby_.Projection, lobby_.view.Create(), TitleMatrix, frame_++);
} }
private: private:
static void SetupLobby(LobbyWorld lobby) { static void SetupLobby(LobbyWorld lobby) {
lobby.view.pos = vec3(0, 0, -1); lobby.view.pos = vec3(0, -0.15, -1);
lobby.view.target = vec3(0, -0.2, 0); lobby.view.target = vec3(0, -0.15, 0);
lobby.view.up = vec3(0, 1, 0);
lobby.background.inner_color = vec4(0.9, 0.9, 0.9, 1); lobby.background.inner_color = vec4(0.9, 0.9, 0.9, 1);
lobby.background.outer_color = vec4(0.2, 0.2, 0.2, 1); lobby.background.outer_color = vec4(-0.1, -0.1, -0.1, 1);
lobby.light_pos = vec3(0, 10, 0); lobby.light_pos = vec3(0, 9, -1);
lobby.cube_material.diffuse_color = vec3(0.1, 0.1, 0.1); lobby.cube_material.diffuse_color = vec3(0.1, 0.1, 0.1);
lobby.cube_material.light_color = vec3(1, 0.8, 0.8); lobby.cube_material.light_color = vec3(1, 0.8, 0.8);
lobby.cube_material.light_power = vec3(100, 100, 100); lobby.cube_material.light_power = vec3(100, 100, 100);
lobby.cube_material.ambient_color = vec3(0.1, 0.1, 0.1); lobby.cube_material.ambient_color = vec3(0.2, 0.2, 0.2);
lobby.cube_material.specular_color = vec3(0.5, 0.2, 0.2); lobby.cube_material.specular_color = vec3(0.5, 0.2, 0.2);
} }
SceneInterface next_scene_; SceneInterface next_scene_;
LobbyWorld lobby_; LobbyWorld lobby_;
TitleTextProgram title_;
int frame_;
} }

View File

@ -3,6 +3,8 @@ module sj.TitleTextProgram;
import gl4d; import gl4d;
import sj.util.image;
/// ///
class TitleTextProgram { class TitleTextProgram {
public: public:
@ -38,16 +40,54 @@ class TitleTextProgram {
/// ///
enum FragmentShaderSrc = ShaderHeader ~ q{ enum FragmentShaderSrc = ShaderHeader ~ q{
layout(location = 3) uniform sampler2D tex; layout(location = 3) uniform sampler2D tex;
layout(location = 4) uniform int frame;
in vec2 uv_; in vec2 uv_;
out vec4 pixel_; out vec4 pixel_;
float stepstep(float a, float b, float x) {
return step(a, x) * (1-step(b, x));
}
void main() { void main() {
pixel_ = texture(tex, uv_); vec2 uv = uv_;
uv.x += stepstep(0.1, 0.2, uv.y) *
step(51.0, float(frame%61)) * 0.03;
uv.x += stepstep(0.3, 0.35, uv.y) *
step(85.0, float(frame%103)) * -0.05;
uv.x += stepstep(0.3, 0.4, uv.y) *
step(294.0, float(frame%303)) * 0.07;
uv.x += stepstep(0.35, 0.45, uv.y) *
step(475.0, float(frame%829)) * -0.01;
uv.x += stepstep(0.5, 0.6, uv.y) *
step(22.0, float(frame%78)) * 0.002;
uv.x += stepstep(0.55, 0.65, uv.y) *
step(32.0, float(frame%37)) * -0.007;
uv.x += stepstep(0.85, 0.95, uv.y) *
step(82.0, float(frame%273)) * 0.004;
uv.x += stepstep(0.7, 0.9, uv.y) *
step(152.0, float(frame%203)) * -0.005;
vec4 texel = texture(tex, clamp(uv, 0, 1));
pixel_.r = texel.a;
pixel_.g = texel.b;
pixel_.b = texel.g;
pixel_.a = texel.r;
pixel_.r += stepstep(0.2, 0.25, uv.y) *
step(20.0, float(frame%30)) * 0.2;
pixel_.r += stepstep(0.5, 0.55, uv.y) *
step(83.0, float(frame%127)) * 0.2;
pixel_.r += stepstep(0.6, 0.75, uv.y) *
step(18, float(frame%21)) * 0.2;
} }
}; };
///
enum ImgBuf = cast(ubyte[]) import("images/title.png");
/// ///
this() { this() {
ProgramLinker linker; ProgramLinker linker;
@ -55,11 +95,21 @@ class TitleTextProgram {
linker.fragment = FragmentShader.Compile(FragmentShaderSrc); linker.fragment = FragmentShader.Compile(FragmentShaderSrc);
program_ = linker.Link(); program_ = linker.Link();
program_.Validate(); program_.Validate();
tex_ = CreateTextureFromBuffer(ImgBuf);
sampler_ = Sampler.Create();
SamplerConfigurer configurer;
with (configurer) {
filterMin = GL_LINEAR;
filterMag = GL_LINEAR;
Configure(sampler_);
} }
/// vao_ = VertexArray.Create();
void SetupVertexArray(ref VertexArrayRef vao, ref ArrayBufferRef vertices) { vertices_ = ArrayBuffer.Create();
vao.Bind();
vao_.Bind();
VertexArrayAttacher attacher; VertexArrayAttacher attacher;
with (attacher) { with (attacher) {
index = 0; index = 0;
@ -67,31 +117,56 @@ class TitleTextProgram {
offset = 0; offset = 0;
stride = Vertex.sizeof; stride = Vertex.sizeof;
dimension = 3; dimension = 3;
Attach(vao, vertices); Attach(vao_, vertices_);
index = 1; index = 1;
type = GL_FLOAT; type = GL_FLOAT;
offset = vec3.sizeof; offset = vec3.sizeof;
stride = Vertex.sizeof; stride = Vertex.sizeof;
dimension = 2; dimension = 2;
Attach(vao, vertices); Attach(vao_, vertices_);
}
vertices_.Bind();
ArrayBufferAllocator allocator;
with (allocator) {
const v = [
-1f, 1f, 0f, 1f, 0f,
-1f, -1f, 0f, 1f, 1f,
1f, -1f, 0f, 0f, 1f,
1f, 1f, 0f, 0f, 0f,
];
data = v.ptr;
size = v.length * v[0].sizeof;
usage = GL_STATIC_DRAW;
Allocate(vertices_);
} }
} }
/// ///
void Use( void Draw(mat4 proj, mat4 view, mat4 model, int frame) {
mat4 proj, mat4 view, mat4 model, tex_.BindToUnit(GL_TEXTURE0);
ref Texture2DRef tex, ref SamplerRef sampler) { sampler_.Bind(0);
tex.BindToUnit(GL_TEXTURE0);
sampler.Bind(0);
program_.Use(); program_.Use();
program_.uniform!0 = proj; program_.uniform!0 = proj;
program_.uniform!1 = view; program_.uniform!1 = view;
program_.uniform!2 = model; program_.uniform!2 = model;
program_.uniform!3 = 0; program_.uniform!3 = 0;
program_.uniform!4 = frame;
vao_.Bind();
gl.DrawArrays(GL_TRIANGLE_FAN, 0, 4);
} }
private: private:
ProgramRef program_; ProgramRef program_;
Texture2DRef tex_;
SamplerRef sampler_;
VertexArrayRef vao_;
ArrayBufferRef vertices_;
} }

37
src/sj/util/image.d Normal file
View File

@ -0,0 +1,37 @@
/// License: MIT
module sj.util.image;
import std.exception,
std.math,
std.string;
import derelict.sfml2.graphics;
import gl4d;
///
Texture2DRef CreateTextureFromBuffer(in ubyte[] buf) {
auto img = sfImage_createFromMemory(buf.ptr, buf.length);
scope(exit) sfImage_destroy(img);
return img.CreateTextureFromImage();
}
///
Texture2DRef CreateTextureFromImage(sfImage* img) {
const sz = sfImage_getSize(img);
sz.x.isPowerOf2.enforce();
sz.y.isPowerOf2.enforce();
auto tex = Texture2D.Create();
Texture2DAllocator allocator;
with (allocator) {
level = 0;
internalFormat = GL_RGBA8;
data = sfImage_getPixelsPtr(img);
size = vec2i(sz.x, sz.y);
format = GL_RGBA;
type = GL_UNSIGNED_INT_8_8_8_8;
Allocate(tex);
}
return tex;
}