Introduce gfx::shader_source to simplify creating shaders from concatenated sources
This commit is contained in:
parent
11d96829b6
commit
1338aa05ed
8 changed files with 80 additions and 45 deletions
|
|
@ -14,13 +14,39 @@
|
|||
namespace psemek::gfx
|
||||
{
|
||||
|
||||
struct shader_source
|
||||
{
|
||||
std::vector<std::string_view> sources;
|
||||
|
||||
template <std::size_t N>
|
||||
shader_source(char const (&source)[N])
|
||||
: sources{std::string_view{source}}
|
||||
{}
|
||||
|
||||
shader_source(char const * source)
|
||||
: sources{std::string_view{source}}
|
||||
{}
|
||||
|
||||
shader_source(std::string_view source)
|
||||
: sources{source}
|
||||
{}
|
||||
|
||||
shader_source(std::initializer_list<std::string_view> sources)
|
||||
: sources(sources)
|
||||
{}
|
||||
|
||||
explicit shader_source(std::vector<std::string_view> sources)
|
||||
: sources{std::move(sources)}
|
||||
{}
|
||||
};
|
||||
|
||||
struct program
|
||||
{
|
||||
program(std::string_view vertex_source, std::string_view fragment_source);
|
||||
program(shader_source const & vertex_source, shader_source const & fragment_source);
|
||||
|
||||
#ifndef __EMSCRIPTEN__
|
||||
program(std::string_view compute_source);
|
||||
program(std::string_view vertex_source, std::string_view geometry_source, std::string_view fragment_source);
|
||||
program(shader_source const & compute_source);
|
||||
program(shader_source const & vertex_source, shader_source const & geometry_source, shader_source const & fragment_source);
|
||||
#endif
|
||||
|
||||
program(program && other);
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ void main()
|
|||
gfx::array array;
|
||||
|
||||
blur_impl(int size, float sigma, float gamma, bool horizontal)
|
||||
: program(std::string(gl::sys::shader_prelude()) + blur_vs, std::string(gl::sys::shader_prelude()) + generate_blur_fs_source(size, sigma, horizontal))
|
||||
: program({gl::sys::shader_prelude(), blur_vs}, {gl::sys::shader_prelude(), generate_blur_fs_source(size, sigma, horizontal)})
|
||||
{
|
||||
program.bind();
|
||||
program["u_texture"] = 0;
|
||||
|
|
|
|||
|
|
@ -206,7 +206,7 @@ void main()
|
|||
|
||||
struct fxaa::impl
|
||||
{
|
||||
gfx::program program{std::string(gl::sys::shader_prelude()) + fxaa_vs, std::string(gl::sys::shader_prelude()) + fxaa_fs};
|
||||
gfx::program program{{gl::sys::shader_prelude(), fxaa_vs}, {gl::sys::shader_prelude(), fxaa_fs}};
|
||||
gfx::array array;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ void main()
|
|||
|
||||
struct gamma_correction::impl
|
||||
{
|
||||
gfx::program program{std::string(gl::sys::shader_prelude()) + gamma_vs, std::string(gl::sys::shader_prelude()) + gamma_fs};
|
||||
gfx::program program{{gl::sys::shader_prelude(), gamma_vs}, {gl::sys::shader_prelude(), gamma_fs}};
|
||||
gfx::array array;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ void main()
|
|||
|
||||
struct overlay::impl
|
||||
{
|
||||
gfx::program program{std::string(gl::sys::shader_prelude()) + overlay_vs, std::string(gl::sys::shader_prelude()) + overlay_fs};
|
||||
gfx::program program{{gl::sys::shader_prelude(), overlay_vs}, {gl::sys::shader_prelude(), overlay_fs}};
|
||||
gfx::array array;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ void main()
|
|||
namespace psemek::gfx
|
||||
{
|
||||
|
||||
static std::string shader_prefix = std::string{gl::sys::shader_prelude()};
|
||||
static auto const shader_prefix = gl::sys::shader_prelude();
|
||||
|
||||
struct painter::impl
|
||||
{
|
||||
|
|
@ -130,9 +130,9 @@ namespace psemek::gfx
|
|||
math::point<std::uint16_t, 2> texcoord;
|
||||
};
|
||||
|
||||
gfx::program program{shader_prefix + vertex_source, shader_prefix + fragment_source};
|
||||
gfx::program text_program{shader_prefix + text_vertex_source, shader_prefix + text_fragment_source};
|
||||
gfx::program texture_program{shader_prefix + texture_vertex_source, shader_prefix + texture_fragment_source};
|
||||
gfx::program program{{shader_prefix, vertex_source}, {shader_prefix, fragment_source}};
|
||||
gfx::program text_program{{shader_prefix, text_vertex_source}, {shader_prefix, text_fragment_source}};
|
||||
gfx::program texture_program{{shader_prefix, texture_vertex_source}, {shader_prefix, texture_fragment_source}};
|
||||
gfx::mesh mesh;
|
||||
gfx::mesh text_mesh;
|
||||
gfx::mesh texture_mesh;
|
||||
|
|
|
|||
|
|
@ -216,13 +216,15 @@ namespace psemek::gfx
|
|||
(*this) = q.coords;
|
||||
}
|
||||
|
||||
static std::string annotated_source(std::string_view source)
|
||||
static std::string annotated_source(shader_source const & sources)
|
||||
{
|
||||
std::ostringstream os;
|
||||
|
||||
bool first = true;
|
||||
|
||||
int line = 1;
|
||||
for (auto const & source : sources.sources)
|
||||
{
|
||||
for (char c : source)
|
||||
{
|
||||
if (first)
|
||||
|
|
@ -238,15 +240,22 @@ namespace psemek::gfx
|
|||
first = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return os.str();
|
||||
}
|
||||
|
||||
static void load_shader(GLuint shader, std::string_view source)
|
||||
static void load_shader(GLuint shader, shader_source const & sources)
|
||||
{
|
||||
char const * vert_sources[1] { source.data() };
|
||||
GLint vert_sources_len[1] { static_cast<GLint>(source.size()) };
|
||||
gl::ShaderSource(shader, 1, vert_sources, vert_sources_len);
|
||||
std::vector<char const *> source_ptrs;
|
||||
std::vector<GLint> source_lens;
|
||||
for (auto const & source : sources.sources)
|
||||
{
|
||||
source_ptrs.push_back(source.data());
|
||||
source_lens.push_back(source.size());
|
||||
}
|
||||
|
||||
gl::ShaderSource(shader, sources.sources.size(), source_ptrs.data(), source_lens.data());
|
||||
gl::CompileShader(shader);
|
||||
|
||||
GLint status;
|
||||
|
|
@ -257,7 +266,7 @@ namespace psemek::gfx
|
|||
gl::GetShaderiv(shader, gl::INFO_LOG_LENGTH, &log_len);
|
||||
std::unique_ptr<char[]> log(new char [log_len]);
|
||||
gl::GetShaderInfoLog(shader, log_len, nullptr, log.get());
|
||||
throw util::exception(util::to_string("Shader compilation failed: ", log.get(), "\nShader source: \n", annotated_source(source)));
|
||||
throw util::exception(util::to_string("Shader compilation failed: ", log.get(), "\nShader source: \n", annotated_source(sources)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -282,7 +291,7 @@ namespace psemek::gfx
|
|||
gl::DetachShader(program, s);
|
||||
}
|
||||
|
||||
static GLuint create_program(std::vector<std::pair<GLenum, std::string_view>> const & sources)
|
||||
static GLuint create_program(std::vector<std::pair<GLenum, shader_source const *>> const & sources)
|
||||
{
|
||||
std::vector<GLuint> shaders;
|
||||
|
||||
|
|
@ -295,7 +304,7 @@ namespace psemek::gfx
|
|||
{
|
||||
GLuint sh = gl::CreateShader(p.first);
|
||||
shaders.push_back(sh);
|
||||
load_shader(sh, p.second);
|
||||
load_shader(sh, *p.second);
|
||||
}
|
||||
|
||||
GLuint program = gl::CreateProgram();
|
||||
|
|
@ -313,20 +322,20 @@ namespace psemek::gfx
|
|||
return program;
|
||||
}
|
||||
|
||||
program::program(std::string_view vertex_source, std::string_view fragment_source)
|
||||
program::program(shader_source const & vertex_source, shader_source const & fragment_source)
|
||||
{
|
||||
program_ = create_program({{gl::VERTEX_SHADER, vertex_source}, {gl::FRAGMENT_SHADER, fragment_source}});
|
||||
program_ = create_program({{gl::VERTEX_SHADER, &vertex_source}, {gl::FRAGMENT_SHADER, &fragment_source}});
|
||||
}
|
||||
|
||||
#ifndef __EMSCRIPTEN__
|
||||
program::program(std::string_view compute_source)
|
||||
program::program(shader_source const & compute_source)
|
||||
{
|
||||
program_ = create_program({{gl::COMPUTE_SHADER, compute_source}});
|
||||
program_ = create_program({{gl::COMPUTE_SHADER, &compute_source}});
|
||||
}
|
||||
|
||||
program::program(std::string_view vertex_source, std::string_view geometry_source, std::string_view fragment_source)
|
||||
program::program(shader_source const & vertex_source, shader_source const & geometry_source, shader_source const & fragment_source)
|
||||
{
|
||||
program_ = create_program({{gl::VERTEX_SHADER, vertex_source}, {gl::GEOMETRY_SHADER, geometry_source}, {gl::FRAGMENT_SHADER, fragment_source}});
|
||||
program_ = create_program({{gl::VERTEX_SHADER, &vertex_source}, {gl::GEOMETRY_SHADER, &geometry_source}, {gl::FRAGMENT_SHADER, &fragment_source}});
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -811,16 +811,16 @@ void main(){}
|
|||
deferred_renderer::position_mode position_mode = deferred_renderer::position_mode::float32;
|
||||
bool position_mode_changed = true;
|
||||
|
||||
gfx::program occlusion_pass_program{occlusion_pass_vs, occlusion_pass_fs};
|
||||
gfx::program g_buffer_pass_program{std::string(g_buffer_pass_common) + g_buffer_pass_vs, std::string(g_buffer_pass_common) + g_buffer_pass_fs};
|
||||
gfx::program ambient_pass_program{fullscreen_vs, std::string(light_common) + ambient_pass_fs};
|
||||
gfx::program directional_light_pass_program{screen_vs, std::string(light_common) + directional_light_pass_fs};
|
||||
gfx::program point_light_pass_program{screen_vs, std::string(light_common) + point_light_pass_fs};
|
||||
gfx::program shadow_builder_program{std::string(g_buffer_pass_common) + shadow_builder_vs, shadow_builder_fs};
|
||||
gfx::program cubemap_shadow_builder_program{std::string(g_buffer_pass_common) + shadow_builder_vs, shadow_builder_gs, shadow_builder_fs};
|
||||
gfx::program transparent_pass_program{std::string(g_buffer_pass_common) + transparent_pass_vs, std::string(g_buffer_pass_common) + transparent_pass_fs};
|
||||
gfx::program bloom_pass_program{std::string(g_buffer_pass_common) + transparent_pass_vs, std::string(g_buffer_pass_common) + transparent_pass_fs};
|
||||
gfx::program ssao_pass_program{fullscreen_vs, std::string(light_common) + ssao_pass_fs};
|
||||
gfx::program occlusion_pass_program{{occlusion_pass_vs}, {occlusion_pass_fs}};
|
||||
gfx::program g_buffer_pass_program{{g_buffer_pass_common, g_buffer_pass_vs}, {g_buffer_pass_common, g_buffer_pass_fs}};
|
||||
gfx::program ambient_pass_program{{fullscreen_vs}, {light_common, ambient_pass_fs}};
|
||||
gfx::program directional_light_pass_program{{screen_vs}, {light_common, directional_light_pass_fs}};
|
||||
gfx::program point_light_pass_program{{screen_vs}, {light_common, point_light_pass_fs}};
|
||||
gfx::program shadow_builder_program{{g_buffer_pass_common, shadow_builder_vs}, {shadow_builder_fs}};
|
||||
gfx::program cubemap_shadow_builder_program{{g_buffer_pass_common, shadow_builder_vs}, {shadow_builder_gs}, {shadow_builder_fs}};
|
||||
gfx::program transparent_pass_program{{g_buffer_pass_common, transparent_pass_vs}, {g_buffer_pass_common, transparent_pass_fs}};
|
||||
gfx::program bloom_pass_program{{g_buffer_pass_common, transparent_pass_vs}, {g_buffer_pass_common, transparent_pass_fs}};
|
||||
gfx::program ssao_pass_program{{fullscreen_vs}, {light_common, ssao_pass_fs}};
|
||||
|
||||
// G-buffer attachments:
|
||||
// 0 - position (rbg)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue