love
parent
c4097f1c9b
commit
3bb0ca1193
|
@ -27,59 +27,111 @@
|
||||||
|
|
||||||
namespace blt::gfx
|
namespace blt::gfx
|
||||||
{
|
{
|
||||||
class shader_base {
|
class uniform_buffer
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
GLuint uboID;
|
||||||
|
size_t size_;
|
||||||
|
GLuint location_;
|
||||||
|
public:
|
||||||
|
uniform_buffer(size_t size, GLuint location = 0);
|
||||||
|
uniform_buffer(void* data, size_t size, GLuint location = 0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resizes the internal UBO
|
||||||
|
* @param newSize new size for the UBO
|
||||||
|
*/
|
||||||
|
uniform_buffer& resize(size_t newSize);
|
||||||
|
/**
|
||||||
|
* Uploads data to the UBO. This can be an arbitrary locations and does not need to be the whole UBO.
|
||||||
|
*/
|
||||||
|
uniform_buffer& upload(void* data, size_t size, size_t offset = 0);
|
||||||
|
/**
|
||||||
|
* Binds the UBO to a binding location
|
||||||
|
*/
|
||||||
|
uniform_buffer& bind(GLuint location);
|
||||||
|
|
||||||
|
~uniform_buffer();
|
||||||
|
|
||||||
|
[[nodiscard]] inline size_t size() const
|
||||||
|
{
|
||||||
|
return size_;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] inline GLuint location() const
|
||||||
|
{
|
||||||
|
return location_;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class shader_base
|
||||||
|
{
|
||||||
|
friend uniform_buffer;
|
||||||
protected:
|
protected:
|
||||||
struct IntDefaultedToMinusOne {
|
struct IntDefaultedToMinusOne
|
||||||
|
{
|
||||||
GLint i = -1;
|
GLint i = -1;
|
||||||
};
|
};
|
||||||
std::unordered_map<std::string, IntDefaultedToMinusOne> uniformVars;
|
std::unordered_map<std::string, IntDefaultedToMinusOne> uniformVars;
|
||||||
GLuint programID = 0;
|
GLuint programID = 0;
|
||||||
|
|
||||||
inline GLint getUniformLocation(const std::string &name) {
|
inline GLint getUniformLocation(const std::string& name)
|
||||||
|
{
|
||||||
if (uniformVars[name].i != -1)
|
if (uniformVars[name].i != -1)
|
||||||
return uniformVars[name].i;
|
return uniformVars[name].i;
|
||||||
int loc = glGetUniformLocation(programID, name.c_str());
|
int loc = glGetUniformLocation(programID, name.c_str());
|
||||||
uniformVars[name].i = loc;
|
uniformVars[name].i = loc;
|
||||||
return loc;
|
return loc;
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
inline void bind() const {
|
inline void bind() const
|
||||||
|
{
|
||||||
glUseProgram(programID);
|
glUseProgram(programID);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void setBool(const std::string &name, bool value) {
|
inline void setBool(const std::string& name, bool value)
|
||||||
|
{
|
||||||
glUniform1i(getUniformLocation(name), (int) value);
|
glUniform1i(getUniformLocation(name), (int) value);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void setInt(const std::string &name, int value) {
|
inline void setInt(const std::string& name, int value)
|
||||||
|
{
|
||||||
glUniform1i(getUniformLocation(name), value);
|
glUniform1i(getUniformLocation(name), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void setFloat(const std::string &name, float value) {
|
inline void setFloat(const std::string& name, float value)
|
||||||
|
{
|
||||||
glUniform1f(getUniformLocation(name), value);
|
glUniform1f(getUniformLocation(name), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void setMatrix(const std::string &name, blt::mat4x4 &matrix) {
|
inline void setMatrix(const std::string& name, blt::mat4x4& matrix)
|
||||||
|
{
|
||||||
glUniformMatrix4fv(getUniformLocation(name), 1, GL_FALSE, matrix.ptr());
|
glUniformMatrix4fv(getUniformLocation(name), 1, GL_FALSE, matrix.ptr());
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void setVec3(const std::string &name, const blt::vec3 &vec) {
|
inline void setVec3(const std::string& name, const blt::vec3& vec)
|
||||||
|
{
|
||||||
glUniform3f(getUniformLocation(name), vec.x(), vec.y(), vec.z());
|
glUniform3f(getUniformLocation(name), vec.x(), vec.y(), vec.z());
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void setVec4(const std::string &name, const blt::vec4 &vec) {
|
inline void setVec4(const std::string& name, const blt::vec4& vec)
|
||||||
|
{
|
||||||
glUniform4f(getUniformLocation(name), vec.x(), vec.y(), vec.z(), vec.w());
|
glUniform4f(getUniformLocation(name), vec.x(), vec.y(), vec.z(), vec.w());
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void setVec2(const std::string &name, float x, float y) {
|
inline void setVec2(const std::string& name, float x, float y)
|
||||||
|
{
|
||||||
glUniform2f(getUniformLocation(name), x, y);
|
glUniform2f(getUniformLocation(name), x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void setVec3(const std::string &name, float x, float y, float z) {
|
inline void setVec3(const std::string& name, float x, float y, float z)
|
||||||
|
{
|
||||||
glUniform3f(getUniformLocation(name), x, y, z);
|
glUniform3f(getUniformLocation(name), x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void setVec4(const std::string &name, float x, float y, float z, float w) {
|
inline void setVec4(const std::string& name, float x, float y, float z, float w)
|
||||||
|
{
|
||||||
glUniform4f(getUniformLocation(name), x, y, z, w);
|
glUniform4f(getUniformLocation(name), x, y, z, w);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -87,13 +139,15 @@ namespace blt::gfx
|
||||||
/**
|
/**
|
||||||
* a basic computer shader class, contains the functions and resources required to use compute shaders!
|
* a basic computer shader class, contains the functions and resources required to use compute shaders!
|
||||||
*/
|
*/
|
||||||
class compute_shader : public shader_base {
|
class compute_shader : public shader_base
|
||||||
|
{
|
||||||
private:
|
private:
|
||||||
GLuint shaderID = 0;
|
GLuint shaderID = 0;
|
||||||
public:
|
public:
|
||||||
explicit compute_shader(const std::string& shader_source, bool loadAsString = true);
|
explicit compute_shader(const std::string& shader_source, bool loadAsString = true);
|
||||||
|
|
||||||
inline void execute(int x, int y, int z) const {
|
inline void execute(int x, int y, int z) const
|
||||||
|
{
|
||||||
bind();
|
bind();
|
||||||
glDispatchCompute(x, y, z);
|
glDispatchCompute(x, y, z);
|
||||||
}
|
}
|
||||||
|
@ -101,18 +155,14 @@ namespace blt::gfx
|
||||||
~compute_shader();
|
~compute_shader();
|
||||||
};
|
};
|
||||||
|
|
||||||
class shader : public shader_base {
|
class shader : public shader_base
|
||||||
|
{
|
||||||
private:
|
private:
|
||||||
GLuint vertexShaderID = 0;
|
GLuint vertexShaderID = 0;
|
||||||
GLuint fragmentShaderID = 0;
|
GLuint fragmentShaderID = 0;
|
||||||
// while these will remain unused. (Webgl2 apparently doesn't support them despite being based on GL4.3? that's a TODO!)
|
|
||||||
GLuint geometryShaderID = 0;
|
|
||||||
// this would be very useful however it is highly unlikely webgl will support it
|
|
||||||
// im leaving some of this stuff in here because I might expand the native application to use some of it.
|
|
||||||
// im trying to keep the web and native versions the same though
|
|
||||||
GLuint tessellationShaderID = 0;
|
|
||||||
|
|
||||||
static unsigned int createShader(const std::string& source, int type);
|
static unsigned int createShader(const std::string& source, int type);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Creates a shader
|
* Creates a shader
|
||||||
|
@ -121,23 +171,17 @@ namespace blt::gfx
|
||||||
* @param geometry geometry shader source or file (optional)
|
* @param geometry geometry shader source or file (optional)
|
||||||
* @param load_as_string load the shader as a string (true) or use the string to load the shader as a file (false)
|
* @param load_as_string load the shader as a string (true) or use the string to load the shader as a file (false)
|
||||||
*/
|
*/
|
||||||
shader(const std::string &vertex, const std::string &fragment, const std::string &geometry = "", bool load_as_string = true);
|
shader(const std::string& vertex, const std::string& fragment, bool load_as_string = true);
|
||||||
|
|
||||||
shader(shader&& move) noexcept;
|
shader(shader&& move) noexcept;
|
||||||
|
|
||||||
// used to set the location of VAOs to the in variables in opengl shaders.
|
// used to set the location of VAOs to the in variables in opengl shaders.
|
||||||
void bindAttribute(int attribute, const std::string &name) const;
|
void bindAttribute(int attribute, const std::string& name) const;
|
||||||
|
|
||||||
// used to set location of shared UBOs like the perspective and view matrix
|
// used to set location of shared UBOs like the perspective and view matrix
|
||||||
void setUniformBlockLocation(const std::string &name, int location) const;
|
void setUniformBlockLocation(const std::string& name, int location) const;
|
||||||
|
|
||||||
~shader();
|
~shader();
|
||||||
|
|
||||||
static void updateProjectionMatrix(const blt::mat4x4& projectionMatrix);
|
|
||||||
static void updateOrthographicMatrix(const blt::mat4x4& orthoMatrix);
|
|
||||||
static void updateViewMatrix(const blt::mat4x4& viewMatrix);
|
|
||||||
// returns the perspective view matrix which is calculated per frame. (This is for optimization)
|
|
||||||
static const blt::mat4x4& getPVM();
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#pragma warning
|
||||||
|
#endif
|
||||||
/* stb_image_resize2 - v2.04 - public domain image resizing
|
/* stb_image_resize2 - v2.04 - public domain image resizing
|
||||||
|
|
||||||
by Jeff Roberts (v2) and Jorge L Rodriguez
|
by Jeff Roberts (v2) and Jorge L Rodriguez
|
||||||
|
@ -2876,12 +2879,12 @@ static float stbir__filter_mitchell(float x, float s, void * user_data)
|
||||||
return (0.0f);
|
return (0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
//static float stbir__support_zero(float s, void * user_data)
|
static float stbir__support_zero(float s, void * user_data)
|
||||||
//{
|
{
|
||||||
// STBIR__UNUSED(s);
|
STBIR__UNUSED(s);
|
||||||
// STBIR__UNUSED(user_data);
|
STBIR__UNUSED(user_data);
|
||||||
// return 0;
|
return 0;
|
||||||
//}
|
}
|
||||||
|
|
||||||
static float stbir__support_zeropoint5(float s, void * user_data)
|
static float stbir__support_zeropoint5(float s, void * user_data)
|
||||||
{
|
{
|
||||||
|
@ -8721,7 +8724,7 @@ static void STBIR__CODER_NAME( stbir__encode_uint8_srgb2_linearalpha )( void * o
|
||||||
unsigned char * end_output = ( (unsigned char*) output ) + width_times_channels;
|
unsigned char * end_output = ( (unsigned char*) output ) + width_times_channels;
|
||||||
|
|
||||||
#ifdef STBIR_SIMD
|
#ifdef STBIR_SIMD
|
||||||
stbir_uint32 const * to_srgb = fp32_to_srgb8_tab4 - (127-13)*8;
|
stbir_uint32 const* to_srgb = fp32_to_srgb8_tab4 - (127-13)*8;
|
||||||
|
|
||||||
if ( width_times_channels >= 16 )
|
if ( width_times_channels >= 16 )
|
||||||
{
|
{
|
||||||
|
|
|
@ -52,7 +52,7 @@ namespace blt::gfx
|
||||||
return m_data;
|
return m_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] inline unsigned char* data() const
|
[[nodiscard]] inline const unsigned char* data() const
|
||||||
{
|
{
|
||||||
return m_data;
|
return m_data;
|
||||||
}
|
}
|
||||||
|
|
10683
include/glad/gl.h
10683
include/glad/gl.h
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1 +1 @@
|
||||||
Subproject commit bc8134e3a2c69877ff008d84e81df3e06729d679
|
Subproject commit b135e5b915e0efaae2f8d9dc30d4752726b74bb4
|
|
@ -1 +1 @@
|
||||||
Subproject commit 0d582dabf34e9e31f072b1ee5c353c18351b4424
|
Subproject commit 4a2426449a4c65028c65c68ed9426495dec251e4
|
|
@ -68,37 +68,28 @@ namespace blt::gfx
|
||||||
return shaderID;
|
return shaderID;
|
||||||
}
|
}
|
||||||
|
|
||||||
shader::shader(const std::string& vertex, const std::string& fragment, const std::string& geometry, bool load_as_string) {
|
shader::shader(const std::string& vertex, const std::string& fragment, bool load_as_string) {
|
||||||
// load shader sources
|
// load shader sources
|
||||||
bool load_geometry = !geometry.empty();
|
|
||||||
std::string vertex_source = vertex;
|
std::string vertex_source = vertex;
|
||||||
std::string fragment_source = fragment;
|
std::string fragment_source = fragment;
|
||||||
std::string geometry_source = geometry;
|
|
||||||
if (!load_as_string){
|
if (!load_as_string){
|
||||||
// BLT provides a recursive file loader for glsl shaders. It's pretty much just a recursive function looking for include statements.
|
// BLT provides a recursive file loader for glsl shaders. It's pretty much just a recursive function looking for include statements.
|
||||||
vertex_source = blt::fs::loadShaderFile(vertex);
|
vertex_source = blt::fs::loadShaderFile(vertex);
|
||||||
fragment_source = blt::fs::loadShaderFile(fragment);
|
fragment_source = blt::fs::loadShaderFile(fragment);
|
||||||
if (load_geometry)
|
|
||||||
geometry_source = blt::fs::loadShaderFile(geometry);
|
|
||||||
} else {
|
} else {
|
||||||
vertex_source = removeEmptyFirstLines(vertex_source);
|
vertex_source = removeEmptyFirstLines(vertex_source);
|
||||||
fragment_source = removeEmptyFirstLines(fragment_source);
|
fragment_source = removeEmptyFirstLines(fragment_source);
|
||||||
geometry_source = removeEmptyFirstLines(geometry_source);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// create the shaders
|
// create the shaders
|
||||||
vertexShaderID = createShader(vertex_source, GL_VERTEX_SHADER);
|
vertexShaderID = createShader(vertex_source, GL_VERTEX_SHADER);
|
||||||
fragmentShaderID = createShader(fragment_source, GL_FRAGMENT_SHADER);
|
fragmentShaderID = createShader(fragment_source, GL_FRAGMENT_SHADER);
|
||||||
if (load_geometry)
|
|
||||||
geometryShaderID = createShader(geometry_source, GL_GEOMETRY_SHADER);
|
|
||||||
|
|
||||||
// bind them to a program
|
// bind them to a program
|
||||||
programID = glCreateProgram();
|
programID = glCreateProgram();
|
||||||
// attach the loaded shaders to the Shader program
|
// attach the loaded shaders to the Shader program
|
||||||
glAttachShader(programID, vertexShaderID);
|
glAttachShader(programID, vertexShaderID);
|
||||||
glAttachShader(programID, fragmentShaderID);
|
glAttachShader(programID, fragmentShaderID);
|
||||||
if (load_geometry)
|
|
||||||
glAttachShader(programID, geometryShaderID);
|
|
||||||
// link and make sure that our program is valid.
|
// link and make sure that our program is valid.
|
||||||
glLinkProgram(programID);
|
glLinkProgram(programID);
|
||||||
|
|
||||||
|
@ -116,7 +107,6 @@ namespace blt::gfx
|
||||||
BLT_ERROR("Unable to link program of ID: %d", programID);
|
BLT_ERROR("Unable to link program of ID: %d", programID);
|
||||||
BLT_ERROR(vertex_source);
|
BLT_ERROR(vertex_source);
|
||||||
BLT_ERROR(fragment_source);
|
BLT_ERROR(fragment_source);
|
||||||
BLT_ERROR(geometry_source);
|
|
||||||
BLT_ERROR("I have an log of %d length", log_length);
|
BLT_ERROR("I have an log of %d length", log_length);
|
||||||
BLT_ERROR(infoLog.data());
|
BLT_ERROR(infoLog.data());
|
||||||
BLT_ERROR("--- --- --- --- --- --- --- --- ---");
|
BLT_ERROR("--- --- --- --- --- --- --- --- ---");
|
||||||
|
@ -124,7 +114,7 @@ namespace blt::gfx
|
||||||
|
|
||||||
glValidateProgram(programID);
|
glValidateProgram(programID);
|
||||||
bind();
|
bind();
|
||||||
setUniformBlockLocation("StandardMatrices", 0);
|
setUniformBlockLocation("GlobalMatrices", 0);
|
||||||
glUseProgram(0);
|
glUseProgram(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,7 +125,11 @@ namespace blt::gfx
|
||||||
|
|
||||||
void shader::setUniformBlockLocation(const std::string &name, int location) const {
|
void shader::setUniformBlockLocation(const std::string &name, int location) const {
|
||||||
bind();
|
bind();
|
||||||
glUniformBlockBinding(programID, glGetUniformBlockIndex(programID, name.c_str()), location);
|
auto blockID = glGetUniformBlockIndex(programID, name.c_str());
|
||||||
|
if (blockID != GL_INVALID_INDEX)
|
||||||
|
glUniformBlockBinding(programID, blockID, location);
|
||||||
|
else
|
||||||
|
BLT_WARN("Unable to find uniform buffer '%s'. Did you forget to declare it?", name.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
shader::~shader() {
|
shader::~shader() {
|
||||||
|
@ -145,46 +139,54 @@ namespace blt::gfx
|
||||||
return;
|
return;
|
||||||
// remove all the shaders from the program
|
// remove all the shaders from the program
|
||||||
glDetachShader(programID, vertexShaderID);
|
glDetachShader(programID, vertexShaderID);
|
||||||
if (geometryShaderID)
|
|
||||||
glDetachShader(programID, geometryShaderID);
|
|
||||||
if (tessellationShaderID)
|
|
||||||
glDetachShader(programID, tessellationShaderID);
|
|
||||||
glDetachShader(programID, fragmentShaderID);
|
glDetachShader(programID, fragmentShaderID);
|
||||||
|
|
||||||
// delete the shaders
|
// delete the shaders
|
||||||
glDeleteShader(vertexShaderID);
|
glDeleteShader(vertexShaderID);
|
||||||
if (geometryShaderID)
|
|
||||||
glDeleteShader(geometryShaderID);
|
|
||||||
if (tessellationShaderID)
|
|
||||||
glDeleteShader(tessellationShaderID);
|
|
||||||
glDeleteShader(fragmentShaderID);
|
glDeleteShader(fragmentShaderID);
|
||||||
|
|
||||||
// delete the Shader program
|
// delete the Shader program
|
||||||
glDeleteProgram(programID);
|
glDeleteProgram(programID);
|
||||||
}
|
}
|
||||||
|
|
||||||
void shader::updateProjectionMatrix(const blt::mat4x4& projectionMatrix) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void shader::updateViewMatrix(const blt::mat4x4& viewMatrix) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void shader::updateOrthographicMatrix(const blt::mat4x4& orthoMatrix) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
shader::shader(shader&& move) noexcept {
|
shader::shader(shader&& move) noexcept {
|
||||||
// the move constructor doesn't need to construct a new shader but it does need to ensure all old variables are moved over
|
// the move constructor doesn't need to construct a new shader but it does need to ensure all old variables are moved over
|
||||||
programID = move.programID;
|
programID = move.programID;
|
||||||
vertexShaderID = move.vertexShaderID;
|
vertexShaderID = move.vertexShaderID;
|
||||||
fragmentShaderID = move.fragmentShaderID;
|
fragmentShaderID = move.fragmentShaderID;
|
||||||
geometryShaderID = move.geometryShaderID;
|
|
||||||
tessellationShaderID = move.tessellationShaderID;
|
|
||||||
for (const auto& pair : move.uniformVars)
|
for (const auto& pair : move.uniformVars)
|
||||||
uniformVars.insert(pair);
|
uniformVars.insert(pair);
|
||||||
// by setting the program ID to -1 we tell the shader it has been moved.
|
// by setting the program ID to -1 we tell the shader it has been moved.
|
||||||
move.programID = -1;
|
move.programID = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uniform_buffer::uniform_buffer(size_t size, GLuint location)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
uniform_buffer::uniform_buffer(void* data, size_t size, GLuint location)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
uniform_buffer& uniform_buffer::resize(size_t newSize)
|
||||||
|
{
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
uniform_buffer& uniform_buffer::upload(void* data, size_t size, size_t offset)
|
||||||
|
{
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
uniform_buffer& uniform_buffer::bind(GLuint location)
|
||||||
|
{
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
uniform_buffer::~uniform_buffer()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,14 @@
|
||||||
#define STB_PERLIN_IMPLEMENTATION
|
#define STB_PERLIN_IMPLEMENTATION
|
||||||
|
|
||||||
#include <blt/gfx/stb/stb_image_write.h>
|
#include <blt/gfx/stb/stb_image_write.h>
|
||||||
#include <blt/gfx/stb/stb_image_resize2.h>
|
#if defined(__GNUC__) || defined(__GNUG__)
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Warray-bounds"
|
||||||
|
#include <blt/gfx/stb/stb_image_resize2.h>
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
#else
|
||||||
|
#include <blt/gfx/stb/stb_image_resize2.h>
|
||||||
|
#endif
|
||||||
#include <blt/gfx/stb/stb_image.h>
|
#include <blt/gfx/stb/stb_image.h>
|
||||||
#include <blt/gfx/stb/stb_perlin.h>
|
#include <blt/gfx/stb/stb_perlin.h>
|
||||||
#include <blt/gfx/texture.h>
|
#include <blt/gfx/texture.h>
|
||||||
|
|
Loading…
Reference in New Issue