2023-12-17 20:39:01 -05:00
|
|
|
/*
|
|
|
|
* <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_SHADER_H
|
|
|
|
#define BLT_WITH_GRAPHICS_SHADER_H
|
|
|
|
|
|
|
|
#include <blt/gfx/gl_includes.h>
|
|
|
|
#include <vector>
|
|
|
|
#include <unordered_map>
|
|
|
|
#include <string>
|
|
|
|
#include <blt/math/math.h>
|
|
|
|
|
|
|
|
namespace blt::gfx
|
|
|
|
{
|
2023-12-26 15:14:24 -05:00
|
|
|
class uniform_buffer
|
|
|
|
{
|
|
|
|
private:
|
2023-12-29 12:19:45 -05:00
|
|
|
GLuint uboID = 0;
|
2023-12-26 15:14:24 -05:00
|
|
|
size_t size_;
|
|
|
|
GLuint location_;
|
|
|
|
public:
|
2023-12-27 01:10:53 -05:00
|
|
|
explicit uniform_buffer(size_t size, GLuint location = 0);
|
2023-12-29 12:19:45 -05:00
|
|
|
|
|
|
|
uniform_buffer(void* data, size_t size, GLuint location = 0);
|
2023-12-26 15:14:24 -05:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Resizes the internal UBO
|
|
|
|
* @param newSize new size for the UBO
|
|
|
|
*/
|
|
|
|
uniform_buffer& resize(size_t newSize);
|
2023-12-29 12:19:45 -05:00
|
|
|
|
2023-12-26 15:14:24 -05:00
|
|
|
/**
|
|
|
|
* 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);
|
2023-12-29 12:19:45 -05:00
|
|
|
|
|
|
|
uniform_buffer& bind();
|
|
|
|
|
|
|
|
inline uniform_buffer& unbind()
|
|
|
|
{
|
|
|
|
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
|
|
|
return *this;
|
|
|
|
}
|
2023-12-26 15:14:24 -05:00
|
|
|
|
|
|
|
~uniform_buffer();
|
|
|
|
|
|
|
|
[[nodiscard]] inline size_t size() const
|
|
|
|
{
|
|
|
|
return size_;
|
|
|
|
}
|
|
|
|
|
|
|
|
[[nodiscard]] inline GLuint location() const
|
|
|
|
{
|
|
|
|
return location_;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2023-12-28 16:14:12 -05:00
|
|
|
class shader_base_t
|
2023-12-26 15:14:24 -05:00
|
|
|
{
|
|
|
|
friend uniform_buffer;
|
2023-12-17 20:39:01 -05:00
|
|
|
protected:
|
2023-12-26 15:14:24 -05:00
|
|
|
struct IntDefaultedToMinusOne
|
|
|
|
{
|
2023-12-17 20:39:01 -05:00
|
|
|
GLint i = -1;
|
2023-12-29 12:34:35 -05:00
|
|
|
|
|
|
|
inline explicit operator bool() const
|
|
|
|
{
|
|
|
|
return i != -1;
|
|
|
|
}
|
2023-12-17 20:39:01 -05:00
|
|
|
};
|
2023-12-29 12:34:35 -05:00
|
|
|
|
2023-12-17 20:39:01 -05:00
|
|
|
std::unordered_map<std::string, IntDefaultedToMinusOne> uniformVars;
|
|
|
|
GLuint programID = 0;
|
|
|
|
|
2023-12-29 12:34:35 -05:00
|
|
|
IntDefaultedToMinusOne getUniformLocation(const std::string& name);
|
2023-12-26 15:14:24 -05:00
|
|
|
|
2023-12-17 20:39:01 -05:00
|
|
|
public:
|
2023-12-29 12:19:45 -05:00
|
|
|
inline const shader_base_t& bind() const
|
2023-12-26 15:14:24 -05:00
|
|
|
{
|
2023-12-17 20:39:01 -05:00
|
|
|
glUseProgram(programID);
|
2023-12-29 12:19:45 -05:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline shader_base_t& unbind()
|
|
|
|
{
|
|
|
|
glUseProgram(0);
|
|
|
|
return *this;
|
2023-12-17 20:39:01 -05:00
|
|
|
}
|
|
|
|
|
2023-12-29 12:34:35 -05:00
|
|
|
shader_base_t& setBool(const std::string& name, bool value);
|
2023-12-17 20:39:01 -05:00
|
|
|
|
2023-12-29 12:34:35 -05:00
|
|
|
shader_base_t& setInt(const std::string& name, int value);
|
2023-12-17 20:39:01 -05:00
|
|
|
|
2023-12-29 12:34:35 -05:00
|
|
|
shader_base_t& setFloat(const std::string& name, float value);
|
2023-12-17 20:39:01 -05:00
|
|
|
|
2023-12-29 12:34:35 -05:00
|
|
|
shader_base_t& setMatrix(const std::string& name, blt::mat4x4& matrix);
|
2024-01-11 14:36:48 -05:00
|
|
|
// poor solution: TODO
|
|
|
|
shader_base_t& setMatrix(const std::string& name, blt::mat4x4&& matrix);
|
2023-12-17 20:39:01 -05:00
|
|
|
|
2023-12-29 12:34:35 -05:00
|
|
|
shader_base_t& setVec2(const std::string& name, const blt::vec2& vec);
|
2023-12-17 20:39:01 -05:00
|
|
|
|
2023-12-29 12:34:35 -05:00
|
|
|
shader_base_t& setVec3(const std::string& name, const blt::vec3& vec);
|
2023-12-17 20:39:01 -05:00
|
|
|
|
2023-12-29 12:34:35 -05:00
|
|
|
shader_base_t& setVec4(const std::string& name, const blt::vec4& vec);
|
2023-12-17 20:39:01 -05:00
|
|
|
|
2023-12-29 12:34:35 -05:00
|
|
|
shader_base_t& setVec2(const std::string& name, float x, float y);
|
2023-12-17 20:39:01 -05:00
|
|
|
|
2023-12-29 12:34:35 -05:00
|
|
|
shader_base_t& setVec3(const std::string& name, float x, float y, float z);
|
|
|
|
|
|
|
|
shader_base_t& setVec4(const std::string& name, float x, float y, float z, float w);
|
2023-12-17 20:39:01 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* a basic computer shader class, contains the functions and resources required to use compute shaders!
|
|
|
|
*/
|
2023-12-28 16:14:12 -05:00
|
|
|
class compute_shader_t : public shader_base_t
|
2023-12-26 15:14:24 -05:00
|
|
|
{
|
2023-12-17 20:39:01 -05:00
|
|
|
private:
|
|
|
|
GLuint shaderID = 0;
|
|
|
|
public:
|
2023-12-28 16:14:12 -05:00
|
|
|
explicit compute_shader_t(const std::string& shader_source, bool loadAsString = true);
|
2023-12-17 20:39:01 -05:00
|
|
|
|
2023-12-26 15:14:24 -05:00
|
|
|
inline void execute(int x, int y, int z) const
|
|
|
|
{
|
2023-12-17 20:39:01 -05:00
|
|
|
bind();
|
|
|
|
glDispatchCompute(x, y, z);
|
|
|
|
}
|
|
|
|
|
2023-12-28 16:14:12 -05:00
|
|
|
~compute_shader_t();
|
2023-12-17 20:39:01 -05:00
|
|
|
};
|
|
|
|
|
2023-12-28 16:14:12 -05:00
|
|
|
class shader_t : public shader_base_t
|
2023-12-26 15:14:24 -05:00
|
|
|
{
|
2023-12-17 20:39:01 -05:00
|
|
|
private:
|
|
|
|
GLuint vertexShaderID = 0;
|
|
|
|
GLuint fragmentShaderID = 0;
|
|
|
|
|
|
|
|
static unsigned int createShader(const std::string& source, int type);
|
2023-12-26 15:14:24 -05:00
|
|
|
|
2023-12-17 20:39:01 -05:00
|
|
|
public:
|
|
|
|
/**
|
|
|
|
* Creates a shader
|
|
|
|
* @param vertex vertex shader source or file
|
|
|
|
* @param fragment fragment shader source or file
|
|
|
|
* @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)
|
|
|
|
*/
|
2023-12-28 16:14:12 -05:00
|
|
|
shader_t(const std::string& vertex, const std::string& fragment, bool load_as_string = true);
|
2023-12-17 20:39:01 -05:00
|
|
|
|
2023-12-28 16:14:12 -05:00
|
|
|
shader_t(shader_t&& move) noexcept;
|
2023-12-17 20:39:01 -05:00
|
|
|
|
|
|
|
// used to set the location of VAOs to the in variables in opengl shaders.
|
2023-12-26 15:14:24 -05:00
|
|
|
void bindAttribute(int attribute, const std::string& name) const;
|
2023-12-17 20:39:01 -05:00
|
|
|
|
|
|
|
// used to set location of shared UBOs like the perspective and view matrix
|
2023-12-26 15:14:24 -05:00
|
|
|
void setUniformBlockLocation(const std::string& name, int location) const;
|
2023-12-17 20:39:01 -05:00
|
|
|
|
2023-12-28 16:14:12 -05:00
|
|
|
~shader_t();
|
2023-12-17 20:39:01 -05:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif //BLT_WITH_GRAPHICS_SHADER_H
|