Implement textures and add more stuff to Shader
This commit is contained in:
parent
79f5fba2ec
commit
97e1ce44cd
|
@ -4,8 +4,15 @@ in vec3 vs_position;
|
||||||
in vec3 vs_color;
|
in vec3 vs_color;
|
||||||
in vec2 vs_texcoord;
|
in vec2 vs_texcoord;
|
||||||
|
|
||||||
|
uniform bool texture_is_set;
|
||||||
|
uniform sampler2D vs_texture;
|
||||||
|
|
||||||
out vec4 fs_color;
|
out vec4 fs_color;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
fs_color = vec4(vs_color, 1.f);
|
if (texture_is_set) {
|
||||||
|
fs_color = texture(vs_texture, vs_texcoord) * vec4(vs_color, 1.0);
|
||||||
|
} else {
|
||||||
|
fs_color = vec4(vs_color, 1.0);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -11,7 +11,7 @@ out vec2 vs_texcoord;
|
||||||
void main() {
|
void main() {
|
||||||
vs_position = vertex_position;
|
vs_position = vertex_position;
|
||||||
vs_color = vertex_color;
|
vs_color = vertex_color;
|
||||||
vs_texcoord = vec2(vertex_texcoord.x, vertex_texcoord.y);
|
vs_texcoord = vertex_texcoord;
|
||||||
|
|
||||||
gl_Position = vec4(vertex_position, 1.f);
|
gl_Position = vec4(vertex_position, 1.f);
|
||||||
}
|
}
|
|
@ -3,8 +3,9 @@
|
||||||
// Github: https://github.com/SeanOMik
|
// Github: https://github.com/SeanOMik
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include "simpleengine/gfx/texture.h"
|
||||||
#include "simpleengine/shapes/2d/square.h"
|
#include "simpleengine/shapes/2d/square.h"
|
||||||
#include <simpleengine/shader.h>
|
#include <simpleengine/gfx/shader.h>
|
||||||
#include <simpleengine/renderable.h>
|
#include <simpleengine/renderable.h>
|
||||||
#include <simpleengine/event/event.h>
|
#include <simpleengine/event/event.h>
|
||||||
#include <simpleengine/shader_program.h>
|
#include <simpleengine/shader_program.h>
|
||||||
|
@ -20,6 +21,8 @@
|
||||||
#include <cmrc/cmrc.hpp>
|
#include <cmrc/cmrc.hpp>
|
||||||
CMRC_DECLARE(resource_shaders);
|
CMRC_DECLARE(resource_shaders);
|
||||||
|
|
||||||
|
#include <SOIL2/SOIL2.h>
|
||||||
|
|
||||||
std::string read_resource_shader(const std::string& path) {
|
std::string read_resource_shader(const std::string& path) {
|
||||||
auto fs = cmrc::resource_shaders::get_filesystem();
|
auto fs = cmrc::resource_shaders::get_filesystem();
|
||||||
cmrc::file vertex_file = fs.open(path);
|
cmrc::file vertex_file = fs.open(path);
|
||||||
|
@ -36,25 +39,29 @@ int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
// Create shader program
|
// Create shader program
|
||||||
simpleengine::ShaderProgram shader_prog;
|
simpleengine::ShaderProgram shader_prog;
|
||||||
shader_prog.add_shader_from_source(simpleengine::ShaderType::ST_Vertex, vertex_core);
|
shader_prog.add_shader_from_source(simpleengine::gfx::ShaderType::ST_Vertex, vertex_core);
|
||||||
shader_prog.add_shader_from_source(simpleengine::ShaderType::ST_Fragment, fragment_core);
|
shader_prog.add_shader_from_source(simpleengine::gfx::ShaderType::ST_Fragment, fragment_core);
|
||||||
shader_prog.link();
|
shader_prog.link();
|
||||||
std::shared_ptr<GLuint> base_shader_program = shader_prog.program;
|
std::shared_ptr<GLuint> base_shader_program = shader_prog.program;
|
||||||
|
|
||||||
|
simpleengine::Texture wall_texture("resources/wall.jpg");
|
||||||
|
simpleengine::Texture crate_texture("resources/container.jpg", true, true);
|
||||||
|
|
||||||
std::vector<simpleengine::Vertex> vertices = {
|
std::vector<simpleengine::Vertex> vertices = {
|
||||||
{glm::vec3(-0.5f, -0.5f, 0.f), glm::vec3(1.f, 0.f, 0.f), glm::vec2(0.f, 1.f)},
|
{glm::vec3(-0.5f, -0.5f, 0.f), glm::vec3(1.f, 0.f, 0.f), glm::vec2(0.f, 0.f)}, // bottom left
|
||||||
{glm::vec3(0.5f, -0.5f, 0.f), glm::vec3(0.f, 1.f, 0.f), glm::vec2(0.f, 0.f)},
|
{glm::vec3(0.5f, -0.5f, 0.f), glm::vec3(0.f, 1.f, 0.f), glm::vec2(1.f, 0.f)}, // bottom right
|
||||||
{glm::vec3(0.f, 0.5f, 0.f), glm::vec3(0.f, 0.f, 1.f), glm::vec2(1.f, 0.f)},
|
{glm::vec3(0.f, 0.5f, 0.f), glm::vec3(0.f, 0.f, 1.f), glm::vec2(0.5f, 1.0f)}, // top
|
||||||
};
|
};
|
||||||
|
|
||||||
std::shared_ptr<simpleengine::Event> tri(new simpleengine::shapes_2d::Triangle(base_shader_program, vertices));
|
std::shared_ptr<simpleengine::shapes_2d::Triangle> tri(new simpleengine::shapes_2d::Triangle(base_shader_program, vertices));
|
||||||
|
//tri->set_texture(wall_texture);
|
||||||
game.add_event(tri);
|
game.add_event(tri);
|
||||||
|
|
||||||
/* std::vector<simpleengine::Vertex> vertices = {
|
/* std::vector<simpleengine::Vertex> vertices = {
|
||||||
{ glm::vec3(0.5f, 0.5f, 0.f), glm::vec3(1.f, 0.f, 0.f), glm::vec2(0.f, 1.f) },
|
{ glm::vec3(0.5f, 0.5f, 0.f), glm::vec3(1.f, 0.f, 0.f), glm::vec2(1.f, 1.f) },
|
||||||
{ glm::vec3(0.5f, -0.5f, 0.f), glm::vec3(0.f, 1.f, 0.f), glm::vec2(0.f, 0.f) },
|
{ glm::vec3(0.5f, -0.5f, 0.f), glm::vec3(0.f, 1.f, 0.f), glm::vec2(1.f, 0.f) },
|
||||||
{ glm::vec3(-0.5f, -0.5f, 0.f), glm::vec3(0.f, 0.f, 1.f), glm::vec2(1.f, 0.f) },
|
{ glm::vec3(-0.5f, -0.5f, 0.f), glm::vec3(0.f, 0.f, 1.f), glm::vec2(0.f, 0.f) },
|
||||||
{ glm::vec3(-0.5f, 0.5f, 0.f), glm::vec3(0.75f, 0.75f, 0.75f), glm::vec2(1.f, 1.f) },
|
{ glm::vec3(-0.5f, 0.5f, 0.f), glm::vec3(1.f, 1.f, 0.f), glm::vec2(0.f, 1.f) },
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<GLuint> indicies = {
|
std::vector<GLuint> indicies = {
|
||||||
|
@ -62,7 +69,7 @@ int main(int argc, char *argv[]) {
|
||||||
1, 2, 3
|
1, 2, 3
|
||||||
};
|
};
|
||||||
|
|
||||||
std::shared_ptr<simpleengine::Event> square(new simpleengine::shapes_2d::Square(base_shader_program, vertices, indicies));
|
std::shared_ptr<simpleengine::Event> square(new simpleengine::shapes_2d::Square(base_shader_program, crate_texture, vertices, indicies));
|
||||||
game.add_event(square); */
|
game.add_event(square); */
|
||||||
|
|
||||||
return game.run();
|
return game.run();
|
||||||
|
|
|
@ -0,0 +1,202 @@
|
||||||
|
//
|
||||||
|
// Created by SeanOMik on 7/2/2020.
|
||||||
|
// Github: https://github.com/SeanOMik
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef SIMPLEENGINE_SHADER_H
|
||||||
|
#define SIMPLEENGINE_SHADER_H
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
#include <gl/glew.h>
|
||||||
|
#include <gl/gl.h>
|
||||||
|
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
|
#include "../event/event.h"
|
||||||
|
|
||||||
|
#include <exception>
|
||||||
|
#include <fstream>
|
||||||
|
#include <memory>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <string>
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
namespace simpleengine::gfx {
|
||||||
|
class ShaderException : public std::runtime_error {
|
||||||
|
public:
|
||||||
|
explicit ShaderException(char const* const msg) : std::runtime_error(msg) {
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ShaderType {
|
||||||
|
ST_Vertex = GL_VERTEX_SHADER,
|
||||||
|
ST_Fragment = GL_FRAGMENT_SHADER,
|
||||||
|
};
|
||||||
|
|
||||||
|
class Shader {
|
||||||
|
protected:
|
||||||
|
Shader() {
|
||||||
|
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
std::shared_ptr<GLuint> program;
|
||||||
|
GLuint shader;
|
||||||
|
|
||||||
|
Shader(std::shared_ptr<GLuint> program);
|
||||||
|
|
||||||
|
Shader(std::shared_ptr<GLuint> program, GLuint shader);
|
||||||
|
|
||||||
|
static Shader from_source(const ShaderType& type, std::string& shader_source);
|
||||||
|
|
||||||
|
static Shader from_source(std::shared_ptr<GLuint> program, const ShaderType& type, std::string& shader_source);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Load a shader from a filepath.
|
||||||
|
*
|
||||||
|
* @param type The type of the shader.
|
||||||
|
* @param shader_path The path of the shader source.
|
||||||
|
*/
|
||||||
|
static Shader from_filepath(const ShaderType& type, const std::string& shader_path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Load a shader from a filepath.
|
||||||
|
*
|
||||||
|
* @param program The shader program that this shader will be attached to.
|
||||||
|
* @param type The type of the shader.
|
||||||
|
* @param shader_path The path of shader source.
|
||||||
|
*/
|
||||||
|
static Shader from_filepath(std::shared_ptr<GLuint> program, const ShaderType& type, const std::string& shader_path);
|
||||||
|
|
||||||
|
virtual ~Shader();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Link the shader program and checks for errors.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void link();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Delete the shader with glDeleteShader. Only do this after we've linked.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void delete_shader();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Use the shader program.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void use() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Un-use the shader program by using the id of "0".
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static void unuse();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get a Uniform Float from the shader using a `location`.
|
||||||
|
*
|
||||||
|
* @param location The location of the uniform float.
|
||||||
|
* @return GLfloat The value of the uniform float from the shader.
|
||||||
|
*/
|
||||||
|
GLfloat getUniformFloat(GLint location) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get a Uniform Float from the shader finding the location of the uniform using `uniform_name`.
|
||||||
|
*
|
||||||
|
* @param uniform_name The name of the uniform inside of the shader.
|
||||||
|
* @return GLfloat The value of the uniform float from the shader.
|
||||||
|
*/
|
||||||
|
GLfloat getUniformFloat(const char* uniform_name) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get a Uniform integer from the shader using a `location`.
|
||||||
|
*
|
||||||
|
* @param location The location of the uniform integer.
|
||||||
|
* @return GLint The value of the uniform integer from the shader.
|
||||||
|
*/
|
||||||
|
GLint getUniformInt(GLint location) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get a Uniform integer from the shader finding the location of the uniform using `uniform_name`.
|
||||||
|
*
|
||||||
|
* @param uniform_name The name of the uniform inside of the shader.
|
||||||
|
* @return GLint The value of the uniform integer from the shader.
|
||||||
|
*/
|
||||||
|
GLint getUniformInt(const char* uniform_name) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get a Uniform unsigned integer from the shader using a `location`.
|
||||||
|
*
|
||||||
|
* @param location The location of the uniform unsigned integer.
|
||||||
|
* @return GLuint The value of the uniform unsigned integer from the shader.
|
||||||
|
*/
|
||||||
|
GLuint getUniformUInt(GLint location) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get a Uniform unsigned integer from the shader finding the location of the uniform using `uniform_name`.
|
||||||
|
*
|
||||||
|
* @param uniform_name The name of the uniform inside of the shader.
|
||||||
|
* @return GLuint The value of the uniform unsigned integer from the shader.
|
||||||
|
*/
|
||||||
|
GLuint getUniformUInt(const char* uniform_name) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get a Uniform double from the shader using a `location`.
|
||||||
|
*
|
||||||
|
* @param location The location of the uniform double.
|
||||||
|
* @return GLdouble The value of the uniform double from the shader.
|
||||||
|
*/
|
||||||
|
GLdouble getUniformDouble(GLint location) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get a Uniform double from the shader finding the location of the uniform using `uniform_name`.
|
||||||
|
*
|
||||||
|
* @param uniform_name The name of the uniform inside of the shader.
|
||||||
|
* @return GLdouble The value of the uniform double from the shader.
|
||||||
|
*/
|
||||||
|
GLdouble getUniformDouble(const char* uniform_name) const;
|
||||||
|
|
||||||
|
void setUniformFloat(GLint location, GLfloat fl, bool bind_shader = true);
|
||||||
|
void setUniformFloat(const char* uniform_name, GLfloat fl, bool bind_shader = true);
|
||||||
|
|
||||||
|
void setUniformFloatVec2(GLint location, glm::vec2 vec, bool bind_shader = true);
|
||||||
|
void setUniformFloatVec2(const char* uniform_name, glm::vec2 vec, bool bind_shader = true);
|
||||||
|
|
||||||
|
void setUniformFloatVec3(GLint location, glm::vec3 vec, bool bind_shader = true);
|
||||||
|
void setUniformFloatVec3(const char* uniform_name, glm::vec3 vec, bool bind_shader = true);
|
||||||
|
|
||||||
|
void setUniformFloatVec4(GLint location, glm::vec4 vec, bool bind_shader = true);
|
||||||
|
void setUniformFloatVec4(const char* uniform_name, glm::vec4 vec, bool bind_shader = true);
|
||||||
|
|
||||||
|
void setUniformInt(GLint location, GLint i, bool bind_shader = true);
|
||||||
|
void setUniformInt(const char* uniform_name, GLint i, bool bind_shader = true);
|
||||||
|
|
||||||
|
void setUniformIntVec2(GLint location, glm::ivec2 vec, bool bind_shader = true);
|
||||||
|
void setUniformIntVec2(const char* uniform_name, glm::ivec2 vec, bool bind_shader = true);
|
||||||
|
|
||||||
|
void setUniformIntVec3(GLint location, glm::ivec3 vec, bool bind_shader = true);
|
||||||
|
void setUniformIntVec3(const char* uniform_name, glm::ivec3 vec, bool bind_shader = true);
|
||||||
|
|
||||||
|
void setUniformIntVec4(GLint location, glm::ivec4 vec, bool bind_shader = true);
|
||||||
|
void setUniformIntVec4(const char* uniform_name, glm::ivec4 vec, bool bind_shader = true);
|
||||||
|
|
||||||
|
void setUniformUInt(GLint location, GLuint ui, bool bind_shader = true);
|
||||||
|
void setUniformUInt(const char* uniform_name, GLuint ui, bool bind_shader = true);
|
||||||
|
|
||||||
|
void setUniformUIntVec2(GLint location, glm::uvec2 vec, bool bind_shader = true);
|
||||||
|
void setUniformUIntVec2(const char* uniform_name, glm::uvec2 vec, bool bind_shader = true);
|
||||||
|
|
||||||
|
void setUniformUIntVec3(GLint location, glm::uvec3 vec, bool bind_shader = true);
|
||||||
|
void setUniformUIntVec3(const char* uniform_name, glm::uvec3 vec, bool bind_shader = true);
|
||||||
|
|
||||||
|
void setUniformUIntVec4(GLint location, glm::uvec4 vec, bool bind_shader = true);
|
||||||
|
void setUniformUIntVec4(const char* uniform_name, glm::uvec4 vec, bool bind_shader = true);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //SIMPLEENGINE_SHADER_H
|
|
@ -0,0 +1,139 @@
|
||||||
|
//
|
||||||
|
// Created by SeanOMik on 7/2/2020.
|
||||||
|
// Github: https://github.com/SeanOMik
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef SIMPLEENGINE_TEXTURE_H
|
||||||
|
#define SIMPLEENGINE_TEXTURE_H
|
||||||
|
|
||||||
|
#include <gl/glew.h>
|
||||||
|
#include <gl/gl.h>
|
||||||
|
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
|
#include <SOIL2/SOIL2.h>
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <vector>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
namespace simpleengine {
|
||||||
|
class Texture {
|
||||||
|
private:
|
||||||
|
unsigned char* img_data;
|
||||||
|
unsigned int texture_id;
|
||||||
|
|
||||||
|
unsigned int image_type;
|
||||||
|
public:
|
||||||
|
int height;
|
||||||
|
int width;
|
||||||
|
int channels;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Construct a new Texture object from a path.
|
||||||
|
*
|
||||||
|
* @param path The path of the image for the Texture.
|
||||||
|
* @param img_2d Whether or not the texture is 2D.
|
||||||
|
* @param mipmap Whether or not to generate mipmaps for this texture.
|
||||||
|
*/
|
||||||
|
Texture(const char* path, bool img_2d = true, bool mipmap = true) {
|
||||||
|
image_type = img_2d ? GL_TEXTURE_2D : GL_TEXTURE_3D;
|
||||||
|
|
||||||
|
glGenTextures(1, &texture_id);
|
||||||
|
bind();
|
||||||
|
|
||||||
|
glTexParameteri(image_type, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||||
|
glTexParameteri(image_type, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||||
|
glTexParameteri(image_type, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||||
|
glTexParameteri(image_type, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
|
||||||
|
img_data = SOIL_load_image
|
||||||
|
(
|
||||||
|
path,
|
||||||
|
&width, &height, &channels,
|
||||||
|
SOIL_LOAD_RGBA
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!img_data) {
|
||||||
|
std::cerr << "Failed to load texture from memory! (" << SOIL_last_result() << ")" << std::endl;
|
||||||
|
throw std::runtime_error("Failed to load texture from memory!");
|
||||||
|
}
|
||||||
|
|
||||||
|
glTexImage2D(image_type, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, img_data);
|
||||||
|
|
||||||
|
if (mipmap) {
|
||||||
|
glGenerateMipmap(image_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
SOIL_free_image_data(img_data);
|
||||||
|
glBindTexture(image_type, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Construct a new Texture object from the loaded file buffer.
|
||||||
|
*
|
||||||
|
* @param buffer The bytes of the loaded file.
|
||||||
|
* @param buffer_length The length of the buffer.
|
||||||
|
* @param img_2d Whether or not the texture is 2D.
|
||||||
|
* @param mipmap Whether or not to generate mipmaps for this texture.
|
||||||
|
*/
|
||||||
|
Texture(const unsigned char *const buffer, int buffer_length, bool img_2d = true, bool mipmap = true) {
|
||||||
|
image_type = img_2d ? GL_TEXTURE_2D : GL_TEXTURE_3D;
|
||||||
|
|
||||||
|
glGenTextures(1, &texture_id);
|
||||||
|
bind();
|
||||||
|
|
||||||
|
glTexParameteri(image_type, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||||
|
glTexParameteri(image_type, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||||
|
glTexParameteri(image_type, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||||
|
glTexParameteri(image_type, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
|
||||||
|
img_data = SOIL_load_image_from_memory
|
||||||
|
(
|
||||||
|
buffer, buffer_length,
|
||||||
|
&width, &height, &channels,
|
||||||
|
SOIL_LOAD_RGBA
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!img_data) {
|
||||||
|
std::cerr << "Failed to load texture from memory! (" << SOIL_last_result() << ")" << std::endl;
|
||||||
|
throw std::runtime_error("Failed to load texture from memory!");
|
||||||
|
}
|
||||||
|
|
||||||
|
glTexImage2D(image_type, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, img_data);
|
||||||
|
|
||||||
|
if (mipmap) {
|
||||||
|
glGenerateMipmap(image_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
SOIL_free_image_data(img_data);
|
||||||
|
glBindTexture(image_type, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Construct a new Texture object from the loaded file buffer.
|
||||||
|
*
|
||||||
|
* @param buffer The bytes of the loaded file.
|
||||||
|
* @param img_2d Whether or not the texture is 2D.
|
||||||
|
* @param mipmap Whether or not to generate mipmaps for this texture.
|
||||||
|
*/
|
||||||
|
Texture(std::vector<unsigned char> buffer, bool img_2d = true, bool mipmap = true) :
|
||||||
|
Texture(buffer.data(), buffer.size(), img_2d, mipmap) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ~Texture() {
|
||||||
|
if (img_data != nullptr) {
|
||||||
|
SOIL_free_image_data(img_data);
|
||||||
|
}
|
||||||
|
} */
|
||||||
|
|
||||||
|
void bind() const {
|
||||||
|
glBindTexture(image_type, texture_id);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -28,23 +28,12 @@ namespace simpleengine::gfx {
|
||||||
glDeleteVertexArrays(1, &handle);
|
glDeleteVertexArrays(1, &handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void bind() {
|
void bind() const {
|
||||||
glBindVertexArray(handle);
|
glBindVertexArray(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void attr(VBO vbo) {
|
|
||||||
bind();
|
|
||||||
vbo.bind();
|
|
||||||
|
|
||||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
|
|
||||||
glEnableVertexAttribArray(0);
|
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
||||||
glBindVertexArray(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Fix this.
|
// TODO: Fix this.
|
||||||
void enable_attrib(VBO vbo, GLuint index, GLint size, GLenum type, GLsizei stride, size_t offset) {
|
void enable_attrib(const VBO& vbo, GLuint index, GLint size, GLenum type, GLsizei stride, size_t offset) const {
|
||||||
bind();
|
bind();
|
||||||
vbo.bind();
|
vbo.bind();
|
||||||
|
|
||||||
|
@ -63,7 +52,7 @@ namespace simpleengine::gfx {
|
||||||
glVertexAttribIPointer(index, size, type, stride, (void *) offset);
|
glVertexAttribIPointer(index, size, type, stride, (void *) offset);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
glVertexAttribPointer(index, size, type, GL_FALSE, stride, (void *) 0);
|
glVertexAttribPointer(index, size, type, GL_FALSE, stride, (void *) offset);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
glEnableVertexAttribArray(index);
|
glEnableVertexAttribArray(index);
|
||||||
|
|
|
@ -28,7 +28,7 @@ namespace simpleengine::gfx {
|
||||||
glDeleteBuffers(1, &handle);
|
glDeleteBuffers(1, &handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void bind() {
|
void bind() const {
|
||||||
glBindBuffer(type, handle);
|
glBindBuffer(type, handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,166 +0,0 @@
|
||||||
//
|
|
||||||
// Created by SeanOMik on 7/2/2020.
|
|
||||||
// Github: https://github.com/SeanOMik
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef SIMPLEENGINE_SHADER_H
|
|
||||||
#define SIMPLEENGINE_SHADER_H
|
|
||||||
|
|
||||||
#include <gl/glew.h>
|
|
||||||
#include <gl/gl.h>
|
|
||||||
|
|
||||||
#include <GLFW/glfw3.h>
|
|
||||||
|
|
||||||
#include "event/event.h"
|
|
||||||
|
|
||||||
#include <exception>
|
|
||||||
#include <fstream>
|
|
||||||
#include <gl/gl.h>
|
|
||||||
#include <memory>
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <string>
|
|
||||||
#include <iostream>
|
|
||||||
#include <sstream>
|
|
||||||
|
|
||||||
namespace simpleengine {
|
|
||||||
class ShaderException : public std::runtime_error {
|
|
||||||
public:
|
|
||||||
explicit ShaderException(char const* const msg) : std::runtime_error(msg) {
|
|
||||||
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
enum ShaderType {
|
|
||||||
ST_Vertex = GL_VERTEX_SHADER,
|
|
||||||
ST_Fragment = GL_FRAGMENT_SHADER,
|
|
||||||
};
|
|
||||||
|
|
||||||
class Shader : public simpleengine::Event {
|
|
||||||
private:
|
|
||||||
using super = simpleengine::Event;
|
|
||||||
protected:
|
|
||||||
Shader() {
|
|
||||||
|
|
||||||
}
|
|
||||||
public:
|
|
||||||
static Shader from_source(const ShaderType& type, std::string& shader_source) {
|
|
||||||
Shader shd = Shader::from_source(std::make_shared<GLuint>(glCreateProgram()), type, shader_source);
|
|
||||||
|
|
||||||
shd.link();
|
|
||||||
shd.delete_shader();
|
|
||||||
|
|
||||||
return shd;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Shader from_source(std::shared_ptr<GLuint> program, const ShaderType& type, std::string& shader_source) {
|
|
||||||
Shader shd;
|
|
||||||
shd.program = program;
|
|
||||||
shd.shader = glCreateShader(type);
|
|
||||||
|
|
||||||
const GLchar* vert_src = shader_source.c_str();
|
|
||||||
glShaderSource(shd.shader, 1, &vert_src, NULL);
|
|
||||||
glCompileShader(shd.shader);
|
|
||||||
|
|
||||||
GLint success = false;
|
|
||||||
glGetShaderiv(shd.shader, GL_COMPILE_STATUS, &success);
|
|
||||||
|
|
||||||
if (!success) {
|
|
||||||
char log[512];
|
|
||||||
glGetShaderInfoLog(shd.shader, 512, NULL, log);
|
|
||||||
|
|
||||||
std::cerr << "Failed to load shader from source:" << std::endl << log << std::endl;
|
|
||||||
throw ShaderException("Failed to compile shader!");
|
|
||||||
}
|
|
||||||
|
|
||||||
glAttachShader(*shd.program, shd.shader);
|
|
||||||
|
|
||||||
return shd;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Load a shader from a filepath.
|
|
||||||
*
|
|
||||||
* @param type The type of the shader.
|
|
||||||
* @param shader_path The path of the shader source.
|
|
||||||
*/
|
|
||||||
static Shader from_filepath(const ShaderType& type, const std::string& shader_path) {
|
|
||||||
Shader shd = Shader::from_filepath(std::make_shared<GLuint>(glCreateProgram()), type, shader_path);
|
|
||||||
|
|
||||||
shd.link();
|
|
||||||
shd.delete_shader();
|
|
||||||
|
|
||||||
return shd;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Load a shader from a filepath.
|
|
||||||
*
|
|
||||||
* @param program The shader program that this shader will be attached to.
|
|
||||||
* @param type The type of the shader.
|
|
||||||
* @param shader_path The path of shader source.
|
|
||||||
*/
|
|
||||||
static Shader from_filepath(std::shared_ptr<GLuint> program, const ShaderType& type,
|
|
||||||
const std::string& shader_path) {
|
|
||||||
std::ifstream fstream(shader_path, std::ios::in);
|
|
||||||
|
|
||||||
if (!fstream.is_open()) {
|
|
||||||
std::cerr << "Failed to open shader file: " << shader_path << std::endl;
|
|
||||||
throw ShaderException("Failed to open shader file!");
|
|
||||||
}
|
|
||||||
|
|
||||||
std::stringstream ss;
|
|
||||||
{
|
|
||||||
std::string str;
|
|
||||||
while (std::getline(fstream, str))
|
|
||||||
{
|
|
||||||
ss << str << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
std::string ss_str = ss.str();
|
|
||||||
|
|
||||||
return Shader::from_source(type, ss_str);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~Shader() {
|
|
||||||
delete_shader();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Link the shader program and checks for errors.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void link() {
|
|
||||||
glLinkProgram(*program);
|
|
||||||
|
|
||||||
GLint success = false;
|
|
||||||
glGetProgramiv(*program, GL_LINK_STATUS, &success);
|
|
||||||
|
|
||||||
if (!success) {
|
|
||||||
std::cerr << "Failed to link shader program!" << std::endl;
|
|
||||||
throw ShaderException("Failed to link shader program!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Delete the shader with glDeleteShader. Only do this after we've linked.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void delete_shader() {
|
|
||||||
glDeleteShader(shader);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void update(const float& delta_time) override {
|
|
||||||
//super::update(delta_time);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void render(std::shared_ptr<GLFWwindow> target) override {
|
|
||||||
//super::render(target);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<GLuint> program;
|
|
||||||
private:
|
|
||||||
GLuint shader;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif //SIMPLEENGINE_SHADER_H
|
|
|
@ -12,7 +12,7 @@
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
#include "event/event.h"
|
#include "event/event.h"
|
||||||
#include "shader.h"
|
#include "gfx/shader.h"
|
||||||
|
|
||||||
#include <exception>
|
#include <exception>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
@ -38,11 +38,11 @@ namespace simpleengine {
|
||||||
/**
|
/**
|
||||||
* @brief Add a shader to this shader program. Also checks that its using the same `program` as this.
|
* @brief Add a shader to this shader program. Also checks that its using the same `program` as this.
|
||||||
*
|
*
|
||||||
* @see ShaderProgram::add_shader(const ShaderType& type, const std::string& shader_path)
|
* @see ShaderProgram::add_shader(const gfx::ShaderType& type, const std::string& shader_path)
|
||||||
* @param shader The shader to add.
|
* @param shader The shader to add.
|
||||||
* @return ShaderProgram& self
|
* @return ShaderProgram& self
|
||||||
*/
|
*/
|
||||||
ShaderProgram& add_shader(Shader& shader) {
|
ShaderProgram& add_shader(gfx::Shader& shader) {
|
||||||
if (shader.program != this->program) {
|
if (shader.program != this->program) {
|
||||||
throw std::runtime_error("The added shader does not have the same program as this shade program!");
|
throw std::runtime_error("The added shader does not have the same program as this shade program!");
|
||||||
}
|
}
|
||||||
|
@ -59,8 +59,8 @@ namespace simpleengine {
|
||||||
* @param shader_path The path of the shader.
|
* @param shader_path The path of the shader.
|
||||||
* @return ShaderProgram& self
|
* @return ShaderProgram& self
|
||||||
*/
|
*/
|
||||||
ShaderProgram& add_shader_from_source(const ShaderType& type, std::string& shader_source) {
|
ShaderProgram& add_shader_from_source(const gfx::ShaderType& type, std::string& shader_source) {
|
||||||
Shader shd = Shader::from_source(program, type, shader_source);
|
gfx::Shader shd = gfx::Shader::from_source(program, type, shader_source);
|
||||||
|
|
||||||
shaders.emplace_back(shd);
|
shaders.emplace_back(shd);
|
||||||
|
|
||||||
|
@ -74,8 +74,8 @@ namespace simpleengine {
|
||||||
* @param shader_path The path of the shader.
|
* @param shader_path The path of the shader.
|
||||||
* @return ShaderProgram& self
|
* @return ShaderProgram& self
|
||||||
*/
|
*/
|
||||||
ShaderProgram& add_shader_from_path(const ShaderType& type, const std::string& shader_path) {
|
ShaderProgram& add_shader_from_path(const gfx::ShaderType& type, const std::string& shader_path) {
|
||||||
Shader shd = Shader::from_filepath(program, type, shader_path);
|
gfx::Shader shd = gfx::Shader::from_filepath(program, type, shader_path);
|
||||||
|
|
||||||
shaders.emplace_back(shd);
|
shaders.emplace_back(shd);
|
||||||
|
|
||||||
|
@ -98,10 +98,10 @@ namespace simpleengine {
|
||||||
|
|
||||||
if (!success) {
|
if (!success) {
|
||||||
std::cerr << "Failed to link shader program!" << std::endl;
|
std::cerr << "Failed to link shader program!" << std::endl;
|
||||||
throw ShaderException("Failed to link shader program!");
|
throw gfx::ShaderException("Failed to link shader program!");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Shader& shader : shaders) {
|
for (gfx::Shader& shader : shaders) {
|
||||||
shader.delete_shader();
|
shader.delete_shader();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -115,7 +115,7 @@ namespace simpleengine {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<GLuint> program;
|
std::shared_ptr<GLuint> program;
|
||||||
std::vector<Shader> shaders;
|
std::vector<gfx::Shader> shaders;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
#include "../../gfx/vbo.h"
|
#include "../../gfx/vbo.h"
|
||||||
#include "../../gfx/vao.h"
|
#include "../../gfx/vao.h"
|
||||||
#include "simpleengine/gfx/vao.h"
|
#include "../../gfx/texture.h"
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -29,6 +29,7 @@ namespace simpleengine::shapes_2d {
|
||||||
using super = simpleengine::Renderable;
|
using super = simpleengine::Renderable;
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<GLuint> shader_program;
|
std::shared_ptr<GLuint> shader_program;
|
||||||
|
Texture& texture;
|
||||||
public:
|
public:
|
||||||
std::vector<Vertex> vertices;
|
std::vector<Vertex> vertices;
|
||||||
std::vector<GLuint> indicies;
|
std::vector<GLuint> indicies;
|
||||||
|
@ -36,10 +37,10 @@ namespace simpleengine::shapes_2d {
|
||||||
gfx::VBO vbo;
|
gfx::VBO vbo;
|
||||||
gfx::VAO vao;
|
gfx::VAO vao;
|
||||||
|
|
||||||
Square(std::shared_ptr<GLuint> shader_program, std::vector<Vertex> vertices, std::vector<GLuint> indicies) :
|
Square(std::shared_ptr<GLuint> shader_program, Texture& texture, std::vector<Vertex> vertices, std::vector<GLuint> indicies) :
|
||||||
super(nullptr), shader_program(shader_program), vertices(vertices), indicies(indicies),
|
super(nullptr), shader_program(shader_program), vertices(vertices), indicies(indicies),
|
||||||
ebo(gfx::VBO(GL_ELEMENT_ARRAY_BUFFER, false)), vbo(gfx::VBO(GL_ARRAY_BUFFER, false)),
|
ebo(gfx::VBO(GL_ELEMENT_ARRAY_BUFFER, false)), vbo(gfx::VBO(GL_ARRAY_BUFFER, false)),
|
||||||
vao(gfx::VAO()) {
|
texture(texture) {
|
||||||
|
|
||||||
vao.bind();
|
vao.bind();
|
||||||
vbo.buffer(vertices.data(), 0, sizeof(Vertex) * vertices.size());
|
vbo.buffer(vertices.data(), 0, sizeof(Vertex) * vertices.size());
|
||||||
|
@ -65,6 +66,8 @@ namespace simpleengine::shapes_2d {
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void render(std::shared_ptr<GLFWwindow> target) override {
|
virtual void render(std::shared_ptr<GLFWwindow> target) override {
|
||||||
|
texture.bind();
|
||||||
|
|
||||||
glUseProgram(*shader_program);
|
glUseProgram(*shader_program);
|
||||||
|
|
||||||
vao.bind();
|
vao.bind();
|
||||||
|
|
|
@ -15,10 +15,11 @@
|
||||||
|
|
||||||
#include "../../renderable.h"
|
#include "../../renderable.h"
|
||||||
#include "../../vertex.h"
|
#include "../../vertex.h"
|
||||||
|
|
||||||
#include "../../gfx/vbo.h"
|
#include "../../gfx/vbo.h"
|
||||||
#include "../../gfx/vao.h"
|
#include "../../gfx/vao.h"
|
||||||
#include "simpleengine/gfx/vao.h"
|
#include "../../gfx/shader.h"
|
||||||
|
#include "../../gfx/texture.h"
|
||||||
|
#include "../../optional.h"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
@ -27,63 +28,51 @@ namespace simpleengine::shapes_2d {
|
||||||
private:
|
private:
|
||||||
using super = simpleengine::Renderable;
|
using super = simpleengine::Renderable;
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<GLuint> shader_program;
|
gfx::Shader shader; // This only stores the shader program
|
||||||
|
nonstd::optional<Texture> texture;
|
||||||
public:
|
public:
|
||||||
std::vector<Vertex> vertices;
|
std::vector<Vertex> vertices;
|
||||||
gfx::VBO vbo;
|
gfx::VBO vbo;
|
||||||
gfx::VAO vao;
|
gfx::VAO vao;
|
||||||
|
|
||||||
Triangle(std::shared_ptr<GLuint> shader_program, std::vector<Vertex> vertices) : super(nullptr),
|
Triangle(gfx::Shader shader, std::vector<Vertex> vertices) : super(nullptr),
|
||||||
shader_program(shader_program), vertices(vertices), vbo(gfx::VBO(GL_ARRAY_BUFFER, false)),
|
shader(shader), vertices(vertices), vbo(gfx::VBO(GL_ARRAY_BUFFER, false)), texture(nonstd::nullopt) {
|
||||||
vao(gfx::VAO()) {
|
|
||||||
|
|
||||||
vao.bind();
|
vao.bind();
|
||||||
vbo.buffer(vertices.data(), 0, sizeof(Vertex) * vertices.size());
|
vbo.buffer(vertices.data(), 0, sizeof(Vertex) * vertices.size());
|
||||||
|
|
||||||
/* vao.enable_attrib(vbo, 0, 3, GL_FLOAT, sizeof(Vertex), offsetof(Vertex, position));
|
vao.enable_attrib(vbo, 0, 3, GL_FLOAT, sizeof(Vertex), offsetof(Vertex, position));
|
||||||
vao.enable_attrib(vbo, 1, 3, GL_FLOAT, sizeof(Vertex), offsetof(Vertex, color));
|
vao.enable_attrib(vbo, 1, 3, GL_FLOAT, sizeof(Vertex), offsetof(Vertex, color));
|
||||||
vao.enable_attrib(vbo, 2, 2, GL_FLOAT, sizeof(Vertex), offsetof(Vertex, tex_coord)); */
|
vao.enable_attrib(vbo, 2, 2, GL_FLOAT, sizeof(Vertex), offsetof(Vertex, tex_coord));
|
||||||
|
|
||||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, position));
|
|
||||||
glEnableVertexAttribArray(0);
|
|
||||||
|
|
||||||
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, color));
|
|
||||||
glEnableVertexAttribArray(1);
|
|
||||||
|
|
||||||
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, tex_coord));
|
|
||||||
glEnableVertexAttribArray(2);
|
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
|
}
|
||||||
|
|
||||||
/* glCreateVertexArrays(1, &vao);
|
Triangle(std::shared_ptr<GLuint> shader_program, std::vector<Vertex> vertices) :
|
||||||
glBindVertexArray(vao);
|
Triangle(gfx::Shader(shader_program), vertices) {
|
||||||
|
|
||||||
glGenBuffers(1, &vbo);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
|
||||||
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) * vertices.size(), vertices.data(), GL_STATIC_DRAW);
|
|
||||||
|
|
||||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, position));
|
|
||||||
glEnableVertexAttribArray(0);
|
|
||||||
|
|
||||||
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, color));
|
|
||||||
glEnableVertexAttribArray(1);
|
|
||||||
|
|
||||||
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, tex_coord));
|
|
||||||
glEnableVertexAttribArray(2);
|
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
||||||
glBindVertexArray(0); */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~Triangle() = default;
|
virtual ~Triangle() = default;
|
||||||
|
|
||||||
|
void set_texture(Texture texture) {
|
||||||
|
this->texture = texture;
|
||||||
|
}
|
||||||
|
|
||||||
virtual void update(const float& delta_time) override {
|
virtual void update(const float& delta_time) override {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void render(std::shared_ptr<GLFWwindow> target) override {
|
virtual void render(std::shared_ptr<GLFWwindow> target) override {
|
||||||
glUseProgram(*shader_program);
|
shader.use();
|
||||||
|
|
||||||
|
// If theres a texture set, tell the fragment shader that and bind to the texture for drawing.
|
||||||
|
if (texture.has_value()) {
|
||||||
|
shader.setUniformInt("texture_is_set", true, false);
|
||||||
|
texture.value().bind();
|
||||||
|
} else {
|
||||||
|
shader.setUniformInt("texture_is_set", false, false);
|
||||||
|
}
|
||||||
|
|
||||||
vao.bind();
|
vao.bind();
|
||||||
glDrawArrays(GL_TRIANGLES, 0, vertices.size());
|
glDrawArrays(GL_TRIANGLES, 0, vertices.size());
|
||||||
|
|
|
@ -0,0 +1,343 @@
|
||||||
|
#include "gfx/shader.h"
|
||||||
|
|
||||||
|
#include <glm/fwd.hpp>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace simpleengine::gfx {
|
||||||
|
Shader::Shader(std::shared_ptr<GLuint> program) : program(program) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Shader::Shader(std::shared_ptr<GLuint> program, GLuint shader) : program(program), shader(shader) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Shader Shader::from_source(const ShaderType& type, std::string& shader_source) {
|
||||||
|
Shader shd = Shader::from_source(std::make_shared<GLuint>(glCreateProgram()), type, shader_source);
|
||||||
|
|
||||||
|
shd.link();
|
||||||
|
shd.delete_shader();
|
||||||
|
|
||||||
|
return shd;
|
||||||
|
}
|
||||||
|
|
||||||
|
Shader Shader::from_source(std::shared_ptr<GLuint> program, const ShaderType& type, std::string& shader_source) {
|
||||||
|
Shader shd;
|
||||||
|
shd.program = program;
|
||||||
|
shd.shader = glCreateShader(type);
|
||||||
|
|
||||||
|
const GLchar* vert_src = shader_source.c_str();
|
||||||
|
glShaderSource(shd.shader, 1, &vert_src, NULL);
|
||||||
|
glCompileShader(shd.shader);
|
||||||
|
|
||||||
|
GLint success = false;
|
||||||
|
glGetShaderiv(shd.shader, GL_COMPILE_STATUS, &success);
|
||||||
|
|
||||||
|
if (!success) {
|
||||||
|
char log[512];
|
||||||
|
glGetShaderInfoLog(shd.shader, 512, NULL, log);
|
||||||
|
|
||||||
|
std::cerr << "Failed to load shader from source:" << std::endl << log << std::endl;
|
||||||
|
throw ShaderException("Failed to compile shader!");
|
||||||
|
}
|
||||||
|
|
||||||
|
glAttachShader(*shd.program, shd.shader);
|
||||||
|
|
||||||
|
return shd;
|
||||||
|
}
|
||||||
|
|
||||||
|
Shader Shader::from_filepath(const ShaderType& type, const std::string& shader_path) {
|
||||||
|
Shader shd = Shader::from_filepath(std::make_shared<GLuint>(glCreateProgram()), type, shader_path);
|
||||||
|
|
||||||
|
shd.link();
|
||||||
|
shd.delete_shader();
|
||||||
|
|
||||||
|
return shd;
|
||||||
|
}
|
||||||
|
|
||||||
|
Shader Shader::from_filepath(std::shared_ptr<GLuint> program, const ShaderType& type,
|
||||||
|
const std::string& shader_path) {
|
||||||
|
std::ifstream fstream(shader_path, std::ios::in);
|
||||||
|
|
||||||
|
if (!fstream.is_open()) {
|
||||||
|
std::cerr << "Failed to open shader file: " << shader_path << std::endl;
|
||||||
|
throw ShaderException("Failed to open shader file!");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::stringstream ss;
|
||||||
|
{
|
||||||
|
std::string str;
|
||||||
|
while (std::getline(fstream, str))
|
||||||
|
{
|
||||||
|
ss << str << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::string ss_str = ss.str();
|
||||||
|
|
||||||
|
return Shader::from_source(type, ss_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
Shader::~Shader() {
|
||||||
|
delete_shader();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shader::link() {
|
||||||
|
glLinkProgram(*program);
|
||||||
|
|
||||||
|
GLint success = false;
|
||||||
|
glGetProgramiv(*program, GL_LINK_STATUS, &success);
|
||||||
|
|
||||||
|
if (!success) {
|
||||||
|
std::cerr << "Failed to link shader program!" << std::endl;
|
||||||
|
throw ShaderException("Failed to link shader program!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shader::delete_shader() {
|
||||||
|
glDeleteShader(shader);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shader::use() const {
|
||||||
|
glUseProgram(*program);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shader::unuse() {
|
||||||
|
glUseProgram(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
GLfloat Shader::getUniformFloat(GLint location) const {
|
||||||
|
use();
|
||||||
|
|
||||||
|
GLfloat fl;
|
||||||
|
glGetUniformfv(*program, location, &fl);
|
||||||
|
|
||||||
|
return fl;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLfloat Shader::getUniformFloat(const char* uniform_name) const {
|
||||||
|
int location = glGetUniformLocation(*program, uniform_name);
|
||||||
|
return getUniformFloat(location);
|
||||||
|
}
|
||||||
|
|
||||||
|
GLint Shader::getUniformInt(GLint location) const {
|
||||||
|
use();
|
||||||
|
|
||||||
|
GLint _int;
|
||||||
|
glGetUniformiv(*program, location, &_int);
|
||||||
|
|
||||||
|
return _int;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLint Shader::getUniformInt(const char* uniform_name) const {
|
||||||
|
int location = glGetUniformLocation(*program, uniform_name);
|
||||||
|
return getUniformInt(location);
|
||||||
|
}
|
||||||
|
|
||||||
|
GLuint Shader::getUniformUInt(GLint location) const {
|
||||||
|
use();
|
||||||
|
|
||||||
|
GLuint _uint;
|
||||||
|
glGetUniformuiv(*program, location, &_uint);
|
||||||
|
|
||||||
|
return _uint;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLuint Shader::getUniformUInt(const char* uniform_name) const {
|
||||||
|
int location = glGetUniformLocation(*program, uniform_name);
|
||||||
|
return getUniformUInt(location);
|
||||||
|
}
|
||||||
|
|
||||||
|
GLdouble Shader::getUniformDouble(GLint location) const {
|
||||||
|
use();
|
||||||
|
|
||||||
|
GLdouble dbl;
|
||||||
|
glGetUniformdv(*program, location, &dbl);
|
||||||
|
|
||||||
|
return dbl;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLdouble Shader::getUniformDouble(const char* uniform_name) const {
|
||||||
|
int location = glGetUniformLocation(*program, uniform_name);
|
||||||
|
return getUniformDouble(location);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shader::setUniformFloat(GLint location, GLfloat fl, bool bind_shader) {
|
||||||
|
if (bind_shader) {
|
||||||
|
use();
|
||||||
|
}
|
||||||
|
glUniform1f(location, fl);
|
||||||
|
if (bind_shader) {
|
||||||
|
unuse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shader::setUniformFloat(const char* uniform_name, GLfloat fl, bool bind_shader) {
|
||||||
|
int location = glGetUniformLocation(*program, uniform_name);
|
||||||
|
setUniformFloat(location, fl, bind_shader);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shader::setUniformFloatVec2(GLint location, glm::vec2 vec, bool bind_shader) {
|
||||||
|
if (bind_shader) {
|
||||||
|
use();
|
||||||
|
}
|
||||||
|
glUniform2f(location, vec.x, vec.y);
|
||||||
|
if (bind_shader) {
|
||||||
|
unuse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shader::setUniformFloatVec2(const char* uniform_name, glm::vec2 vec, bool bind_shader) {
|
||||||
|
int location = glGetUniformLocation(*program, uniform_name);
|
||||||
|
setUniformFloatVec2(location, vec, bind_shader);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shader::setUniformFloatVec3(GLint location, glm::vec3 vec, bool bind_shader) {
|
||||||
|
if (bind_shader) {
|
||||||
|
use();
|
||||||
|
}
|
||||||
|
glUniform3f(location, vec.x, vec.y, vec.z);
|
||||||
|
if (bind_shader) {
|
||||||
|
unuse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shader::setUniformFloatVec3(const char* uniform_name, glm::vec3 vec, bool bind_shader) {
|
||||||
|
int location = glGetUniformLocation(*program, uniform_name);
|
||||||
|
setUniformFloatVec3(location, vec, bind_shader);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shader::setUniformFloatVec4(GLint location, glm::vec4 vec, bool bind_shader) {
|
||||||
|
if (bind_shader) {
|
||||||
|
use();
|
||||||
|
}
|
||||||
|
glUniform4f(location, vec.x, vec.y, vec.z, vec.w);
|
||||||
|
if (bind_shader) {
|
||||||
|
unuse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shader::setUniformFloatVec4(const char* uniform_name, glm::vec4 vec, bool bind_shader) {
|
||||||
|
int location = glGetUniformLocation(*program, uniform_name);
|
||||||
|
setUniformFloatVec4(location, vec, bind_shader);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shader::setUniformInt(GLint location, GLint i, bool bind_shader) {
|
||||||
|
if (bind_shader) {
|
||||||
|
use();
|
||||||
|
}
|
||||||
|
glUniform1i(location, i);
|
||||||
|
if (bind_shader) {
|
||||||
|
unuse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shader::setUniformInt(const char* uniform_name, GLint i, bool bind_shader) {
|
||||||
|
int location = glGetUniformLocation(*program, uniform_name);
|
||||||
|
setUniformInt(location, i, bind_shader);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shader::setUniformIntVec2(GLint location, glm::ivec2 vec, bool bind_shader) {
|
||||||
|
if (bind_shader) {
|
||||||
|
use();
|
||||||
|
}
|
||||||
|
glUniform2i(location, vec.x, vec.y);
|
||||||
|
if (bind_shader) {
|
||||||
|
unuse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shader::setUniformIntVec2(const char* uniform_name, glm::ivec2 vec, bool bind_shader) {
|
||||||
|
int location = glGetUniformLocation(*program, uniform_name);
|
||||||
|
setUniformIntVec2(location, vec, bind_shader);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shader::setUniformIntVec3(GLint location, glm::ivec3 vec, bool bind_shader) {
|
||||||
|
if (bind_shader) {
|
||||||
|
use();
|
||||||
|
}
|
||||||
|
glUniform3i(location, vec.x, vec.y, vec.z);
|
||||||
|
if (bind_shader) {
|
||||||
|
unuse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shader::setUniformIntVec3(const char* uniform_name, glm::ivec3 vec, bool bind_shader) {
|
||||||
|
int location = glGetUniformLocation(*program, uniform_name);
|
||||||
|
setUniformIntVec3(location, vec, bind_shader);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shader::setUniformIntVec4(GLint location, glm::ivec4 vec, bool bind_shader) {
|
||||||
|
if (bind_shader) {
|
||||||
|
use();
|
||||||
|
}
|
||||||
|
glUniform4i(location, vec.x, vec.y, vec.z, vec.w);
|
||||||
|
if (bind_shader) {
|
||||||
|
unuse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shader::setUniformIntVec4(const char* uniform_name, glm::ivec4 vec, bool bind_shader) {
|
||||||
|
int location = glGetUniformLocation(*program, uniform_name);
|
||||||
|
setUniformIntVec4(location, vec, bind_shader);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shader::setUniformUInt(GLint location, GLuint ui, bool bind_shader) {
|
||||||
|
if (bind_shader) {
|
||||||
|
use();
|
||||||
|
}
|
||||||
|
glUniform1ui(location, ui);
|
||||||
|
if (bind_shader) {
|
||||||
|
unuse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shader::setUniformUInt(const char* uniform_name, GLuint ui, bool bind_shader) {
|
||||||
|
int location = glGetUniformLocation(*program, uniform_name);
|
||||||
|
setUniformUInt(location, ui, bind_shader);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shader::setUniformUIntVec2(GLint location, glm::uvec2 vec, bool bind_shader) {
|
||||||
|
if (bind_shader) {
|
||||||
|
use();
|
||||||
|
}
|
||||||
|
glUniform2ui(location, vec.x, vec.y);
|
||||||
|
if (bind_shader) {
|
||||||
|
unuse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shader::setUniformUIntVec2(const char* uniform_name, glm::uvec2 vec, bool bind_shader) {
|
||||||
|
int location = glGetUniformLocation(*program, uniform_name);
|
||||||
|
setUniformUIntVec2(location, vec, bind_shader);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shader::setUniformUIntVec3(GLint location, glm::uvec3 vec, bool bind_shader) {
|
||||||
|
if (bind_shader) {
|
||||||
|
use();
|
||||||
|
}
|
||||||
|
glUniform3ui(location, vec.x, vec.y, vec.z);
|
||||||
|
if (bind_shader) {
|
||||||
|
unuse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shader::setUniformUIntVec3(const char* uniform_name, glm::uvec3 vec, bool bind_shader) {
|
||||||
|
int location = glGetUniformLocation(*program, uniform_name);
|
||||||
|
setUniformUIntVec3(location, vec, bind_shader);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shader::setUniformUIntVec4(GLint location, glm::uvec4 vec, bool bind_shader) {
|
||||||
|
if (bind_shader) {
|
||||||
|
use();
|
||||||
|
}
|
||||||
|
glUniform4ui(location, vec.x, vec.y, vec.z, vec.w);
|
||||||
|
if (bind_shader) {
|
||||||
|
unuse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shader::setUniformUIntVec4(const char* uniform_name, glm::uvec4 vec, bool bind_shader) {
|
||||||
|
int location = glGetUniformLocation(*program, uniform_name);
|
||||||
|
setUniformUIntVec4(location, vec, bind_shader);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue