vertex and index declarations

This commit is contained in:
2018-10-06 01:33:55 +07:00
parent 2c9a5fd327
commit 278e80f682
8 changed files with 1083 additions and 334 deletions

View File

@@ -11,5 +11,6 @@
#include "debug.hpp"
#include "input.hpp"
#include "render.hpp"
#include "render.inl"
#include "vfs.hpp"
#include "window.hpp"

View File

@@ -16,7 +16,6 @@ namespace e2d
class mouse;
class keyboard;
class input;
class vertex;
class shader;
class texture;
class index_buffer;

View File

@@ -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

View 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

View File

@@ -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();

View File

@@ -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

View File

@@ -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);
}
}