we can see a quad
This commit is contained in:
parent
612677c52d
commit
ddc0f85805
10 changed files with 261 additions and 140 deletions
|
@ -7,13 +7,24 @@
|
|||
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
#include <cassert>
|
||||
|
||||
namespace paradiso {
|
||||
struct Bitmap final {
|
||||
constexpr static Bitmap create(Size size) noexcept {
|
||||
|
||||
constexpr static Bitmap empty(Size size) noexcept {
|
||||
return {.size = size, .data = std::vector<RGBA>{size.area()}};
|
||||
}
|
||||
|
||||
template <typename... Arguments>
|
||||
static constexpr Bitmap from_data(Size size, Arguments... values) noexcept {
|
||||
assert(sizeof...(Arguments) == size.height * size.width);
|
||||
return {
|
||||
.size = size,
|
||||
.data = {values...}
|
||||
};
|
||||
}
|
||||
|
||||
constexpr auto fill(const RGBA& color) noexcept {
|
||||
std::fill(data.begin(), data.end(), color);
|
||||
return *this;
|
||||
|
|
|
@ -8,18 +8,19 @@
|
|||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
|
||||
namespace paradiso {
|
||||
|
||||
struct Renderer::impl {
|
||||
|
||||
uint64_t change_count{};
|
||||
uint64_t change_count{ std::numeric_limits<uint64_t>::max() };
|
||||
|
||||
uint32_t vertex_array_obj{};
|
||||
uint32_t element_buffer_obj{};
|
||||
std::vector<uint32_t> vertex_buffer_ob{};
|
||||
uint32_t texture_id{};
|
||||
GLint _mesh_elements = {0};
|
||||
|
||||
impl() = default;
|
||||
|
||||
|
@ -37,11 +38,10 @@ struct Renderer::impl {
|
|||
|
||||
void unbind_texture() { glBindTexture(GL_TEXTURE_2D, 0); }
|
||||
|
||||
bool build(const Sprite& s) {
|
||||
bool build(const Sprite& sprite) {
|
||||
// reset if the Renderer already in use
|
||||
if (ready())
|
||||
release();
|
||||
|
||||
//
|
||||
glGenVertexArrays(1, &vertex_array_obj);
|
||||
glBindVertexArray(vertex_array_obj);
|
||||
|
@ -52,7 +52,7 @@ struct Renderer::impl {
|
|||
// indices -> elements
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, element_buffer_obj);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
|
||||
s.indices.size() * sizeof(uint32_t), s.indices.data(),
|
||||
sprite.indices.size() * sizeof(uint32_t), sprite.indices.data(),
|
||||
GL_STATIC_DRAW);
|
||||
|
||||
vertex_buffer_ob.resize(vertex_buffer_ob.size() + 1);
|
||||
|
@ -62,8 +62,8 @@ struct Renderer::impl {
|
|||
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_ob.back());
|
||||
glVertexAttribPointer(vertex_buffer_ob.size() - 1, 3, GL_FLOAT,
|
||||
GL_FALSE, 0, nullptr);
|
||||
glBufferData(GL_ARRAY_BUFFER, s.vertices.size() * sizeof(float) * 3,
|
||||
s.vertices.data(), GL_STATIC_DRAW);
|
||||
glBufferData(GL_ARRAY_BUFFER, sprite.vertices.size() * sizeof(float) * 3,
|
||||
sprite.vertices.data(), GL_STATIC_DRAW);
|
||||
glEnableVertexAttribArray(vertex_buffer_ob.size() - 1);
|
||||
|
||||
vertex_buffer_ob.resize(vertex_buffer_ob.size() + 1);
|
||||
|
@ -73,8 +73,8 @@ struct Renderer::impl {
|
|||
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_ob.back());
|
||||
glVertexAttribPointer(vertex_buffer_ob.size() - 1, 3, GL_FLOAT,
|
||||
GL_FALSE, 0, nullptr);
|
||||
glBufferData(GL_ARRAY_BUFFER, s.normals.size() * sizeof(float) * 3,
|
||||
s.normals.data(), GL_STATIC_DRAW);
|
||||
glBufferData(GL_ARRAY_BUFFER, sprite.normals.size() * sizeof(float) * 3,
|
||||
sprite.normals.data(), GL_STATIC_DRAW);
|
||||
glEnableVertexAttribArray(vertex_buffer_ob.size() - 1);
|
||||
|
||||
vertex_buffer_ob.resize(vertex_buffer_ob.size() + 1);
|
||||
|
@ -85,13 +85,18 @@ struct Renderer::impl {
|
|||
glVertexAttribPointer(vertex_buffer_ob.size() - 1, 2, GL_FLOAT,
|
||||
GL_FALSE, 0, nullptr);
|
||||
glBufferData(GL_ARRAY_BUFFER,
|
||||
s.texture_coordinates.size() * sizeof(float) * 2,
|
||||
s.texture_coordinates.data(), GL_STATIC_DRAW);
|
||||
sprite.texture_coordinates.size() * sizeof(float) * 2,
|
||||
sprite.texture_coordinates.data(), GL_STATIC_DRAW);
|
||||
glEnableVertexAttribArray(vertex_buffer_ob.size() - 1);
|
||||
|
||||
// stop binding
|
||||
glBindVertexArray(0);
|
||||
|
||||
|
||||
|
||||
|
||||
change_count = sprite.change_count;
|
||||
|
||||
return ready();
|
||||
}
|
||||
|
||||
|
@ -156,14 +161,23 @@ struct Renderer::impl {
|
|||
|
||||
glDeleteVertexArrays(1, &vertex_array_obj);
|
||||
|
||||
glDeleteTextures(1, &texture_id);
|
||||
// glDeleteTextures(1, &texture_id);
|
||||
}
|
||||
|
||||
void draw() {
|
||||
void just_draw(const Sprite& sprite)
|
||||
{
|
||||
glBindVertexArray(vertex_array_obj);
|
||||
glDrawElements(GL_TRIANGLES, _mesh_elements, GL_UNSIGNED_INT, nullptr);
|
||||
glDrawElements(GL_TRIANGLES, sprite.indices.size(), GL_UNSIGNED_INT, nullptr);
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
static void fetch_errors(std::string_view tag) {
|
||||
std::cout << tag << '\n';
|
||||
GLenum e{};
|
||||
while ((e = glGetError()) != GL_NO_ERROR) {
|
||||
std::cerr << '\t' << " OpenGL error 0x" << std::hex << e << '\n';
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
|
@ -172,19 +186,27 @@ struct Renderer::impl {
|
|||
|
||||
Renderer::Renderer() : impl_(std::make_unique<Renderer::impl>()) {}
|
||||
|
||||
Renderer::~Renderer() {
|
||||
}
|
||||
Renderer::~Renderer() {}
|
||||
|
||||
bool Renderer::ready() const { return impl_->ready(); }
|
||||
|
||||
bool Renderer::draw(const Sprite& m) { return impl_->build(m); }
|
||||
bool Renderer::draw(const Sprite& m)
|
||||
{
|
||||
if (!impl_->ready() || m.change_count != impl_->change_count)
|
||||
{
|
||||
impl_->build(m);
|
||||
}
|
||||
|
||||
// void Renderer::release() { impl_->release(); }
|
||||
|
||||
// void renderer::draw() { impl_->draw(); }
|
||||
if (impl_->ready() && m.change_count == impl_->change_count) {
|
||||
|
||||
// uint64_t Renderer::change_count() const { return impl_->change_count; }
|
||||
impl_->just_draw(m);
|
||||
|
||||
// void Renderer::set_change_count(uint64_t n) { impl_->change_count = n; }
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
} // namespace paradiso
|
||||
|
|
|
@ -11,6 +11,7 @@ struct Sprite;
|
|||
* @brief a Renderer2D for sprites
|
||||
*/
|
||||
struct Renderer final {
|
||||
|
||||
Renderer();
|
||||
~Renderer();
|
||||
Renderer(const Renderer&) = delete;
|
||||
|
|
|
@ -3,61 +3,61 @@
|
|||
|
||||
#include "globals.hpp"
|
||||
|
||||
namespace paradiso
|
||||
{
|
||||
struct RGBA final
|
||||
{
|
||||
using value_type = std::uint32_t;
|
||||
value_type pixel{0x0};
|
||||
namespace paradiso {
|
||||
struct RGBA final {
|
||||
using value_type = std::uint32_t;
|
||||
value_type pixel{0x0};
|
||||
|
||||
static constexpr RGBA from_rgb(uint8_t red, uint8_t green, uint8_t blue) noexcept
|
||||
{
|
||||
return from_rgba(red, green, blue, 0xFF);
|
||||
}
|
||||
static constexpr RGBA from_rgb(uint8_t red, uint8_t green,
|
||||
uint8_t blue) noexcept {
|
||||
return from_rgba(red, green, blue, 0xFF);
|
||||
}
|
||||
|
||||
static constexpr RGBA from_rgba(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha) noexcept
|
||||
{
|
||||
return {
|
||||
.pixel = (value_type)(((((red << 8) | green) << 8) | blue) << 8) | alpha};
|
||||
}
|
||||
static constexpr RGBA from_rgba(uint8_t red, uint8_t green, uint8_t blue,
|
||||
uint8_t alpha) noexcept {
|
||||
return {.pixel =
|
||||
(value_type)(((((red << 8) | green) << 8) | blue) << 8) |
|
||||
alpha};
|
||||
}
|
||||
|
||||
constexpr void to_float(float rgba_f[4]) const noexcept
|
||||
{
|
||||
rgba_f[0] = static_cast<float>(this->red()) / 0xFF;
|
||||
rgba_f[1] = static_cast<float>(this->green()) / 0xFF;
|
||||
rgba_f[2] = static_cast<float>(this->blue()) / 0xFF;
|
||||
rgba_f[3] = static_cast<float>(this->alpha()) / 0xFF;
|
||||
}
|
||||
constexpr void to_float(float rgba_f[4]) const noexcept {
|
||||
rgba_f[0] = static_cast<float>(this->red()) / 0xFF;
|
||||
rgba_f[1] = static_cast<float>(this->green()) / 0xFF;
|
||||
rgba_f[2] = static_cast<float>(this->blue()) / 0xFF;
|
||||
rgba_f[3] = static_cast<float>(this->alpha()) / 0xFF;
|
||||
}
|
||||
|
||||
constexpr uint8_t red() const noexcept { return (pixel & 0xFF000000) >> 24; }
|
||||
constexpr uint8_t green() const noexcept { return uint8_t((pixel & 0xFF0000) >> 16); }
|
||||
constexpr uint8_t blue() const noexcept { return uint8_t((pixel & 0xFF00) >> 8); }
|
||||
constexpr uint8_t alpha() const noexcept { return uint8_t(pixel & 0xFF); }
|
||||
constexpr uint8_t red() const noexcept {
|
||||
return (pixel & 0xFF000000) >> 24;
|
||||
}
|
||||
constexpr uint8_t green() const noexcept {
|
||||
return uint8_t((pixel & 0xFF0000) >> 16);
|
||||
}
|
||||
constexpr uint8_t blue() const noexcept {
|
||||
return uint8_t((pixel & 0xFF00) >> 8);
|
||||
}
|
||||
constexpr uint8_t alpha() const noexcept { return uint8_t(pixel & 0xFF); }
|
||||
|
||||
constexpr RGBA &set_red(uint8_t v) noexcept
|
||||
{
|
||||
pixel = (pixel & 0x00FFFFFF) | (v << 24);
|
||||
return *this;
|
||||
}
|
||||
constexpr RGBA& set_red(uint8_t v) noexcept {
|
||||
pixel = (pixel & 0x00FFFFFF) | (v << 24);
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr RGBA &set_green(uint8_t v) noexcept
|
||||
{
|
||||
pixel = (pixel & 0xFF00FFFF) | (v << 16);
|
||||
return *this;
|
||||
}
|
||||
constexpr RGBA& set_green(uint8_t v) noexcept {
|
||||
pixel = (pixel & 0xFF00FFFF) | (v << 16);
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr RGBA &set_blue(uint8_t v) noexcept
|
||||
{
|
||||
pixel = (pixel & 0xFFFF00FF) | (v << 8);
|
||||
return *this;
|
||||
}
|
||||
constexpr RGBA& set_blue(uint8_t v) noexcept {
|
||||
pixel = (pixel & 0xFFFF00FF) | (v << 8);
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr RGBA &set_alpha(uint8_t v) noexcept
|
||||
{
|
||||
pixel = (pixel & 0xFFFFFF00) | v;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
}
|
||||
constexpr RGBA& set_alpha(uint8_t v) noexcept {
|
||||
pixel = (pixel & 0xFFFFFF00) | v;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
} // namespace paradiso
|
||||
|
||||
#endif
|
|
@ -3,84 +3,84 @@
|
|||
|
||||
#include "globals.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <unordered_map>
|
||||
#include <variant>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <tuple>
|
||||
|
||||
namespace paradiso
|
||||
{
|
||||
namespace paradiso {
|
||||
|
||||
struct Shader final
|
||||
{
|
||||
Shader();
|
||||
~Shader();
|
||||
Shader(const Shader &) = delete;
|
||||
Shader(Shader &&) = default;
|
||||
struct Shader final {
|
||||
Shader();
|
||||
~Shader();
|
||||
Shader(const Shader&) = delete;
|
||||
Shader(Shader&&) = default;
|
||||
|
||||
enum class Type
|
||||
{
|
||||
Vertex,
|
||||
Fragment,
|
||||
Geometry,
|
||||
Compute
|
||||
};
|
||||
enum class Type { Vertex, Fragment, Geometry, Compute };
|
||||
|
||||
void set_source(Type t, const std::string &c) { source_[t] = c; }
|
||||
std::string source(Type t) const { return source_.at(t); }
|
||||
void set_source(Type t, const std::string& c) { source_[t] = c; }
|
||||
std::string source(Type t) const { return source_.at(t); }
|
||||
|
||||
bool ready() const;
|
||||
bool ready() const;
|
||||
|
||||
bool build();
|
||||
bool build();
|
||||
|
||||
void use();
|
||||
void use();
|
||||
|
||||
Shader &set_uniform_at_location(int location, float v); //!< sets a float in a shader
|
||||
Shader &set_uniform_at_location(int location, uint32_t v); //!< sets a 32bit unsigned in a shader
|
||||
Shader &set_uniform_at_location(int location, int32_t v); //!< sets a 32bit signed in a shader
|
||||
Shader& set_uniform_at_location(int location,
|
||||
float v); //!< sets a float in a shader
|
||||
Shader&
|
||||
set_uniform_at_location(int location,
|
||||
uint32_t v); //!< sets a 32bit unsigned in a shader
|
||||
Shader&
|
||||
set_uniform_at_location(int location,
|
||||
int32_t v); //!< sets a 32bit signed in a shader
|
||||
|
||||
/**
|
||||
* @brief retrieves the position of a uniform
|
||||
* @param name of the uniform
|
||||
* @return position of the uniform or negative if it doesn't exist
|
||||
*/
|
||||
int uniform_location(std::string const &name) const;
|
||||
/**
|
||||
* @brief retrieves the position of a uniform
|
||||
* @param name of the uniform
|
||||
* @return position of the uniform or negative if it doesn't exist
|
||||
*/
|
||||
int uniform_location(std::string const& name) const;
|
||||
|
||||
/**
|
||||
* @brief check if a uniform with the given name exists
|
||||
* @param name of the uniform
|
||||
* @return true if found
|
||||
*/
|
||||
bool has_uniform(std::string const &name) const { return uniform_location(name) >= 0; }
|
||||
/**
|
||||
* @brief check if a uniform with the given name exists
|
||||
* @param name of the uniform
|
||||
* @return true if found
|
||||
*/
|
||||
bool has_uniform(std::string const& name) const {
|
||||
return uniform_location(name) >= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* sets data of the
|
||||
*/
|
||||
template <typename T>
|
||||
Shader &set_uniform(std::string const &name, T &&value)
|
||||
{
|
||||
return set_uniform_at_location(uniform_location(name), std::forward<T>(value));
|
||||
}
|
||||
/**
|
||||
* sets data of the
|
||||
*/
|
||||
template <typename T>
|
||||
Shader& set_uniform(std::string const& name, T&& value) {
|
||||
return set_uniform_at_location(uniform_location(name),
|
||||
std::forward<T>(value));
|
||||
}
|
||||
|
||||
using uniform_t =
|
||||
std::variant<bool, int, float,
|
||||
double /*,vector2f,vector3f,vector4f,matrix4x4f*/>;
|
||||
using uniform_entry_t = std::tuple<std::string, uniform_t, int>;
|
||||
|
||||
using uniform_t = std::variant<bool, int, float, double /*,vector2f,vector3f,vector4f,matrix4x4f*/>;
|
||||
using uniform_entry_t = std::tuple<std::string, uniform_t, int>;
|
||||
using uniform_cache_t = std::vector<uniform_entry_t>;
|
||||
|
||||
using uniform_cache_t = std::vector<uniform_entry_t>;
|
||||
void set_uniforms(uniform_cache_t c);
|
||||
|
||||
void set_uniforms(uniform_cache_t c);
|
||||
uint32_t native_handle() const;
|
||||
|
||||
uint32_t native_handle() const;
|
||||
private:
|
||||
std::unordered_map<Type, std::string> source_;
|
||||
|
||||
private:
|
||||
std::unordered_map<Type, std::string> source_;
|
||||
struct impl;
|
||||
std::unique_ptr<impl> impl_;
|
||||
};
|
||||
|
||||
struct impl;
|
||||
std::unique_ptr<impl> impl_;
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace paradiso
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue