mirror of
https://github.com/enduro2d/enduro2d.git
synced 2025-12-12 15:26:14 +07:00
283 lines
9.3 KiB
C++
283 lines
9.3 KiB
C++
/*******************************************************************************
|
|
* This file is part of the "Enduro2D"
|
|
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
|
* Copyright (C) 2018-2020, by Matvey Cherevko (blackmatov@gmail.com)
|
|
******************************************************************************/
|
|
|
|
#include "../common.hpp"
|
|
using namespace e2d;
|
|
|
|
namespace
|
|
{
|
|
const char* vs_source_cstr = R"glsl(
|
|
attribute vec3 a_position;
|
|
attribute vec2 a_uv;
|
|
attribute vec4 a_color;
|
|
|
|
uniform mat4 u_MVP;
|
|
|
|
varying vec4 v_color;
|
|
varying vec2 v_uv;
|
|
|
|
void main(){
|
|
v_color = a_color;
|
|
v_uv = a_uv;
|
|
|
|
gl_Position = vec4(a_position, 1.0) * u_MVP;
|
|
}
|
|
)glsl";
|
|
|
|
const char* fs_source_cstr = R"glsl(
|
|
uniform sampler2D u_texture;
|
|
varying vec4 v_color;
|
|
varying vec2 v_uv;
|
|
|
|
void main(){
|
|
vec2 uv = vec2(v_uv.s, 1.0 - v_uv.t);
|
|
gl_FragColor = v_color * texture2D(u_texture, uv);
|
|
}
|
|
)glsl";
|
|
|
|
struct vertex1 {
|
|
v3f position;
|
|
v2hu uv;
|
|
static vertex_declaration decl() noexcept {
|
|
return vertex_declaration()
|
|
.add_attribute<v3f>("a_position")
|
|
.add_attribute<v2hu>("a_uv");
|
|
}
|
|
};
|
|
|
|
struct vertex2 {
|
|
color32 color;
|
|
static vertex_declaration decl() noexcept {
|
|
return vertex_declaration()
|
|
.add_attribute<color32>("a_color").normalized();
|
|
}
|
|
};
|
|
|
|
std::array<u16,36> generate_cube_indices() noexcept {
|
|
return {
|
|
0, 1, 2,
|
|
2, 3, 0,
|
|
|
|
4, 5, 6,
|
|
6, 7, 4,
|
|
|
|
8, 9, 10,
|
|
10, 11, 8,
|
|
|
|
12, 13, 14,
|
|
14, 15, 12,
|
|
|
|
16, 17, 18,
|
|
18, 19, 16,
|
|
|
|
20, 21, 22,
|
|
22, 23, 20};
|
|
}
|
|
|
|
std::array<vertex1,24> generate_cube_vertices(const v3f& size) noexcept {
|
|
f32 x = size.x * 0.5f;
|
|
f32 y = size.y * 0.5f;
|
|
f32 z = size.z * 0.5f;
|
|
return {
|
|
vertex1{{-x, -y, -z}, {0, 1}},
|
|
vertex1{{ x, -y, -z}, {1, 1}},
|
|
vertex1{{ x, y, -z}, {1, 0}},
|
|
vertex1{{-x, y, -z}, {0, 0}},
|
|
|
|
vertex1{{-x, -y, z}, {0, 1}},
|
|
vertex1{{ x, -y, z}, {1, 1}},
|
|
vertex1{{ x, -y, -z}, {1, 0}},
|
|
vertex1{{-x, -y, -z}, {0, 0}},
|
|
|
|
vertex1{{ x, -y, z}, {0, 1}},
|
|
vertex1{{-x, -y, z}, {1, 1}},
|
|
vertex1{{-x, y, z}, {1, 0}},
|
|
vertex1{{ x, y, z}, {0, 0}},
|
|
|
|
vertex1{{-x, y, -z}, {0, 1}},
|
|
vertex1{{ x, y, -z}, {1, 1}},
|
|
vertex1{{ x, y, z}, {1, 0}},
|
|
vertex1{{-x, y, z}, {0, 0}},
|
|
|
|
vertex1{{ x, -y, -z}, {0, 1}},
|
|
vertex1{{ x, -y, z}, {1, 1}},
|
|
vertex1{{ x, y, z}, {1, 0}},
|
|
vertex1{{ x, y, -z}, {0, 0}},
|
|
|
|
vertex1{{-x, -y, z}, {0, 1}},
|
|
vertex1{{-x, -y, -z}, {1, 1}},
|
|
vertex1{{-x, y, -z}, {1, 0}},
|
|
vertex1{{-x, y, z}, {0, 0}}};
|
|
}
|
|
|
|
std::array<vertex2,24> generate_cube_colors() noexcept {
|
|
return {
|
|
vertex2{color32::red()},
|
|
vertex2{color32::green()},
|
|
vertex2{color32::blue()},
|
|
vertex2{color32::yellow()},
|
|
|
|
vertex2{color32::red()},
|
|
vertex2{color32::green()},
|
|
vertex2{color32::blue()},
|
|
vertex2{color32::yellow()},
|
|
|
|
vertex2{color32::red()},
|
|
vertex2{color32::green()},
|
|
vertex2{color32::blue()},
|
|
vertex2{color32::yellow()},
|
|
|
|
vertex2{color32::red()},
|
|
vertex2{color32::green()},
|
|
vertex2{color32::blue()},
|
|
vertex2{color32::yellow()},
|
|
|
|
vertex2{color32::red()},
|
|
vertex2{color32::green()},
|
|
vertex2{color32::blue()},
|
|
vertex2{color32::yellow()},
|
|
|
|
vertex2{color32::red()},
|
|
vertex2{color32::green()},
|
|
vertex2{color32::blue()},
|
|
vertex2{color32::yellow()}};
|
|
}
|
|
|
|
class game final : public engine::application {
|
|
public:
|
|
bool initialize() final {
|
|
the<vfs>().register_scheme<archive_file_source>(
|
|
"piratepack",
|
|
the<vfs>().read(url("resources://bin/kenney_piratepack.zip")));
|
|
|
|
the<vfs>().register_scheme_alias(
|
|
"ships",
|
|
url("piratepack://PNG/Retina/Ships"));
|
|
|
|
image texture_image;
|
|
if ( !images::try_load_image(texture_image, the<vfs>().read(url("ships://ship (3).png"))) ) {
|
|
return false;
|
|
}
|
|
|
|
shader_ = the<render>().create_shader(vs_source_cstr, fs_source_cstr);
|
|
texture_ = the<render>().create_texture(texture_image);
|
|
|
|
if ( !shader_ || !texture_ ) {
|
|
return false;
|
|
}
|
|
|
|
const auto indices = generate_cube_indices();
|
|
index_buffer_ = the<render>().create_index_buffer(
|
|
indices,
|
|
index_declaration::index_type::unsigned_short,
|
|
index_buffer::usage::static_draw);
|
|
|
|
const auto vertices1 = generate_cube_vertices(make_vec3(1.f));
|
|
vertex_buffer1_ = the<render>().create_vertex_buffer(
|
|
vertices1,
|
|
vertex1::decl(),
|
|
vertex_buffer::usage::static_draw);
|
|
|
|
const auto vertices2 = generate_cube_colors();
|
|
vertex_buffer2_ = the<render>().create_vertex_buffer(
|
|
vertices2,
|
|
vertex2::decl(),
|
|
vertex_buffer::usage::static_draw);
|
|
|
|
if ( !index_buffer_ || !vertex_buffer1_ || !vertex_buffer2_ ) {
|
|
return false;
|
|
}
|
|
|
|
material_ = render::material()
|
|
.add_pass(render::pass_state()
|
|
.states(render::state_block()
|
|
.capabilities(render::capabilities_state()
|
|
.culling(true)
|
|
.depth_test(true))
|
|
.culling(render::culling_state()
|
|
.mode(render::culling_mode::ccw)
|
|
.face(render::culling_face::back)))
|
|
.shader(shader_)
|
|
.properties(render::property_block()
|
|
.sampler("u_texture", render::sampler_state()
|
|
.texture(texture_)
|
|
.min_filter(render::sampler_min_filter::linear)
|
|
.mag_filter(render::sampler_mag_filter::linear))));
|
|
|
|
geometry_ = render::geometry()
|
|
.indices(index_buffer_)
|
|
.add_vertices(vertex_buffer1_)
|
|
.add_vertices(vertex_buffer2_);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool frame_tick() final {
|
|
const keyboard& k = the<input>().keyboard();
|
|
|
|
if ( the<window>().should_close() || k.is_key_just_released(keyboard_key::escape) ) {
|
|
return false;
|
|
}
|
|
|
|
if ( k.is_key_just_pressed(keyboard_key::f1) ) {
|
|
the<dbgui>().toggle_visible(!the<dbgui>().visible());
|
|
}
|
|
|
|
if ( k.is_key_pressed(keyboard_key::lsuper) && k.is_key_just_released(keyboard_key::enter) ) {
|
|
the<window>().toggle_fullscreen(!the<window>().fullscreen());
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void frame_render() final {
|
|
const auto framebuffer_size = the<window>().real_size().cast_to<f32>();
|
|
const auto projection = math::make_perspective_lh_matrix4(
|
|
make_deg(45.f),
|
|
framebuffer_size.x / framebuffer_size.y,
|
|
0.1f,
|
|
100.f);
|
|
|
|
const auto MVP =
|
|
math::make_rotation_matrix4(make_rad(the<engine>().time()), 1.f, 0.f, 0.f) *
|
|
math::make_rotation_matrix4(make_rad(the<engine>().time()), 0.f, 1.f, 0.f) *
|
|
math::make_rotation_matrix4(make_rad(the<engine>().time()), 0.f, 0.f, 1.f) *
|
|
math::make_translation_matrix4(0.f, 0.f, 0.f) *
|
|
math::make_look_at_lh_matrix4({0.f, 0.f, -3.f}, v3f::zero(), v3f::unit_y()) *
|
|
projection;
|
|
|
|
material_.properties()
|
|
.property("u_MVP", MVP);
|
|
|
|
the<render>().execute(render::command_block<64>()
|
|
.add_command(render::viewport_command(
|
|
the<window>().framebuffer_size().cast_to<i32>()))
|
|
.add_command(render::clear_command()
|
|
.color_value({1.f, 0.4f, 0.f, 1.f}))
|
|
.add_command(render::draw_command(material_, geometry_)));
|
|
}
|
|
private:
|
|
shader_ptr shader_;
|
|
texture_ptr texture_;
|
|
index_buffer_ptr index_buffer_;
|
|
vertex_buffer_ptr vertex_buffer1_;
|
|
vertex_buffer_ptr vertex_buffer2_;
|
|
render::material material_;
|
|
render::geometry geometry_;
|
|
};
|
|
}
|
|
|
|
int e2d_main(int argc, char *argv[]) {
|
|
auto params = engine::parameters("sample_01", "enduro2d")
|
|
.window_params(engine::window_parameters()
|
|
.size({1024, 768}))
|
|
.timer_params(engine::timer_parameters()
|
|
.maximal_framerate(100));
|
|
modules::initialize<engine>(argc, argv, params).start<game>();
|
|
modules::shutdown<engine>();
|
|
return 0;
|
|
}
|