2016-02-07 22:32:38 +00:00
|
|
|
//
|
|
|
|
// Shader.hpp
|
|
|
|
// Clock Signal
|
|
|
|
//
|
|
|
|
// Created by Thomas Harte on 07/02/2016.
|
2018-05-13 19:19:52 +00:00
|
|
|
// Copyright 2016 Thomas Harte. All rights reserved.
|
2016-02-07 22:32:38 +00:00
|
|
|
//
|
|
|
|
|
2024-01-17 04:34:46 +00:00
|
|
|
#pragma once
|
2016-02-07 22:32:38 +00:00
|
|
|
|
2017-11-09 03:36:41 +00:00
|
|
|
#include "../OpenGL.hpp"
|
2017-11-24 23:45:24 +00:00
|
|
|
|
2016-05-14 22:06:55 +00:00
|
|
|
#include <functional>
|
2016-05-15 19:19:52 +00:00
|
|
|
#include <mutex>
|
2017-11-24 23:45:24 +00:00
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
2016-02-08 00:21:22 +00:00
|
|
|
|
2023-05-10 21:02:18 +00:00
|
|
|
namespace Outputs::Display::OpenGL {
|
2016-04-20 00:53:55 +00:00
|
|
|
|
|
|
|
/*!
|
|
|
|
A @c Shader compiles and holds a shader object, based on a single
|
|
|
|
vertex program and a single fragment program. Attribute bindings
|
|
|
|
may be supplied if desired.
|
|
|
|
*/
|
|
|
|
class Shader {
|
|
|
|
public:
|
|
|
|
enum {
|
|
|
|
VertexShaderCompilationError,
|
|
|
|
FragmentShaderCompilationError,
|
|
|
|
ProgramLinkageError
|
|
|
|
};
|
|
|
|
|
|
|
|
struct AttributeBinding {
|
2019-01-26 02:56:55 +00:00
|
|
|
AttributeBinding(const std::string &name, GLuint index) : name(name), index(index) {}
|
2017-11-24 23:45:24 +00:00
|
|
|
const std::string name;
|
2016-11-21 03:57:45 +00:00
|
|
|
const GLuint index;
|
2016-04-20 00:53:55 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Attempts to compile a shader, throwing @c VertexShaderCompilationError, @c FragmentShaderCompilationError or @c ProgramLinkageError upon failure.
|
|
|
|
@param vertex_shader The vertex shader source code.
|
|
|
|
@param fragment_shader The fragment shader source code.
|
2017-11-24 23:45:24 +00:00
|
|
|
@param attribute_bindings A vector of attribute bindings.
|
2016-04-20 00:53:55 +00:00
|
|
|
*/
|
2017-11-24 23:45:24 +00:00
|
|
|
Shader(const std::string &vertex_shader, const std::string &fragment_shader, const std::vector<AttributeBinding> &attribute_bindings = {});
|
2019-01-26 02:56:55 +00:00
|
|
|
/*!
|
|
|
|
Attempts to compile a shader, throwing @c VertexShaderCompilationError, @c FragmentShaderCompilationError or @c ProgramLinkageError upon failure.
|
|
|
|
@param vertex_shader The vertex shader source code.
|
|
|
|
@param fragment_shader The fragment shader source code.
|
2019-02-12 23:55:58 +00:00
|
|
|
@param binding_names A list of attributes to generate bindings for; these will be given indices 0, 1, 2 ... n-1.
|
2019-01-26 02:56:55 +00:00
|
|
|
*/
|
|
|
|
Shader(const std::string &vertex_shader, const std::string &fragment_shader, const std::vector<std::string> &binding_names);
|
2016-04-20 00:53:55 +00:00
|
|
|
~Shader();
|
|
|
|
|
|
|
|
/*!
|
2016-05-01 15:07:49 +00:00
|
|
|
Performs an @c glUseProgram to make this the active shader unless:
|
2017-11-08 03:54:22 +00:00
|
|
|
(i) it was the previous shader bound; and
|
2016-05-01 15:07:49 +00:00
|
|
|
(ii) no calls have been received to unbind in the interim.
|
2016-05-15 18:59:59 +00:00
|
|
|
|
|
|
|
Subsequently performs all work queued up for the next bind irrespective of whether a @c glUseProgram call occurred.
|
2016-04-20 00:53:55 +00:00
|
|
|
*/
|
2018-11-24 03:33:28 +00:00
|
|
|
void bind() const;
|
2016-04-20 00:53:55 +00:00
|
|
|
|
2016-05-01 15:07:49 +00:00
|
|
|
/*!
|
|
|
|
Unbinds the current instance of Shader, if one is bound.
|
|
|
|
*/
|
|
|
|
static void unbind();
|
|
|
|
|
2016-04-20 00:53:55 +00:00
|
|
|
/*!
|
|
|
|
Performs a @c glGetAttribLocation call.
|
|
|
|
@param name The name of the attribute to locate.
|
|
|
|
@returns The location of the requested attribute.
|
|
|
|
*/
|
2018-11-24 03:33:28 +00:00
|
|
|
GLint get_attrib_location(const std::string &name) const;
|
2016-04-20 00:53:55 +00:00
|
|
|
|
|
|
|
/*!
|
|
|
|
Performs a @c glGetUniformLocation call.
|
|
|
|
@param name The name of the uniform to locate.
|
|
|
|
@returns The location of the requested uniform.
|
|
|
|
*/
|
2018-11-24 03:33:28 +00:00
|
|
|
GLint get_uniform_location(const std::string &name) const;
|
2016-04-20 00:53:55 +00:00
|
|
|
|
2016-05-10 23:11:48 +00:00
|
|
|
/*!
|
|
|
|
Shorthand for an appropriate sequence of:
|
|
|
|
* @c get_attrib_location;
|
|
|
|
* @c glEnableVertexAttribArray;
|
|
|
|
* @c glVertexAttribPointer;
|
|
|
|
* @c glVertexAttribDivisor.
|
|
|
|
*/
|
2017-11-24 23:45:24 +00:00
|
|
|
void enable_vertex_attribute_with_pointer(const std::string &name, GLint size, GLenum type, GLboolean normalised, GLsizei stride, const GLvoid *pointer, GLuint divisor);
|
2016-04-20 00:53:55 +00:00
|
|
|
|
2016-05-14 02:08:32 +00:00
|
|
|
/*!
|
2016-05-14 22:06:55 +00:00
|
|
|
All @c set_uniforms queue up the requested uniform changes. Changes are applied automatically the next time the shader is bound.
|
2016-05-14 02:08:32 +00:00
|
|
|
*/
|
2016-05-14 22:06:55 +00:00
|
|
|
void set_uniform(const std::string &name, GLint value);
|
|
|
|
void set_uniform(const std::string &name, GLint value1, GLint value2);
|
|
|
|
void set_uniform(const std::string &name, GLint value1, GLint value2, GLint value3);
|
|
|
|
void set_uniform(const std::string &name, GLint value1, GLint value2, GLint value3, GLint value4);
|
|
|
|
void set_uniform(const std::string &name, GLint size, GLsizei count, const GLint *values);
|
|
|
|
|
|
|
|
void set_uniform(const std::string &name, GLfloat value);
|
|
|
|
void set_uniform(const std::string &name, GLfloat value1, GLfloat value2);
|
|
|
|
void set_uniform(const std::string &name, GLfloat value1, GLfloat value2, GLfloat value3);
|
|
|
|
void set_uniform(const std::string &name, GLfloat value1, GLfloat value2, GLfloat value3, GLfloat value4);
|
|
|
|
void set_uniform(const std::string &name, GLint size, GLsizei count, const GLfloat *values);
|
|
|
|
|
|
|
|
void set_uniform(const std::string &name, GLuint value);
|
|
|
|
void set_uniform(const std::string &name, GLuint value1, GLuint value2);
|
|
|
|
void set_uniform(const std::string &name, GLuint value1, GLuint value2, GLuint value3);
|
|
|
|
void set_uniform(const std::string &name, GLuint value1, GLuint value2, GLuint value3, GLuint value4);
|
|
|
|
void set_uniform(const std::string &name, GLint size, GLsizei count, const GLuint *values);
|
|
|
|
|
|
|
|
void set_uniform_matrix(const std::string &name, GLint size, bool transpose, const GLfloat *values);
|
|
|
|
void set_uniform_matrix(const std::string &name, GLint size, GLsizei count, bool transpose, const GLfloat *values);
|
2016-05-14 02:08:32 +00:00
|
|
|
|
2016-04-20 00:53:55 +00:00
|
|
|
private:
|
2019-01-26 02:56:55 +00:00
|
|
|
void init(const std::string &vertex_shader, const std::string &fragment_shader, const std::vector<AttributeBinding> &attribute_bindings);
|
|
|
|
|
2017-02-20 15:35:33 +00:00
|
|
|
GLuint compile_shader(const std::string &source, GLenum type);
|
2016-11-21 03:57:45 +00:00
|
|
|
GLuint shader_program_;
|
2016-05-14 02:08:32 +00:00
|
|
|
|
2018-11-24 03:33:28 +00:00
|
|
|
void flush_functions() const;
|
|
|
|
mutable std::vector<std::function<void(void)>> enqueued_functions_;
|
|
|
|
mutable std::mutex function_mutex_;
|
2016-05-15 18:59:59 +00:00
|
|
|
|
|
|
|
protected:
|
|
|
|
void enqueue_function(std::function<void(void)> function);
|
2016-04-20 00:53:55 +00:00
|
|
|
};
|
|
|
|
|
2016-02-07 22:32:38 +00:00
|
|
|
}
|