297 lines
8.3 KiB
C++
297 lines
8.3 KiB
C++
/**
|
|
This file is a part of our_dick
|
|
Copyright (C) 2020-2022 rexy712
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Affero General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#ifndef OUR_DICK_GRAPHICS_OGL_SHADER_PROGRAM_HPP
|
|
#define OUR_DICK_GRAPHICS_OGL_SHADER_PROGRAM_HPP
|
|
|
|
#include "gl_include.hpp"
|
|
#include "shader_stage.hpp"
|
|
#include "texture.hpp"
|
|
#include "ubo.hpp"
|
|
|
|
#include <utility> //forward
|
|
#include <string>
|
|
|
|
#include <rml/math.hpp>
|
|
|
|
namespace gfx::ogl{
|
|
|
|
class uniform
|
|
{
|
|
private:
|
|
GLuint m_shader_id;
|
|
GLint m_location;
|
|
|
|
public:
|
|
uniform(GLuint owner, const char* name);
|
|
uniform(GLuint owner, GLint location);
|
|
uniform(const uniform&) = default;
|
|
uniform(uniform&&) = default;
|
|
~uniform(void) = default;
|
|
|
|
uniform& operator=(const uniform&) = default;
|
|
uniform& operator=(uniform&&) = default;
|
|
|
|
GLenum get_type(void)const;
|
|
|
|
GLfloat get_float(void)const;
|
|
rml::vec2f get_vec2(void)const;
|
|
rml::vec3f get_vec3(void)const;
|
|
rml::vec4f get_vec4(void)const;
|
|
|
|
GLdouble get_double(void)const;
|
|
rml::vec2d get_dvec2(void)const;
|
|
rml::vec3d get_dvec3(void)const;
|
|
rml::vec4d get_dvec4(void)const;
|
|
|
|
GLint get_int(void)const;
|
|
rml::vec2i get_ivec2(void)const;
|
|
rml::vec3i get_ivec3(void)const;
|
|
rml::vec4i get_ivec4(void)const;
|
|
|
|
GLuint get_uint(void)const;
|
|
rml::vec2u get_uvec2(void)const;
|
|
rml::vec3u get_uvec3(void)const;
|
|
rml::vec4u get_uvec4(void)const;
|
|
|
|
GLboolean get_bool(void)const;
|
|
rml::vec2i get_bvec2(void)const;
|
|
rml::vec3i get_bvec3(void)const;
|
|
rml::vec4i get_bvec4(void)const;
|
|
|
|
rml::mat2f get_mat2(void)const;
|
|
rml::mat3f get_mat3(void)const;
|
|
rml::mat4f get_mat4(void)const;
|
|
rml::matrix<float,2,3> get_mat2x3(void)const;
|
|
rml::matrix<float,2,4> get_mat2x4(void)const;
|
|
rml::matrix<float,3,2> get_mat3x2(void)const;
|
|
rml::matrix<float,3,4> get_mat3x4(void)const;
|
|
rml::matrix<float,4,2> get_mat4x2(void)const;
|
|
rml::matrix<float,4,3> get_mat4x3(void)const;
|
|
|
|
rml::mat2d get_dmat2(void)const;
|
|
rml::mat3d get_dmat3(void)const;
|
|
rml::mat4d get_dmat4(void)const;
|
|
rml::matrix<double,2,3> get_dmat2x3(void)const;
|
|
rml::matrix<double,2,4> get_dmat2x4(void)const;
|
|
rml::matrix<double,3,2> get_dmat3x2(void)const;
|
|
rml::matrix<double,3,4> get_dmat3x4(void)const;
|
|
rml::matrix<double,4,2> get_dmat4x2(void)const;
|
|
rml::matrix<double,4,3> get_dmat4x3(void)const;
|
|
|
|
//float
|
|
void set(GLfloat);
|
|
void set(GLfloat, GLfloat);
|
|
void set(GLfloat, GLfloat, GLfloat);
|
|
void set(GLfloat, GLfloat, GLfloat, GLfloat);
|
|
|
|
//int
|
|
void set(GLint);
|
|
void set(GLint, GLint);
|
|
void set(GLint, GLint, GLint);
|
|
void set(GLint, GLint, GLint, GLint);
|
|
|
|
//unsigned int
|
|
void set(GLuint);
|
|
void set(GLuint, GLuint);
|
|
void set(GLuint, GLuint, GLuint);
|
|
void set(GLuint, GLuint, GLuint, GLuint);
|
|
|
|
//Texture
|
|
void set(const texture&, GLuint tex_unit = 0);
|
|
void set(const texture_array& t, GLuint tex_unit = 0);
|
|
|
|
//Float vectors
|
|
void set(const rml::vec2f&);
|
|
void set(const rml::vec3f&);
|
|
void set(const rml::vec4f&);
|
|
|
|
//Float vector array
|
|
void set(GLsizei count, const rml::vec2f*);
|
|
void set(GLsizei count, const rml::vec3f*);
|
|
void set(GLsizei count, const rml::vec4f*);
|
|
|
|
//Explicit float vectors
|
|
void set_1(GLsizei count, const GLfloat*);
|
|
void set_2(GLsizei count, const GLfloat*);
|
|
void set_3(GLsizei count, const GLfloat*);
|
|
void set_4(GLsizei count, const GLfloat*);
|
|
|
|
//Int vectors
|
|
void set(const rml::vec2i&);
|
|
void set(const rml::vec3i&);
|
|
void set(const rml::vec4i&);
|
|
|
|
//Int vector array
|
|
void set(GLsizei count, const rml::vec2i*);
|
|
void set(GLsizei count, const rml::vec3i*);
|
|
void set(GLsizei count, const rml::vec4i*);
|
|
|
|
//Explicit int vectors
|
|
void set_1(GLsizei count, const GLint*);
|
|
void set_2(GLsizei count, const GLint*);
|
|
void set_3(GLsizei count, const GLint*);
|
|
void set_4(GLsizei count, const GLint*);
|
|
|
|
//Unsigned int vectors
|
|
void set(const rml::vec2u&);
|
|
void set(const rml::vec3u&);
|
|
void set(const rml::vec4u&);
|
|
|
|
//Unsigned int vector array
|
|
void set(GLsizei count, const rml::vec2u*);
|
|
void set(GLsizei count, const rml::vec3u*);
|
|
void set(GLsizei count, const rml::vec4u*);
|
|
|
|
//Explicit unsigned int vectors
|
|
void set_1(GLsizei count, const GLuint*);
|
|
void set_2(GLsizei count, const GLuint*);
|
|
void set_3(GLsizei count, const GLuint*);
|
|
void set_4(GLsizei count, const GLuint*);
|
|
|
|
//Matrices
|
|
void set(const rml::mat2f&);
|
|
void set(const rml::mat3f&);
|
|
void set(const rml::mat4f&);
|
|
|
|
//Matrix array
|
|
void set(GLsizei count, const rml::mat2f*);
|
|
void set(GLsizei count, const rml::mat3f*);
|
|
void set(GLsizei count, const rml::mat4f*);
|
|
|
|
//Explicit matrices
|
|
void set_mat2(GLsizei count, const GLfloat*);
|
|
void set_mat3(GLsizei count, const GLfloat*);
|
|
void set_mat4(GLsizei count, const GLfloat*);
|
|
void set_mat2x3(GLsizei count, const GLfloat*);
|
|
void set_mat3x2(GLsizei count, const GLfloat*);
|
|
void set_mat2x4(GLsizei count, const GLfloat*);
|
|
void set_mat4x2(GLsizei count, const GLfloat*);
|
|
void set_mat3x4(GLsizei count, const GLfloat*);
|
|
void set_mat4x3(GLsizei count, const GLfloat*);
|
|
|
|
private:
|
|
GLint get_location_from_name_(const char* name);
|
|
};
|
|
|
|
class uniform_block
|
|
{
|
|
private:
|
|
GLuint m_shader_id;
|
|
GLuint m_index;
|
|
|
|
public:
|
|
uniform_block(GLuint owner, GLuint index);
|
|
uniform_block(GLuint owner, const char* name);
|
|
uniform_block(const uniform_block&) = default;
|
|
uniform_block(uniform_block&&) = default;
|
|
~uniform_block(void) = default;
|
|
|
|
uniform_block& operator=(const uniform_block&) = default;
|
|
uniform_block& operator=(uniform_block&&) = default;
|
|
|
|
void set_binding(size_t binding);
|
|
template<class... Types>
|
|
void set_binding(size_t binding, const ubo<Types...>& u);
|
|
|
|
private:
|
|
GLuint get_index_from_name_(const char* name);
|
|
};
|
|
|
|
//represents an opengl program (NOT a shader object)
|
|
class shader_program
|
|
{
|
|
private:
|
|
GLuint m_shader_id = 0; //handle to opengl program
|
|
|
|
public:
|
|
//create the program with no shaders attached
|
|
shader_program(void);
|
|
//create the program and attach 'args'... as shaders
|
|
template<class... Args>
|
|
shader_program(Args&&... args);
|
|
shader_program(const shader_program&) = delete;
|
|
shader_program(shader_program&&);
|
|
~shader_program(void);
|
|
|
|
shader_program& operator=(const shader_program&) = delete;
|
|
shader_program& operator=(shader_program&&);
|
|
|
|
//release ownership of the program handle. unsafe
|
|
GLuint release(void);
|
|
|
|
//attach a single shader to this program
|
|
void attach_shader(const shader_stage& s);
|
|
//attach many shaders to this program
|
|
template<class... Args>
|
|
void attach_shaders(const shader_stage& s, Args&&... args);
|
|
|
|
//attempt to link the program with the currently attached shaders. returns true on success
|
|
bool link(void);
|
|
|
|
//set this program as the currently active one in the gl context
|
|
void use(void);
|
|
|
|
//search for a uniform by name in this program
|
|
GLint get_uniform_loc(const char* u)const;
|
|
GLuint get_uniform_block_loc(const char* u)const;
|
|
|
|
//raw access to the program handle
|
|
GLuint raw(void)const;
|
|
|
|
//check if an error exists after a link attempt
|
|
bool has_link_error(void)const;
|
|
|
|
//get the most recently generated error from this program's infolog
|
|
std::string get_error(void)const;
|
|
|
|
uniform get_uniform(const char* name);
|
|
uniform get_uniform(int uloc);
|
|
|
|
GLenum get_uniform_type(const char* name)const;
|
|
GLenum get_uniform_type(int uloc)const;
|
|
|
|
uniform_block get_uniform_block(const char* name);
|
|
uniform_block get_uniform_block(unsigned int uloc);
|
|
};
|
|
|
|
template<class... Args>
|
|
shader_program::shader_program(Args&&... args):
|
|
shader_program()
|
|
{
|
|
attach_shaders(std::forward<Args>(args)...);
|
|
link();
|
|
}
|
|
template<class... Args>
|
|
void shader_program::attach_shaders(const shader_stage& s, Args&&... args){
|
|
attach_shader(s);
|
|
if constexpr(sizeof...(args) > 0){
|
|
attach_shaders(std::forward<Args>(args)...);
|
|
}
|
|
}
|
|
|
|
template<class... Types>
|
|
void uniform_block::set_binding(size_t binding, const ubo<Types...>& u){
|
|
u.bind(binding);
|
|
set_binding(binding);
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|