[update] Implemented showing a title logo in TitleScene.
This commit is contained in:
parent
e3e149f451
commit
3f05669fbd
2
dub.json
2
dub.json
@ -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
BIN
res/images/title.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.8 KiB |
@ -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:
|
||||||
|
@ -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_;
|
||||||
}
|
}
|
||||||
|
@ -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
37
src/sj/util/image.d
Normal 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;
|
||||||
|
}
|
Reference in New Issue
Block a user