Merge branch 'master' into feature/scripting

This commit is contained in:
2019-10-03 21:12:45 +07:00
19 changed files with 213 additions and 111 deletions

View File

@@ -5,7 +5,7 @@ environment:
E2D_WITHOUT_GRAPHICS: true
image:
- Visual Studio 2017
- Visual Studio 2019 Preview
- Visual Studio 2019
platform:
- Win32
- x64

View File

@@ -2,5 +2,15 @@
-Iheaders/3rdparty
-Iheaders/3rdparty/lua
-Isources
-Imodules/ecs.hpp/headers
-Imodules/flat.hpp/headers
-Imodules/curly.hpp/headers
-Imodules/promise.hpp/headers
-Imodules/glew/include
-Imodules/glfw/include
-Imodules/spine/spine-c/spine-c/include
-std=c++17
-stdlib=libc++

View File

@@ -114,7 +114,6 @@ namespace e2d
class index_declaration final {
public:
enum class index_type : u8 {
unsigned_byte,
unsigned_short,
unsigned_int
};
@@ -881,9 +880,10 @@ namespace e2d
enum class api_profile {
unknown,
opengles2,
opengles3,
opengl_compat
gles_2_0,
gles_3_0,
gl_2_1_compat,
gl_3_2_compat
};
struct device_caps {

View File

@@ -61,7 +61,6 @@
#include "node.hpp"
#include "node.inl"
#include "prefab.hpp"
#include "spine.hpp"
#include "script.hpp"
#include "spine.hpp"
#include "sprite.hpp"

View File

@@ -19,6 +19,14 @@ function(add_e2d_sample NAME)
target_link_libraries(${SAMPLE_NAME} enduro2d)
set_target_properties(${SAMPLE_NAME} PROPERTIES FOLDER samples)
target_compile_options(${SAMPLE_NAME}
PRIVATE
$<$<CXX_COMPILER_ID:MSVC>:
/W3 /MP /bigobj>
PRIVATE
$<$<OR:$<CXX_COMPILER_ID:GNU>,$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:
-Wall -Wextra -Wpedantic>)
#
# resources
#

View File

@@ -64,7 +64,7 @@ namespace
}
};
std::array<u8,6> generate_quad_indices() noexcept {
std::array<u16,6> generate_quad_indices() noexcept {
return {0, 1, 2, 2, 1, 3};
}
@@ -111,7 +111,7 @@ namespace
const auto indices = generate_quad_indices();
index_buffer_ = the<render>().create_index_buffer(
indices,
index_declaration::index_type::unsigned_byte,
index_declaration::index_type::unsigned_short,
index_buffer::usage::static_draw);
const auto vertices1 = generate_quad_vertices(texture1_->size());

View File

@@ -56,7 +56,7 @@ namespace
}
};
std::array<u8,36> generate_cube_indices() noexcept {
std::array<u16,36> generate_cube_indices() noexcept {
return {
0, 1, 2,
2, 3, 0,
@@ -170,7 +170,7 @@ namespace
const auto indices = generate_cube_indices();
index_buffer_ = the<render>().create_index_buffer(
indices,
index_declaration::index_type::unsigned_byte,
index_declaration::index_type::unsigned_short,
index_buffer::usage::static_draw);
const auto vertices1 = generate_cube_vertices(make_vec3(1.f));

View File

@@ -44,7 +44,7 @@ namespace
}
};
std::array<u8,36> generate_cube_indices() noexcept {
std::array<u16,36> generate_cube_indices() noexcept {
return {
0, 1, 2,
2, 3, 0,
@@ -125,7 +125,7 @@ namespace
const auto indices = generate_cube_indices();
index_buffer_ = the<render>().create_index_buffer(
indices,
index_declaration::index_type::unsigned_byte,
index_declaration::index_type::unsigned_short,
index_buffer::usage::static_draw);
const auto vertices = generate_cube_vertices(make_vec3(1.f));

View File

@@ -0,0 +1,12 @@
@echo off
set BUILD_DIR=%~dp0%\..\build
mkdir %BUILD_DIR%\msvc2019 || goto :error
cd %BUILD_DIR%\msvc2019 || goto :error
cmake -G "Visual Studio 16 2019" ..\.. || goto :error
start enduro2d.sln || goto :error
goto :EOF
:error
echo Failed with error #%errorlevel%.
exit /b %errorlevel%

View File

@@ -68,7 +68,6 @@ namespace
const char* index_element_cstr(index_declaration::index_type it) noexcept {
#define DEFINE_CASE(x) case index_declaration::index_type::x: return #x;
switch ( it ) {
DEFINE_CASE(unsigned_byte);
DEFINE_CASE(unsigned_short);
DEFINE_CASE(unsigned_int);
default:
@@ -81,7 +80,6 @@ namespace
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));
DEFINE_CASE(unsigned_int, sizeof(u32));
default:

View File

@@ -19,19 +19,26 @@ namespace
switch ( profile ) {
case e2d::render::api_profile::unknown:
return "";
case e2d::render::api_profile::opengles2:
case e2d::render::api_profile::opengles3:
case e2d::render::api_profile::gles_2_0:
case e2d::render::api_profile::gles_3_0:
return R"glsl(
precision highp int;
precision highp float;
)glsl";
case e2d::render::api_profile::opengl_compat:
case e2d::render::api_profile::gl_2_1_compat:
return R"glsl(
#version 120
#define highp
#define mediump
#define lowp
)glsl";
case e2d::render::api_profile::gl_3_2_compat:
return R"glsl(
#version 150
#define texture2D texture
#define varying out
#define attribute in
)glsl";
default:
E2D_ASSERT_MSG(false, "unexpected render API profile");
return "";
@@ -42,19 +49,25 @@ namespace
switch ( profile ) {
case e2d::render::api_profile::unknown:
return "";
case e2d::render::api_profile::opengles2:
case e2d::render::api_profile::opengles3:
case e2d::render::api_profile::gles_2_0:
case e2d::render::api_profile::gles_3_0:
return R"glsl(
precision mediump int;
precision mediump float;
)glsl";
case e2d::render::api_profile::opengl_compat:
case e2d::render::api_profile::gl_2_1_compat:
return R"glsl(
#version 120
#define highp
#define mediump
#define lowp
)glsl";
case e2d::render::api_profile::gl_3_2_compat:
return R"glsl(
#version 150
#define texture2D texture
#define varying in
)glsl";
default:
E2D_ASSERT_MSG(false, "unexpected render API profile");
return "";
@@ -1204,7 +1217,6 @@ namespace e2d
E2D_ASSERT(is_in_main_thread());
const device_caps& caps = device_capabilities();
switch ( decl.type() ) {
case index_declaration::index_type::unsigned_byte:
case index_declaration::index_type::unsigned_short:
return true;
case index_declaration::index_type::unsigned_int:

View File

@@ -78,24 +78,6 @@ namespace
return success == GL_TRUE;
}
bool process_program_validation_result(debug& debug, GLuint program) noexcept {
E2D_ASSERT(glIsProgram(program));
GL_CHECK_CODE(debug, glValidateProgram(program));
GLint success = GL_FALSE;
GL_CHECK_CODE(debug, glGetProgramiv(program, GL_VALIDATE_STATUS, &success));
GLint log_len = 0;
GL_CHECK_CODE(debug, glGetProgramiv(program, GL_INFO_LOG_LENGTH, &log_len));
if ( log_len > 0 ) {
GLchar* log_buffer = static_cast<GLchar*>(E2D_ALLOCA(
sizeof(GLchar) * math::numeric_cast<std::size_t>(log_len)));
GL_CHECK_CODE(debug, glGetProgramInfoLog(
program, log_len, nullptr, log_buffer));
debug.log(success ? debug::level::warning : debug::level::error,
"RENDER: program validation info:\n--> %0", log_buffer);
}
return success == GL_TRUE;
}
template < typename... Ext >
bool gl_has_any_extension(debug& debug, Ext... required) noexcept {
const GLubyte* all_extensions = nullptr;
@@ -125,10 +107,34 @@ namespace
gl_bit_ = 1 << 28,
gles_bit_ = 2 << 28,
gl_210 = 210 | gl_bit_,
gl_300 = 300 | gl_bit_,
gles_200 = 200 | gles_bit_,
gles_300 = 300 | gles_bit_
gl_1_0 = 100 | gl_bit_,
gl_1_1 = 110 | gl_bit_,
gl_1_2 = 120 | gl_bit_,
gl_1_3 = 130 | gl_bit_,
gl_1_4 = 140 | gl_bit_,
gl_1_5 = 150 | gl_bit_,
gl_2_0 = 200 | gl_bit_,
gl_2_1 = 210 | gl_bit_,
gl_3_0 = 300 | gl_bit_,
gl_3_1 = 310 | gl_bit_,
gl_3_2 = 320 | gl_bit_,
gl_3_3 = 330 | gl_bit_,
gl_4_0 = 400 | gl_bit_,
gl_4_1 = 410 | gl_bit_,
gl_4_2 = 420 | gl_bit_,
gl_4_3 = 430 | gl_bit_,
gl_4_4 = 440 | gl_bit_,
gl_4_5 = 450 | gl_bit_,
gl_4_6 = 460 | gl_bit_,
gles_2_0 = 200 | gles_bit_,
gles_3_0 = 300 | gles_bit_,
gles_3_1 = 310 | gles_bit_,
gles_3_2 = 320 | gles_bit_
};
bool operator>=(gl_version lhs, gl_version rhs) noexcept {
@@ -910,7 +916,6 @@ namespace e2d::opengl
GLenum convert_index_type(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, GL_UNSIGNED_BYTE);
DEFINE_CASE(unsigned_short, GL_UNSIGNED_SHORT);
DEFINE_CASE(unsigned_int, GL_UNSIGNED_INT);
default:
@@ -1334,6 +1339,10 @@ namespace e2d::opengl
max_combined_texture_image_units);
}
bool gl_has_extension(debug& debug, str_view name) noexcept {
return gl_has_any_extension(debug, name);
}
void gl_fill_device_caps(debug& debug, render::device_caps& caps) noexcept {
GLint max_texture_size = 0;
GLint max_renderbuffer_size = 0;
@@ -1391,55 +1400,56 @@ namespace e2d::opengl
const gl_version version = gl_get_version(debug);
caps.profile =
version >= gl_version::gles_300 ? render::api_profile::opengles3 :
version >= gl_version::gles_200 ? render::api_profile::opengles2 :
render::api_profile::opengl_compat;
version >= gl_version::gles_3_0 ? render::api_profile::gles_3_0 :
version >= gl_version::gles_2_0 ? render::api_profile::gles_2_0 :
version >= gl_version::gl_3_2 ? render::api_profile::gl_3_2_compat :
render::api_profile::gl_2_1_compat;
caps.npot_texture_supported =
version >= gl_version::gl_210 || // gl_200
version >= gl_version::gles_300 ||
version >= gl_version::gl_2_0 ||
version >= gl_version::gles_3_0 ||
gl_has_any_extension(debug,
"GL_OES_texture_npot",
"GL_ARB_texture_non_power_of_two");
caps.depth_texture_supported =
version >= gl_version::gl_210 ||
version >= gl_version::gles_300 ||
version >= gl_version::gl_1_4 ||
version >= gl_version::gles_3_0 ||
gl_has_any_extension(debug,
"GL_OES_depth_texture",
"GL_ARB_depth_texture"); // gl_140
"GL_ARB_depth_texture");
caps.render_target_supported =
version >= gl_version::gl_300 || // gl_300
version >= gl_version::gles_200 ||
version >= gl_version::gl_3_0 ||
version >= gl_version::gles_2_0 ||
gl_has_any_extension(debug,
"GL_OES_framebuffer_object",
"GL_EXT_framebuffer_object",
"GL_ARB_framebuffer_object");
caps.element_index_uint =
version >= gl_version::gl_210 || // gl_100
version >= gl_version::gles_300 ||
version >= gl_version::gl_1_1 ||
version >= gl_version::gles_3_0 ||
gl_has_any_extension(debug,
"GL_OES_element_index_uint");
caps.depth16_supported =
version >= gl_version::gl_210 || // gl_140
version >= gl_version::gles_300 ||
version >= gl_version::gl_1_4 ||
version >= gl_version::gles_3_0 ||
gl_has_any_extension(debug,
"GL_OES_depth_texture",
"GL_ARB_depth_texture");
caps.depth24_supported =
version >= gl_version::gl_210 || // gl_140
version >= gl_version::gles_300 ||
version >= gl_version::gl_1_4 ||
version >= gl_version::gles_3_0 ||
gl_has_any_extension(debug,
"GL_OES_depth24",
"GL_ARB_depth_texture");
caps.depth24_stencil8_supported =
version >= gl_version::gl_300 || // gl_300
version >= gl_version::gles_300 ||
version >= gl_version::gl_3_0 ||
version >= gl_version::gles_3_0 ||
gl_has_any_extension(debug,
"GL_OES_packed_depth_stencil",
"GL_EXT_packed_depth_stencil");
@@ -1453,7 +1463,8 @@ namespace e2d::opengl
"GL_OES_compressed_ETC1_RGB8_texture");
caps.etc2_compression_supported =
version >= gl_version::gles_300 ||
version >= gl_version::gl_4_3 ||
version >= gl_version::gles_3_0 ||
gl_has_any_extension(debug,
"GL_ARB_ES3_compatibility");
@@ -1515,7 +1526,6 @@ namespace e2d::opengl
GL_CHECK_CODE(debug, glLinkProgram(*id));
return process_program_linking_result(debug, *id)
&& process_program_validation_result(debug, *id)
? std::move(id)
: gl_program_id(debug);
}

