mirror of
https://github.com/RPCSX/rpcsx.git
synced 2026-01-04 15:50:10 +01:00
307 lines
6.4 KiB
C++
307 lines
6.4 KiB
C++
#pragma once
|
|
|
|
#include "common.h"
|
|
#include "buffer_object.h"
|
|
|
|
#include "Utilities/geometry.h"
|
|
|
|
namespace gl
|
|
{
|
|
class vao;
|
|
|
|
class buffer_pointer
|
|
{
|
|
public:
|
|
enum class type
|
|
{
|
|
s8 = GL_BYTE,
|
|
u8 = GL_UNSIGNED_BYTE,
|
|
s16 = GL_SHORT,
|
|
u16 = GL_UNSIGNED_SHORT,
|
|
s32 = GL_INT,
|
|
u32 = GL_UNSIGNED_INT,
|
|
f16 = GL_HALF_FLOAT,
|
|
f32 = GL_FLOAT,
|
|
f64 = GL_DOUBLE,
|
|
fixed = GL_FIXED,
|
|
s32_2_10_10_10_rev = GL_INT_2_10_10_10_REV,
|
|
u32_2_10_10_10_rev = GL_UNSIGNED_INT_2_10_10_10_REV,
|
|
u32_10f_11f_11f_rev = GL_UNSIGNED_INT_10F_11F_11F_REV
|
|
};
|
|
|
|
private:
|
|
vao* m_vao;
|
|
u32 m_offset;
|
|
u32 m_stride;
|
|
u32 m_size = 4;
|
|
type m_type = type::f32;
|
|
bool m_normalize = false;
|
|
|
|
public:
|
|
buffer_pointer(vao* vao, u32 offset = 0, u32 stride = 0)
|
|
: m_vao(vao)
|
|
, m_offset(offset)
|
|
, m_stride(stride)
|
|
{
|
|
}
|
|
|
|
const class ::gl::vao& get_vao() const
|
|
{
|
|
return *m_vao;
|
|
}
|
|
|
|
class ::gl::vao& get_vao()
|
|
{
|
|
return *m_vao;
|
|
}
|
|
|
|
buffer_pointer& offset(u32 value)
|
|
{
|
|
m_offset = value;
|
|
return *this;
|
|
}
|
|
|
|
u32 offset() const
|
|
{
|
|
return m_offset;
|
|
}
|
|
|
|
buffer_pointer& stride(u32 value)
|
|
{
|
|
m_stride = value;
|
|
return *this;
|
|
}
|
|
|
|
u32 stride() const
|
|
{
|
|
return m_stride;
|
|
}
|
|
|
|
buffer_pointer& size(u32 value)
|
|
{
|
|
m_size = value;
|
|
return *this;
|
|
}
|
|
|
|
u32 size() const
|
|
{
|
|
return m_size;
|
|
}
|
|
|
|
buffer_pointer& set_type(type value)
|
|
{
|
|
m_type = value;
|
|
return *this;
|
|
}
|
|
|
|
type get_type() const
|
|
{
|
|
return m_type;
|
|
}
|
|
|
|
buffer_pointer& normalize(bool value)
|
|
{
|
|
m_normalize = value;
|
|
return *this;
|
|
}
|
|
|
|
bool normalize() const
|
|
{
|
|
return m_normalize;
|
|
}
|
|
|
|
buffer_pointer& operator >> (u32 value)
|
|
{
|
|
return stride(value);
|
|
}
|
|
|
|
buffer_pointer& config(type type_ = type::f32, u32 size_ = 4, bool normalize_ = false)
|
|
{
|
|
return set_type(type_).size(size_).normalize(normalize_);
|
|
}
|
|
};
|
|
|
|
class attrib_t;
|
|
|
|
class vao
|
|
{
|
|
template<buffer::target BindId, uint GetStateId>
|
|
class entry
|
|
{
|
|
vao& m_parent;
|
|
|
|
public:
|
|
using save_binding_state = save_binding_state_base<entry, (static_cast<GLuint>(BindId)), GetStateId>;
|
|
|
|
entry(vao* parent) noexcept : m_parent(*parent)
|
|
{
|
|
}
|
|
|
|
entry& operator = (const buffer& buf) noexcept
|
|
{
|
|
m_parent.bind();
|
|
buf.bind(BindId);
|
|
|
|
return *this;
|
|
}
|
|
};
|
|
|
|
GLuint m_id = GL_NONE;
|
|
|
|
public:
|
|
entry<buffer::target::pixel_pack, GL_PIXEL_PACK_BUFFER_BINDING> pixel_pack_buffer{ this };
|
|
entry<buffer::target::pixel_unpack, GL_PIXEL_UNPACK_BUFFER_BINDING> pixel_unpack_buffer{ this };
|
|
entry<buffer::target::array, GL_ARRAY_BUFFER_BINDING> array_buffer{ this };
|
|
entry<buffer::target::element_array, GL_ELEMENT_ARRAY_BUFFER_BINDING> element_array_buffer{ this };
|
|
|
|
vao() = default;
|
|
vao(const vao&) = delete;
|
|
|
|
vao(vao&& vao_) noexcept
|
|
{
|
|
swap(vao_);
|
|
}
|
|
vao(GLuint id) noexcept
|
|
{
|
|
set_id(id);
|
|
}
|
|
|
|
~vao() noexcept
|
|
{
|
|
if (created())
|
|
remove();
|
|
}
|
|
|
|
void swap(vao& vao_) noexcept
|
|
{
|
|
auto my_old_id = id();
|
|
set_id(vao_.id());
|
|
vao_.set_id(my_old_id);
|
|
}
|
|
|
|
vao& operator = (const vao& rhs) = delete;
|
|
vao& operator = (vao&& rhs) noexcept
|
|
{
|
|
swap(rhs);
|
|
return *this;
|
|
}
|
|
|
|
void bind() const noexcept
|
|
{
|
|
glBindVertexArray(m_id);
|
|
}
|
|
|
|
void create() noexcept
|
|
{
|
|
glGenVertexArrays(1, &m_id);
|
|
}
|
|
|
|
void remove() noexcept
|
|
{
|
|
if (m_id != GL_NONE)
|
|
{
|
|
glDeleteVertexArrays(1, &m_id);
|
|
m_id = GL_NONE;
|
|
}
|
|
}
|
|
|
|
uint id() const noexcept
|
|
{
|
|
return m_id;
|
|
}
|
|
|
|
void set_id(uint id) noexcept
|
|
{
|
|
m_id = id;
|
|
}
|
|
|
|
bool created() const noexcept
|
|
{
|
|
return m_id != GL_NONE;
|
|
}
|
|
|
|
explicit operator bool() const noexcept
|
|
{
|
|
return created();
|
|
}
|
|
|
|
void enable_for_attributes(std::initializer_list<GLuint> indexes) noexcept
|
|
{
|
|
for (auto& index : indexes)
|
|
{
|
|
glEnableVertexAttribArray(index);
|
|
}
|
|
}
|
|
|
|
void disable_for_attributes(std::initializer_list<GLuint> indexes) noexcept
|
|
{
|
|
for (auto& index : indexes)
|
|
{
|
|
glDisableVertexAttribArray(index);
|
|
}
|
|
}
|
|
|
|
void enable_for_attribute(GLuint index) noexcept
|
|
{
|
|
enable_for_attributes({ index });
|
|
}
|
|
|
|
void disable_for_attribute(GLuint index) noexcept
|
|
{
|
|
disable_for_attributes({ index });
|
|
}
|
|
|
|
buffer_pointer operator + (u32 offset) noexcept
|
|
{
|
|
return{ this, offset };
|
|
}
|
|
|
|
buffer_pointer operator >> (u32 stride) noexcept
|
|
{
|
|
return{ this, {}, stride };
|
|
}
|
|
|
|
operator buffer_pointer() noexcept
|
|
{
|
|
return{ this };
|
|
}
|
|
|
|
attrib_t operator [] (u32 index) const noexcept;
|
|
};
|
|
|
|
class attrib_t
|
|
{
|
|
GLint m_location;
|
|
|
|
public:
|
|
attrib_t(GLint location)
|
|
: m_location(location)
|
|
{
|
|
}
|
|
|
|
GLint location() const
|
|
{
|
|
return m_location;
|
|
}
|
|
|
|
void operator = (float rhs) const { glDisableVertexAttribArray(location()); glVertexAttrib1f(location(), rhs); }
|
|
void operator = (double rhs) const { glDisableVertexAttribArray(location()); glVertexAttrib1d(location(), rhs); }
|
|
|
|
void operator = (const color1f& rhs) const { glDisableVertexAttribArray(location()); glVertexAttrib1f(location(), rhs.r); }
|
|
void operator = (const color1d& rhs) const { glDisableVertexAttribArray(location()); glVertexAttrib1d(location(), rhs.r); }
|
|
void operator = (const color2f& rhs) const { glDisableVertexAttribArray(location()); glVertexAttrib2f(location(), rhs.r, rhs.g); }
|
|
void operator = (const color2d& rhs) const { glDisableVertexAttribArray(location()); glVertexAttrib2d(location(), rhs.r, rhs.g); }
|
|
void operator = (const color3f& rhs) const { glDisableVertexAttribArray(location()); glVertexAttrib3f(location(), rhs.r, rhs.g, rhs.b); }
|
|
void operator = (const color3d& rhs) const { glDisableVertexAttribArray(location()); glVertexAttrib3d(location(), rhs.r, rhs.g, rhs.b); }
|
|
void operator = (const color4f& rhs) const { glDisableVertexAttribArray(location()); glVertexAttrib4f(location(), rhs.r, rhs.g, rhs.b, rhs.a); }
|
|
void operator = (const color4d& rhs) const { glDisableVertexAttribArray(location()); glVertexAttrib4d(location(), rhs.r, rhs.g, rhs.b, rhs.a); }
|
|
|
|
void operator = (buffer_pointer& pointer) const
|
|
{
|
|
pointer.get_vao().enable_for_attribute(m_location);
|
|
glVertexAttribPointer(location(), pointer.size(), static_cast<GLenum>(pointer.get_type()), pointer.normalize(),
|
|
pointer.stride(), reinterpret_cast<const void*>(u64{ pointer.offset() }));
|
|
}
|
|
};
|
|
}
|