mirror of
https://github.com/enduro2d/enduro2d.git
synced 2025-12-15 00:11:55 +07:00
vertex and index declarations
This commit is contained in:
@@ -11,5 +11,6 @@
|
||||
#include "debug.hpp"
|
||||
#include "input.hpp"
|
||||
#include "render.hpp"
|
||||
#include "render.inl"
|
||||
#include "vfs.hpp"
|
||||
#include "window.hpp"
|
||||
|
||||
@@ -16,7 +16,6 @@ namespace e2d
|
||||
class mouse;
|
||||
class keyboard;
|
||||
class input;
|
||||
class vertex;
|
||||
class shader;
|
||||
class texture;
|
||||
class index_buffer;
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
* Copyright (C) 2018 Matvey Cherevko
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef E2D_INCLUDE_GUARD_64EC1BED88C24F57851A315A761E9D48
|
||||
#define E2D_INCLUDE_GUARD_64EC1BED88C24F57851A315A761E9D48
|
||||
#pragma once
|
||||
|
||||
#include "_core.hpp"
|
||||
@@ -11,16 +13,141 @@
|
||||
namespace e2d
|
||||
{
|
||||
//
|
||||
// vertex
|
||||
// index_declaration
|
||||
//
|
||||
|
||||
class vertex {
|
||||
class index_declaration final {
|
||||
public:
|
||||
v3f pos;
|
||||
v2f uv[2];
|
||||
color32 color;
|
||||
enum class index_type : u8 {
|
||||
unsigned_byte,
|
||||
unsigned_short
|
||||
};
|
||||
|
||||
class index_info final {
|
||||
public:
|
||||
index_type type = index_type::unsigned_short;
|
||||
public:
|
||||
index_info() noexcept = default;
|
||||
~index_info() noexcept = default;
|
||||
|
||||
index_info(const index_info&) noexcept = default;
|
||||
index_info& operator=(const index_info&) noexcept = default;
|
||||
|
||||
explicit index_info(index_type type) noexcept;
|
||||
};
|
||||
public:
|
||||
index_declaration() noexcept;
|
||||
~index_declaration() noexcept;
|
||||
|
||||
index_declaration(const index_declaration&) noexcept = default;
|
||||
index_declaration& operator=(const index_declaration&) noexcept = default;
|
||||
|
||||
explicit index_declaration(index_type index_type) noexcept;
|
||||
|
||||
const index_info& index() const noexcept;
|
||||
std::size_t index_size() const noexcept;
|
||||
private:
|
||||
index_info index_;
|
||||
};
|
||||
|
||||
bool operator==(
|
||||
const index_declaration& l,
|
||||
const index_declaration& r) noexcept;
|
||||
bool operator!=(
|
||||
const index_declaration& l,
|
||||
const index_declaration& r) noexcept;
|
||||
bool operator==(
|
||||
const index_declaration::index_info& l,
|
||||
const index_declaration::index_info& r) noexcept;
|
||||
bool operator!=(
|
||||
const index_declaration::index_info& l,
|
||||
const index_declaration::index_info& r) noexcept;
|
||||
|
||||
//
|
||||
// vertex_declaration
|
||||
//
|
||||
|
||||
class vertex_declaration final {
|
||||
public:
|
||||
constexpr static std::size_t max_attribute_name = 128;
|
||||
constexpr static std::size_t max_attribute_count = 16;
|
||||
|
||||
enum class attribute_type : u8 {
|
||||
signed_byte,
|
||||
unsigned_byte,
|
||||
signed_short,
|
||||
unsigned_short,
|
||||
floating_point
|
||||
};
|
||||
|
||||
class attribute_info final {
|
||||
public:
|
||||
char name[max_attribute_name] = {0};
|
||||
std::size_t rows = 0;
|
||||
std::size_t columns = 0;
|
||||
std::size_t stride = 0;
|
||||
attribute_type type = attribute_type::floating_point;
|
||||
bool normalized = false;
|
||||
public:
|
||||
attribute_info() noexcept = default;
|
||||
~attribute_info() noexcept = default;
|
||||
|
||||
attribute_info(const attribute_info&) noexcept = default;
|
||||
attribute_info& operator=(const attribute_info&) noexcept = default;
|
||||
|
||||
attribute_info(
|
||||
str_view name,
|
||||
std::size_t rows,
|
||||
std::size_t columns,
|
||||
std::size_t stride,
|
||||
attribute_type type,
|
||||
bool normalized);
|
||||
|
||||
std::size_t row_size() const noexcept;
|
||||
};
|
||||
public:
|
||||
vertex_declaration() noexcept;
|
||||
~vertex_declaration() noexcept;
|
||||
|
||||
vertex_declaration(const vertex_declaration&) noexcept = default;
|
||||
vertex_declaration& operator=(const vertex_declaration&) noexcept = default;
|
||||
|
||||
template < typename T >
|
||||
vertex_declaration& add_attribute(str_view name) noexcept;
|
||||
vertex_declaration& normalized() noexcept;
|
||||
|
||||
vertex_declaration& skip_bytes(
|
||||
std::size_t bytes) noexcept;
|
||||
|
||||
vertex_declaration& add_attribute(
|
||||
str_view name,
|
||||
std::size_t rows,
|
||||
std::size_t columns,
|
||||
attribute_type type,
|
||||
bool normalized) noexcept;
|
||||
|
||||
const attribute_info& attribute(std::size_t i) const noexcept;
|
||||
std::size_t attribute_count() const noexcept;
|
||||
std::size_t vertex_size() const noexcept;
|
||||
private:
|
||||
array<attribute_info, max_attribute_count> attributes_;
|
||||
std::size_t attribute_count_ = 0;
|
||||
std::size_t vertex_size_ = 0;
|
||||
};
|
||||
|
||||
bool operator==(
|
||||
const vertex_declaration& l,
|
||||
const vertex_declaration& r) noexcept;
|
||||
bool operator!=(
|
||||
const vertex_declaration& l,
|
||||
const vertex_declaration& r) noexcept;
|
||||
bool operator==(
|
||||
const vertex_declaration::attribute_info& l,
|
||||
const vertex_declaration::attribute_info& r) noexcept;
|
||||
bool operator!=(
|
||||
const vertex_declaration::attribute_info& l,
|
||||
const vertex_declaration::attribute_info& r) noexcept;
|
||||
|
||||
//
|
||||
// shader
|
||||
//
|
||||
@@ -31,9 +158,9 @@ namespace e2d
|
||||
class internal_state;
|
||||
using internal_state_uptr = std::unique_ptr<internal_state>;
|
||||
public:
|
||||
enum class uniform_type {
|
||||
i,
|
||||
f,
|
||||
enum class uniform_type : u8 {
|
||||
signed_integer,
|
||||
floating_point,
|
||||
|
||||
v2i,
|
||||
v3i,
|
||||
@@ -47,9 +174,10 @@ namespace e2d
|
||||
m3f,
|
||||
m4f,
|
||||
|
||||
s2d
|
||||
sampler_2d,
|
||||
sampler_cube
|
||||
};
|
||||
enum class attribute_type {
|
||||
enum class attribute_type : u8 {
|
||||
f,
|
||||
|
||||
v2f,
|
||||
@@ -61,8 +189,11 @@ namespace e2d
|
||||
m4f
|
||||
};
|
||||
public:
|
||||
shader(internal_state_uptr);
|
||||
explicit shader(internal_state_uptr);
|
||||
~shader() noexcept;
|
||||
const vertex_declaration& decl() const noexcept;
|
||||
void set_uniform(str_view name, i32 value) const noexcept;
|
||||
void set_uniform(str_view name, f32 value) const noexcept;
|
||||
private:
|
||||
internal_state_uptr state_;
|
||||
};
|
||||
@@ -78,17 +209,17 @@ namespace e2d
|
||||
class internal_state;
|
||||
using internal_state_uptr = std::unique_ptr<internal_state>;
|
||||
public:
|
||||
enum class wrap {
|
||||
enum class wrap : u8 {
|
||||
clamp,
|
||||
repeat,
|
||||
mirror
|
||||
};
|
||||
enum class filter {
|
||||
enum class filter : u8 {
|
||||
linear,
|
||||
nearest
|
||||
};
|
||||
public:
|
||||
texture(internal_state_uptr);
|
||||
explicit texture(internal_state_uptr);
|
||||
~texture() noexcept;
|
||||
|
||||
void set_wrap(wrap u, wrap v) noexcept;
|
||||
@@ -108,16 +239,19 @@ namespace e2d
|
||||
class internal_state;
|
||||
using internal_state_uptr = std::unique_ptr<internal_state>;
|
||||
public:
|
||||
enum class usage {
|
||||
enum class usage : u8 {
|
||||
static_draw,
|
||||
stream_draw,
|
||||
dynamic_draw
|
||||
};
|
||||
public:
|
||||
index_buffer(internal_state_uptr);
|
||||
explicit index_buffer(internal_state_uptr);
|
||||
~index_buffer() noexcept;
|
||||
void update(const u16* indices, std::size_t count, std::size_t offset) noexcept;
|
||||
std::size_t count() const noexcept;
|
||||
void update(const buffer& indices, std::size_t offset) noexcept;
|
||||
const index_declaration& decl() const noexcept;
|
||||
usage buffer_usage() const noexcept;
|
||||
std::size_t buffer_size() const noexcept;
|
||||
std::size_t index_count() const noexcept;
|
||||
private:
|
||||
internal_state_uptr state_;
|
||||
};
|
||||
@@ -133,16 +267,19 @@ namespace e2d
|
||||
class internal_state;
|
||||
using internal_state_uptr = std::unique_ptr<internal_state>;
|
||||
public:
|
||||
enum class usage {
|
||||
enum class usage : u8{
|
||||
static_draw,
|
||||
stream_draw,
|
||||
dynamic_draw
|
||||
};
|
||||
public:
|
||||
vertex_buffer(internal_state_uptr);
|
||||
explicit vertex_buffer(internal_state_uptr);
|
||||
~vertex_buffer() noexcept;
|
||||
void update(const vertex* vertices, std::size_t count, std::size_t offset) noexcept;
|
||||
std::size_t count() const noexcept;
|
||||
void update(const buffer& vertices, std::size_t offset) noexcept;
|
||||
const vertex_declaration& decl() const noexcept;
|
||||
usage buffer_usage() const noexcept;
|
||||
std::size_t buffer_size() const noexcept;
|
||||
std::size_t vertex_count() const noexcept;
|
||||
private:
|
||||
internal_state_uptr state_;
|
||||
};
|
||||
@@ -154,18 +291,20 @@ namespace e2d
|
||||
|
||||
class render final : public module<render> {
|
||||
public:
|
||||
enum class state {
|
||||
enum class state : u8 {
|
||||
blend,
|
||||
cull_face,
|
||||
depth_test,
|
||||
stencil_test
|
||||
};
|
||||
enum class cull_face {
|
||||
|
||||
enum class cull_face : u8 {
|
||||
front,
|
||||
back,
|
||||
front_back
|
||||
};
|
||||
enum class blend_func {
|
||||
|
||||
enum class blend_func : u8 {
|
||||
zero,
|
||||
one,
|
||||
src_color,
|
||||
@@ -182,12 +321,14 @@ namespace e2d
|
||||
one_minus_constant_alpha,
|
||||
src_alpha_saturate
|
||||
};
|
||||
enum class blend_equation {
|
||||
|
||||
enum class blend_equation : u8 {
|
||||
add,
|
||||
subtract,
|
||||
reverse_subtract
|
||||
};
|
||||
enum class depth_func {
|
||||
|
||||
enum class depth_func : u8 {
|
||||
never,
|
||||
less,
|
||||
lequal,
|
||||
@@ -197,7 +338,8 @@ namespace e2d
|
||||
notequal,
|
||||
always
|
||||
};
|
||||
enum class stencil_func {
|
||||
|
||||
enum class stencil_func : u8 {
|
||||
never,
|
||||
less,
|
||||
lequal,
|
||||
@@ -207,7 +349,8 @@ namespace e2d
|
||||
notequal,
|
||||
always
|
||||
};
|
||||
enum class stencil_op {
|
||||
|
||||
enum class stencil_op : u8 {
|
||||
keep,
|
||||
zero,
|
||||
replace,
|
||||
@@ -217,13 +360,20 @@ namespace e2d
|
||||
decr_wrap,
|
||||
invert
|
||||
};
|
||||
|
||||
enum class topology : u8 {
|
||||
triangles,
|
||||
triangles_fan,
|
||||
triangles_strip
|
||||
};
|
||||
public:
|
||||
render(debug& d, window& w);
|
||||
~render() noexcept;
|
||||
~render() noexcept final;
|
||||
|
||||
shader_ptr create_shader(
|
||||
input_stream_uptr vertex,
|
||||
input_stream_uptr fragment);
|
||||
input_stream_uptr fragment,
|
||||
const vertex_declaration& decl);
|
||||
|
||||
texture_ptr create_texture(
|
||||
const image& image);
|
||||
@@ -233,22 +383,27 @@ namespace e2d
|
||||
image_data_format format);
|
||||
|
||||
index_buffer_ptr create_index_buffer(
|
||||
const u16* indices,
|
||||
std::size_t count,
|
||||
index_buffer::usage usage);
|
||||
const buffer& indices,
|
||||
const index_declaration& decl,
|
||||
enum index_buffer::usage usage);
|
||||
|
||||
vertex_buffer_ptr create_vertex_buffer(
|
||||
const vertex* vertices,
|
||||
std::size_t count,
|
||||
vertex_buffer::usage usage);
|
||||
const buffer& vertices,
|
||||
const vertex_declaration& decl,
|
||||
enum vertex_buffer::usage usage);
|
||||
|
||||
void clear(bool color, bool depth, bool stencil) noexcept;
|
||||
void clear(
|
||||
bool color,
|
||||
bool depth,
|
||||
bool stencil) noexcept;
|
||||
|
||||
void draw(
|
||||
topology tp,
|
||||
const shader_ptr& ps,
|
||||
const index_buffer_ptr& ib,
|
||||
const vertex_buffer_ptr& vb) noexcept;
|
||||
|
||||
void set_model(const m4f& model) noexcept;
|
||||
void set_view(const m4f& view) noexcept;
|
||||
void set_projection(const m4f& projection) noexcept;
|
||||
void set_viewport(u32 x, u32 y, u32 w, u32 h) noexcept;
|
||||
@@ -278,3 +433,6 @@ namespace e2d
|
||||
std::unique_ptr<internal_state> state_;
|
||||
};
|
||||
}
|
||||
|
||||
#include "render.inl"
|
||||
#endif
|
||||
|
||||
74
headers/enduro2d/core/render.inl
Normal file
74
headers/enduro2d/core/render.inl
Normal file
@@ -0,0 +1,74 @@
|
||||
/*******************************************************************************
|
||||
* This file is part of the "Enduro2D"
|
||||
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
||||
* Copyright (C) 2018 Matvey Cherevko
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef E2D_INCLUDE_GUARD_8247225BE32B4135BDAECEEE88535A86
|
||||
#define E2D_INCLUDE_GUARD_8247225BE32B4135BDAECEEE88535A86
|
||||
#pragma once
|
||||
|
||||
#include "_core.hpp"
|
||||
#include "render.hpp"
|
||||
|
||||
namespace e2d
|
||||
{
|
||||
template < typename T >
|
||||
vertex_declaration& vertex_declaration::add_attribute(str_view name) noexcept {
|
||||
E2D_UNUSED(name);
|
||||
static_assert(sizeof(T) == 0, "not implemented for this type");
|
||||
}
|
||||
|
||||
#define DEFINE_ADD_ATTRIBUTE_SPECIALIZATION(t, rows, columns, type)\
|
||||
template <>\
|
||||
inline vertex_declaration& vertex_declaration::add_attribute<t>(str_view name) noexcept {\
|
||||
return add_attribute(name, (rows), (columns), attribute_type::type, false);\
|
||||
}
|
||||
|
||||
DEFINE_ADD_ATTRIBUTE_SPECIALIZATION(i8, 1, 1, signed_byte)
|
||||
DEFINE_ADD_ATTRIBUTE_SPECIALIZATION(vec2<i8>, 1, 2, signed_byte)
|
||||
DEFINE_ADD_ATTRIBUTE_SPECIALIZATION(vec3<i8>, 1, 3, signed_byte)
|
||||
DEFINE_ADD_ATTRIBUTE_SPECIALIZATION(vec4<i8>, 1, 4, signed_byte)
|
||||
DEFINE_ADD_ATTRIBUTE_SPECIALIZATION(mat2<i8>, 2, 2, signed_byte)
|
||||
DEFINE_ADD_ATTRIBUTE_SPECIALIZATION(mat3<i8>, 3, 3, signed_byte)
|
||||
DEFINE_ADD_ATTRIBUTE_SPECIALIZATION(mat4<i8>, 4, 4, signed_byte)
|
||||
|
||||
DEFINE_ADD_ATTRIBUTE_SPECIALIZATION(u8, 1, 1, unsigned_byte)
|
||||
DEFINE_ADD_ATTRIBUTE_SPECIALIZATION(vec2<u8>, 1, 2, unsigned_byte)
|
||||
DEFINE_ADD_ATTRIBUTE_SPECIALIZATION(vec3<u8>, 1, 3, unsigned_byte)
|
||||
DEFINE_ADD_ATTRIBUTE_SPECIALIZATION(vec4<u8>, 1, 4, unsigned_byte)
|
||||
DEFINE_ADD_ATTRIBUTE_SPECIALIZATION(mat2<u8>, 2, 2, unsigned_byte)
|
||||
DEFINE_ADD_ATTRIBUTE_SPECIALIZATION(mat3<u8>, 3, 3, unsigned_byte)
|
||||
DEFINE_ADD_ATTRIBUTE_SPECIALIZATION(mat4<u8>, 4, 4, unsigned_byte)
|
||||
|
||||
DEFINE_ADD_ATTRIBUTE_SPECIALIZATION(i16, 1, 1, signed_short)
|
||||
DEFINE_ADD_ATTRIBUTE_SPECIALIZATION(vec2<i16>, 1, 2, signed_short)
|
||||
DEFINE_ADD_ATTRIBUTE_SPECIALIZATION(vec3<i16>, 1, 3, signed_short)
|
||||
DEFINE_ADD_ATTRIBUTE_SPECIALIZATION(vec4<i16>, 1, 4, signed_short)
|
||||
DEFINE_ADD_ATTRIBUTE_SPECIALIZATION(mat2<i16>, 2, 2, signed_short)
|
||||
DEFINE_ADD_ATTRIBUTE_SPECIALIZATION(mat3<i16>, 3, 3, signed_short)
|
||||
DEFINE_ADD_ATTRIBUTE_SPECIALIZATION(mat4<i16>, 4, 4, signed_short)
|
||||
|
||||
DEFINE_ADD_ATTRIBUTE_SPECIALIZATION(u16, 1, 1, unsigned_short)
|
||||
DEFINE_ADD_ATTRIBUTE_SPECIALIZATION(vec2<u16>, 1, 2, unsigned_short)
|
||||
DEFINE_ADD_ATTRIBUTE_SPECIALIZATION(vec3<u16>, 1, 3, unsigned_short)
|
||||
DEFINE_ADD_ATTRIBUTE_SPECIALIZATION(vec4<u16>, 1, 4, unsigned_short)
|
||||
DEFINE_ADD_ATTRIBUTE_SPECIALIZATION(mat2<u16>, 2, 2, unsigned_short)
|
||||
DEFINE_ADD_ATTRIBUTE_SPECIALIZATION(mat3<u16>, 3, 3, unsigned_short)
|
||||
DEFINE_ADD_ATTRIBUTE_SPECIALIZATION(mat4<u16>, 4, 4, unsigned_short)
|
||||
|
||||
DEFINE_ADD_ATTRIBUTE_SPECIALIZATION(f32, 1, 1, floating_point)
|
||||
DEFINE_ADD_ATTRIBUTE_SPECIALIZATION(vec2<f32>, 1, 2, floating_point)
|
||||
DEFINE_ADD_ATTRIBUTE_SPECIALIZATION(vec3<f32>, 1, 3, floating_point)
|
||||
DEFINE_ADD_ATTRIBUTE_SPECIALIZATION(vec4<f32>, 1, 4, floating_point)
|
||||
DEFINE_ADD_ATTRIBUTE_SPECIALIZATION(mat2<f32>, 2, 2, floating_point)
|
||||
DEFINE_ADD_ATTRIBUTE_SPECIALIZATION(mat3<f32>, 3, 3, floating_point)
|
||||
DEFINE_ADD_ATTRIBUTE_SPECIALIZATION(mat4<f32>, 4, 4, floating_point)
|
||||
|
||||
DEFINE_ADD_ATTRIBUTE_SPECIALIZATION(color, 1, 4, floating_point)
|
||||
DEFINE_ADD_ATTRIBUTE_SPECIALIZATION(color32, 1, 4, unsigned_byte)
|
||||
|
||||
#undef DEFINE_ADD_ATTRIBUTE_SPECIALIZATION
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -12,67 +12,86 @@ namespace
|
||||
const char* vs_source_cstr =
|
||||
"#version 120 \n"
|
||||
" \n"
|
||||
"attribute vec3 in_pos; \n"
|
||||
"attribute vec2 in_uv0; \n"
|
||||
"attribute vec2 in_uv1; \n"
|
||||
"attribute vec4 in_color; \n"
|
||||
"attribute vec3 a_position; \n"
|
||||
"attribute vec4 a_color; \n"
|
||||
" \n"
|
||||
"uniform float u_time = 0.0; \n"
|
||||
" \n"
|
||||
"varying vec2 uv0; \n"
|
||||
"varying vec2 uv1; \n"
|
||||
"varying vec4 color; \n"
|
||||
" \n"
|
||||
"void main(){ \n"
|
||||
" uv0 = in_uv0; \n"
|
||||
" uv1 = in_uv1; \n"
|
||||
" color = in_color; \n"
|
||||
" gl_Position = vec4(in_pos, 1.0); \n"
|
||||
" color = a_color; \n"
|
||||
" \n"
|
||||
" float s = 0.7 + 0.3 * (cos(u_time * 0.003) + 1); \n"
|
||||
" gl_Position = vec4(a_position * s, 1.0); \n"
|
||||
"}";
|
||||
|
||||
const char* fs_source_cstr =
|
||||
"#version 120 \n"
|
||||
" \n"
|
||||
"varying vec2 uv0; \n"
|
||||
"varying vec2 uv1; \n"
|
||||
"varying vec4 color; \n"
|
||||
" \n"
|
||||
"void main(){ \n"
|
||||
" gl_FragColor = color; \n"
|
||||
"}";
|
||||
|
||||
u16 indices[] = {
|
||||
struct vertex {
|
||||
v3f position;
|
||||
color32 color;
|
||||
};
|
||||
|
||||
u8 indices[] = {
|
||||
0, 1, 2, 2, 1, 3};
|
||||
|
||||
const vertex vertices[] = {
|
||||
{{-0.5f, 0.5f, 0.0f}, {{0.f, 0.f}, {0.f, 0.f}}, {0xFF, 0x00, 0x00, 0xFF}},
|
||||
{{-0.5f, -0.5f, 0.0f}, {{0.f, 0.f}, {0.f, 0.f}}, {0x00, 0xFF, 0x00, 0xFF}},
|
||||
{{ 0.5f, 0.5f, 0.0f}, {{0.f, 0.f}, {0.f, 0.f}}, {0x00, 0x00, 0xFF, 0xFF}},
|
||||
{{ 0.5f, -0.5f, 0.0f}, {{0.f, 0.f}, {0.f, 0.f}}, {0xFF, 0xFF, 0xFF, 0xFF}}};
|
||||
{{-0.5f, 0.5f, 0.0f}, color32::red()},
|
||||
{{-0.5f, -0.5f, 0.0f}, color32::green()},
|
||||
{{ 0.5f, 0.5f, 0.0f}, color32::blue()},
|
||||
{{ 0.5f, -0.5f, 0.0f}, color32::white()}};
|
||||
}
|
||||
|
||||
int e2d_main() {
|
||||
modules::initialize<debug>();
|
||||
modules::initialize<debug>()
|
||||
.register_sink<debug_console_sink>();
|
||||
modules::initialize<input>();
|
||||
modules::initialize<window>(v2u{640, 480}, "Enduro2D", false);
|
||||
modules::initialize<window>(v2u{640, 480}, "Enduro2D", false)
|
||||
.register_event_listener<window_input_source>(the<input>());
|
||||
modules::initialize<render>(the<debug>(), the<window>());
|
||||
|
||||
the<debug>().register_sink<debug_console_sink>();
|
||||
the<window>().register_event_listener<window_input_source>(the<input>());
|
||||
auto index_decl = index_declaration(
|
||||
index_declaration::index_type::unsigned_byte);
|
||||
|
||||
auto vertex_decl = vertex_declaration()
|
||||
.add_attribute<v3f>("a_position")
|
||||
.add_attribute<color32>("a_color").normalized();
|
||||
|
||||
const auto ps = the<render>().create_shader(
|
||||
make_memory_stream(buffer(vs_source_cstr, std::strlen(vs_source_cstr))),
|
||||
make_memory_stream(buffer(fs_source_cstr, std::strlen(fs_source_cstr))));
|
||||
make_memory_stream(buffer(fs_source_cstr, std::strlen(fs_source_cstr))),
|
||||
vertex_decl);
|
||||
|
||||
const auto ib = the<render>().create_index_buffer(
|
||||
indices, E2D_COUNTOF(indices), index_buffer::usage::static_draw);
|
||||
buffer(indices, E2D_COUNTOF(indices) * sizeof(indices[0])),
|
||||
index_decl,
|
||||
index_buffer::usage::static_draw);
|
||||
|
||||
const auto vb = the<render>().create_vertex_buffer(
|
||||
vertices, E2D_COUNTOF(vertices), vertex_buffer::usage::static_draw);
|
||||
buffer(vertices, E2D_COUNTOF(vertices) * sizeof(vertices[0])),
|
||||
vertex_decl,
|
||||
vertex_buffer::usage::static_draw);
|
||||
|
||||
const auto begin_time = time::now_ms();
|
||||
|
||||
const keyboard& k = the<input>().keyboard();
|
||||
while ( !the<window>().should_close() && !k.is_key_just_released(keyboard_key::escape) ) {
|
||||
the<render>().set_clear_color({1.f, 0.4f, 0.f});
|
||||
the<render>().set_clear_color({1.f, 0.4f, 0.f, 1.f});
|
||||
the<render>().clear(true, true, true);
|
||||
the<render>().draw(ps, ib, vb);
|
||||
|
||||
f32 t = (time::now_ms() - begin_time).cast_to<f32>().value;
|
||||
ps->set_uniform("u_time", t);
|
||||
{
|
||||
the<render>().draw(render::topology::triangles, ps, ib, vb);
|
||||
}
|
||||
the<window>().swap_buffers(true);
|
||||
the<input>().frame_tick();
|
||||
window::poll_events();
|
||||
|
||||
@@ -5,3 +5,202 @@
|
||||
******************************************************************************/
|
||||
|
||||
#include "render_impl/render.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
using namespace e2d;
|
||||
|
||||
std::size_t index_element_size(index_declaration::index_type it) noexcept {
|
||||
#define DEFINE_CASE(x,y) case index_declaration::index_type::x: return y;
|
||||
switch ( it ) {
|
||||
DEFINE_CASE(unsigned_byte, sizeof(u8));
|
||||
DEFINE_CASE(unsigned_short, sizeof(u16));
|
||||
default:
|
||||
E2D_ASSERT_MSG(false, "unexpected index type");
|
||||
break;
|
||||
}
|
||||
#undef DEFINE_CASE
|
||||
}
|
||||
|
||||
std::size_t attribute_element_size(vertex_declaration::attribute_type at) noexcept {
|
||||
#define DEFINE_CASE(x,y) case vertex_declaration::attribute_type::x: return y;
|
||||
switch ( at ) {
|
||||
DEFINE_CASE(signed_byte, sizeof(u8));
|
||||
DEFINE_CASE(unsigned_byte, sizeof(u8));
|
||||
DEFINE_CASE(signed_short, sizeof(u16));
|
||||
DEFINE_CASE(unsigned_short, sizeof(u16));
|
||||
DEFINE_CASE(floating_point, sizeof(u32));
|
||||
default:
|
||||
E2D_ASSERT_MSG(false, "unexpected attribute type");
|
||||
break;
|
||||
}
|
||||
#undef DEFINE_CASE
|
||||
}
|
||||
}
|
||||
|
||||
namespace e2d
|
||||
{
|
||||
//
|
||||
// index_declaration::index_info
|
||||
//
|
||||
|
||||
index_declaration::index_info::index_info(index_type ntype) noexcept
|
||||
: type(ntype) {}
|
||||
|
||||
//
|
||||
// index_declaration
|
||||
//
|
||||
|
||||
index_declaration::index_declaration() noexcept = default;
|
||||
index_declaration::~index_declaration() noexcept = default;
|
||||
|
||||
index_declaration::index_declaration(index_type type) noexcept
|
||||
: index_(type) {}
|
||||
|
||||
const index_declaration::index_info& index_declaration::index() const noexcept {
|
||||
return index_;
|
||||
}
|
||||
|
||||
std::size_t index_declaration::index_size() const noexcept {
|
||||
return index_element_size(index_.type);
|
||||
}
|
||||
|
||||
bool operator==(const index_declaration& l, const index_declaration& r) noexcept {
|
||||
return l.index_size() == r.index_size()
|
||||
&& l.index() == r.index();
|
||||
}
|
||||
|
||||
bool operator!=(const index_declaration& l, const index_declaration& r) noexcept {
|
||||
return !(l == r);
|
||||
}
|
||||
|
||||
bool operator==(
|
||||
const index_declaration::index_info& l,
|
||||
const index_declaration::index_info& r) noexcept
|
||||
{
|
||||
return l.type == r.type;
|
||||
}
|
||||
|
||||
bool operator!=(
|
||||
const index_declaration::index_info& l,
|
||||
const index_declaration::index_info& r) noexcept
|
||||
{
|
||||
return !(l == r);
|
||||
}
|
||||
|
||||
//
|
||||
// vertex_declaration::attribute_info
|
||||
//
|
||||
|
||||
vertex_declaration::attribute_info::attribute_info(
|
||||
str_view nname,
|
||||
std::size_t nrows,
|
||||
std::size_t ncolumns,
|
||||
std::size_t nstride,
|
||||
attribute_type ntype,
|
||||
bool nnormalized)
|
||||
: rows(nrows)
|
||||
, columns(ncolumns)
|
||||
, stride(nstride)
|
||||
, type(ntype)
|
||||
, normalized(nnormalized) {
|
||||
bool name_format_success = strings::format_nothrow(
|
||||
name, E2D_COUNTOF(name), nullptr, "%0", nname);
|
||||
E2D_UNUSED(name_format_success);
|
||||
E2D_ASSERT(name_format_success);
|
||||
}
|
||||
|
||||
std::size_t vertex_declaration::attribute_info::row_size() const noexcept {
|
||||
return attribute_element_size(type) * columns;
|
||||
}
|
||||
|
||||
//
|
||||
// vertex_declaration
|
||||
//
|
||||
|
||||
vertex_declaration::vertex_declaration() noexcept = default;
|
||||
vertex_declaration::~vertex_declaration() noexcept = default;
|
||||
|
||||
vertex_declaration& vertex_declaration::normalized() noexcept {
|
||||
E2D_ASSERT(attribute_count_ > 0);
|
||||
attributes_[attribute_count_ - 1].normalized = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
vertex_declaration& vertex_declaration::skip_bytes(std::size_t bytes) noexcept {
|
||||
vertex_size_ += bytes;
|
||||
return *this;
|
||||
}
|
||||
|
||||
vertex_declaration& vertex_declaration::add_attribute(
|
||||
str_view name,
|
||||
std::size_t rows,
|
||||
std::size_t columns,
|
||||
attribute_type type,
|
||||
bool normalized) noexcept
|
||||
{
|
||||
E2D_ASSERT(attribute_count_ < attributes_.size());
|
||||
const std::size_t stride = vertex_size_;
|
||||
attributes_[attribute_count_] = attribute_info(
|
||||
name,
|
||||
rows,
|
||||
columns,
|
||||
stride,
|
||||
type,
|
||||
normalized);
|
||||
vertex_size_ += attribute_element_size(type) * rows * columns;
|
||||
++attribute_count_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const vertex_declaration::attribute_info& vertex_declaration::attribute(std::size_t i) const noexcept {
|
||||
E2D_ASSERT(i < attribute_count_);
|
||||
return attributes_[i];
|
||||
}
|
||||
|
||||
std::size_t vertex_declaration::attribute_count() const noexcept {
|
||||
return attribute_count_;
|
||||
}
|
||||
|
||||
std::size_t vertex_declaration::vertex_size() const noexcept {
|
||||
return vertex_size_;
|
||||
}
|
||||
|
||||
bool operator==(const vertex_declaration& l, const vertex_declaration& r) noexcept {
|
||||
if ( l.vertex_size() != r.vertex_size() ) {
|
||||
return false;
|
||||
}
|
||||
if ( l.attribute_count() != r.attribute_count() ) {
|
||||
return false;
|
||||
}
|
||||
for ( std::size_t i = 0, e = l.attribute_count(); i < e; ++i ) {
|
||||
if ( l.attribute(i) != r.attribute(i) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator!=(const vertex_declaration& l, const vertex_declaration& r) noexcept {
|
||||
return !(l == r);
|
||||
}
|
||||
|
||||
bool operator==(
|
||||
const vertex_declaration::attribute_info& l,
|
||||
const vertex_declaration::attribute_info& r) noexcept
|
||||
{
|
||||
return !std::strcmp(l.name, r.name)
|
||||
&& l.rows == r.rows
|
||||
&& l.columns == r.columns
|
||||
&& l.stride == r.stride
|
||||
&& l.type == r.type
|
||||
&& l.normalized == r.normalized;
|
||||
}
|
||||
|
||||
bool operator!=(
|
||||
const vertex_declaration::attribute_info& l,
|
||||
const vertex_declaration::attribute_info& r) noexcept
|
||||
{
|
||||
return !(l == r);
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -8,4 +8,82 @@
|
||||
using namespace e2d;
|
||||
|
||||
TEST_CASE("render"){
|
||||
SECTION("index_declaration"){
|
||||
index_declaration id;
|
||||
REQUIRE(id.index().type == index_declaration::index_type::unsigned_short);
|
||||
REQUIRE(id.index_size() == 2);
|
||||
|
||||
index_declaration id2(index_declaration::index_type::unsigned_short);
|
||||
REQUIRE(id2.index().type == index_declaration::index_type::unsigned_short);
|
||||
REQUIRE(id2.index_size() == 2);
|
||||
|
||||
index_declaration id3(index_declaration::index_type::unsigned_byte);
|
||||
REQUIRE(id3.index().type == index_declaration::index_type::unsigned_byte);
|
||||
REQUIRE(id3.index_size() == 1);
|
||||
|
||||
REQUIRE(id == id2);
|
||||
REQUIRE_FALSE(id == id3);
|
||||
|
||||
REQUIRE_FALSE(id != id2);
|
||||
REQUIRE(id != id3);
|
||||
|
||||
index_declaration id4 = id;
|
||||
REQUIRE(id4 == id2);
|
||||
id4 = id3;
|
||||
REQUIRE(id4 != id2);
|
||||
REQUIRE(id4 == id3);
|
||||
}
|
||||
SECTION("vertex_declaration"){
|
||||
vertex_declaration vd;
|
||||
REQUIRE(vd.attribute_count() == 0);
|
||||
REQUIRE(vd.vertex_size() == 0);
|
||||
|
||||
REQUIRE(&vd == &vd.add_attribute<v2f>("hello"));
|
||||
REQUIRE(vd.attribute_count() == 1);
|
||||
REQUIRE(vd.vertex_size() == 8);
|
||||
|
||||
vertex_declaration::attribute_info ai = vd.attribute(0);
|
||||
REQUIRE(!std::strcmp(ai.name, "hello"));
|
||||
REQUIRE(ai.columns == 2);
|
||||
REQUIRE(ai.stride == 0);
|
||||
REQUIRE(ai.type == vertex_declaration::attribute_type::floating_point);
|
||||
REQUIRE_FALSE(ai.normalized);
|
||||
|
||||
REQUIRE(&vd == &vd.skip_bytes(4));
|
||||
REQUIRE(vd.vertex_size() == 12);
|
||||
|
||||
REQUIRE(&vd == &vd.add_attribute<u16>("world").normalized());
|
||||
REQUIRE(vd.attribute_count() == 2);
|
||||
REQUIRE(vd.vertex_size() == 14);
|
||||
|
||||
vertex_declaration::attribute_info ai2 = vd.attribute(1);
|
||||
REQUIRE(!std::strcmp(ai2.name, "world"));
|
||||
REQUIRE(ai2.columns == 1);
|
||||
REQUIRE(ai2.stride == 12);
|
||||
REQUIRE(ai2.type == vertex_declaration::attribute_type::unsigned_short);
|
||||
REQUIRE(ai2.normalized);
|
||||
|
||||
auto vd2 = vertex_declaration()
|
||||
.add_attribute("hello", 1, 2, vertex_declaration::attribute_type::floating_point, false)
|
||||
.skip_bytes(4)
|
||||
.add_attribute("world", 1, 1, vertex_declaration::attribute_type::unsigned_short, true);
|
||||
REQUIRE(vd == vd2);
|
||||
REQUIRE_FALSE(vd != vd2);
|
||||
|
||||
auto vd3 = vertex_declaration()
|
||||
.add_attribute<v2f>("hello")
|
||||
.add_attribute<v2f>("world");
|
||||
REQUIRE_FALSE(vd == vd3);
|
||||
REQUIRE(vd != vd3);
|
||||
|
||||
REQUIRE(vd3.vertex_size() == 16);
|
||||
vd3.skip_bytes(4);
|
||||
REQUIRE(vd3.vertex_size() == 20);
|
||||
|
||||
vertex_declaration vd4 = vd2;
|
||||
REQUIRE(vd4 == vd);
|
||||
vd4 = vd3;
|
||||
REQUIRE(vd4 != vd);
|
||||
REQUIRE(vd4 == vd3);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user