View File

@@ -294,6 +294,7 @@ namespace e2d::opengl
{
void gl_trace_info(debug& debug) noexcept;
void gl_trace_limits(debug& debug) noexcept;
bool gl_has_extension(debug& debug, str_view name) noexcept;
void gl_fill_device_caps(debug& debug, render::device_caps& caps) noexcept;
gl_shader_id gl_compile_shader(

View File

@@ -13,6 +13,86 @@ namespace
{
using namespace e2d;
using namespace e2d::opengl;
const char* debug_output_severity_to_cstr(GLenum severity) noexcept {
switch ( severity ) {
case GL_DEBUG_SEVERITY_HIGH: return "high";
case GL_DEBUG_SEVERITY_MEDIUM: return "medium";
case GL_DEBUG_SEVERITY_LOW: return "low";
case GL_DEBUG_SEVERITY_NOTIFICATION: return "notification";
default: return "unknown";
}
}
const char* debug_output_source_to_cstr(GLenum source) noexcept {
switch (source) {
case GL_DEBUG_SOURCE_API: return "API";
case GL_DEBUG_SOURCE_WINDOW_SYSTEM: return "window system";
case GL_DEBUG_SOURCE_SHADER_COMPILER: return "shader compiler";
case GL_DEBUG_SOURCE_THIRD_PARTY: return "third party";
case GL_DEBUG_SOURCE_APPLICATION: return "application";
case GL_DEBUG_SOURCE_OTHER: return "other";
default: return "unknown";
}
}
const char* debug_output_type_to_cstr(GLenum type) noexcept {
switch ( type ) {
case GL_DEBUG_TYPE_ERROR: return "error";
case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: return "deprecated behavior";
case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: return "undefined behavior";
case GL_DEBUG_TYPE_PORTABILITY: return "portability";
case GL_DEBUG_TYPE_PERFORMANCE: return "performance";
case GL_DEBUG_TYPE_OTHER: return "other";
case GL_DEBUG_TYPE_MARKER: return "marker";
case GL_DEBUG_TYPE_PUSH_GROUP: return "push group";
case GL_DEBUG_TYPE_POP_GROUP: return "pop group";
default: return "unknown";
}
}
void GLAPIENTRY debug_output_callback(
GLenum source,
GLenum type,
GLuint id,
GLenum severity,
GLsizei length,
const GLchar* message,
const void* user_param) noexcept
{
if ( !length || !message || !user_param ) {
return;
}
const_cast<debug*>(static_cast<const debug*>(user_param))->trace(
"RENDER: Debug output message:\n"
"--> Id: %0\n"
"--> Severity: %1\n"
"--> Source: %2\n"
"--> Type: %3\n"
"--> Message: %4",
id,
debug_output_severity_to_cstr(severity),
debug_output_source_to_cstr(source),
debug_output_type_to_cstr(type),
str_view(message, length));
}
void setup_debug_output(debug& debug) noexcept {
if ( !gl_has_extension(debug, "GL_KHR_debug") ) {
return;
}
GL_CHECK_CODE(debug, glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS));
GL_CHECK_CODE(debug, glDebugMessageCallback(debug_output_callback, &debug));
GL_CHECK_CODE(debug, glDebugMessageControl(
GL_DONT_CARE,
GL_DONT_CARE,
GL_DEBUG_SEVERITY_NOTIFICATION,
0,
nullptr,
GL_FALSE));
}
}
namespace e2d
@@ -216,6 +296,7 @@ namespace e2d
gl_trace_limits(debug_);
gl_fill_device_caps(debug_, device_caps_);
setup_debug_output(debug_);
GL_CHECK_CODE(debug_, glPixelStorei(GL_PACK_ALIGNMENT, 1));
GL_CHECK_CODE(debug_, glPixelStorei(GL_UNPACK_ALIGNMENT, 1));
@@ -239,7 +320,7 @@ namespace e2d
const render_target_ptr& render::internal_state::render_target() const noexcept {
return render_target_;
}
render::internal_state& render::internal_state::reset_states() noexcept {
set_depth_state_(state_block_.depth());
set_stencil_state_(state_block_.stencil());
@@ -307,7 +388,7 @@ namespace e2d
GL_CHECK_CODE(debug_, glBindFramebuffer(rt_id.target(), *rt_id));
return *this;
}
render::internal_state& render::internal_state::set_render_target(const render_target_ptr& rt) noexcept {
if ( rt == render_target_ ) {
return *this;

View File

@@ -26,7 +26,7 @@ namespace
const b2f& texrect,
const color32& color)
{
const std::size_t start_vertex = vertices_.size();
const u32 start_vertex = math::numeric_cast<u32>(vertices_.size());
// Y
// ^

View File

@@ -10,13 +10,6 @@
namespace e2d::render_system_impl
{
struct index_u8 {
using type = u8;
static index_declaration decl() noexcept {
return index_declaration::index_type::unsigned_byte;
}
};
struct index_u16 {
using type = u16;
static index_declaration decl() noexcept {

View File

@@ -19,6 +19,14 @@ function(add_e2d_tests NAME)
target_link_libraries(${TESTS_NAME} enduro2d)
set_target_properties(${TESTS_NAME} PROPERTIES FOLDER untests)
target_compile_options(${TESTS_NAME}
PRIVATE
$<$<CXX_COMPILER_ID:MSVC>:
/W3 /MP /bigobj>
PRIVATE
$<$<OR:$<CXX_COMPILER_ID:GNU>,$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:
-Wall -Wextra -Wpedantic>)
#
# resources
#
@@ -36,28 +44,8 @@ function(add_e2d_tests NAME)
add_test(${TESTS_NAME} ${TESTS_NAME})
endfunction(add_e2d_tests)
option(E2D_BUILD_BASE_UNTESTS "Build base untests" ON)
option(E2D_BUILD_CORE_UNTESTS "Build core untests" ON)
option(E2D_BUILD_HIGH_UNTESTS "Build high untests" ON)
option(E2D_BUILD_MATH_UNTESTS "Build math untests" ON)
option(E2D_BUILD_UTILS_UNTESTS "Build utils untests" ON)
if(E2D_BUILD_BASE_UNTESTS)
add_e2d_tests(base)
endif()
if(E2D_BUILD_CORE_UNTESTS)
add_e2d_tests(core)
endif()
if(E2D_BUILD_HIGH_UNTESTS)
add_e2d_tests(high)
endif()
if(E2D_BUILD_MATH_UNTESTS)
add_e2d_tests(math)
endif()
if(E2D_BUILD_UTILS_UNTESTS)
add_e2d_tests(utils)
endif()
add_e2d_tests(base)
add_e2d_tests(core)
add_e2d_tests(high)
add_e2d_tests(math)
add_e2d_tests(utils)

View File

@@ -114,21 +114,11 @@ TEST_CASE("render"){
REQUIRE(id2.type() == index_declaration::index_type::unsigned_short);
REQUIRE(id2.bytes_per_index() == 2);
index_declaration id3(index_declaration::index_type::unsigned_byte);
REQUIRE(id3.type() == index_declaration::index_type::unsigned_byte);
REQUIRE(id3.bytes_per_index() == 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;

View File

@@ -212,9 +212,9 @@ TEST_CASE("strings") {
REQUIRE(wildcard_match(
// 你好你好你好你好世界世界世界世界世界世界世界世界彡ಠ
mark_string("\u4F60\u597D\u4F60\u597D\u4F60\u597D\u4F60\u597D\u4E16\u754C\u4E16\u754C\u4E16\u754C\u4E16\u754C\u4E16\u754C\u4E16\u754C\u4E16\u754C\u4E16\u754C\u5F61\u0CA0"),
mark_string(u8"\u4F60\u597D\u4F60\u597D\u4F60\u597D\u4F60\u597D\u4E16\u754C\u4E16\u754C\u4E16\u754C\u4E16\u754C\u4E16\u754C\u4E16\u754C\u4E16\u754C\u4E16\u754C\u5F61\u0CA0"),
// 你好你好你好你好*世界世界彡*ಠ
mark_pattern("\u4F60\u597D\u4F60\u597D\u4F60\u597D\u4F60\u597D*\u4E16\u754C\u4E16\u754C\u5F61*\u0CA0")) == true);
mark_pattern(u8"\u4F60\u597D\u4F60\u597D\u4F60\u597D\u4F60\u597D*\u4E16\u754C\u4E16\u754C\u5F61*\u0CA0")) == true);
REQUIRE(wildcard_match("", "") == true);
REQUIRE(wildcard_match("a", "") == false);