300 lines
8.7 KiB
C++
300 lines
8.7 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.hpp"
|
|
#include "texture.hpp"
|
|
#include "ubo.hpp"
|
|
|
|
#include <utility> //forward
|
|
#include <string>
|
|
|
|
#include "math/math.hpp"
|
|
|
|
namespace gfx::ogl{
|
|
|
|
using namespace math;
|
|
|
|
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;
|
|
math::vec2<GLfloat> get_vec2(void)const;
|
|
math::vec3<GLfloat> get_vec3(void)const;
|
|
math::vec4<GLfloat> get_vec4(void)const;
|
|
|
|
GLdouble get_double(void)const;
|
|
math::vec2<GLdouble> get_dvec2(void)const;
|
|
math::vec3<GLdouble> get_dvec3(void)const;
|
|
math::vec4<GLdouble> get_dvec4(void)const;
|
|
|
|
GLint get_int(void)const;
|
|
math::vec2<GLint> get_ivec2(void)const;
|
|
math::vec3<GLint> get_ivec3(void)const;
|
|
math::vec4<GLint> get_ivec4(void)const;
|
|
|
|
GLuint get_uint(void)const;
|
|
math::vec2<GLuint> get_uvec2(void)const;
|
|
math::vec3<GLuint> get_uvec3(void)const;
|
|
math::vec4<GLuint> get_uvec4(void)const;
|
|
|
|
GLboolean get_bool(void)const;
|
|
math::vec2<GLboolean> get_bvec2(void)const;
|
|
math::vec3<GLboolean> get_bvec3(void)const;
|
|
math::vec4<GLboolean> get_bvec4(void)const;
|
|
|
|
math::mat2<GLfloat> get_mat2(void)const;
|
|
math::mat3<GLfloat> get_mat3(void)const;
|
|
math::mat4<GLfloat> get_mat4(void)const;
|
|
math::matrix<GLfloat,2,3> get_mat2x3(void)const;
|
|
math::matrix<GLfloat,2,4> get_mat2x4(void)const;
|
|
math::matrix<GLfloat,3,2> get_mat3x2(void)const;
|
|
math::matrix<GLfloat,3,4> get_mat3x4(void)const;
|
|
math::matrix<GLfloat,4,2> get_mat4x2(void)const;
|
|
math::matrix<GLfloat,4,3> get_mat4x3(void)const;
|
|
|
|
math::mat2<GLdouble> get_dmat2(void)const;
|
|
math::mat3<GLdouble> get_dmat3(void)const;
|
|
math::mat4<GLdouble> get_dmat4(void)const;
|
|
math::matrix<GLdouble,2,3> get_dmat2x3(void)const;
|
|
math::matrix<GLdouble,2,4> get_dmat2x4(void)const;
|
|
math::matrix<GLdouble,3,2> get_dmat3x2(void)const;
|
|
math::matrix<GLdouble,3,4> get_dmat3x4(void)const;
|
|
math::matrix<GLdouble,4,2> get_dmat4x2(void)const;
|
|
math::matrix<GLdouble,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);
|
|
void set(const weak_texture&, GLuint tex_unit = 0);
|
|
|
|
//Float vectors
|
|
void set(const vec2<GLfloat>&);
|
|
void set(const vec3<GLfloat>&);
|
|
void set(const vec4<GLfloat>&);
|
|
|
|
//Float vector array
|
|
void set(GLsizei count, const vec2<GLfloat>*);
|
|
void set(GLsizei count, const vec3<GLfloat>*);
|
|
void set(GLsizei count, const vec4<GLfloat>*);
|
|
|
|
//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 vec2<GLint>&);
|
|
void set(const vec3<GLint>&);
|
|
void set(const vec4<GLint>&);
|
|
|
|
//Int vector array
|
|
void set(GLsizei count, const vec2<GLint>*);
|
|
void set(GLsizei count, const vec3<GLint>*);
|
|
void set(GLsizei count, const vec4<GLint>*);
|
|
|
|
//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 vec2<GLuint>&);
|
|
void set(const vec3<GLuint>&);
|
|
void set(const vec4<GLuint>&);
|
|
|
|
//Unsigned int vector array
|
|
void set(GLsizei count, const vec2<GLuint>*);
|
|
void set(GLsizei count, const vec3<GLuint>*);
|
|
void set(GLsizei count, const vec4<GLuint>*);
|
|
|
|
//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 mat2<GLfloat>&);
|
|
void set(const mat3<GLfloat>&);
|
|
void set(const mat4<GLfloat>&);
|
|
|
|
//Matrix array
|
|
void set(GLsizei count, const mat2<GLfloat>*);
|
|
void set(GLsizei count, const mat3<GLfloat>*);
|
|
void set(GLsizei count, const mat4<GLfloat>*);
|
|
|
|
//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& s);
|
|
//attach many shaders to this program
|
|
template<class... Args>
|
|
void attach_shaders(const shader& 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& 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
|