178 lines
4.6 KiB
C++
178 lines
4.6 KiB
C++
#pragma once
|
|
|
|
#include <psemek/gfx/gl.hpp>
|
|
|
|
#include <psemek/geom/vector.hpp>
|
|
#include <psemek/geom/point.hpp>
|
|
#include <psemek/geom/matrix.hpp>
|
|
#include <psemek/geom/interval.hpp>
|
|
|
|
#include <unordered_map>
|
|
#include <string_view>
|
|
|
|
namespace psemek::gfx
|
|
{
|
|
|
|
struct program
|
|
{
|
|
program(std::string_view vertex_source, std::string_view fragment_source);
|
|
program(std::string_view vertex_source, std::string_view geometry_source, std::string_view fragment_source);
|
|
|
|
~program();
|
|
|
|
GLuint id() const;
|
|
|
|
void bind() const;
|
|
|
|
GLint location(char const * name) const;
|
|
|
|
struct uniform_proxy
|
|
{
|
|
uniform_proxy(GLint location)
|
|
: location_(location)
|
|
{}
|
|
|
|
GLint location() const { return location_; }
|
|
|
|
void operator = (bool b);
|
|
void operator = (int i);
|
|
void operator = (unsigned int i);
|
|
void operator = (float f);
|
|
|
|
void operator = (geom::vector<int, 1> const & v);
|
|
void operator = (geom::vector<int, 2> const & v);
|
|
void operator = (geom::vector<int, 3> const & v);
|
|
void operator = (geom::vector<int, 4> const & v);
|
|
|
|
void operator = (geom::vector<unsigned int, 1> const & v);
|
|
void operator = (geom::vector<unsigned int, 2> const & v);
|
|
void operator = (geom::vector<unsigned int, 3> const & v);
|
|
void operator = (geom::vector<unsigned int, 4> const & v);
|
|
|
|
void operator = (geom::vector<float, 1> const & v);
|
|
void operator = (geom::vector<float, 2> const & v);
|
|
void operator = (geom::vector<float, 3> const & v);
|
|
void operator = (geom::vector<float, 4> const & v);
|
|
|
|
template <typename T, std::size_t D>
|
|
void operator = (geom::vector<T, D> const & v);
|
|
|
|
void operator = (geom::point<int, 1> const & v);
|
|
void operator = (geom::point<int, 2> const & v);
|
|
void operator = (geom::point<int, 3> const & v);
|
|
void operator = (geom::point<int, 4> const & v);
|
|
|
|
void operator = (geom::point<unsigned int, 1> const & v);
|
|
void operator = (geom::point<unsigned int, 2> const & v);
|
|
void operator = (geom::point<unsigned int, 3> const & v);
|
|
void operator = (geom::point<unsigned int, 4> const & v);
|
|
|
|
void operator = (geom::point<float, 1> const & v);
|
|
void operator = (geom::point<float, 2> const & v);
|
|
void operator = (geom::point<float, 3> const & v);
|
|
void operator = (geom::point<float, 4> const & v);
|
|
|
|
template <typename T, std::size_t D>
|
|
void operator = (geom::point<T, D> const & v);
|
|
|
|
void operator = (geom::matrix<float, 2, 2> const & m);
|
|
void operator = (geom::matrix<float, 2, 3> const & m);
|
|
void operator = (geom::matrix<float, 2, 4> const & m);
|
|
void operator = (geom::matrix<float, 3, 2> const & m);
|
|
void operator = (geom::matrix<float, 3, 3> const & m);
|
|
void operator = (geom::matrix<float, 3, 4> const & m);
|
|
void operator = (geom::matrix<float, 4, 2> const & m);
|
|
void operator = (geom::matrix<float, 4, 3> const & m);
|
|
void operator = (geom::matrix<float, 4, 4> const & m);
|
|
|
|
void operator = (geom::interval<int> const & i);
|
|
void operator = (geom::interval<unsigned int> const & i);
|
|
void operator = (geom::interval<float> const & i);
|
|
|
|
template <typename T>
|
|
void operator = (geom::interval<T> const & i);
|
|
|
|
private:
|
|
GLint location_;
|
|
};
|
|
|
|
uniform_proxy operator[] (char const * name) const;
|
|
|
|
private:
|
|
GLuint program_;
|
|
mutable std::unordered_map<std::string, GLint> uniforms_;
|
|
};
|
|
|
|
template <typename T, std::size_t D>
|
|
void program::uniform_proxy::operator = (geom::vector<T, D> const & v)
|
|
{
|
|
if constexpr (std::is_floating_point_v<T>)
|
|
{
|
|
(*this) = geom::cast<float>(v);
|
|
}
|
|
else if (std::is_integral_v<T>)
|
|
{
|
|
if constexpr (std::is_unsigned_v<T>)
|
|
{
|
|
(*this) = geom::cast<unsigned int>(v);
|
|
}
|
|
else
|
|
{
|
|
(*this) = geom::cast<int>(v);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
static_assert("Unknown uniform data type");
|
|
}
|
|
}
|
|
|
|
template <typename T, std::size_t D>
|
|
void program::uniform_proxy::operator = (geom::point<T, D> const & p)
|
|
{
|
|
if constexpr (std::is_floating_point_v<T>)
|
|
{
|
|
(*this) = geom::cast<float>(p);
|
|
}
|
|
else if (std::is_integral_v<T>)
|
|
{
|
|
if constexpr (std::is_unsigned_v<T>)
|
|
{
|
|
(*this) = geom::cast<unsigned int>(p);
|
|
}
|
|
else
|
|
{
|
|
(*this) = geom::cast<int>(p);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
static_assert("Unknown uniform data type");
|
|
}
|
|
}
|
|
|
|
template <typename T>
|
|
void program::uniform_proxy::operator = (geom::interval<T> const & i)
|
|
{
|
|
if constexpr (std::is_floating_point_v<T>)
|
|
{
|
|
(*this) = geom::cast<float>(i);
|
|
}
|
|
else if (std::is_integral_v<T>)
|
|
{
|
|
if constexpr (std::is_unsigned_v<T>)
|
|
{
|
|
(*this) = geom::cast<unsigned int>(i);
|
|
}
|
|
else
|
|
{
|
|
(*this) = geom::cast<int>(i);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
static_assert("Unknown uniform data type");
|
|
}
|
|
}
|
|
|
|
}
|