Implemented ShaderProgramBuilder
This commit is contained in:
@@ -7,3 +7,4 @@ find_package(glfw3 CONFIG REQUIRED)
|
|||||||
find_package(glm CONFIG REQUIRED)
|
find_package(glm CONFIG REQUIRED)
|
||||||
|
|
||||||
add_subdirectory(./source/app)
|
add_subdirectory(./source/app)
|
||||||
|
add_subdirectory(./source/shader)
|
||||||
|
|||||||
@@ -13,4 +13,5 @@ target_link_libraries(${PROJECT_NAME}
|
|||||||
GLEW::GLEW
|
GLEW::GLEW
|
||||||
glfw
|
glfw
|
||||||
glm::glm
|
glm::glm
|
||||||
|
UglyShaderLib
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
|
#include "ShaderProgramBuilder.hpp"
|
||||||
|
|
||||||
int App::main(std::vector<std::string> &args) {
|
int App::main(std::vector<std::string> &args) {
|
||||||
auto app = App{};
|
auto app = App{};
|
||||||
@@ -57,9 +58,9 @@ App::~App() {
|
|||||||
|
|
||||||
void App::game_loop() {
|
void App::game_loop() {
|
||||||
float vertices[] = {
|
float vertices[] = {
|
||||||
.0f, .5f,
|
.0f, .5f, 1.f, 0.f, 0.f,
|
||||||
.5f, -.5f,
|
.5f, -.5f, 0.f, 1.f, 0.f,
|
||||||
-.5f, -.5f
|
-.5f, -.5f, 0.f, 0.f, 1.f
|
||||||
};
|
};
|
||||||
|
|
||||||
GLuint vbo;
|
GLuint vbo;
|
||||||
@@ -70,56 +71,38 @@ void App::game_loop() {
|
|||||||
auto vertexSource = R"glsl(
|
auto vertexSource = R"glsl(
|
||||||
#version 150 core
|
#version 150 core
|
||||||
in vec2 position;
|
in vec2 position;
|
||||||
void main() { gl_Position = vec4(position, 0.0, 1.0); }
|
in vec3 color;
|
||||||
|
out vec3 _color;
|
||||||
|
void main() { _color = color; gl_Position = vec4(position, 0.0, 1.0); }
|
||||||
)glsl";
|
)glsl";
|
||||||
|
|
||||||
GLint status;
|
|
||||||
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
|
|
||||||
glShaderSource(vertexShader, 1, &vertexSource, NULL);
|
|
||||||
glCompileShader(vertexShader);
|
|
||||||
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &status);
|
|
||||||
if(!status) {
|
|
||||||
error_callback_s(GLFW_NO_ERROR, "glShaderSource() failed");
|
|
||||||
}
|
|
||||||
|
|
||||||
auto fragmentSource = R"glsl(
|
auto fragmentSource = R"glsl(
|
||||||
#version 150 core
|
#version 150 core
|
||||||
uniform vec3 triangleColor;
|
in vec3 _color;
|
||||||
out vec4 color;
|
out vec4 color;
|
||||||
void main() { color = vec4(triangleColor, 1.0); }
|
void main() { color = vec4(_color, 1.0); }
|
||||||
)glsl";
|
)glsl";
|
||||||
|
|
||||||
|
GLuint shaderProgram = ugly::ShaderProgramBuilder{}
|
||||||
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
|
.attachFromMemory(GL_VERTEX_SHADER, vertexSource)
|
||||||
glShaderSource(fragmentShader, 1, &fragmentSource, NULL);
|
.attachFromMemory(GL_FRAGMENT_SHADER, fragmentSource)
|
||||||
glCompileShader(fragmentShader);
|
.link();
|
||||||
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &status);
|
|
||||||
if(!status) {
|
|
||||||
error_callback_s(GLFW_NO_ERROR, "glShaderSource() failed");
|
|
||||||
}
|
|
||||||
|
|
||||||
GLuint shaderProgram = glCreateProgram();
|
|
||||||
glAttachShader(shaderProgram, vertexShader);
|
|
||||||
glAttachShader(shaderProgram, fragmentShader);
|
|
||||||
glLinkProgram(shaderProgram);
|
|
||||||
glUseProgram(shaderProgram);
|
glUseProgram(shaderProgram);
|
||||||
|
|
||||||
GLuint vao;
|
GLuint vao;
|
||||||
glGenVertexArrays(1, &vao);
|
glGenVertexArrays(1, &vao);
|
||||||
glBindVertexArray(vao);
|
glBindVertexArray(vao);
|
||||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
|
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 5*sizeof(float), 0);
|
||||||
glEnableVertexAttribArray(0);
|
glEnableVertexAttribArray(0);
|
||||||
|
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 5*sizeof(float), (void*)(2*sizeof(float)));
|
||||||
auto start = glfwGetTime();
|
glEnableVertexAttribArray(1);
|
||||||
|
|
||||||
while(!glfwWindowShouldClose(mpWindow)) {
|
while(!glfwWindowShouldClose(mpWindow)) {
|
||||||
glfwPollEvents();
|
glfwPollEvents();
|
||||||
|
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||||
|
|
||||||
auto now = glfwGetTime();
|
|
||||||
glUniform3f(glGetUniformLocation(shaderProgram, "triangleColor"), (sin(now-start) + 1.0f) / 2.0f, 0.0f, 0.0f);
|
|
||||||
|
|
||||||
glfwSwapBuffers(mpWindow);
|
glfwSwapBuffers(mpWindow);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
14
source/shader/CMakeLists.txt
Normal file
14
source/shader/CMakeLists.txt
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
project(UglyShaderLib)
|
||||||
|
|
||||||
|
add_library(${PROJECT_NAME}
|
||||||
|
./src/ShaderProgramBuilder.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
target_include_directories(${PROJECT_NAME}
|
||||||
|
PUBLIC ./include
|
||||||
|
PRIVATE ./src
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(${PROJECT_NAME}
|
||||||
|
GLEW::GLEW
|
||||||
|
)
|
||||||
28
source/shader/include/ShaderProgramBuilder.hpp
Normal file
28
source/shader/include/ShaderProgramBuilder.hpp
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
#include <GL/glew.h>
|
||||||
|
|
||||||
|
namespace ugly{
|
||||||
|
|
||||||
|
class ShaderProgramBuilder {
|
||||||
|
public:
|
||||||
|
class Error: public std::runtime_error{
|
||||||
|
public:
|
||||||
|
using std::runtime_error::runtime_error;
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
ShaderProgramBuilder();
|
||||||
|
~ShaderProgramBuilder();
|
||||||
|
void reset();
|
||||||
|
ShaderProgramBuilder &attachFromMemory(GLenum type, const GLchar *string, GLint length = 0);
|
||||||
|
ShaderProgramBuilder &attachFromFile(GLenum type, const char *filename);
|
||||||
|
GLuint link();
|
||||||
|
|
||||||
|
private:
|
||||||
|
GLuint mProgram;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
73
source/shader/src/ShaderProgramBuilder.cpp
Normal file
73
source/shader/src/ShaderProgramBuilder.cpp
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
#include "ShaderProgramBuilder.hpp"
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
|
||||||
|
ugly::ShaderProgramBuilder::ShaderProgramBuilder():
|
||||||
|
mProgram{glCreateProgram()} {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ugly::ShaderProgramBuilder::~ShaderProgramBuilder() {
|
||||||
|
if(mProgram != 0) {
|
||||||
|
glDeleteProgram(mProgram);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ugly::ShaderProgramBuilder::reset() {
|
||||||
|
using namespace std;
|
||||||
|
swap(*this, ShaderProgramBuilder{});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ugly::ShaderProgramBuilder &ugly::ShaderProgramBuilder::attachFromMemory(GLenum type, const GLchar *string, GLint length) {
|
||||||
|
auto shader = glCreateShader(type);
|
||||||
|
glShaderSource(shader, 1, &string, length != 0 ? &length : NULL);
|
||||||
|
glCompileShader(shader);
|
||||||
|
|
||||||
|
GLint status;
|
||||||
|
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
|
||||||
|
if(status != GL_TRUE) {
|
||||||
|
char buf[512];
|
||||||
|
glGetShaderInfoLog(shader, 512, NULL, buf);
|
||||||
|
glDeleteShader(shader);
|
||||||
|
std::cerr << "Failed to compile shader:\n\t" << buf << '\n';
|
||||||
|
throw Error{"shader failed to compile"};
|
||||||
|
}
|
||||||
|
|
||||||
|
glAttachShader(mProgram, shader);
|
||||||
|
glDeleteShader(shader);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ugly::ShaderProgramBuilder &ugly::ShaderProgramBuilder::attachFromFile(GLenum type, const char *filename) {
|
||||||
|
auto file = std::ifstream{filename};
|
||||||
|
file.exceptions(std::ios_base::badbit);
|
||||||
|
std::ostringstream ss;
|
||||||
|
ss << file.rdbuf();
|
||||||
|
return attachFromMemory(type, ss.str().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
GLuint ugly::ShaderProgramBuilder::link() {
|
||||||
|
glLinkProgram(mProgram);
|
||||||
|
|
||||||
|
GLint status;
|
||||||
|
glGetProgramiv(mProgram, GL_LINK_STATUS, &status);
|
||||||
|
if(status != GL_TRUE) {
|
||||||
|
char buf[512];
|
||||||
|
glGetProgramInfoLog(mProgram, 512, NULL, buf);
|
||||||
|
std::cerr << "Failed to link program:\n\t" << buf << '\n';
|
||||||
|
throw Error{"program failed to link"};
|
||||||
|
}
|
||||||
|
|
||||||
|
auto result = mProgram;
|
||||||
|
mProgram = 0;
|
||||||
|
reset();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user