More work on shader support.
Some checks failed
Run ReCI Build Test / Explore-Gitea-Actions (push) Failing after 1m24s
Some checks failed
Run ReCI Build Test / Explore-Gitea-Actions (push) Failing after 1m24s
This commit is contained in:
@@ -21,6 +21,7 @@
|
||||
#include <JGL/types/enums.h>
|
||||
#include <JGL/types/FontCache.h>
|
||||
#include <JGL/types/Font.h>
|
||||
#include <JGL/types/Shader.h>
|
||||
#include <J3ML/LinearAlgebra.hpp>
|
||||
#include <J3ML/LinearAlgebra/Vector2.hpp>
|
||||
#include <J3ML/LinearAlgebra/Vector3.hpp>
|
||||
@@ -72,6 +73,11 @@ namespace JGL {
|
||||
/// @see Begin().
|
||||
void End();
|
||||
|
||||
/// Sets the active shader program to be used for rendering.
|
||||
/// 0 for default shader (fixed-function rendering).
|
||||
void UseProgram(const Shader& shader);
|
||||
void UseProgram(unsigned int shader_program_handle);
|
||||
|
||||
/// Plots a single pixel on the screen.
|
||||
/// @param color A 3-or-4 channel color value. @see class Color3, class Color4
|
||||
/// @param coordinates The pixel-point on-screen at which to plot the pixel.
|
||||
|
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <J3ML/J3ML.hpp>
|
||||
#include <J3ML/LinearAlgebra.hpp>
|
||||
#include <glad/glad.h>
|
||||
|
||||
namespace JGL {
|
||||
@@ -11,8 +12,76 @@ namespace JGL {
|
||||
FRAGMENT = 1,
|
||||
COMBINED = 2,
|
||||
};
|
||||
|
||||
//You could definitely do this with Typename T.
|
||||
//Idk it increases the likelihood for mistakes.
|
||||
class Uniform;
|
||||
|
||||
class Uniform_Float;
|
||||
class Uniform_Int;
|
||||
class Uniform_Bool;
|
||||
|
||||
class Uniform_Vector2;
|
||||
class Uniform_Vector3;
|
||||
class Uniform_Vector4;
|
||||
|
||||
class Uniform_Matrix2x2;
|
||||
class Uniform_Matrix3x3;
|
||||
class Uniform_Matrix4x4;
|
||||
}
|
||||
|
||||
class JGL::Uniform {
|
||||
public:
|
||||
std::string name;
|
||||
GLint location = NULL;
|
||||
};
|
||||
|
||||
class JGL::Uniform_Float : public Uniform {
|
||||
public:
|
||||
float value = 0;
|
||||
};
|
||||
|
||||
class JGL::Uniform_Int : public Uniform {
|
||||
public:
|
||||
int value = 0;
|
||||
};
|
||||
|
||||
class JGL::Uniform_Bool : public Uniform {
|
||||
public:
|
||||
bool value = false;
|
||||
};
|
||||
|
||||
|
||||
class JGL::Uniform_Vector2 : public Uniform {
|
||||
public:
|
||||
Vector2 value;
|
||||
};
|
||||
|
||||
class JGL::Uniform_Vector3 : public Uniform {
|
||||
public:
|
||||
Vector3 value;
|
||||
};
|
||||
|
||||
class JGL::Uniform_Vector4 : public Uniform {
|
||||
public:
|
||||
Vector4 value;
|
||||
};
|
||||
|
||||
class JGL::Uniform_Matrix2x2 : public Uniform {
|
||||
public:
|
||||
Matrix2x2 value;
|
||||
};
|
||||
|
||||
class JGL::Uniform_Matrix3x3 : public Uniform {
|
||||
public:
|
||||
Matrix3x3 value;
|
||||
};
|
||||
|
||||
class JGL::Uniform_Matrix4x4 : public Uniform {
|
||||
public:
|
||||
Matrix4x4 value;
|
||||
};
|
||||
|
||||
class JGL::Shader {
|
||||
private:
|
||||
///Shader program.
|
||||
@@ -23,6 +92,24 @@ private:
|
||||
///Individual shaders which are compiled into the shader program.
|
||||
GLuint vertex_shader = 0;
|
||||
GLuint fragment_shader = 0;
|
||||
|
||||
/// Uniforms allow you to DMA values from the CPU to the GPU for this draw call.
|
||||
/// The Uniform will be the same for both the Vertex Shader & the Fragment Shader.
|
||||
std::vector<Uniform_Float> float_uniforms;
|
||||
std::vector<Uniform_Int> int_uniforms;
|
||||
std::vector<Uniform_Bool> bool_uniforms;
|
||||
|
||||
// TODO v2i, v3i, v4i
|
||||
std::vector<Uniform_Vector2> vector2_uniforms;
|
||||
std::vector<Uniform_Vector3> vector3_uniforms;
|
||||
std::vector<Uniform_Vector4> vector4_uniforms;
|
||||
|
||||
std::vector<Uniform_Matrix2x2> matrix2x2_uniforms;
|
||||
std::vector<Uniform_Matrix3x3> matrix3x3_uniforms;
|
||||
std::vector<Uniform_Matrix4x4> matrix4x4_uniforms;
|
||||
|
||||
/// Varyings allow you to pass values from the Vertex pass to the Fragment pass.
|
||||
/// They are defined in the shader source only.
|
||||
private:
|
||||
void load(const char* file_path, ShaderType type);
|
||||
void load(const std::string& shader_program_text, ShaderType type);
|
||||
@@ -30,11 +117,23 @@ private:
|
||||
public:
|
||||
[[nodiscard]] GLuint GetGLShaderProgramHandle() const;
|
||||
[[nodiscard]] ShaderType GetShaderType() const;
|
||||
void Erase() const;
|
||||
public:
|
||||
void SetFloat(const std::string& uniform_name, float value);
|
||||
void SetInt(const std::string& uniform_name, int value);
|
||||
void SetBool(const std::string& uniform_name, bool value);
|
||||
|
||||
void SetVector2(const std::string& uniform_name, const Vector2& value);
|
||||
void SetVector3(const std::string& uniform_name, const Vector3& value);
|
||||
void SetVector4(const std::string& uniform_name, const Vector4& value);
|
||||
|
||||
void SetMatrix2x2(const std::string& uniform_name, const Matrix2x2& value);
|
||||
void SetMatrix3x3(const std::string& uniform_name, const Matrix3x3& value);
|
||||
void SetMatrix4x4(const std::string& uniform_name, const Matrix4x4& value);
|
||||
|
||||
void ResetUniforms();
|
||||
public:
|
||||
Shader(const char* vertex_shader_file, const char* fragment_shader_file);
|
||||
Shader(const char* shader_file, ShaderType type);
|
||||
Shader(const std::string& vertex_shader_text, const std::string& fragment_shader_text);
|
||||
Shader(const std::string& shader_text, ShaderType type);
|
||||
void Erase() const;
|
||||
~Shader();
|
||||
};
|
@@ -96,6 +96,49 @@ void JGL::Shader::link() {
|
||||
|
||||
glLinkProgram(shader_program_handle);
|
||||
checkLinkingError(shader_program_handle);
|
||||
|
||||
GLint num_uniforms;
|
||||
glGetProgramiv(shader_program_handle, GL_ACTIVE_UNIFORMS, &num_uniforms);
|
||||
|
||||
//Set up the uniforms from the shader program after linking.
|
||||
//This is "Active" uniforms. So, If you have a uniform that never receives a value it won't be here iirc.
|
||||
for (GLint i = 0; i < num_uniforms; ++i) {
|
||||
char uniform_name[256];
|
||||
GLsizei length;
|
||||
GLint size;
|
||||
GLenum type;
|
||||
glGetActiveUniform(shader_program_handle, i, sizeof(uniform_name), &length, &size, &type, uniform_name);
|
||||
GLint location = glGetUniformLocation(shader_program_handle, uniform_name);
|
||||
|
||||
if (type == GL_FLOAT)
|
||||
float_uniforms.push_back(Uniform_Float({uniform_name, location}, 0));
|
||||
|
||||
else if (type == GL_INT)
|
||||
int_uniforms.push_back(Uniform_Int({uniform_name, location}, 0));
|
||||
|
||||
else if (type == GL_BOOL)
|
||||
bool_uniforms.push_back(Uniform_Bool({uniform_name, location}, false));
|
||||
|
||||
|
||||
else if (type == GL_FLOAT_VEC2)
|
||||
vector2_uniforms.push_back(Uniform_Vector2({uniform_name, location}, {0, 0}));
|
||||
|
||||
else if (type == GL_FLOAT_VEC3)
|
||||
vector3_uniforms.push_back(Uniform_Vector3({uniform_name, location}, {0, 0, 0}));
|
||||
|
||||
else if (type == GL_FLOAT_VEC4)
|
||||
vector4_uniforms.push_back(Uniform_Vector4({uniform_name, location}, {0, 0, 0, 0}));
|
||||
|
||||
|
||||
else if (type == GL_FLOAT_MAT2)
|
||||
matrix2x2_uniforms.push_back(Uniform_Matrix2x2({uniform_name, location}));
|
||||
|
||||
else if (type == GL_FLOAT_MAT3)
|
||||
matrix3x3_uniforms.push_back(Uniform_Matrix3x3({uniform_name, location}));
|
||||
|
||||
else if (type == GL_FLOAT_MAT4)
|
||||
matrix4x4_uniforms.push_back(Uniform_Matrix4x4({uniform_name, location}));
|
||||
}
|
||||
}
|
||||
|
||||
JGL::Shader::Shader(const char* vertex_shader_file, const char* fragment_shader_file) {
|
||||
@@ -105,12 +148,6 @@ JGL::Shader::Shader(const char* vertex_shader_file, const char* fragment_shader_
|
||||
link();
|
||||
}
|
||||
|
||||
JGL::Shader::Shader(const char* shader_file, const JGL::ShaderType type) {
|
||||
shader_type = type;
|
||||
load(shader_file, type);
|
||||
link();
|
||||
}
|
||||
|
||||
JGL::Shader::Shader(const std::string& vertex_shader_text, const std::string& fragment_shader_text) {
|
||||
shader_type = ShaderType::COMBINED;
|
||||
load(vertex_shader_text, ShaderType::VERTEX);
|
||||
@@ -118,12 +155,124 @@ JGL::Shader::Shader(const std::string& vertex_shader_text, const std::string& fr
|
||||
link();
|
||||
}
|
||||
|
||||
JGL::Shader::Shader(const std::string& shader_text, const JGL::ShaderType type) {
|
||||
shader_type = type;
|
||||
load(shader_text, type);
|
||||
link();
|
||||
void JGL::Shader::ResetUniforms() {
|
||||
for (auto& u : float_uniforms)
|
||||
u.value = 0;
|
||||
|
||||
for (auto& u : int_uniforms)
|
||||
u.value = 0;
|
||||
|
||||
for (auto& u : bool_uniforms)
|
||||
u.value = false;
|
||||
|
||||
|
||||
for (auto& u : vector2_uniforms)
|
||||
u.value = {0, 0};
|
||||
|
||||
for (auto& u : vector3_uniforms)
|
||||
u.value = {0, 0, 0};
|
||||
|
||||
for (auto& u : vector4_uniforms)
|
||||
u.value = {0, 0, 0, 0};
|
||||
|
||||
|
||||
for (auto& u : matrix2x2_uniforms)
|
||||
u.value = {};
|
||||
|
||||
for (auto& u : matrix3x3_uniforms)
|
||||
u.value = {};
|
||||
|
||||
for (auto& u : matrix4x4_uniforms)
|
||||
u.value = {0.0f};
|
||||
}
|
||||
|
||||
void JGL::Shader::SetFloat(const std::string& uniform_name, float value) {
|
||||
for (auto& u : float_uniforms) {
|
||||
if (u.name == uniform_name) {
|
||||
u.value = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void JGL::Shader::SetInt(const std::string& uniform_name, int value) {
|
||||
for (auto& u : int_uniforms) {
|
||||
if (u.name == uniform_name) {
|
||||
u.value = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void JGL::Shader::SetBool(const std::string& uniform_name, bool value) {
|
||||
for (auto& u : bool_uniforms) {
|
||||
if (u.name == uniform_name) {
|
||||
u.value = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void JGL::Shader::SetVector2(const std::string& uniform_name, const Vector2& value) {
|
||||
for (auto& u : vector2_uniforms) {
|
||||
if (u.name == uniform_name) {
|
||||
u.value = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void JGL::Shader::SetVector3(const std::string& uniform_name, const Vector3& value) {
|
||||
for (auto& u : vector3_uniforms) {
|
||||
if (u.name == uniform_name) {
|
||||
u.value = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void JGL::Shader::SetVector4(const std::string& uniform_name, const Vector4& value) {
|
||||
for (auto& u : vector4_uniforms) {
|
||||
if (u.name == uniform_name) {
|
||||
u.value = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void JGL::Shader::SetMatrix2x2(const std::string& uniform_name, const Matrix2x2& value) {
|
||||
for (auto& u : matrix2x2_uniforms) {
|
||||
if (u.name == uniform_name) {
|
||||
u.value = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void JGL::Shader::SetMatrix3x3(const std::string& uniform_name, const Matrix3x3& value) {
|
||||
for (auto& u : matrix3x3_uniforms) {
|
||||
if (u.name == uniform_name) {
|
||||
u.value = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void JGL::Shader::SetMatrix4x4(const std::string& uniform_name, const Matrix4x4& value) {
|
||||
for (auto& u : matrix4x4_uniforms) {
|
||||
if (u.name == uniform_name) {
|
||||
u.value = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user