breaking change, new VAO/VBO. Updated renderers not tested.
parent
c28f8e6109
commit
dd3a242b41
|
@ -1,7 +1,7 @@
|
|||
cmake_minimum_required(VERSION 3.25)
|
||||
include(FetchContent)
|
||||
|
||||
set(BLT_GRAPHICS_VERSION 2.0.11)
|
||||
set(BLT_GRAPHICS_VERSION 3.0.0)
|
||||
set(BLT_GRAPHICS_TEST_VERSION 0.0.1)
|
||||
|
||||
project(BLT_WITH_GRAPHICS VERSION ${BLT_GRAPHICS_VERSION})
|
||||
|
|
|
@ -1,243 +0,0 @@
|
|||
/*
|
||||
* <Short Description>
|
||||
* Copyright (C) 2023 Brett Terpstra
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef BLT_WITH_GRAPHICS_MODEL_H
|
||||
#define BLT_WITH_GRAPHICS_MODEL_H
|
||||
|
||||
#include <blt/math/vectors.h>
|
||||
#include <vector>
|
||||
#include <blt/gfx/gl_includes.h>
|
||||
#include <variant>
|
||||
#include <array>
|
||||
#include <blt/std/hashmap.h>
|
||||
|
||||
namespace blt::gfx
|
||||
{
|
||||
struct vbo_t_owner;
|
||||
|
||||
class static_dynamic_array;
|
||||
|
||||
class vertex_array_t;
|
||||
|
||||
// vbo
|
||||
struct vertex_buffer_t
|
||||
{
|
||||
friend vbo_t_owner;
|
||||
friend vertex_array_t;
|
||||
friend static_dynamic_array;
|
||||
private:
|
||||
GLuint bufferID_ = 0;
|
||||
GLsizeiptr size_ = 0;
|
||||
GLint buffer_type = 0;
|
||||
GLint memory_type = 0;
|
||||
public:
|
||||
|
||||
void create(GLint type = GL_ARRAY_BUFFER);
|
||||
|
||||
void bind() const;
|
||||
|
||||
void unbind() const;
|
||||
|
||||
void allocate(GLsizeiptr size, GLint mem_type = GL_STATIC_DRAW, const void* data = nullptr);
|
||||
|
||||
template<typename T>
|
||||
void allocate(GLsizeiptr size, const T* data, GLint mem_type = GL_STATIC_DRAW)
|
||||
{
|
||||
allocate(size, mem_type, static_cast<const void*>(data));
|
||||
}
|
||||
|
||||
void sub_update(GLsizeiptr offset, GLsizeiptr size, const void* data) const;
|
||||
|
||||
void update(GLsizeiptr size, const void* data);
|
||||
|
||||
void destroy();
|
||||
};
|
||||
|
||||
// ssbo
|
||||
struct shader_buffer_t : public vertex_buffer_t
|
||||
{
|
||||
public:
|
||||
inline void create()
|
||||
{
|
||||
vertex_buffer_t::create(GL_SHADER_STORAGE_BUFFER);
|
||||
}
|
||||
};
|
||||
|
||||
// ebo
|
||||
struct element_buffer_t : public vertex_buffer_t
|
||||
{
|
||||
public:
|
||||
inline void create()
|
||||
{
|
||||
vertex_buffer_t::create(GL_ELEMENT_ARRAY_BUFFER);
|
||||
}
|
||||
};
|
||||
|
||||
struct vbo_t_owner
|
||||
{
|
||||
vertex_buffer_t vbo;
|
||||
|
||||
vbo_t_owner() = default;
|
||||
|
||||
explicit vbo_t_owner(vertex_buffer_t vbo): vbo(vbo)
|
||||
{}
|
||||
|
||||
vertex_buffer_t* operator->()
|
||||
{
|
||||
return &vbo;
|
||||
}
|
||||
|
||||
~vbo_t_owner()
|
||||
{
|
||||
if (!vbo.bufferID_)
|
||||
return;
|
||||
vbo.destroy();
|
||||
vbo.unbind();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Since most VAOs will not use more than 8 VBOs it makes no sense to heap allocate memory to store them
|
||||
* This class is used to make that easier to handle
|
||||
*/
|
||||
class static_dynamic_array
|
||||
{
|
||||
public:
|
||||
using vbo_type = std::shared_ptr<vbo_t_owner>;
|
||||
private:
|
||||
static constexpr size_t DATA_SIZE = 8;
|
||||
using array_t = std::array<vbo_type, DATA_SIZE>;
|
||||
std::variant<array_t, vbo_type*> data_;
|
||||
size_t size_ = DATA_SIZE;
|
||||
size_t max = 0;
|
||||
|
||||
void swap();
|
||||
|
||||
public:
|
||||
static_dynamic_array();
|
||||
|
||||
static_dynamic_array(const static_dynamic_array& copy) = delete;
|
||||
|
||||
static_dynamic_array(static_dynamic_array&& move) noexcept = default;
|
||||
|
||||
static_dynamic_array& operator=(const static_dynamic_array& copy) = delete;
|
||||
|
||||
static_dynamic_array& operator=(static_dynamic_array&& move) noexcept = default;
|
||||
|
||||
vbo_type& operator[](size_t index);
|
||||
|
||||
[[nodiscard]] inline size_t used() const noexcept
|
||||
{
|
||||
return max;
|
||||
}
|
||||
|
||||
~static_dynamic_array()
|
||||
{
|
||||
if (std::holds_alternative<vbo_type*>(data_))
|
||||
delete[] std::get<vbo_type*>(data_);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* basic VAO class.
|
||||
*/
|
||||
class vertex_array_t
|
||||
{
|
||||
private:
|
||||
GLuint vaoID;
|
||||
static_dynamic_array VBOs;
|
||||
blt::hashset_t<GLuint> used_attributes;
|
||||
vertex_buffer_t element;
|
||||
|
||||
void handle_vbo(const vertex_buffer_t& vbo, int attribute_number, int coordinate_size, GLenum type, int stride, long offset);
|
||||
|
||||
public:
|
||||
vertex_array_t();
|
||||
|
||||
vertex_array_t(const vertex_array_t&) = delete;
|
||||
|
||||
vertex_array_t(vertex_array_t&&) = delete;
|
||||
|
||||
vertex_array_t& operator=(const vertex_array_t&) = delete;
|
||||
|
||||
vertex_array_t& operator=(vertex_array_t&&) = delete;
|
||||
|
||||
/**
|
||||
* This function takes ownership of the underlying VBO (GPU side). It will be freed when the basic vertex array is deleted
|
||||
* @param vbo vbo to bind to this attribute
|
||||
* @param attribute_number attribute number to bind to
|
||||
* @param coordinate_size size of the data (number of
|
||||
* @param type type of data
|
||||
* @param stride how many bytes this data takes (for the entire per-vertex data structure) 0 will assume packed data
|
||||
* This is in effect how many bytes until the next block of data
|
||||
* @param offset offset into the data structure to where the data is stored
|
||||
* @return a shared pointer to the stored vbo. used for chaining VAOs with multiple shared VBOs
|
||||
*/
|
||||
void bindVBO(const vertex_buffer_t& vbo, int attribute_number, int coordinate_size, GLenum type, int stride, long offset);
|
||||
|
||||
// same as the other bind method except you provide the shared reference.
|
||||
void bindVBO(const static_dynamic_array::vbo_type& vbo, int attribute_number, int coordinate_size, GLenum type, int stride, long offset);
|
||||
|
||||
inline void bindElement(const vertex_buffer_t& vbo)
|
||||
{
|
||||
bind();
|
||||
element = vbo;
|
||||
vbo.bind();
|
||||
unbind();
|
||||
}
|
||||
|
||||
inline vertex_buffer_t& getElement()
|
||||
{
|
||||
return element;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a non-owning reference to a vbo allowing for updating the VBO
|
||||
* The VBO is considered invalid if its ID is 0
|
||||
*/
|
||||
inline vertex_buffer_t& operator[](size_t index)
|
||||
{
|
||||
return getBuffer(index);
|
||||
}
|
||||
|
||||
inline vertex_buffer_t& getBuffer(size_t index)
|
||||
{
|
||||
return VBOs[index]->vbo;
|
||||
}
|
||||
|
||||
inline void bind() const
|
||||
{
|
||||
glBindVertexArray(vaoID);
|
||||
}
|
||||
|
||||
static inline void unbind()
|
||||
{
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
static inline static_dynamic_array::vbo_type make_vbo(const vertex_buffer_t& vbo)
|
||||
{
|
||||
return std::make_shared<vbo_t_owner>(vbo);
|
||||
}
|
||||
|
||||
~vertex_array_t();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //BLT_WITH_GRAPHICS_MODEL_H
|
|
@ -19,16 +19,16 @@
|
|||
#ifndef BLT_WITH_GRAPHICS_BATCH_2D_RENDERER_H
|
||||
#define BLT_WITH_GRAPHICS_BATCH_2D_RENDERER_H
|
||||
|
||||
#include "blt/gfx/model.h"
|
||||
#include "blt/gfx/shader.h"
|
||||
#include "blt/gfx/framebuffer.h"
|
||||
#include "blt/gfx/renderer/resource_manager.h"
|
||||
#include "blt/gfx/renderer/postprocess.h"
|
||||
#include <blt/std/hashmap.h>
|
||||
#include <blt/std/memory_util.h>
|
||||
#include <blt/math/vectors.h>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
#include <blt/math/vectors.h>
|
||||
#include <blt/std/hashmap.h>
|
||||
#include <blt/std/memory_util.h>
|
||||
#include "blt/gfx/framebuffer.h"
|
||||
#include "blt/gfx/shader.h"
|
||||
#include "blt/gfx/vao.h"
|
||||
#include "blt/gfx/renderer/postprocess.h"
|
||||
#include "blt/gfx/renderer/resource_manager.h"
|
||||
|
||||
namespace blt::gfx
|
||||
{
|
||||
|
@ -121,12 +121,12 @@ namespace blt::gfx
|
|||
|
||||
struct draw_t
|
||||
{
|
||||
std::unique_ptr<vertex_array_t> vao;
|
||||
std::optional<unique_vao_t> vao;
|
||||
i32 count;
|
||||
};
|
||||
|
||||
[[nodiscard]] draw_t to_vertex_array() const;
|
||||
size_t populate_vertex_array(vertex_array_t& va) const;
|
||||
[[nodiscard]] size_t populate_vertex_array(const unique_vao_t& va) const;
|
||||
|
||||
[[nodiscard]] std::vector<line_vertex_t> calculate_vertices() const;
|
||||
|
||||
|
@ -254,9 +254,9 @@ namespace blt::gfx
|
|||
using object_container = hashmap_t<std::string, std::vector<std::pair<render_info_t, T>>>;
|
||||
|
||||
private:
|
||||
std::unique_ptr<vertex_array_t> square_vao;
|
||||
std::unique_ptr<vertex_array_t> line_vao;
|
||||
std::unique_ptr<vertex_array_t> curve_vao;
|
||||
std::optional<unique_vao_t> square_vao;
|
||||
std::optional<unique_vao_t> line_vao;
|
||||
std::optional<unique_vao_t> curve_vao;
|
||||
std::unique_ptr<shader_t> square_shader;
|
||||
std::unique_ptr<shader_t> point_shader;
|
||||
resource_manager& resources;
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#include <blt/gfx/font/font.h>
|
||||
#include <blt/gfx/texture.h>
|
||||
#include <blt/gfx/shader.h>
|
||||
#include <blt/gfx/model.h>
|
||||
#include <blt/gfx/vao.h>
|
||||
#include <blt/gfx/framebuffer.h>
|
||||
#include <blt/std/hashmap.h>
|
||||
#include <blt/std/binary_tree.h>
|
||||
|
@ -368,7 +368,7 @@ namespace blt::gfx
|
|||
|
||||
font_generator_t& generator;
|
||||
std::string contents, font;
|
||||
vertex_array_t vao{};
|
||||
unique_vao_t vao{};
|
||||
std::vector<text_render_info_t> renders;
|
||||
blt::vec2f position, bounds;
|
||||
blt::vec2f scale = DEFAULT_SCALE;
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#include <blt/std/types.h>
|
||||
#include <blt/gfx/framebuffer.h>
|
||||
#include <blt/gfx/shader.h>
|
||||
#include <blt/gfx/model.h>
|
||||
#include <blt/gfx/vao.h>
|
||||
#include <blt/gfx/state.h>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
@ -271,10 +271,10 @@ namespace blt::gfx
|
|||
private:
|
||||
pp_engine_t() = default;
|
||||
|
||||
pp_step_t& find_last_frame_buffer(size_t index);
|
||||
pp_step_t& find_last_frame_buffer(size_t index) const;
|
||||
|
||||
std::vector<std::unique_ptr<pp_step_t>> steps;
|
||||
std::unique_ptr<vertex_array_t> screen_vao;
|
||||
std::optional<unique_vao_t> screen_vao{};
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -54,14 +54,6 @@ namespace blt::gfx
|
|||
*/
|
||||
vbo_context_t& resize(GLsizeiptr size, GLint mem_type);
|
||||
|
||||
/**
|
||||
* Reserves a chunk of GPU memory for future use
|
||||
*/
|
||||
vbo_context_t& resize(const size_t size, const GLint mem_type)
|
||||
{
|
||||
return resize(static_cast<GLsizeiptr>(size), mem_type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Uploads a chunk of memory to the GPU. If the existing VBO has enough space, the memory will be reused.
|
||||
*/
|
||||
|
@ -71,9 +63,9 @@ namespace blt::gfx
|
|||
* Uploads a chunk of memory to the GPU. If the existing VBO has enough space, the memory will be reused.
|
||||
*/
|
||||
template <typename T, std::enable_if_t<!std::is_same_v<T, void>, bool> = true>
|
||||
vbo_context_t& upload(const size_t size, T* ptr, const GLint mem_type)
|
||||
vbo_context_t& upload(const size_t size, const T* ptr, const GLint mem_type)
|
||||
{
|
||||
return upload(size, static_cast<void*>(ptr), mem_type);
|
||||
return upload(size, static_cast<const void*>(ptr), mem_type);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,155 +0,0 @@
|
|||
/*
|
||||
* <Short Description>
|
||||
* Copyright (C) 2023 Brett Terpstra
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <blt/gfx/model.h>
|
||||
#include <blt/std/memory_util.h>
|
||||
#include "blt/logging/logging.h"
|
||||
|
||||
namespace blt::gfx
|
||||
{
|
||||
void static_dynamic_array::swap()
|
||||
{
|
||||
size_t next_size = blt::mem::next_byte_allocation(size_);
|
||||
|
||||
auto* new_data = new vbo_type[next_size];
|
||||
|
||||
if (std::holds_alternative<vbo_type*>(data_))
|
||||
{
|
||||
auto* ptr = std::get<vbo_type*>(data_);
|
||||
for (size_t i = 0; i < size_; i++)
|
||||
new_data[i] = ptr[i];
|
||||
delete[] ptr;
|
||||
} else
|
||||
{
|
||||
auto data = std::get<array_t>(data_);
|
||||
for (size_t i = 0; i < DATA_SIZE; i++)
|
||||
new_data[i] = data[i];
|
||||
}
|
||||
data_ = new_data;
|
||||
size_ = next_size;
|
||||
}
|
||||
|
||||
static_dynamic_array::static_dynamic_array() = default;
|
||||
|
||||
static_dynamic_array::vbo_type& static_dynamic_array::operator[](size_t index)
|
||||
{
|
||||
if (index >= size_)
|
||||
swap();
|
||||
max = std::max(index, max);
|
||||
if (std::holds_alternative<vbo_type*>(data_))
|
||||
return std::get<vbo_type*>(data_)[index];
|
||||
else
|
||||
return std::get<array_t>(data_)[index];
|
||||
}
|
||||
|
||||
/*
|
||||
* -----------------------------------
|
||||
* vbo_t
|
||||
* -----------------------------------
|
||||
*/
|
||||
void vertex_buffer_t::create(GLint type)
|
||||
{
|
||||
glGenBuffers(1, &bufferID_);
|
||||
buffer_type = type;
|
||||
}
|
||||
|
||||
void vertex_buffer_t::destroy()
|
||||
{
|
||||
// prevent multiple destroys of the same object, in cases of multi attribute binds
|
||||
if (bufferID_ == 0)
|
||||
return;
|
||||
glDeleteBuffers(1, &bufferID_);
|
||||
bufferID_ = 0;
|
||||
}
|
||||
|
||||
void vertex_buffer_t::allocate(GLsizeiptr size, GLint mem_type, const void* data)
|
||||
{
|
||||
bind();
|
||||
size_ = size;
|
||||
glBufferData(buffer_type, size, data, mem_type);
|
||||
memory_type = mem_type;
|
||||
}
|
||||
|
||||
void vertex_buffer_t::update(GLsizeiptr size, const void* data)
|
||||
{
|
||||
if (size <= size_)
|
||||
sub_update(0, size, data);
|
||||
else
|
||||
allocate(size, memory_type, data);
|
||||
size_ = size;
|
||||
}
|
||||
|
||||
void vertex_buffer_t::sub_update(GLsizeiptr offset, GLsizeiptr size, const void* data) const
|
||||
{
|
||||
bind();
|
||||
glBufferSubData(buffer_type, offset, size, data);
|
||||
}
|
||||
|
||||
void vertex_buffer_t::bind() const
|
||||
{
|
||||
glBindBuffer(buffer_type, bufferID_);
|
||||
}
|
||||
|
||||
void vertex_buffer_t::unbind() const
|
||||
{
|
||||
glBindBuffer(buffer_type, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------
|
||||
* basic_vertex_array
|
||||
* ----------------------------
|
||||
*/
|
||||
|
||||
vertex_array_t::vertex_array_t(): vaoID(0)
|
||||
{
|
||||
glGenVertexArrays(1, &vaoID);
|
||||
}
|
||||
|
||||
vertex_array_t::~vertex_array_t()
|
||||
{
|
||||
// free all VBOs
|
||||
for (size_t i = 0; i < VBOs.used(); i++)
|
||||
VBOs[i] = nullptr;
|
||||
element.destroy();
|
||||
// then free the vertex array
|
||||
glDeleteVertexArrays(1, &vaoID);
|
||||
}
|
||||
|
||||
void vertex_array_t::bindVBO(const vertex_buffer_t& vbo, int attribute_number, int coordinate_size, GLenum type, int stride, long offset)
|
||||
{
|
||||
handle_vbo(vbo, attribute_number, coordinate_size, type, stride, offset);
|
||||
VBOs[attribute_number] = make_vbo(vbo);
|
||||
}
|
||||
|
||||
void vertex_array_t::bindVBO(const static_dynamic_array::vbo_type& vbo, int attribute_number, int coordinate_size, GLenum type, int stride, long offset)
|
||||
{
|
||||
handle_vbo(vbo->vbo, attribute_number, coordinate_size, type, stride, offset);
|
||||
VBOs[attribute_number] = vbo;
|
||||
}
|
||||
|
||||
void vertex_array_t::handle_vbo(const vertex_buffer_t& vbo, int attribute_number, int coordinate_size, GLenum type, int stride, long offset)
|
||||
{
|
||||
used_attributes.insert(attribute_number);
|
||||
bind();
|
||||
vbo.bind();
|
||||
|
||||
glEnableVertexAttribArray(attribute_number);
|
||||
glVertexAttribPointer(attribute_number, coordinate_size, type, GL_FALSE, stride < 0 ? 0 : stride, (void*) offset);
|
||||
unbind();
|
||||
}
|
||||
}
|
|
@ -23,22 +23,58 @@
|
|||
|
||||
float square_vertices[20] = {
|
||||
// positions // texture coords
|
||||
0.5f, 0.5f, 0.0f, 1.0f, 1.0f, // top right
|
||||
0.5f, -0.5f, 0.0f, 1.0f, 0.0f, // bottom right
|
||||
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, // bottom left
|
||||
-0.5f, 0.5f, 0.0f, 0.0f, 1.0f // top left
|
||||
0.5f,
|
||||
0.5f,
|
||||
0.0f,
|
||||
1.0f,
|
||||
1.0f, // top right
|
||||
0.5f,
|
||||
-0.5f,
|
||||
0.0f,
|
||||
1.0f,
|
||||
0.0f, // bottom right
|
||||
-0.5f,
|
||||
-0.5f,
|
||||
0.0f,
|
||||
0.0f,
|
||||
0.0f, // bottom left
|
||||
-0.5f,
|
||||
0.5f,
|
||||
0.0f,
|
||||
0.0f,
|
||||
1.0f // top left
|
||||
};
|
||||
const unsigned int square_indices[6] = {
|
||||
0, 1, 3, // first triangle
|
||||
1, 2, 3 // second triangle
|
||||
0,
|
||||
1,
|
||||
3, // first triangle
|
||||
1,
|
||||
2,
|
||||
3 // second triangle
|
||||
};
|
||||
|
||||
float line_vertices[20] = {
|
||||
// positions // texture coords
|
||||
0.5f, 0.5f, 0.0f, 1.0f, 1.0f, // top right
|
||||
0.5f, -0.5f, 0.0f, 1.0f, 0.0f, // bottom right
|
||||
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, // bottom left
|
||||
-0.5f, 0.5f, 0.0f, 0.0f, 1.0f // top left
|
||||
0.5f,
|
||||
0.5f,
|
||||
0.0f,
|
||||
1.0f,
|
||||
1.0f, // top right
|
||||
0.5f,
|
||||
-0.5f,
|
||||
0.0f,
|
||||
1.0f,
|
||||
0.0f, // bottom right
|
||||
-0.5f,
|
||||
-0.5f,
|
||||
0.0f,
|
||||
0.0f,
|
||||
0.0f, // bottom left
|
||||
-0.5f,
|
||||
0.5f,
|
||||
0.0f,
|
||||
0.0f,
|
||||
1.0f // top left
|
||||
};
|
||||
|
||||
// 0, 1 (top right)
|
||||
|
@ -51,23 +87,23 @@ namespace blt::gfx
|
|||
curve2d_mesh_data_t::draw_t curve2d_mesh_data_t::to_vertex_array() const
|
||||
{
|
||||
const auto vertices = calculate_vertices();
|
||||
auto vao = std::make_unique<vertex_array_t>();
|
||||
auto vao = unique_vao_t{};
|
||||
|
||||
vertex_buffer_t vertex_buffer;
|
||||
vertex_buffer.create();
|
||||
vertex_buffer.allocate(static_cast<long>(vertices.size() * sizeof(line_vertex_t)), vertices.data());
|
||||
unique_vbo_t vertex_buffer{GL_ARRAY_BUFFER};
|
||||
vertex_buffer.bind().upload(static_cast<long>(vertices.size() * sizeof(line_vertex_t)), vertices.data(), GL_STATIC_DRAW);
|
||||
|
||||
const auto vb = vertex_array_t::make_vbo(vertex_buffer);
|
||||
vao->bindVBO(vb, 0, 3, GL_FLOAT, sizeof(line_vertex_t), 0);
|
||||
vao->bindVBO(vb, 1, 2, GL_FLOAT, sizeof(line_vertex_t), sizeof(vec3));
|
||||
const auto ctx = vao.configure();
|
||||
auto vbo = ctx.attach_vbo(std::move(vertex_buffer));
|
||||
vbo.attribute_ptr(0, 3, GL_FLOAT, sizeof(line_vertex_t), 0);
|
||||
vbo.attribute_ptr(1, 2, GL_FLOAT, sizeof(line_vertex_t), sizeof(vec3));
|
||||
|
||||
return {std::move(vao), static_cast<i32>(vertices.size())};
|
||||
}
|
||||
|
||||
size_t curve2d_mesh_data_t::populate_vertex_array(vertex_array_t& va) const
|
||||
size_t curve2d_mesh_data_t::populate_vertex_array(const unique_vao_t& va) const
|
||||
{
|
||||
const auto vertices = calculate_vertices();
|
||||
va.getBuffer(0).update(static_cast<long>(vertices.size() * sizeof(line_vertex_t)), vertices.data());
|
||||
va.get_attribute(0)->get().bind().upload(static_cast<long>(vertices.size() * sizeof(line_vertex_t)), vertices.data(), GL_STATIC_DRAW);
|
||||
return vertices.size();
|
||||
}
|
||||
|
||||
|
@ -210,47 +246,43 @@ namespace blt::gfx
|
|||
void batch_renderer_2d::create()
|
||||
{
|
||||
{
|
||||
vertex_buffer_t vertices_vbo;
|
||||
element_buffer_t indices_vbo;
|
||||
unique_vbo_t vertices_vbo{GL_ARRAY_BUFFER};
|
||||
unique_ebo_t indices_vbo;
|
||||
|
||||
vertices_vbo.create();
|
||||
indices_vbo.create();
|
||||
vertices_vbo.bind().upload(sizeof(square_vertices), square_vertices, GL_STATIC_DRAW);
|
||||
indices_vbo.bind().upload(sizeof(square_indices), square_indices, GL_STATIC_DRAW);
|
||||
|
||||
vertices_vbo.allocate(sizeof(square_vertices), square_vertices);
|
||||
indices_vbo.allocate(sizeof(square_indices), square_indices);
|
||||
|
||||
square_vao = std::make_unique<vertex_array_t>();
|
||||
auto vb = vertex_array_t::make_vbo(vertices_vbo);
|
||||
square_vao->bindVBO(vb, 0, 3, GL_FLOAT, 5 * sizeof(float), 0);
|
||||
square_vao->bindVBO(vb, 1, 2, GL_FLOAT, 5 * sizeof(float), 3 * sizeof(float));
|
||||
square_vao->bindElement(indices_vbo);
|
||||
square_vao = unique_vao_t{};
|
||||
const auto ctx = square_vao->configure();
|
||||
auto vbo = ctx.attach_vbo(std::move(vertices_vbo));
|
||||
vbo.attribute_ptr(0, 3, GL_FLOAT, 5 * sizeof(float), 0);
|
||||
vbo.attribute_ptr(1, 2, GL_FLOAT, 5 * sizeof(float), 3 * sizeof(float));
|
||||
ctx.attach_vbo(std::move(indices_vbo));
|
||||
}
|
||||
{
|
||||
vertex_buffer_t vertices_vbo;
|
||||
element_buffer_t indices_vbo;
|
||||
unique_vbo_t vertices_vbo{GL_ARRAY_BUFFER};
|
||||
unique_ebo_t indices_vbo;
|
||||
|
||||
vertices_vbo.create();
|
||||
indices_vbo.create();
|
||||
vertices_vbo.bind().upload(sizeof(line_vertices), line_vertices, GL_DYNAMIC_DRAW);
|
||||
indices_vbo.bind().upload(sizeof(square_indices), square_indices, GL_DYNAMIC_DRAW);
|
||||
|
||||
vertices_vbo.allocate(sizeof(line_vertices), line_vertices, GL_DYNAMIC_DRAW);
|
||||
indices_vbo.allocate(sizeof(square_indices), square_indices, GL_DYNAMIC_DRAW);
|
||||
|
||||
line_vao = std::make_unique<vertex_array_t>();
|
||||
const auto vb = vertex_array_t::make_vbo(vertices_vbo);
|
||||
line_vao->bindVBO(vb, 0, 3, GL_FLOAT, 5 * sizeof(float), 0);
|
||||
line_vao->bindVBO(vb, 1, 2, GL_FLOAT, 5 * sizeof(float), 3 * sizeof(float));
|
||||
line_vao->bindElement(indices_vbo);
|
||||
line_vao = unique_vao_t{};
|
||||
const auto ctx = line_vao->configure();
|
||||
auto vbo = ctx.attach_vbo(std::move(vertices_vbo));
|
||||
vbo.attribute_ptr(0, 3, GL_FLOAT, 5 * sizeof(float), 0);
|
||||
vbo.attribute_ptr(1, 2, GL_FLOAT, 5 * sizeof(float), 3 * sizeof(float));
|
||||
ctx.attach_vbo(std::move(indices_vbo));
|
||||
}
|
||||
{
|
||||
curve_vao = std::make_unique<vertex_array_t>();
|
||||
curve_vao = unique_vao_t{};
|
||||
|
||||
vertex_buffer_t vertex_buffer;
|
||||
vertex_buffer.create();
|
||||
vertex_buffer.allocate(0, GL_DYNAMIC_DRAW);
|
||||
unique_vbo_t vertex_buffer{GL_ARRAY_BUFFER};
|
||||
vertex_buffer.bind().resize(0, GL_DYNAMIC_DRAW);
|
||||
|
||||
const auto vb = vertex_array_t::make_vbo(vertex_buffer);
|
||||
curve_vao->bindVBO(vb, 0, 3, GL_FLOAT, sizeof(curve2d_mesh_data_t::line_vertex_t), 0);
|
||||
curve_vao->bindVBO(vb, 1, 2, GL_FLOAT, sizeof(curve2d_mesh_data_t::line_vertex_t), sizeof(vec3));
|
||||
const auto ctx = curve_vao->configure();
|
||||
auto vbo = ctx.attach_vbo(std::move(vertex_buffer));
|
||||
vbo.attribute_ptr(0, 3, GL_FLOAT, sizeof(curve2d_mesh_data_t::line_vertex_t), 0);
|
||||
vbo.attribute_ptr(1, 2, GL_FLOAT, sizeof(curve2d_mesh_data_t::line_vertex_t), sizeof(vec3));
|
||||
}
|
||||
|
||||
square_shader = shader_t::make_unique(shader_2d_textured_vert, shader_2d_textured_frag);
|
||||
|
@ -340,9 +372,9 @@ namespace blt::gfx
|
|||
{
|
||||
engine->cleanup();
|
||||
engine = nullptr;
|
||||
square_vao = nullptr;
|
||||
line_vao = nullptr;
|
||||
curve_vao = nullptr;
|
||||
square_vao.reset();
|
||||
line_vao.reset();
|
||||
curve_vao.reset();
|
||||
square_shader = nullptr;
|
||||
point_shader = nullptr;
|
||||
}
|
||||
|
@ -435,8 +467,8 @@ namespace blt::gfx
|
|||
mat4x4 empty_model;
|
||||
square_shader->setMatrix("model", empty_model);
|
||||
line_vao->bind();
|
||||
auto& buf = line_vao->getBuffer(0);
|
||||
buf.bind();
|
||||
auto& buf = line_vao->get_attribute(0)->get();
|
||||
auto vbo = buf.bind();
|
||||
for (auto& [texture, objects] : draw.complex_lines)
|
||||
{
|
||||
// resource manager handles the check for empty string
|
||||
|
@ -479,7 +511,7 @@ namespace blt::gfx
|
|||
line_vertices[15] = top_left.x();
|
||||
line_vertices[16] = top_left.y();
|
||||
|
||||
buf.update(sizeof(line_vertices), line_vertices);
|
||||
vbo.update(0, sizeof(line_vertices), line_vertices);
|
||||
|
||||
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
|
||||
draw.draw_count++;
|
||||
|
|
|
@ -328,12 +328,9 @@ namespace blt::gfx
|
|||
|
||||
font_renderer_t::compiled_text_t::compiled_text_t(font_generator_t& generator): generator(generator)
|
||||
{
|
||||
auto vbo = vertex_array_t::make_vbo({});
|
||||
vbo->vbo.create();
|
||||
vbo->vbo.bind();
|
||||
vbo->vbo.allocate(sizeof(float) * 6 * 4, GL_DYNAMIC_DRAW);
|
||||
vao.bind();
|
||||
vao.bindVBO(vbo, 0, 4, GL_FLOAT, 4 * sizeof(float), 0);
|
||||
unique_vbo_t vbo{GL_ARRAY_BUFFER};
|
||||
vbo.bind().resize(sizeof(float) * 6 * 4, GL_DYNAMIC_DRAW);
|
||||
vao.configure().attach_vbo(std::move(vbo)).attribute_ptr(0, 4, GL_FLOAT, 4 * sizeof(float), 0);
|
||||
}
|
||||
|
||||
void font_renderer_t::compiled_text_t::draw()
|
||||
|
@ -433,7 +430,7 @@ namespace blt::gfx
|
|||
// BLT_TRACE("size: %ld %ld %ld", draw_count, vertices.size(), vertices.size() / 4);
|
||||
|
||||
renders.emplace_back(last_texture, draw_start, draw_count);
|
||||
vao.getBuffer(0).update(static_cast<long>(vertices.size() * sizeof(float)), vertices.data());
|
||||
vao.get_attribute(0)->get().bind().update(0, static_cast<long>(vertices.size() * sizeof(float)), vertices.data());
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,295 +27,306 @@
|
|||
#include <blt/std/ranges.h>
|
||||
#include <blt/math/log_util.h>
|
||||
|
||||
#define __EMSCRIPTEN__
|
||||
// #define __EMSCRIPTEN__
|
||||
|
||||
float full_screen_vertices[20] = {
|
||||
1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
|
||||
1.0f, -1.0f, 0.0f, 1.0f, 0.0f,
|
||||
-1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
|
||||
-1.0f, 1.0f, 0.0f, 0.0f, 1.0f
|
||||
};
|
||||
const unsigned int full_screen_indices[6] = {
|
||||
0, 1, 3,
|
||||
1, 2, 3
|
||||
1.0f,
|
||||
1.0f,
|
||||
0.0f,
|
||||
1.0f,
|
||||
1.0f,
|
||||
1.0f,
|
||||
-1.0f,
|
||||
0.0f,
|
||||
1.0f,
|
||||
0.0f,
|
||||
-1.0f,
|
||||
-1.0f,
|
||||
0.0f,
|
||||
0.0f,
|
||||
0.0f,
|
||||
-1.0f,
|
||||
1.0f,
|
||||
0.0f,
|
||||
0.0f,
|
||||
1.0f
|
||||
};
|
||||
const unsigned int full_screen_indices[6] = {0, 1, 3, 1, 2, 3};
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
bool once()
|
||||
{
|
||||
static bool ran = true;
|
||||
return std::exchange(ran, false);
|
||||
static bool ran = true;
|
||||
return std::exchange(ran, false);
|
||||
}
|
||||
|
||||
namespace blt::gfx
|
||||
{
|
||||
void pp_engine_t::create()
|
||||
{
|
||||
{
|
||||
vertex_buffer_t vertices_vbo;
|
||||
element_buffer_t indices_vbo;
|
||||
void pp_engine_t::create()
|
||||
{
|
||||
{
|
||||
unique_vbo_t vertices_vbo{GL_ARRAY_BUFFER};
|
||||
unique_ebo_t indices_vbo;
|
||||
|
||||
vertices_vbo.create();
|
||||
indices_vbo.create();
|
||||
vertices_vbo.bind().upload(sizeof(full_screen_vertices), full_screen_vertices, GL_STATIC_DRAW);
|
||||
indices_vbo.bind().upload(sizeof(full_screen_indices), full_screen_indices, GL_STATIC_DRAW);
|
||||
|
||||
vertices_vbo.allocate(sizeof(full_screen_vertices), full_screen_vertices);
|
||||
indices_vbo.allocate(sizeof(full_screen_indices), full_screen_indices);
|
||||
screen_vao = unique_vao_t{};
|
||||
const auto ctx = screen_vao->configure();
|
||||
auto vbo = ctx.attach_vbo(std::move(vertices_vbo));
|
||||
vbo.attribute_ptr(0, 3, GL_FLOAT, 5 * sizeof(float), 0);
|
||||
vbo.attribute_ptr(1, 2, GL_FLOAT, 5 * sizeof(float), 3 * sizeof(float));
|
||||
ctx.attach_vbo(std::move(indices_vbo));
|
||||
}
|
||||
#ifdef __EMSCRIPTEN__
|
||||
addStep(std::make_unique<pp_to_screen_step_t>());
|
||||
#endif
|
||||
for (const auto& step : steps)
|
||||
step->create();
|
||||
}
|
||||
|
||||
screen_vao = std::make_unique<vertex_array_t>();
|
||||
auto vb = vertex_array_t::make_vbo(vertices_vbo);
|
||||
screen_vao->bindVBO(vb, 0, 3, GL_FLOAT, 5 * sizeof(float), 0);
|
||||
screen_vao->bindVBO(vb, 1, 2, GL_FLOAT, 5 * sizeof(float), 3 * sizeof(float));
|
||||
screen_vao->bindElement(indices_vbo);
|
||||
}
|
||||
#ifdef __EMSCRIPTEN__
|
||||
addStep(std::make_unique<pp_to_screen_step_t>());
|
||||
#endif
|
||||
for (auto& step : steps)
|
||||
step->create();
|
||||
}
|
||||
pp_step_t& pp_engine_t::find_last_frame_buffer(const size_t index) const
|
||||
{
|
||||
for (i64 i = static_cast<i64>(index); i >= 0; i--)
|
||||
{
|
||||
if (steps[i]->requests(pp_request_t::BIND_BUFFER))
|
||||
return *steps[i];
|
||||
}
|
||||
BLT_FATAL("We reached the end trying to find a previous frame buffer, unable to do so! Please ensure this in-place step has a framebuffer!");
|
||||
std::exit(1);
|
||||
}
|
||||
|
||||
pp_step_t& pp_engine_t::find_last_frame_buffer(size_t index)
|
||||
{
|
||||
for (i64 i = static_cast<i64>(index); i >= 0; i--)
|
||||
{
|
||||
if (steps[i]->requests(pp_request_t::BIND_BUFFER))
|
||||
return *steps[i];
|
||||
}
|
||||
BLT_FATAL("We reached the end trying to find a previous frame buffer, unable to do so! Please ensure this in-place step has a framebuffer!");
|
||||
std::exit(1);
|
||||
}
|
||||
|
||||
void pp_engine_t::render()
|
||||
{
|
||||
screen_vao->bind();
|
||||
for (const auto& [index, step] : blt::enumerate(steps))
|
||||
{
|
||||
if (index == 0)
|
||||
continue;
|
||||
auto& previous = find_last_frame_buffer(index - 1);
|
||||
if (step->requests(pp_request_t::BIND_BUFFER))
|
||||
step->getBuffer().bind();
|
||||
else
|
||||
previous.getBuffer().bind();
|
||||
if (step->requests(pp_request_t::CLEAR_BUFFER))
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
step->draw(previous.getBuffer());
|
||||
if (step->hasShader())
|
||||
step->getShader().bind();
|
||||
render_quad();
|
||||
step->post_draw(previous.getBuffer());
|
||||
}
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
frame_buffer_t::unbind();
|
||||
#ifndef __EMSCRIPTEN__
|
||||
void pp_engine_t::render()
|
||||
{
|
||||
screen_vao->bind();
|
||||
for (const auto& [index, step] : blt::enumerate(steps))
|
||||
{
|
||||
if (index == 0)
|
||||
continue;
|
||||
auto& previous = find_last_frame_buffer(index - 1);
|
||||
if (step->requests(pp_request_t::BIND_BUFFER))
|
||||
step->getBuffer().bind();
|
||||
else
|
||||
previous.getBuffer().bind();
|
||||
if (step->requests(pp_request_t::CLEAR_BUFFER))
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
step->draw(previous.getBuffer());
|
||||
if (step->hasShader())
|
||||
step->getShader().bind();
|
||||
render_quad();
|
||||
step->post_draw(previous.getBuffer());
|
||||
}
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
frame_buffer_t::unbind();
|
||||
#ifndef __EMSCRIPTEN__
|
||||
steps.back()->getBuffer().blitToScreen(getWindowWidth(), getWindowHeight());
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void pp_engine_t::cleanup()
|
||||
{
|
||||
screen_vao = nullptr;
|
||||
for (auto& v : steps)
|
||||
v = nullptr;
|
||||
steps.clear();
|
||||
}
|
||||
void pp_engine_t::cleanup()
|
||||
{
|
||||
screen_vao.reset();
|
||||
for (auto& v : steps)
|
||||
v = nullptr;
|
||||
steps.clear();
|
||||
}
|
||||
|
||||
std::unique_ptr<shader_t> pp_engine_t::createShader(std::string_view fragment, std::optional<std::reference_wrapper<template_engine_t>> engine)
|
||||
{
|
||||
std::unique_ptr<shader_t> shader;
|
||||
if (engine)
|
||||
{
|
||||
shader = shader_t::make_unique(engine, shader_postprocess_vert, std::string(fragment));
|
||||
} else
|
||||
{
|
||||
template_engine_t templateEngine;
|
||||
templateEngine.set("LAYOUT_STRING", "");
|
||||
shader = shader_t::make_unique(templateEngine, shader_postprocess_vert, std::string(fragment));
|
||||
}
|
||||
shader->bindAttribute(0, "vertex");
|
||||
shader->bindAttribute(1, "uv_in");
|
||||
return shader;
|
||||
}
|
||||
std::unique_ptr<shader_t> pp_engine_t::createShader(std::string_view fragment, std::optional<std::reference_wrapper<template_engine_t>> engine)
|
||||
{
|
||||
std::unique_ptr<shader_t> shader;
|
||||
if (engine)
|
||||
{
|
||||
shader = shader_t::make_unique(engine, shader_postprocess_vert, std::string(fragment));
|
||||
} else
|
||||
{
|
||||
template_engine_t templateEngine;
|
||||
templateEngine.set("LAYOUT_STRING", "");
|
||||
shader = shader_t::make_unique(templateEngine, shader_postprocess_vert, std::string(fragment));
|
||||
}
|
||||
shader->bindAttribute(0, "vertex");
|
||||
shader->bindAttribute(1, "uv_in");
|
||||
return shader;
|
||||
}
|
||||
|
||||
void pp_engine_t::bind()
|
||||
{
|
||||
steps.front()->getBuffer().bind();
|
||||
steps.front()->draw();
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
}
|
||||
void pp_engine_t::bind()
|
||||
{
|
||||
steps.front()->getBuffer().bind();
|
||||
steps.front()->draw();
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
}
|
||||
|
||||
void pp_engine_t::render_quad()
|
||||
{
|
||||
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
|
||||
}
|
||||
void pp_engine_t::render_quad()
|
||||
{
|
||||
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
|
||||
}
|
||||
|
||||
void pp_in_place_t::create()
|
||||
{
|
||||
template_engine_t engine;
|
||||
engine.set("LAYOUT_STRING", "layout (location = ${IF(LAYOUT_LOCATION) { LAYOUT_LOCATION } ELSE { ~DISCARD }}) ");
|
||||
engine.set("LAYOUT_LOCATION", std::to_string(static_cast<int>(to) - static_cast<int>(frame_buffer_t::attachment_t::COLOR0)));
|
||||
shader_pass = pp_engine_t::createShader(shader_pp_screen_frag, engine);
|
||||
draw_buffer = frame_buffer_t::make_render_texture(getWindowWidth(), getWindowHeight());
|
||||
}
|
||||
void pp_in_place_t::create()
|
||||
{
|
||||
template_engine_t engine;
|
||||
engine.set("LAYOUT_STRING", "layout (location = ${IF(LAYOUT_LOCATION) { LAYOUT_LOCATION } ELSE { ~DISCARD }}) ");
|
||||
engine.set("LAYOUT_LOCATION", std::to_string(static_cast<int>(to) - static_cast<int>(frame_buffer_t::attachment_t::COLOR0)));
|
||||
shader_pass = pp_engine_t::createShader(shader_pp_screen_frag, engine);
|
||||
draw_buffer = frame_buffer_t::make_render_texture(getWindowWidth(), getWindowHeight());
|
||||
}
|
||||
|
||||
void pp_in_place_t::post_draw(frame_buffer_t& previous)
|
||||
{
|
||||
// draw_buffer.blitTexture(previous, 0, 0, 0, 0, GL_NEAREST, from, to);
|
||||
handle_errors();
|
||||
previous.bind();
|
||||
GLenum buf[32];
|
||||
auto to_val = static_cast<GLenum>(to);
|
||||
auto size = to_val - GL_COLOR_ATTACHMENT0;
|
||||
for (GLenum i = 0; i < size; i++)
|
||||
buf[i] = GL_NONE;
|
||||
buf[size] = to_val;
|
||||
glDrawBuffers(static_cast<int>(size) + 1, buf);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
shader_pass->bind();
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
draw_buffer.getTexture(frame_buffer_t::attachment_t::COLOR0).bind();
|
||||
pp_engine_t::render_quad();
|
||||
}
|
||||
void pp_in_place_t::post_draw(frame_buffer_t& previous)
|
||||
{
|
||||
// draw_buffer.blitTexture(previous, 0, 0, 0, 0, GL_NEAREST, from, to);
|
||||
handle_errors();
|
||||
previous.bind();
|
||||
GLenum buf[32];
|
||||
auto to_val = static_cast<GLenum>(to);
|
||||
auto size = to_val - GL_COLOR_ATTACHMENT0;
|
||||
for (GLenum i = 0; i < size; i++)
|
||||
buf[i] = GL_NONE;
|
||||
buf[size] = to_val;
|
||||
glDrawBuffers(static_cast<int>(size) + 1, buf);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
shader_pass->bind();
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
draw_buffer.getTexture(frame_buffer_t::attachment_t::COLOR0).bind();
|
||||
pp_engine_t::render_quad();
|
||||
}
|
||||
|
||||
void pp_in_place_t::draw(frame_buffer_t& previous)
|
||||
{
|
||||
draw_buffer.updateBuffersStorage(getWindowWidth(), getWindowHeight());
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
previous.getTexture(from).bind();
|
||||
draw_buffer.bind();
|
||||
GLenum buf[]{static_cast<GLenum>(frame_buffer_t::attachment_t::COLOR0)};
|
||||
glDrawBuffers(1, buf);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
void pp_in_place_t::draw(frame_buffer_t& previous)
|
||||
{
|
||||
draw_buffer.updateBuffersStorage(getWindowWidth(), getWindowHeight());
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
previous.getTexture(from).bind();
|
||||
draw_buffer.bind();
|
||||
GLenum buf[]{static_cast<GLenum>(frame_buffer_t::attachment_t::COLOR0)};
|
||||
glDrawBuffers(1, buf);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
|
||||
void pp_to_screen_step_t::create()
|
||||
{
|
||||
shader = pp_engine_t::createShader(shader_pp_screen_frag);
|
||||
}
|
||||
void pp_to_screen_step_t::create()
|
||||
{
|
||||
shader = pp_engine_t::createShader(shader_pp_screen_frag);
|
||||
}
|
||||
|
||||
void pp_to_screen_step_t::draw(frame_buffer_t& previous)
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
previous.getTexture(frame_buffer_t::attachment_t::COLOR0).bind();
|
||||
GLenum buf[]{GL_BACK};
|
||||
glDrawBuffers(1, buf);
|
||||
}
|
||||
void pp_to_screen_step_t::draw(frame_buffer_t& previous)
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
previous.getTexture(frame_buffer_t::attachment_t::COLOR0).bind();
|
||||
GLenum buf[]{GL_BACK};
|
||||
glDrawBuffers(1, buf);
|
||||
}
|
||||
|
||||
void pp_render_target_t::create()
|
||||
{
|
||||
draw_buffer = frame_buffer_t::make_render_texture(getWindowWidth(), getWindowHeight());
|
||||
}
|
||||
void pp_render_target_t::create()
|
||||
{
|
||||
draw_buffer = frame_buffer_t::make_render_texture(getWindowWidth(), getWindowHeight());
|
||||
}
|
||||
|
||||
void pp_render_target_t::draw()
|
||||
{
|
||||
draw_buffer.updateBuffersStorage(getWindowWidth(), getWindowHeight());
|
||||
GLenum buf[]{static_cast<GLenum>(frame_buffer_t::attachment_t::COLOR0)};
|
||||
glDrawBuffers(1, buf);
|
||||
}
|
||||
void pp_render_target_t::draw()
|
||||
{
|
||||
draw_buffer.updateBuffersStorage(getWindowWidth(), getWindowHeight());
|
||||
GLenum buf[]{static_cast<GLenum>(frame_buffer_t::attachment_t::COLOR0)};
|
||||
glDrawBuffers(1, buf);
|
||||
}
|
||||
|
||||
void pp_outline_target_t::create()
|
||||
{
|
||||
draw_buffer.create();
|
||||
draw_buffer.bind();
|
||||
void pp_outline_target_t::create()
|
||||
{
|
||||
draw_buffer.create();
|
||||
draw_buffer.bind();
|
||||
|
||||
auto* texture = new texture_gl2D(getWindowWidth(), getWindowHeight(), GL_RGBA8);
|
||||
draw_buffer.attachTexture(texture, frame_buffer_t::attachment_t::COLOR0);
|
||||
auto* texture = new texture_gl2D(getWindowWidth(), getWindowHeight(), GL_RGBA8);
|
||||
draw_buffer.attachTexture(texture, frame_buffer_t::attachment_t::COLOR0);
|
||||
|
||||
auto* mask = new texture_gl2D(getWindowWidth(), getWindowHeight(), GL_RGBA8);
|
||||
draw_buffer.attachTexture(mask, frame_buffer_t::attachment_t::COLOR1);
|
||||
auto* mask = new texture_gl2D(getWindowWidth(), getWindowHeight(), GL_RGBA8);
|
||||
draw_buffer.attachTexture(mask, frame_buffer_t::attachment_t::COLOR1);
|
||||
|
||||
render_buffer_t depth_rbo = render_buffer_t::make_render_buffer(GL_DEPTH24_STENCIL8, getWindowWidth(), getWindowHeight());
|
||||
draw_buffer.attachRenderBuffer(depth_rbo, frame_buffer_t::attachment_t::DEPTH_STENCIL);
|
||||
render_buffer_t depth_rbo = render_buffer_t::make_render_buffer(GL_DEPTH24_STENCIL8, getWindowWidth(), getWindowHeight());
|
||||
draw_buffer.attachRenderBuffer(depth_rbo, frame_buffer_t::attachment_t::DEPTH_STENCIL);
|
||||
|
||||
if (!frame_buffer_t::validate())
|
||||
BLT_ERROR("Failed to create render texture framebuffer!");
|
||||
frame_buffer_t::unbind();
|
||||
}
|
||||
if (!frame_buffer_t::validate())
|
||||
BLT_ERROR("Failed to create render texture framebuffer!");
|
||||
frame_buffer_t::unbind();
|
||||
}
|
||||
|
||||
void pp_outline_target_t::draw()
|
||||
{
|
||||
draw_buffer.updateBuffersStorage(getWindowWidth(), getWindowHeight());
|
||||
const GLenum buffers[]{static_cast<GLenum>(frame_buffer_t::attachment_t::COLOR0), static_cast<GLenum>(frame_buffer_t::attachment_t::COLOR1)};
|
||||
glDrawBuffers(2, buffers);
|
||||
}
|
||||
void pp_outline_target_t::draw()
|
||||
{
|
||||
draw_buffer.updateBuffersStorage(getWindowWidth(), getWindowHeight());
|
||||
const GLenum buffers[]{static_cast<GLenum>(frame_buffer_t::attachment_t::COLOR0), static_cast<GLenum>(frame_buffer_t::attachment_t::COLOR1)};
|
||||
glDrawBuffers(2, buffers);
|
||||
}
|
||||
|
||||
void pp_outline_step_t::create()
|
||||
{
|
||||
draw_buffer = frame_buffer_t::make_render_texture(getWindowHeight(), getWindowHeight());
|
||||
shader = pp_engine_t::createShader(shader_pp_outline_step_frag);
|
||||
shader->setInt("albedo", 0);
|
||||
shader->setInt("mask", 1);
|
||||
}
|
||||
void pp_outline_step_t::create()
|
||||
{
|
||||
draw_buffer = frame_buffer_t::make_render_texture(getWindowHeight(), getWindowHeight());
|
||||
shader = pp_engine_t::createShader(shader_pp_outline_step_frag);
|
||||
shader->setInt("albedo", 0);
|
||||
shader->setInt("mask", 1);
|
||||
}
|
||||
|
||||
void pp_outline_step_t::draw(frame_buffer_t& previous)
|
||||
{
|
||||
draw_buffer.updateBuffersStorage(getWindowWidth(), getWindowHeight());
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
previous.getTexture(frame_buffer_t::attachment_t::COLOR0).bind();
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
previous.getTexture(frame_buffer_t::attachment_t::COLOR1).bind();
|
||||
shader->bind();
|
||||
//auto v = vec2(getWindowWidth(), getWindowHeight()) * (1.0 / blt::make_vec2(manager.getScale2D()));
|
||||
//BLT_TRACE_STREAM << v << '\n';
|
||||
//shader->setVec2("viewportSize", static_cast<f32>(v.x()), static_cast<f32>(v.y()));
|
||||
GLenum buf[]{static_cast<GLenum>(frame_buffer_t::attachment_t::COLOR0)};
|
||||
glDrawBuffers(1, buf);
|
||||
}
|
||||
void pp_outline_step_t::draw(frame_buffer_t& previous)
|
||||
{
|
||||
draw_buffer.updateBuffersStorage(getWindowWidth(), getWindowHeight());
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
previous.getTexture(frame_buffer_t::attachment_t::COLOR0).bind();
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
previous.getTexture(frame_buffer_t::attachment_t::COLOR1).bind();
|
||||
shader->bind();
|
||||
//auto v = vec2(getWindowWidth(), getWindowHeight()) * (1.0 / blt::make_vec2(manager.getScale2D()));
|
||||
//BLT_TRACE_STREAM << v << '\n';
|
||||
//shader->setVec2("viewportSize", static_cast<f32>(v.x()), static_cast<f32>(v.y()));
|
||||
GLenum buf[]{static_cast<GLenum>(frame_buffer_t::attachment_t::COLOR0)};
|
||||
glDrawBuffers(1, buf);
|
||||
}
|
||||
|
||||
void pp_blur_step_inplace_t::create()
|
||||
{
|
||||
pp_in_place_t::create();
|
||||
shader = pp_engine_t::createShader(shader_gaussian_blur_frag);
|
||||
}
|
||||
void pp_blur_step_inplace_t::create()
|
||||
{
|
||||
pp_in_place_t::create();
|
||||
shader = pp_engine_t::createShader(shader_gaussian_blur_frag);
|
||||
}
|
||||
|
||||
void pp_blur_step_inplace_t::draw(frame_buffer_t& previous)
|
||||
{
|
||||
pp_in_place_t::draw(previous);
|
||||
shader->bind();
|
||||
//auto v = vec2(getWindowWidth(), getWindowHeight()) * (1.0 / blt::make_vec2(manager.getScale2D()));
|
||||
auto v = vec2(getWindowWidth(), getWindowHeight());
|
||||
shader->setVec4i("size", {static_cast<i32>(v.x()), static_cast<i32>(v.y()), x_blur, y_blur});
|
||||
}
|
||||
void pp_blur_step_inplace_t::draw(frame_buffer_t& previous)
|
||||
{
|
||||
pp_in_place_t::draw(previous);
|
||||
shader->bind();
|
||||
//auto v = vec2(getWindowWidth(), getWindowHeight()) * (1.0 / blt::make_vec2(manager.getScale2D()));
|
||||
auto v = vec2(getWindowWidth(), getWindowHeight());
|
||||
shader->setVec4i("size", {static_cast<i32>(v.x()), static_cast<i32>(v.y()), x_blur, y_blur});
|
||||
}
|
||||
|
||||
void pp_multiplier_step_inplace_t::create()
|
||||
{
|
||||
pp_in_place_t::create();
|
||||
shader = pp_engine_t::createShader(shader_multiplier_frag);
|
||||
}
|
||||
void pp_multiplier_step_inplace_t::create()
|
||||
{
|
||||
pp_in_place_t::create();
|
||||
shader = pp_engine_t::createShader(shader_multiplier_frag);
|
||||
}
|
||||
|
||||
void pp_multiplier_step_inplace_t::draw(frame_buffer_t& previous)
|
||||
{
|
||||
pp_in_place_t::draw(previous);
|
||||
shader->bind();
|
||||
shader->setVec4("multiplier", multiplier);
|
||||
}
|
||||
void pp_multiplier_step_inplace_t::draw(frame_buffer_t& previous)
|
||||
{
|
||||
pp_in_place_t::draw(previous);
|
||||
shader->bind();
|
||||
shader->setVec4("multiplier", multiplier);
|
||||
}
|
||||
|
||||
void pp_overlay_blur_step_t::create()
|
||||
{
|
||||
pp_in_place_t::create();
|
||||
shader = pp_engine_t::createShader(shader_overlay_blur_frag);
|
||||
}
|
||||
void pp_overlay_blur_step_t::create()
|
||||
{
|
||||
pp_in_place_t::create();
|
||||
shader = pp_engine_t::createShader(shader_overlay_blur_frag);
|
||||
}
|
||||
|
||||
void pp_overlay_blur_step_t::draw(frame_buffer_t& previous)
|
||||
{
|
||||
pp_in_place_t::draw(previous);
|
||||
shader->bind();
|
||||
auto v = vec2(getWindowWidth(), getWindowHeight());
|
||||
shader->setVec4i("size", {static_cast<i32>(v.x()), static_cast<i32>(v.y()), x_blur, y_blur});
|
||||
}
|
||||
void pp_overlay_blur_step_t::draw(frame_buffer_t& previous)
|
||||
{
|
||||
pp_in_place_t::draw(previous);
|
||||
shader->bind();
|
||||
auto v = vec2(getWindowWidth(), getWindowHeight());
|
||||
shader->setVec4i("size", {static_cast<i32>(v.x()), static_cast<i32>(v.y()), x_blur, y_blur});
|
||||
}
|
||||
|
||||
void pp_mouse_highlight_step_t::create()
|
||||
{
|
||||
pp_in_place_t::create();
|
||||
shader = pp_engine_t::createShader(shader_highlight_frag);
|
||||
}
|
||||
void pp_mouse_highlight_step_t::create()
|
||||
{
|
||||
pp_in_place_t::create();
|
||||
shader = pp_engine_t::createShader(shader_highlight_frag);
|
||||
}
|
||||
|
||||
void pp_mouse_highlight_step_t::draw(frame_buffer_t& previous)
|
||||
{
|
||||
pp_in_place_t::draw(previous);
|
||||
shader->bind();
|
||||
auto v = vec2(getWindowWidth(), getWindowHeight());
|
||||
shader->setVec4("mousePos", blt::make_vec4(blt::vec2{getMouseX(), v.y() - getMouseY()}));
|
||||
shader->setVec4i("size", {static_cast<i32>(v.x()), static_cast<i32>(v.y()), 4, 4});
|
||||
}
|
||||
void pp_mouse_highlight_step_t::draw(frame_buffer_t& previous)
|
||||
{
|
||||
pp_in_place_t::draw(previous);
|
||||
shader->bind();
|
||||
auto v = vec2(getWindowWidth(), getWindowHeight());
|
||||
shader->setVec4("mousePos", blt::make_vec4(blt::vec2{getMouseX(), v.y() - getMouseY()}));
|
||||
shader->setVec4i("size", {static_cast<i32>(v.x()), static_cast<i32>(v.y()), 4, 4});
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue