From 7501a6d6763d27d12db0f8ad33d4c894bbed1d16 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Wed, 31 Jul 2019 01:51:48 +0700 Subject: [PATCH] auto opengl/es shader headers --- headers/enduro2d/core/render.hpp | 4 +- samples/bin/library/model_shader.frag | 2 - samples/bin/library/model_shader.vert | 2 - samples/bin/library/sprite_shader.frag | 2 - samples/bin/library/sprite_shader.vert | 2 - samples/sources/sample_00/sample_00.cpp | 4 -- samples/sources/sample_01/sample_01.cpp | 4 -- samples/sources/sample_02/sample_02.cpp | 4 -- .../core/dbgui_impl/dbgui_shaders.cpp | 4 -- .../enduro2d/core/render_impl/render_none.cpp | 4 +- .../core/render_impl/render_opengl.cpp | 72 +++++++++++++++++-- .../core/render_impl/render_opengl_base.cpp | 26 ++++++- .../core/render_impl/render_opengl_base.hpp | 12 +++- untests/bin/library/shader.frag | 2 - untests/bin/library/shader.vert | 2 - 15 files changed, 104 insertions(+), 42 deletions(-) diff --git a/headers/enduro2d/core/render.hpp b/headers/enduro2d/core/render.hpp index abcdca04..e442a716 100644 --- a/headers/enduro2d/core/render.hpp +++ b/headers/enduro2d/core/render.hpp @@ -912,8 +912,8 @@ namespace e2d ~render() noexcept final; shader_ptr create_shader( - const str& vertex_source, - const str& fragment_source); + str_view vertex_source, + str_view fragment_source); shader_ptr create_shader( const input_stream_uptr& vertex_stream, diff --git a/samples/bin/library/model_shader.frag b/samples/bin/library/model_shader.frag index fd0fff5a..64fab438 100644 --- a/samples/bin/library/model_shader.frag +++ b/samples/bin/library/model_shader.frag @@ -1,5 +1,3 @@ -#version 120 - uniform sampler2D u_texture; varying vec2 v_st0; diff --git a/samples/bin/library/model_shader.vert b/samples/bin/library/model_shader.vert index dfd99550..0e1f4a33 100644 --- a/samples/bin/library/model_shader.vert +++ b/samples/bin/library/model_shader.vert @@ -1,5 +1,3 @@ -#version 120 - uniform mat4 u_matrix_m; uniform mat4 u_matrix_vp; diff --git a/samples/bin/library/sprite_shader.frag b/samples/bin/library/sprite_shader.frag index b1579c37..7efd0b8b 100644 --- a/samples/bin/library/sprite_shader.frag +++ b/samples/bin/library/sprite_shader.frag @@ -1,5 +1,3 @@ -#version 120 - uniform sampler2D u_texture; varying vec4 v_tint; diff --git a/samples/bin/library/sprite_shader.vert b/samples/bin/library/sprite_shader.vert index 57e41375..193f5f04 100644 --- a/samples/bin/library/sprite_shader.vert +++ b/samples/bin/library/sprite_shader.vert @@ -1,5 +1,3 @@ -#version 120 - uniform mat4 u_matrix_vp; attribute vec3 a_vertex; diff --git a/samples/sources/sample_00/sample_00.cpp b/samples/sources/sample_00/sample_00.cpp index 82edf983..2b57fd4f 100644 --- a/samples/sources/sample_00/sample_00.cpp +++ b/samples/sources/sample_00/sample_00.cpp @@ -10,8 +10,6 @@ using namespace e2d; namespace { const char* vs_source_cstr = R"glsl( - #version 120 - attribute vec3 a_position; attribute vec2 a_uv; attribute vec4 a_color; @@ -32,8 +30,6 @@ namespace )glsl"; const char* fs_source_cstr = R"glsl( - #version 120 - uniform float u_time; uniform sampler2D u_texture1; uniform sampler2D u_texture2; diff --git a/samples/sources/sample_01/sample_01.cpp b/samples/sources/sample_01/sample_01.cpp index 7a23c8eb..fd477224 100644 --- a/samples/sources/sample_01/sample_01.cpp +++ b/samples/sources/sample_01/sample_01.cpp @@ -10,8 +10,6 @@ using namespace e2d; namespace { const char* vs_source_cstr = R"glsl( - #version 120 - attribute vec3 a_position; attribute vec2 a_uv; attribute vec4 a_color; @@ -30,8 +28,6 @@ namespace )glsl"; const char* fs_source_cstr = R"glsl( - #version 120 - uniform sampler2D u_texture; varying vec4 v_color; varying vec2 v_uv; diff --git a/samples/sources/sample_02/sample_02.cpp b/samples/sources/sample_02/sample_02.cpp index d1253245..0d9f11cc 100644 --- a/samples/sources/sample_02/sample_02.cpp +++ b/samples/sources/sample_02/sample_02.cpp @@ -10,8 +10,6 @@ using namespace e2d; namespace { const char* vs_source_cstr = R"glsl( - #version 120 - attribute vec3 a_position; attribute vec2 a_uv; @@ -27,8 +25,6 @@ namespace )glsl"; const char* fs_source_cstr = R"glsl( - #version 120 - uniform sampler2D u_texture; varying vec2 v_uv; diff --git a/sources/enduro2d/core/dbgui_impl/dbgui_shaders.cpp b/sources/enduro2d/core/dbgui_impl/dbgui_shaders.cpp index d2de6f54..2ecec8ab 100644 --- a/sources/enduro2d/core/dbgui_impl/dbgui_shaders.cpp +++ b/sources/enduro2d/core/dbgui_impl/dbgui_shaders.cpp @@ -9,8 +9,6 @@ namespace { const char* vs_src_cstr = R"glsl( - #version 120 - attribute vec2 a_position; attribute vec2 a_uv; attribute vec4 a_color; @@ -28,8 +26,6 @@ namespace )glsl"; const char* fs_src_cstr = R"glsl( - #version 120 - uniform sampler2D u_texture; varying vec4 v_color; varying vec2 v_uv; diff --git a/sources/enduro2d/core/render_impl/render_none.cpp b/sources/enduro2d/core/render_impl/render_none.cpp index e561a51c..4713cfd7 100644 --- a/sources/enduro2d/core/render_impl/render_none.cpp +++ b/sources/enduro2d/core/render_impl/render_none.cpp @@ -173,8 +173,8 @@ namespace e2d render::~render() noexcept = default; shader_ptr render::create_shader( - const str& vertex_source, - const str& fragment_source) + str_view vertex_source, + str_view fragment_source) { E2D_UNUSED(vertex_source, fragment_source); return nullptr; diff --git a/sources/enduro2d/core/render_impl/render_opengl.cpp b/sources/enduro2d/core/render_impl/render_opengl.cpp index 79abad03..9ecfe0ce 100644 --- a/sources/enduro2d/core/render_impl/render_opengl.cpp +++ b/sources/enduro2d/core/render_impl/render_opengl.cpp @@ -11,6 +11,57 @@ #if defined(E2D_RENDER_MODE) #if E2D_RENDER_MODE == E2D_RENDER_MODE_OPENGL || E2D_RENDER_MODE == E2D_RENDER_MODE_OPENGLES +namespace +{ + using namespace e2d; + + const char* vertex_shader_header_cstr(render::api_profile profile) noexcept { + switch ( profile ) { + case e2d::render::api_profile::unknown: + return ""; + case e2d::render::api_profile::opengles2: + case e2d::render::api_profile::opengles3: + return R"glsl( + precision highp int; + precision highp float; + )glsl"; + case e2d::render::api_profile::opengl_compat: + return R"glsl( + #version 120 + #define highp + #define mediump + #define lowp + )glsl"; + default: + E2D_ASSERT_MSG(false, "unexpected render API profile"); + return ""; + } + } + + const char* fragment_shader_header_cstr(render::api_profile profile) noexcept { + switch ( profile ) { + case e2d::render::api_profile::unknown: + return ""; + case e2d::render::api_profile::opengles2: + case e2d::render::api_profile::opengles3: + return R"glsl( + precision mediump int; + precision mediump float; + )glsl"; + case e2d::render::api_profile::opengl_compat: + return R"glsl( + #version 120 + #define highp + #define mediump + #define lowp + )glsl"; + default: + E2D_ASSERT_MSG(false, "unexpected render API profile"); + return ""; + } + } +} + namespace { using namespace e2d; @@ -428,25 +479,36 @@ namespace e2d render::~render() noexcept = default; shader_ptr render::create_shader( - const str& vertex_source, - const str& fragment_source) + str_view vertex_source, + str_view fragment_source) { E2D_ASSERT(is_in_main_thread()); gl_shader_id vs = gl_compile_shader( - state_->dbg(), vertex_source, GL_VERTEX_SHADER); + state_->dbg(), + vertex_shader_header_cstr(device_capabilities().profile), + vertex_source, + GL_VERTEX_SHADER); + if ( vs.empty() ) { return nullptr; } gl_shader_id fs = gl_compile_shader( - state_->dbg(), fragment_source, GL_FRAGMENT_SHADER); + state_->dbg(), + fragment_shader_header_cstr(device_capabilities().profile), + fragment_source, + GL_FRAGMENT_SHADER); + if ( fs.empty() ) { return nullptr; } gl_program_id ps = gl_link_program( - state_->dbg(), std::move(vs), std::move(fs)); + state_->dbg(), + std::move(vs), + std::move(fs)); + if ( ps.empty() ) { return nullptr; } diff --git a/sources/enduro2d/core/render_impl/render_opengl_base.cpp b/sources/enduro2d/core/render_impl/render_opengl_base.cpp index a2a73d33..0b8818f3 100644 --- a/sources/enduro2d/core/render_impl/render_opengl_base.cpp +++ b/sources/enduro2d/core/render_impl/render_opengl_base.cpp @@ -1441,14 +1441,32 @@ namespace e2d::opengl "GL_IMG_texture_compression_pvrtc2"); } - gl_shader_id gl_compile_shader(debug& debug, const str& source, GLenum type) noexcept { + gl_shader_id gl_compile_shader( + debug& debug, + str_view header, + str_view source, + GLenum type) noexcept + { gl_shader_id id = gl_shader_id::create(debug, type); if ( id.empty() ) { return id; } - const char* source_cstr = source.c_str(); - GL_CHECK_CODE(debug, glShaderSource(*id, 1, &source_cstr, nullptr)); + + const GLchar* sources[] = { + header.empty() ? "" : header.data(), + source.empty() ? "" : source.data()}; + const GLint source_lengths[] = { + math::numeric_cast(header.size()), + math::numeric_cast(source.size())}; + static_assert(std::size(sources) == std::size(source_lengths)); + + GL_CHECK_CODE(debug, glShaderSource( + *id, + math::numeric_cast(std::size(sources)), + sources, + source_lengths)); GL_CHECK_CODE(debug, glCompileShader(*id)); + return process_shader_compilation_result(debug, *id) ? std::move(id) : gl_shader_id(debug); @@ -1460,9 +1478,11 @@ namespace e2d::opengl if ( id.empty() ) { return id; } + GL_CHECK_CODE(debug, glAttachShader(*id, *vs)); GL_CHECK_CODE(debug, glAttachShader(*id, *fs)); GL_CHECK_CODE(debug, glLinkProgram(*id)); + return process_program_linking_result(debug, *id) && process_program_validation_result(debug, *id) ? std::move(id) diff --git a/sources/enduro2d/core/render_impl/render_opengl_base.hpp b/sources/enduro2d/core/render_impl/render_opengl_base.hpp index f4a37eab..cbb8acd2 100644 --- a/sources/enduro2d/core/render_impl/render_opengl_base.hpp +++ b/sources/enduro2d/core/render_impl/render_opengl_base.hpp @@ -299,8 +299,16 @@ namespace e2d::opengl void gl_trace_limits(debug& debug) noexcept; void gl_fill_device_caps(debug& debug, render::device_caps& caps) noexcept; - gl_shader_id gl_compile_shader(debug& debug, const str& source, GLenum type) noexcept; - gl_program_id gl_link_program(debug& debug, gl_shader_id vs, gl_shader_id fs) noexcept; + gl_shader_id gl_compile_shader( + debug& debug, + str_view header, + str_view source, + GLenum type) noexcept; + + gl_program_id gl_link_program( + debug& debug, + gl_shader_id vs, + gl_shader_id fs) noexcept; bool gl_check_framebuffer( debug& debug, diff --git a/untests/bin/library/shader.frag b/untests/bin/library/shader.frag index da069db1..4689b337 100644 --- a/untests/bin/library/shader.frag +++ b/untests/bin/library/shader.frag @@ -1,5 +1,3 @@ -#version 120 - uniform sampler2D u_texture; varying vec2 v_st; diff --git a/untests/bin/library/shader.vert b/untests/bin/library/shader.vert index c686019b..10fcdcae 100644 --- a/untests/bin/library/shader.vert +++ b/untests/bin/library/shader.vert @@ -1,5 +1,3 @@ -#version 120 - attribute vec3 a_position; attribute vec2 a_st;