Use the shader class

This commit is contained in:
Adrian Hedqvist 2018-01-18 21:27:49 +01:00
parent e0d1bcad3a
commit edb5cece7f
7 changed files with 174 additions and 124 deletions

View file

@ -11,7 +11,7 @@ execute_process(
file(WRITE "src/gitparams.h" "#define GIT_CUR_COMMIT ${GIT_COMMIT}") file(WRITE "src/gitparams.h" "#define GIT_CUR_COMMIT ${GIT_COMMIT}")
set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 -Wall -Wextra")
set(TARGET dungeon) set(TARGET dungeon)
project(${TARGET} LANGUAGES CXX) project(${TARGET} LANGUAGES CXX)

View file

@ -96,9 +96,9 @@ bool line_of_sight(Tilemap *map, vec2i start, vec2i end) {
if (delta.x >= delta.y) if (delta.x >= delta.y)
{ {
// error may go below zero // error may go below zero
int error(delta.y - (delta.x >> 1)); int error = delta.y - (delta.x >> 1);
while (!start.x != end.x && map->get_tile(start.x, start.y).opaque) // TODO: Hardcoded tiles while (start.x != end.x && map->get_tile(start.x, start.y).opaque)
{ {
// reduce error, while taking into account the corner case of error == 0 // reduce error, while taking into account the corner case of error == 0
if ((error > 0) || (!error && (ix > 0))) if ((error > 0) || (!error && (ix > 0)))
@ -115,9 +115,9 @@ bool line_of_sight(Tilemap *map, vec2i start, vec2i end) {
else else
{ {
// error may go below zero // error may go below zero
int error(delta.x - (delta.y >> 1)); int error = delta.x - (delta.y >> 1);
while (start.y != end.y && !map->get_tile(start.x, start.y).opaque) // TODO: Stop hardcoding tiles while (start.y != end.y && !map->get_tile(start.x, start.y).opaque)
{ {
// reduce error, while taking into account the corner case of error == 0 // reduce error, while taking into account the corner case of error == 0
if ((error > 0) || (!error && (iy > 0))) if ((error > 0) || (!error && (iy > 0)))

View file

@ -12,7 +12,7 @@ class Gamestate {
protected: protected:
App* app; App* app;
public: public:
//virtual ~Gamestate() {}; virtual ~Gamestate() = default;
void init(App* app); void init(App* app);
virtual void load() = 0; virtual void load() = 0;
virtual Gamestate* update(double delta) = 0; virtual Gamestate* update(double delta) = 0;

View file

@ -7,4 +7,3 @@ public:
~IfSeeEnemyNode(); ~IfSeeEnemyNode();
BehaviourTreeStatus tick(BTTick* tick); BehaviourTreeStatus tick(BTTick* tick);
}; };

View file

@ -11,6 +11,7 @@
#include <glm/gtx/transform.hpp> #include <glm/gtx/transform.hpp>
#include <glm/matrix.hpp> #include <glm/matrix.hpp>
#include <utility> #include <utility>
#include "Shader.h"
using namespace gl; using namespace gl;
@ -106,12 +107,42 @@ Renderer::~Renderer() {
SDL_LogDebug(SDL_LOG_CATEGORY_RENDER, "Renderer destroyed."); SDL_LogDebug(SDL_LOG_CATEGORY_RENDER, "Renderer destroyed.");
} }
GLuint shaderProg; Shader mainshader;
GLuint wireShaderProg; Shader wireshader;
GLuint spriteVertArrayId; GLuint spriteVertArrayId;
GLint colorUniform;
GLint bgUniform;
GLint mvpUniform; void MessageCallback( GLenum source,
GLenum type,
GLuint id,
GLenum severity,
GLsizei length,
const GLchar* message,
const void* userParam )
{
const char* sev;
switch (severity) {
case GL_DEBUG_SEVERITY_HIGH:
sev = "HIGH";
break;
case GL_DEBUG_SEVERITY_MEDIUM:
sev = "MEDIUM";
break;
case GL_DEBUG_SEVERITY_LOW:
sev = "LOW";
break;
case GL_DEBUG_SEVERITY_NOTIFICATION:
sev = "NOTIFY";
break;
default:
sev = "UKNOWN";
}
fprintf( stderr, "GL CALLBACK: %s type = 0x%x, severity = %s, message = %s\n",
( type == GL_DEBUG_TYPE_ERROR ? "** GL ERROR **" : "" ),
type, sev, message );
}
bool Renderer::Init(std::string title, int width, int height) { bool Renderer::Init(std::string title, int width, int height) {
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
@ -132,19 +163,9 @@ bool Renderer::Init(std::string title, int width, int height) {
} }
glbinding::Binding::initialize(); glbinding::Binding::initialize();
glEnable(GL_DEBUG_OUTPUT);
//glDebugMessageCallback((GLDEBUGPROC)MessageCallback, 0);
/*
GLenum err = glewInit();
if (err != GLEW_OK) {
SDL_LogCritical(SDL_LOG_CATEGORY_RENDER, "Failed to initialize OpenGl: %s\n", glewGetErrorString(err));
return false;
}
if (!GLEW_VERSION_3_2) {
SDL_LogCritical(SDL_LOG_CATEGORY_RENDER,"OpenGl 3.2 is not supported, please try updating your drivers!\n");
return false;
}
*/
glClearColor(0, 0, 0, 1); glClearColor(0, 0, 0, 1);
ImGui_ImplSdlGL3_Init(window); ImGui_ImplSdlGL3_Init(window);
@ -156,22 +177,10 @@ bool Renderer::Init(std::string title, int width, int height) {
glBindBuffer(GL_ARRAY_BUFFER, spriteVBuf); glBindBuffer(GL_ARRAY_BUFFER, spriteVBuf);
glBufferData(GL_ARRAY_BUFFER, sizeof(rectVertData), rectVertData, GL_STATIC_DRAW); glBufferData(GL_ARRAY_BUFFER, sizeof(rectVertData), rectVertData, GL_STATIC_DRAW);
GLuint frag = LoadShader("assets/main.frag", GL_FRAGMENT_SHADER); mainshader = Shader("assets/main.vert", "assets/main.frag");
GLuint vert = LoadShader("assets/main.vert", GL_VERTEX_SHADER); mainshader.print_values();
shaderProg = CreateShaderProgram(vert, frag);
GLuint wirefrag = LoadShader("assets/wireframe.frag", GL_FRAGMENT_SHADER);
GLuint wirevert = LoadShader("assets/wireframe.vert", GL_VERTEX_SHADER);
wireShaderProg = CreateShaderProgram(wirevert, wirefrag);
glDeleteShader(frag);
glDeleteShader(vert);
glDeleteShader(wirefrag);
glDeleteShader(wirevert);
glUseProgram(shaderProg); wireshader = Shader("assets/wireframe.vert", "assets/wireframe.frag");
colorUniform = glGetUniformLocation(shaderProg, "colortint");
bgUniform = glGetUniformLocation(shaderProg, "colorbackground");
mvpUniform = glGetUniformLocation(shaderProg, "MVP");
set_window_size(width, height); set_window_size(width, height);
@ -193,7 +202,7 @@ void Renderer::set_window_size(int width, int height) {
heightmult = 1. / windowheight * 2; heightmult = 1. / windowheight * 2;
glm::mat4 projection = glm::ortho(-1, 1, 1, -1); glm::mat4 projection = glm::ortho(-1, 1, 1, -1);
glm::mat4 view = glm::scale(glm::vec3(widthmult, heightmult, 1)) * glm::translate(glm::vec3(-windowwidth / 2, -windowheight / 2, 0)) * glm::mat4(1); glm::mat4 view = glm::scale(glm::vec3(widthmult, heightmult, 1)) * glm::translate(glm::vec3(-windowwidth / 2, -windowheight / 2, 0));
screenVPmat = projection * view; screenVPmat = projection * view;
SDL_LogDebug(SDL_LOG_CATEGORY_RENDER, "Window size set to %dx%d.\n", windowwidth, windowheight); SDL_LogDebug(SDL_LOG_CATEGORY_RENDER, "Window size set to %dx%d.\n", windowwidth, windowheight);
@ -237,9 +246,11 @@ bool Renderer::ImguiProcessEvents(SDL_Event *e) {
void Renderer::ImguiNewFrame() { void Renderer::ImguiNewFrame() {
ImGui_ImplSdlGL3_NewFrame(window); ImGui_ImplSdlGL3_NewFrame(window);
} }
Texture * Renderer::LoadTexture(std::string path) { Texture * Renderer::LoadTexture(std::string path) {
auto it = textures.find(path); auto it = textures.find(path);
if (it == textures.end()) { if (it != textures.end()) return &it->second; // Texture already loaded
SDL_LogVerbose(SDL_LOG_CATEGORY_RENDER, "Loading texture: %s\n", path.c_str()); SDL_LogVerbose(SDL_LOG_CATEGORY_RENDER, "Loading texture: %s\n", path.c_str());
// Texture not loaded, let's load it. // Texture not loaded, let's load it.
SDL_Surface* surface = SDL_LoadBMP(path.c_str()); SDL_Surface* surface = SDL_LoadBMP(path.c_str());
@ -282,11 +293,6 @@ Texture * Renderer::LoadTexture(std::string path) {
return nullptr; return nullptr;
} }
} }
else {
// Texture already loaded, no need to load it again
return &it->second;
}
}
Sprite Renderer::CreateSprite(std::string path, int x, int y, int w, int h) { Sprite Renderer::CreateSprite(std::string path, int x, int y, int w, int h) {
@ -306,7 +312,6 @@ Sprite Renderer::CreateSprite(std::string path, int x, int y, int w, int h) {
(x + w) / tw, (y + h) / th, (x + w) / tw, (y + h) / th,
}; };
glCreateBuffers(1, &sprite.uvBuf); glCreateBuffers(1, &sprite.uvBuf);
glBindBuffer(GL_ARRAY_BUFFER, sprite.uvBuf); glBindBuffer(GL_ARRAY_BUFFER, sprite.uvBuf);
glBufferData(GL_ARRAY_BUFFER, sizeof(uvs), uvs, GL_STATIC_DRAW); glBufferData(GL_ARRAY_BUFFER, sizeof(uvs), uvs, GL_STATIC_DRAW);
@ -327,11 +332,10 @@ void Renderer::draw_sprite(Sprite *sprite, Color fg, Color bg, int x, int y, flo
glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD); glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD);
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO); glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);
glUseProgram(shaderProg); mainshader.use();
glUniform4f(colorUniform, fg.r, fg.g, fg.b, fg.a); mainshader.set_mvp(mvp);
glUniform4f(bgUniform, bg.r, bg.g, bg.b, bg.a); mainshader.set_color_tint(fg);
mainshader.set_aux_uniform("colorbackground", bg);
glUniformMatrix4fv(mvpUniform, 1, GL_FALSE, &mvp[0][0]);
glBindVertexArray(spriteVertArrayId); glBindVertexArray(spriteVertArrayId);
@ -343,13 +347,13 @@ void Renderer::draw_sprite(Sprite *sprite, Color fg, Color bg, int x, int y, flo
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, nullptr); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
if (wireframe) { if (wireframe) {
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); wireshader.use();
wireshader.set_mvp(mvp);
Color white = Color(1.0f,1.0f,1.0f,1.0f);
wireshader.set_color_tint(white);
glUseProgram(wireShaderProg); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glUniform4f(colorUniform, 1, 1, 1, 1);
glUniformMatrix4fv(mvpUniform, 1, GL_FALSE, &mvp[0][0]);
glBindVertexArray(spriteVertArrayId); glBindVertexArray(spriteVertArrayId);
glEnableVertexAttribArray(0); glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1); glEnableVertexAttribArray(1);
@ -360,11 +364,8 @@ void Renderer::draw_sprite(Sprite *sprite, Color fg, Color bg, int x, int y, flo
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
} }
glDisableVertexAttribArray(0); glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1); glDisableVertexAttribArray(1);
} }
void Renderer::Clear() { void Renderer::Clear() {

View file

@ -12,13 +12,15 @@ gl::GLint Shader::get_uniform_location(std::string name) {
auto it = uniforms.find(name); auto it = uniforms.find(name);
if (it == uniforms.end()) { if (it == uniforms.end()) {
GLint loc = glGetUniformLocation(program_id, name.c_str()); GLint loc = glGetUniformLocation(program_id, name.c_str());
uniforms.insert(std::pair<std::string, GLint>(name, glGetUniformLocation(program_id, name.c_str()))); uniforms.insert(std::pair<std::string, GLint>(name, loc));
if (loc < 0){
}
return loc; return loc;
} }
return it->second; return it->second;
} }
Shader::Shader(std::ifstream vert, std::ifstream frag) { void Shader::init_streams(std::ifstream vert, std::ifstream frag) {
std::string vsource; std::string vsource;
if (vert.is_open()) { if (vert.is_open()) {
std::string line; std::string line;
@ -27,6 +29,9 @@ Shader::Shader(std::ifstream vert, std::ifstream frag) {
} }
vert.close(); vert.close();
} }
else {
SDL_LogWarn(SDL_LOG_CATEGORY_RENDER, "Could not load vert shader!");
}
std::string fsource; std::string fsource;
if (frag.is_open()) { if (frag.is_open()) {
@ -36,13 +41,16 @@ Shader::Shader(std::ifstream vert, std::ifstream frag) {
} }
frag.close(); frag.close();
} }
else {
Shader(vsource, fsource); SDL_LogWarn(SDL_LOG_CATEGORY_RENDER, "Could not load frag shader!");
} }
Shader::Shader(std::string vertsource, std::string fragsource) { init_source(vsource, fsource);
GLuint vert_id = glCreateShader(GL_VERTEX_SHADER); }
GLuint frag_id = glCreateShader(GL_FRAGMENT_SHADER);
void Shader::init_source(std::string vertsource, std::string fragsource) {
vert_id = glCreateShader(GL_VERTEX_SHADER);
frag_id = glCreateShader(GL_FRAGMENT_SHADER);
char const * vs = vertsource.c_str(); char const * vs = vertsource.c_str();
glShaderSource(vert_id, 1, &vs, nullptr); glShaderSource(vert_id, 1, &vs, nullptr);
@ -79,39 +87,73 @@ Shader::Shader(std::string vertsource, std::string fragsource) {
result = GL_FALSE; result = GL_FALSE;
infologlength = 0; infologlength = 0;
glGetShaderiv(program_id, GL_LINK_STATUS, &result); glGetProgramiv(program_id, GL_LINK_STATUS, &result);
glGetShaderiv(program_id, GL_INFO_LOG_LENGTH, &infologlength); glGetProgramiv(program_id, GL_INFO_LOG_LENGTH, &infologlength);
if (infologlength > 0) { if (infologlength > 0) {
std::string errorlog(infologlength + 1, ' '); std::string errorlog(infologlength + 1, ' ');
glGetShaderInfoLog(program_id, infologlength, NULL, &errorlog[0]); glGetProgramInfoLog(program_id, infologlength, NULL, &errorlog[0]);
SDL_LogWarn(SDL_LOG_CATEGORY_RENDER, "Errors when linking shader program:\n%s\n", &errorlog[0]); SDL_LogWarn(SDL_LOG_CATEGORY_RENDER, "Errors when linking shader program:\n%s\n", &errorlog[0]);
} }
glDetachShader(program_id, vert_id); glDetachShader(program_id, vert_id);
glDetachShader(program_id, frag_id); glDetachShader(program_id, frag_id);
glDeleteShader(vert_id); // glDeleteShader(vert_id);
glDeleteShader(frag_id); // glDeleteShader(frag_id);
uniform_color = glGetUniformLocation(program_id, "colortint"); uniform_color = glGetUniformLocation(program_id, "colortint");
if (uniform_color < 0){
SDL_LogWarn(SDL_LOG_CATEGORY_RENDER, "No shader color?????\n");
}
uniform_mvp = glGetUniformLocation(program_id, "MVP"); uniform_mvp = glGetUniformLocation(program_id, "MVP");
if (uniform_mvp < 0){
SDL_LogWarn(SDL_LOG_CATEGORY_RENDER, "No shader mvp?????\n");
}
print_values();
}
Shader::Shader() {}
Shader::Shader(const char* vertpath, const char* fragpath) {
SDL_LogVerbose(SDL_LOG_CATEGORY_RENDER, "Creating shader with '%s' and '%s'\n", vertpath, fragpath);
init_streams(std::ifstream(vertpath), std::ifstream(fragpath));
}
Shader::Shader(std::string vertsource, std::string fragsource) {
init_source(vertsource, fragsource);
} }
void Shader::use() { glUseProgram(program_id); } void Shader::use() { glUseProgram(program_id); }
void Shader::set_color_tint(Color col) { glUniform4f(uniform_color, col.r, col.g, col.b, col.a); } void Shader::set_color_tint(Color &col) { glUniform4f(uniform_color, col.r, col.g, col.b, col.a); }
void Shader::set_mvp(glm::mat4x4 mvp) { glUniformMatrix4fv(uniform_mvp, 1, GL_FALSE, &mvp[0][0]); } void Shader::set_mvp(glm::mat4x4 &mvp) { glUniformMatrix4fv(uniform_mvp, 1, GL_FALSE, &mvp[0][0]); }
void Shader::set_aux_uniform(std::string name, glm::fvec4 val) { glUniform4f(get_uniform_location(name), val.r, val.g, val.b, val.a); } void Shader::set_aux_uniform(std::string name, Color &val) { glUniform4f(get_uniform_location(name), val.r, val.g, val.b, val.a); }
void Shader::set_aux_uniform(std::string name, float val) { void Shader::set_aux_uniform(std::string name, glm::fvec4 &val) { glUniform4f(get_uniform_location(name), val.r, val.g, val.b, val.a); }
void Shader::set_aux_uniform(std::string name, float &val) {
glUniform1f(get_uniform_location(name), val); glUniform1f(get_uniform_location(name), val);
} }
Shader::~Shader() {}
void Shader::erase() { void Shader::erase() {
if (program_id) { if (frag_id != 0)
glDeleteShader(program_id); {
glDeleteShader(frag_id);
frag_id = 0;
}
if (vert_id != 0)
{
glDeleteShader(vert_id);
vert_id = 0;
}
if (program_id != 0)
{
glDeleteProgram(program_id);
program_id = 0;
} }
} }
void Shader::print_values() {
fprintf(stderr, "program_id: %i\nvert_id: %i\nfrag_id: %i\nuniform_mvp: %i\nuniform_color: %i\n", program_id, vert_id, frag_id, uniform_mvp, uniform_color);
}

View file

@ -2,26 +2,34 @@
#include <string> #include <string>
#include <map> #include <map>
#include <fstream>
#include <glbinding/gl/types.h> #include <glbinding/gl/types.h>
#include <glm/common.hpp> #include <glm/common.hpp>
#include "Renderer.h" #include "Renderer.h"
class Shader { class Shader {
gl::GLuint program_id = 0; gl::GLuint program_id;
gl::GLuint vert_id;
gl::GLuint frag_id;
gl::GLint uniform_color; gl::GLint uniform_color;
gl::GLint uniform_mvp; gl::GLint uniform_mvp;
std::map<std::string, gl::GLint> uniforms; std::map<std::string, gl::GLint> uniforms;
gl::GLint get_uniform_location(std::string name); gl::GLint get_uniform_location(std::string name);
void init_streams(std::ifstream vert, std::ifstream frag);
void init_source(std::string vertsource, std::string fragsource);
public: public:
Shader(std::ifstream vert, std::ifstream frag); Shader();
Shader(const char* vertpath, const char* fragpath);
Shader(std::string vert, std::string frag); Shader(std::string vert, std::string frag);
void use(); void use();
void set_color_tint(Color col); void set_color_tint(Color &col);
void set_mvp(glm::mat4x4 mvp); void set_mvp(glm::mat4x4 &mvp);
void set_aux_uniform(std::string name, glm::fvec4 val); void set_aux_uniform(std::string name, Color &val);
void set_aux_uniform(std::string name, float val); void set_aux_uniform(std::string name, glm::fvec4 &val);
~Shader(); void set_aux_uniform(std::string name, float &val);
~Shader() = default;
void erase(); void erase();
void print_values();
}; };