Josh Attempts Shaders
All checks were successful
Run ReCI Build Test / Explore-Gitea-Actions (push) Successful in 3m24s
All checks were successful
Run ReCI Build Test / Explore-Gitea-Actions (push) Successful in 3m24s
This commit is contained in:
@@ -1,5 +1,15 @@
|
||||
#version 120
|
||||
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif
|
||||
|
||||
uniform vec2 u_resolution;
|
||||
uniform float u_time;
|
||||
|
||||
void main() {
|
||||
gl_FragColor = vec4(1, 1, 1, 1);
|
||||
vec2 st = gl_FragCoord.xy/u_resolution;
|
||||
gl_FragColor = vec4(st.x,st.y,0.0,1.0);
|
||||
|
||||
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
|
||||
}
|
@@ -1,7 +1,5 @@
|
||||
#version 120
|
||||
|
||||
attribute vec2 position;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(position.x, position.y, 1.0, 1.0);
|
||||
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
|
||||
}
|
||||
|
77
include/JGL/types/Shader.h
Normal file
77
include/JGL/types/Shader.h
Normal file
@@ -0,0 +1,77 @@
|
||||
#pragma once
|
||||
|
||||
#include <filesystem>
|
||||
#include <J3ML/LinearAlgebra.hpp>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include "glad/glad.h"
|
||||
|
||||
// LearnOpenGL::Shader
|
||||
// OpenGL Shader Class Wrapper
|
||||
// Updated by dawsh
|
||||
// https://learnopengl.com/code_viewer_gh.php?code=includes/learnopengl/shader.h
|
||||
|
||||
namespace JGL {
|
||||
using namespace J3ML::LinearAlgebra;
|
||||
|
||||
class Shader;
|
||||
}
|
||||
|
||||
/// TODO: Eventually support Hot-reloading shaders like in shadertoy. Should help tremendously with debugging.
|
||||
|
||||
class JGL::Shader {
|
||||
public:
|
||||
Shader() {}
|
||||
Shader(std::filesystem::path vertex_source_path, std::filesystem::path fragment_source_path);
|
||||
|
||||
Shader(const std::string& vertex_code, const std::string& fragment_code);
|
||||
|
||||
bool Loaded() const;
|
||||
unsigned int ID() const;
|
||||
void Use();
|
||||
|
||||
|
||||
void Reload();
|
||||
void Unload();
|
||||
|
||||
template <typename T>
|
||||
void Set(const std::string& name, T value) const {
|
||||
// TODO: Throw error, no function-specialization: cannot pass shader uniform of type T.
|
||||
}
|
||||
template <typename T>
|
||||
void Set(const std::string& name, const T& value) const {
|
||||
// TODO: Throw error, no function-specialization: cannot pass shader uniform of type T.
|
||||
}
|
||||
|
||||
GLint Uniform(const std::string& name) const;
|
||||
GLint Attribute(const std::string& name) const;
|
||||
|
||||
/*template<> void Set<bool> (const std::string& name, bool value) const { SetBool(name, value); }
|
||||
template<> void Set<int> (const std::string& name, int value) const { SetInt(name, value); }
|
||||
template<> void Set<float>(const std::string& name, float value) const { SetFloat(name, value); }
|
||||
template<> void Set<Vector2>(const std::string& name, const Vector2& value) const { SetVector2(name, value); }
|
||||
template<> void Set<Vector3>(const std::string& name, const Vector3& value) const { SetVector3(name, value); }
|
||||
template<> void Set<Vector4>(const std::string& name, const Vector4& value) const { SetVector4(name, value); }*/
|
||||
|
||||
void SetBool (const std::string& name, bool value) const { glUniform1i(Uniform(name), (int)value); }
|
||||
void SetInt (const std::string& name, int value) const { glUniform1i(Uniform(name), value); }
|
||||
void SetFloat(const std::string& name, float value) const { glUniform1f(Uniform(name), value); }
|
||||
void SetVector2(const std::string& name, const Vector2& value) const { glUniform2f(Uniform(name), value.x, value.y); }
|
||||
void SetVector2(const std::string& name, float x, float y) const { glUniform2f(Uniform(name), x, y); }
|
||||
void SetVector3(const std::string& name, const Vector3& value) const { glUniform3f(Uniform(name), value.x, value.y, value.z); }
|
||||
void SetVector3(const std::string& name, float x, float y, float z) const { glUniform3f(Uniform(name), x, y, z); }
|
||||
void SetVector4(const std::string& name, const Vector4& value) const { glUniform4f(Uniform(name), value.x, value.y, value.z, value.w); }
|
||||
void SetVector4(const std::string& name, float x, float y, float z, float w) const { glUniform4f(Uniform(name), x, y, z, w); }
|
||||
|
||||
void SetMatrix2x2(const std::string& name, const Matrix2x2& value) const {}
|
||||
void SetMatrix3x3(const std::string& name, const Matrix3x3& value) const {}
|
||||
void SetMatrix4x4(const std::string& name, const Matrix4x4& value) const {}
|
||||
|
||||
protected:
|
||||
private:
|
||||
bool loaded;
|
||||
unsigned int id;
|
||||
std::string vertexPath;
|
||||
std::string fragmentPath;
|
||||
static void checkCompileErrors(GLuint shader, const std::string& type);
|
||||
};
|
18
main.cpp
18
main.cpp
@@ -7,6 +7,7 @@
|
||||
#include <J3ML/Geometry/AABB.hpp>
|
||||
#include <ReWindow/Logger.h>
|
||||
#include <JGL/types/VertexArray.h>
|
||||
#include <JGL/types/Shader.h>
|
||||
|
||||
using J3ML::LinearAlgebra::Vector2;
|
||||
using namespace JGL::Fonts;
|
||||
@@ -111,6 +112,8 @@ JGL::Font FreeSans;
|
||||
Texture* image;
|
||||
Texture* image_mask;
|
||||
RenderTarget* j2d_render_target;
|
||||
Shader shader;
|
||||
float u_time = 0;
|
||||
|
||||
class JGLDemoWindow : public ReWindow::OpenGLWindow
|
||||
{
|
||||
@@ -134,6 +137,8 @@ public:
|
||||
SampleRate::NONE, FilteringMode::MIPMAP_TRILINEAR);
|
||||
|
||||
//Texture::MultiplyByAlphaMask(*image, *image_mask);
|
||||
|
||||
shader = Shader(std::filesystem::path("assets/shader_programs/test_vertex.glsl"), std::filesystem::path("assets/shader_programs/test_fragment.glsl"));
|
||||
}
|
||||
|
||||
EulerAngleXYZ textAngle = {0,0,0};
|
||||
@@ -166,6 +171,8 @@ public:
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
|
||||
|
||||
|
||||
camera->render();
|
||||
// All 3D elements of the scene and JGL elements *must* be rendered before the 2D stuff
|
||||
/* if rendering to screen space directly. */
|
||||
@@ -223,6 +230,8 @@ public:
|
||||
d.Draw();
|
||||
J2D::End();
|
||||
|
||||
shader.Use();
|
||||
|
||||
J2D::Begin();
|
||||
J2D::DrawRenderTarget(j2d_render_target, {0, 0});
|
||||
J2D::DrawSprite(image, image_mask, {0, 0}, 0.25, {0.5, 0.5}, {1,1});
|
||||
@@ -232,6 +241,15 @@ public:
|
||||
|
||||
void OnRefresh(float elapsed) override {
|
||||
|
||||
u_time += elapsed;
|
||||
|
||||
shader.SetFloat("u_time", u_time);
|
||||
|
||||
auto dimensions = GetSize();
|
||||
|
||||
shader.SetVector2("u_resolution", Vector2(dimensions.x, dimensions.y));
|
||||
|
||||
|
||||
fps = GetRefreshRate();
|
||||
|
||||
if (IsKeyDown(Keys::RightArrow))
|
||||
|
@@ -15,6 +15,8 @@ namespace JGL {
|
||||
|
||||
class JGL::State {
|
||||
public:
|
||||
|
||||
//Matrix4x4 transformation = Matrix4x4::Identity;
|
||||
GLfloat clear_color[4] = {0, 0, 0, 1};
|
||||
GLfloat draw_color[4] = {1, 1, 1, 1};
|
||||
GLint viewport[4] = {0, 0, 0, 0};
|
||||
|
186
src/types/Shader.cpp
Normal file
186
src/types/Shader.cpp
Normal file
@@ -0,0 +1,186 @@
|
||||
#include <JGL/types/Shader.h>
|
||||
|
||||
#include <glad/glad.h>
|
||||
|
||||
namespace JGL {
|
||||
Shader::Shader(std::filesystem::path vertex_source_path, std::filesystem::path fragment_source_path) {
|
||||
std::string vertex_code;
|
||||
std::string fragment_code;
|
||||
std::string geometry_code; // Currently unused, might be supported later.
|
||||
std::string compute_code; // Currently unused, might be supported later.
|
||||
|
||||
std::ifstream vShaderFile;
|
||||
std::ifstream fShaderFile;
|
||||
std::ifstream gShaderFile;
|
||||
std::ifstream cShaderFile;
|
||||
|
||||
|
||||
vShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
|
||||
fShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
|
||||
gShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
|
||||
cShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
|
||||
|
||||
try {
|
||||
// Open Files
|
||||
vShaderFile.open(vertex_source_path);
|
||||
fShaderFile.open(fragment_source_path);
|
||||
|
||||
std::stringstream vShaderStream, fShaderStream;
|
||||
|
||||
// Read file's buffer contents into streams
|
||||
vShaderStream << vShaderFile.rdbuf();
|
||||
fShaderStream << fShaderFile.rdbuf();
|
||||
|
||||
// close file handlers
|
||||
vShaderFile.close();
|
||||
fShaderFile.close();
|
||||
|
||||
|
||||
// convert stream into string
|
||||
|
||||
vertex_code = vShaderStream.str();
|
||||
fragment_code = fShaderStream.str();
|
||||
|
||||
if (false) {
|
||||
gShaderFile.open("");
|
||||
std::stringstream gShaderStream;
|
||||
gShaderStream << gShaderFile.rdbuf();
|
||||
gShaderFile.close();
|
||||
geometry_code = gShaderStream.str();
|
||||
}
|
||||
} catch (std::ifstream::failure& e) {
|
||||
std::cout << "ERROR::SHADER::FILE_NOT_SUCCESSFULLY_READ: " << e.what() << std::endl;
|
||||
}
|
||||
|
||||
const char* vShaderCode = vertex_code.c_str();
|
||||
const char* fShaderCode = fragment_code.c_str();
|
||||
|
||||
// 2. Compile shaders.
|
||||
unsigned int vertex, fragment;
|
||||
|
||||
// vertex shader.
|
||||
vertex = glCreateShader(GL_VERTEX_SHADER);
|
||||
glShaderSource(vertex, 1, &vShaderCode, NULL);
|
||||
glCompileShader(vertex);
|
||||
checkCompileErrors(vertex, "VERTEX");
|
||||
|
||||
// fragment shader
|
||||
fragment = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
glShaderSource(fragment, 1, &fShaderCode, NULL);
|
||||
glCompileShader(fragment);
|
||||
checkCompileErrors(fragment, "FRAGMENT");
|
||||
|
||||
// if geometry shader is given, compile geometry shader.
|
||||
unsigned int geometry;
|
||||
if (false) {
|
||||
// const char* gShaderCode = geometry_code.c_str();
|
||||
// geometry = glCreateShader(GL_GEOMETRY_SHADER);
|
||||
// glShaderSource(geometry, 1 &gShaderCode, NULL);
|
||||
// glCompileShader(geometry);
|
||||
// checkCompileErrors(geometry, "GEOMETRY");
|
||||
}
|
||||
|
||||
// shader Program
|
||||
id = glCreateProgram();
|
||||
glAttachShader(id, vertex);
|
||||
glAttachShader(id, fragment);
|
||||
|
||||
if (false)
|
||||
glAttachShader(id, geometry);
|
||||
|
||||
glLinkProgram(id);
|
||||
checkCompileErrors(id, "PROGRAM");
|
||||
|
||||
// delete the shaders as they're linked into our program now and are no longer necessary
|
||||
glDeleteShader(vertex);
|
||||
glDeleteShader(fragment);
|
||||
if (false)
|
||||
glDeleteShader(geometry);
|
||||
|
||||
}
|
||||
|
||||
void Shader::checkCompileErrors(GLuint shader, const std::string& type) {
|
||||
GLint success;
|
||||
GLchar infoLog[1024];
|
||||
|
||||
if (type != "PROGRAM") {
|
||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
|
||||
if (!success) {
|
||||
glGetShaderInfoLog(shader, 1024, NULL, infoLog);
|
||||
std::cout << "ERROR::SHADER_COMPILATION_ERROR of " << type << "\n" << infoLog << std::endl;
|
||||
}
|
||||
} else {
|
||||
glGetProgramiv(shader, GL_LINK_STATUS, &success);
|
||||
if (!success) {
|
||||
glGetProgramInfoLog(shader, 1024, NULL, infoLog);
|
||||
std::cout << "ERROR::PROGRAM_LINKING_ERROR of " << type << "\n" << infoLog << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
if (success)
|
||||
std::cout << "Shader compiled successfully" << std::endl;
|
||||
}
|
||||
|
||||
GLint Shader::Uniform(const std::string &name) const {
|
||||
return glGetUniformLocation(id, name.c_str());
|
||||
}
|
||||
|
||||
GLint Shader::Attribute(const std::string &name) const {
|
||||
return glGetAttribLocation(id, name.c_str());
|
||||
}
|
||||
|
||||
Shader::Shader(const std::string &vertex_code, const std::string &fragment_code) {
|
||||
const char* vShaderCode = vertex_code.c_str();
|
||||
const char* fShaderCode = fragment_code.c_str();
|
||||
|
||||
// 2. Compile shaders.
|
||||
unsigned int vertex, fragment;
|
||||
|
||||
// vertex shader.
|
||||
vertex = glCreateShader(GL_VERTEX_SHADER);
|
||||
glShaderSource(vertex, 1, &vShaderCode, NULL);
|
||||
glCompileShader(vertex);
|
||||
checkCompileErrors(vertex, "VERTEX");
|
||||
|
||||
// fragment shader
|
||||
fragment = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
glShaderSource(fragment, 1, &fShaderCode, NULL);
|
||||
glCompileShader(fragment);
|
||||
checkCompileErrors(fragment, "FRAGMENT");
|
||||
|
||||
// if geometry shader is given, compile geometry shader.
|
||||
unsigned int geometry;
|
||||
if (false) {
|
||||
// const char* gShaderCode = geometry_code.c_str();
|
||||
// geometry = glCreateShader(GL_GEOMETRY_SHADER);
|
||||
// glShaderSource(geometry, 1 &gShaderCode, NULL);
|
||||
// glCompileShader(geometry);
|
||||
// checkCompileErrors(geometry, "GEOMETRY");
|
||||
}
|
||||
|
||||
// shader Program
|
||||
id = glCreateProgram();
|
||||
glAttachShader(id, vertex);
|
||||
glAttachShader(id, fragment);
|
||||
|
||||
if (false)
|
||||
glAttachShader(id, geometry);
|
||||
|
||||
glLinkProgram(id);
|
||||
checkCompileErrors(id, "PROGRAM");
|
||||
|
||||
// delete the shaders as they're linked into our program now and are no longer necessary
|
||||
glDeleteShader(vertex);
|
||||
glDeleteShader(fragment);
|
||||
if (false)
|
||||
glDeleteShader(geometry);
|
||||
}
|
||||
|
||||
void Shader::Use() {
|
||||
glUseProgram(id);
|
||||
}
|
||||
|
||||
bool Shader::Loaded() const { return loaded;}
|
||||
|
||||
unsigned int Shader::ID() const { return id;}
|
||||
}
|
Reference in New Issue
Block a user