Compare commits
4 commits
63f247c877
...
03e063213d
| Author | SHA1 | Date | |
|---|---|---|---|
| 03e063213d | |||
| 1338aa05ed | |||
| 11d96829b6 | |||
| 0236fc97b7 |
12 changed files with 240 additions and 45 deletions
|
|
@ -24,6 +24,7 @@ namespace psemek::app
|
||||||
std::string name;
|
std::string name;
|
||||||
int multisampling = 4;
|
int multisampling = 4;
|
||||||
bool highdpi = false;
|
bool highdpi = false;
|
||||||
|
bool srgb = false;
|
||||||
#if defined(PSEMEK_GRAPHICS_API_WEBGPU)
|
#if defined(PSEMEK_GRAPHICS_API_WEBGPU)
|
||||||
std::vector<wgpu::feature> required_features = {};
|
std::vector<wgpu::feature> required_features = {};
|
||||||
std::optional<wgpu::limits> required_limits = {};
|
std::optional<wgpu::limits> required_limits = {};
|
||||||
|
|
|
||||||
|
|
@ -14,13 +14,39 @@
|
||||||
namespace psemek::gfx
|
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
|
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__
|
#ifndef __EMSCRIPTEN__
|
||||||
program(std::string_view compute_source);
|
program(shader_source const & compute_source);
|
||||||
program(std::string_view vertex_source, std::string_view geometry_source, std::string_view fragment_source);
|
program(shader_source const & vertex_source, shader_source const & geometry_source, shader_source const & fragment_source);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
program(program && other);
|
program(program && other);
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,7 @@ void main()
|
||||||
gfx::array array;
|
gfx::array array;
|
||||||
|
|
||||||
blur_impl(int size, float sigma, float gamma, bool horizontal)
|
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.bind();
|
||||||
program["u_texture"] = 0;
|
program["u_texture"] = 0;
|
||||||
|
|
|
||||||
|
|
@ -206,7 +206,7 @@ void main()
|
||||||
|
|
||||||
struct fxaa::impl
|
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;
|
gfx::array array;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ void main()
|
||||||
|
|
||||||
struct gamma_correction::impl
|
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;
|
gfx::array array;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ void main()
|
||||||
|
|
||||||
struct overlay::impl
|
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;
|
gfx::array array;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -107,7 +107,7 @@ void main()
|
||||||
namespace psemek::gfx
|
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
|
struct painter::impl
|
||||||
{
|
{
|
||||||
|
|
@ -130,9 +130,9 @@ namespace psemek::gfx
|
||||||
math::point<std::uint16_t, 2> texcoord;
|
math::point<std::uint16_t, 2> texcoord;
|
||||||
};
|
};
|
||||||
|
|
||||||
gfx::program program{shader_prefix + vertex_source, shader_prefix + 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 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 texture_program{{shader_prefix, texture_vertex_source}, {shader_prefix, texture_fragment_source}};
|
||||||
gfx::mesh mesh;
|
gfx::mesh mesh;
|
||||||
gfx::mesh text_mesh;
|
gfx::mesh text_mesh;
|
||||||
gfx::mesh texture_mesh;
|
gfx::mesh texture_mesh;
|
||||||
|
|
|
||||||
|
|
@ -216,37 +216,46 @@ namespace psemek::gfx
|
||||||
(*this) = q.coords;
|
(*this) = q.coords;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string annotated_source(std::string_view source)
|
static std::string annotated_source(shader_source const & sources)
|
||||||
{
|
{
|
||||||
std::ostringstream os;
|
std::ostringstream os;
|
||||||
|
|
||||||
bool first = true;
|
bool first = true;
|
||||||
|
|
||||||
int line = 1;
|
int line = 1;
|
||||||
for (char c : source)
|
for (auto const & source : sources.sources)
|
||||||
{
|
{
|
||||||
if (first)
|
for (char c : source)
|
||||||
{
|
{
|
||||||
os << line << ": ";
|
if (first)
|
||||||
first = false;
|
{
|
||||||
}
|
os << line << ": ";
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
|
||||||
os.put(c);
|
os.put(c);
|
||||||
if (c == '\n')
|
if (c == '\n')
|
||||||
{
|
{
|
||||||
++line;
|
++line;
|
||||||
first = true;
|
first = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return os.str();
|
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() };
|
std::vector<char const *> source_ptrs;
|
||||||
GLint vert_sources_len[1] { static_cast<GLint>(source.size()) };
|
std::vector<GLint> source_lens;
|
||||||
gl::ShaderSource(shader, 1, vert_sources, vert_sources_len);
|
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);
|
gl::CompileShader(shader);
|
||||||
|
|
||||||
GLint status;
|
GLint status;
|
||||||
|
|
@ -257,7 +266,7 @@ namespace psemek::gfx
|
||||||
gl::GetShaderiv(shader, gl::INFO_LOG_LENGTH, &log_len);
|
gl::GetShaderiv(shader, gl::INFO_LOG_LENGTH, &log_len);
|
||||||
std::unique_ptr<char[]> log(new char [log_len]);
|
std::unique_ptr<char[]> log(new char [log_len]);
|
||||||
gl::GetShaderInfoLog(shader, log_len, nullptr, log.get());
|
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);
|
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;
|
std::vector<GLuint> shaders;
|
||||||
|
|
||||||
|
|
@ -295,7 +304,7 @@ namespace psemek::gfx
|
||||||
{
|
{
|
||||||
GLuint sh = gl::CreateShader(p.first);
|
GLuint sh = gl::CreateShader(p.first);
|
||||||
shaders.push_back(sh);
|
shaders.push_back(sh);
|
||||||
load_shader(sh, p.second);
|
load_shader(sh, *p.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint program = gl::CreateProgram();
|
GLuint program = gl::CreateProgram();
|
||||||
|
|
@ -313,20 +322,20 @@ namespace psemek::gfx
|
||||||
return program;
|
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__
|
#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
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -811,16 +811,16 @@ void main(){}
|
||||||
deferred_renderer::position_mode position_mode = deferred_renderer::position_mode::float32;
|
deferred_renderer::position_mode position_mode = deferred_renderer::position_mode::float32;
|
||||||
bool position_mode_changed = true;
|
bool position_mode_changed = true;
|
||||||
|
|
||||||
gfx::program occlusion_pass_program{occlusion_pass_vs, occlusion_pass_fs};
|
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 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, std::string(light_common) + ambient_pass_fs};
|
gfx::program ambient_pass_program{{fullscreen_vs}, {light_common, ambient_pass_fs}};
|
||||||
gfx::program directional_light_pass_program{screen_vs, std::string(light_common) + directional_light_pass_fs};
|
gfx::program directional_light_pass_program{{screen_vs}, {light_common, directional_light_pass_fs}};
|
||||||
gfx::program point_light_pass_program{screen_vs, std::string(light_common) + point_light_pass_fs};
|
gfx::program point_light_pass_program{{screen_vs}, {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 shadow_builder_program{{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 cubemap_shadow_builder_program{{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 transparent_pass_program{{g_buffer_pass_common, transparent_pass_vs}, {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 bloom_pass_program{{g_buffer_pass_common, transparent_pass_vs}, {g_buffer_pass_common, transparent_pass_fs}};
|
||||||
gfx::program ssao_pass_program{fullscreen_vs, std::string(light_common) + ssao_pass_fs};
|
gfx::program ssao_pass_program{{fullscreen_vs}, {light_common, ssao_pass_fs}};
|
||||||
|
|
||||||
// G-buffer attachments:
|
// G-buffer attachments:
|
||||||
// 0 - position (rbg)
|
// 0 - position (rbg)
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
#include <psemek/math/box.hpp>
|
#include <psemek/math/box.hpp>
|
||||||
#include <psemek/math/matrix.hpp>
|
#include <psemek/math/matrix.hpp>
|
||||||
#include <psemek/math/homogeneous.hpp>
|
#include <psemek/math/homogeneous.hpp>
|
||||||
|
#include <psemek/math/affine_transform.hpp>
|
||||||
|
|
||||||
namespace psemek::math
|
namespace psemek::math
|
||||||
{
|
{
|
||||||
|
|
@ -14,6 +15,8 @@ namespace psemek::math
|
||||||
{
|
{
|
||||||
using vector_type = math::vector<T, D>;
|
using vector_type = math::vector<T, D>;
|
||||||
using point_type = math::point<T, D>;
|
using point_type = math::point<T, D>;
|
||||||
|
using affine_matrix_type = math::matrix<T, D, D + 1>;
|
||||||
|
using linear_matrix_type = math::matrix<T, D, D>;
|
||||||
using homogeneous_matrix_type = math::matrix<T, D + 1, D + 1>;
|
using homogeneous_matrix_type = math::matrix<T, D + 1, D + 1>;
|
||||||
using box_type = math::box<T, D>;
|
using box_type = math::box<T, D>;
|
||||||
|
|
||||||
|
|
@ -26,8 +29,13 @@ namespace psemek::math
|
||||||
vector_type operator() (vector_type v) const;
|
vector_type operator() (vector_type v) const;
|
||||||
point_type operator() (point_type p) const;
|
point_type operator() (point_type p) const;
|
||||||
|
|
||||||
|
affine_matrix_type affine_matrix() const;
|
||||||
|
linear_matrix_type linear_matrix() const;
|
||||||
|
vector_type translation_vector() const;
|
||||||
homogeneous_matrix_type homogeneous_matrix() const;
|
homogeneous_matrix_type homogeneous_matrix() const;
|
||||||
|
|
||||||
|
affine_transform<T, D, D> transform() const;
|
||||||
|
|
||||||
orthographic inverse() const;
|
orthographic inverse() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -76,6 +84,24 @@ namespace psemek::math
|
||||||
return as_point(homogeneous_matrix() * homogeneous(p));
|
return as_point(homogeneous_matrix() * homogeneous(p));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T, std::size_t D>
|
||||||
|
matrix<T, D, D + 1> orthographic<T, D>::affine_matrix() const
|
||||||
|
{
|
||||||
|
return submatrix<0, 0, D, D + 1>(homogeneous_matrix());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, std::size_t D>
|
||||||
|
matrix<T, D, D> orthographic<T, D>::linear_matrix() const
|
||||||
|
{
|
||||||
|
return submatrix<0, 0, D, D>(homogeneous_matrix());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, std::size_t D>
|
||||||
|
vector<T, D> orthographic<T, D>::translation_vector() const
|
||||||
|
{
|
||||||
|
return column(affine_matrix(), D);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T, std::size_t D>
|
template <typename T, std::size_t D>
|
||||||
matrix<T, D + 1, D + 1> orthographic<T, D>::homogeneous_matrix() const
|
matrix<T, D + 1, D + 1> orthographic<T, D>::homogeneous_matrix() const
|
||||||
{
|
{
|
||||||
|
|
@ -92,6 +118,12 @@ namespace psemek::math
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T, std::size_t D>
|
||||||
|
affine_transform<T, D, D> orthographic<T, D>::transform() const
|
||||||
|
{
|
||||||
|
return {affine_matrix()};
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T, std::size_t D>
|
template <typename T, std::size_t D>
|
||||||
orthographic<T, D> orthographic<T, D>::inverse() const
|
orthographic<T, D> orthographic<T, D>::inverse() const
|
||||||
{
|
{
|
||||||
|
|
|
||||||
123
libs/math/include/psemek/math/shear.hpp
Normal file
123
libs/math/include/psemek/math/shear.hpp
Normal file
|
|
@ -0,0 +1,123 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <psemek/math/affine_transform.hpp>
|
||||||
|
#include <psemek/math/quaternion.hpp>
|
||||||
|
|
||||||
|
#include <psemek/util/assert.hpp>
|
||||||
|
|
||||||
|
namespace psemek::math
|
||||||
|
{
|
||||||
|
|
||||||
|
// Shear in the (i,j)-plane that replaces x[i] with x[i] + x[j] * factor
|
||||||
|
// E.g. shear(0, 1, m) is the usual 2D horizontal shear
|
||||||
|
template <typename T, std::size_t N>
|
||||||
|
struct shear
|
||||||
|
{
|
||||||
|
std::size_t i, j;
|
||||||
|
T factor;
|
||||||
|
|
||||||
|
shear();
|
||||||
|
shear(std::size_t i, std::size_t j, T factor);
|
||||||
|
shear(shear const &) = default;
|
||||||
|
|
||||||
|
matrix<T, N, N + 1> affine_matrix() const;
|
||||||
|
matrix<T, N, N> linear_matrix() const;
|
||||||
|
vector<T, N> translation_vector() const;
|
||||||
|
matrix<T, N + 1, N + 1> homogeneous_matrix() const;
|
||||||
|
|
||||||
|
affine_transform<T, N, N> transform() const;
|
||||||
|
|
||||||
|
vector<T, N> operator()(vector<T, N> const & v) const;
|
||||||
|
point<T, N> operator()(point<T, N> const & p) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
template <typename Matrix>
|
||||||
|
void fill_matrix(Matrix & m) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, std::size_t N>
|
||||||
|
shear<T, N>::shear()
|
||||||
|
: i{0}
|
||||||
|
, j{1}
|
||||||
|
, factor{0}
|
||||||
|
{
|
||||||
|
assert(i < N);
|
||||||
|
assert(j < N);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, std::size_t N>
|
||||||
|
shear<T, N>::shear(std::size_t i, std::size_t j, T factor)
|
||||||
|
: i{i}
|
||||||
|
, j{j}
|
||||||
|
, factor{factor}
|
||||||
|
{
|
||||||
|
assert(i < N);
|
||||||
|
assert(j < N);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, std::size_t N>
|
||||||
|
matrix<T, N, N + 1> shear<T, N>::affine_matrix() const
|
||||||
|
{
|
||||||
|
auto result = matrix<T, N, N + 1>::identity();
|
||||||
|
fill_matrix(result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, std::size_t N>
|
||||||
|
matrix<T, N, N> shear<T, N>::linear_matrix() const
|
||||||
|
{
|
||||||
|
auto result = matrix<T, N, N>::identity();
|
||||||
|
fill_matrix(result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, std::size_t N>
|
||||||
|
vector<T, N> shear<T, N>::translation_vector() const
|
||||||
|
{
|
||||||
|
return vector<T, N>::zero();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, std::size_t N>
|
||||||
|
matrix<T, N + 1, N + 1> shear<T, N>::homogeneous_matrix() const
|
||||||
|
{
|
||||||
|
auto result = matrix<T, N + 1, N + 1>::identity();
|
||||||
|
fill_matrix(result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, std::size_t N>
|
||||||
|
affine_transform<T, N, N> shear<T, N>::transform() const
|
||||||
|
{
|
||||||
|
return {affine_matrix()};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, std::size_t N>
|
||||||
|
vector<T, N> shear<T, N>::operator()(vector<T, N> const & v) const
|
||||||
|
{
|
||||||
|
auto result = v;
|
||||||
|
result[i] += result[j] * factor;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, std::size_t N>
|
||||||
|
point<T, N> shear<T, N>::operator()(point<T, N> const & p) const
|
||||||
|
{
|
||||||
|
auto result = p;
|
||||||
|
result[i] += result[j] * factor;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, std::size_t N>
|
||||||
|
template <typename Matrix>
|
||||||
|
void shear<T, N>::fill_matrix(Matrix & m) const
|
||||||
|
{
|
||||||
|
m[i][j] = factor;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, std::size_t N>
|
||||||
|
shear<T, N> inverse(shear<T, N> const & r)
|
||||||
|
{
|
||||||
|
return {r.i, r.j, -r.factor};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -38,6 +38,7 @@ namespace psemek::sdl2
|
||||||
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
|
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
|
||||||
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
|
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
|
||||||
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
|
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_FRAMEBUFFER_SRGB_CAPABLE, options.srgb ? 1 : 0);
|
||||||
|
|
||||||
if (options.multisampling == 0)
|
if (options.multisampling == 0)
|
||||||
{
|
{
|
||||||
|
|
@ -83,6 +84,9 @@ namespace psemek::sdl2
|
||||||
SDL_GL_MakeCurrent(window_, gl_context_);
|
SDL_GL_MakeCurrent(window_, gl_context_);
|
||||||
|
|
||||||
gfx::init();
|
gfx::init();
|
||||||
|
|
||||||
|
if (options.srgb)
|
||||||
|
gl::Enable(gl::FRAMEBUFFER_SRGB);
|
||||||
#elif defined(PSEMEK_GRAPHICS_API_WEBGPU)
|
#elif defined(PSEMEK_GRAPHICS_API_WEBGPU)
|
||||||
wgpu::setup_logging(log::level::error);
|
wgpu::setup_logging(log::level::error);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue