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}")
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)
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)
{
// 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
if ((error > 0) || (!error && (ix > 0)))
@ -115,9 +115,9 @@ bool line_of_sight(Tilemap *map, vec2i start, vec2i end) {
else
{
// 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
if ((error > 0) || (!error && (iy > 0)))

View file

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

View file

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

View file

@ -11,6 +11,7 @@
#include <glm/gtx/transform.hpp>
#include <glm/matrix.hpp>
#include <utility>
#include "Shader.h"
using namespace gl;
@ -106,12 +107,42 @@ Renderer::~Renderer() {
SDL_LogDebug(SDL_LOG_CATEGORY_RENDER, "Renderer destroyed.");
}
GLuint shaderProg;
GLuint wireShaderProg;
Shader mainshader;
Shader wireshader;
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) {
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();
/*
GLenum err = glewInit();
if (err != GLEW_OK) {
SDL_LogCritical(SDL_LOG_CATEGORY_RENDER, "Failed to initialize OpenGl: %s\n", glewGetErrorString(err));
return false;
}
glEnable(GL_DEBUG_OUTPUT);
//glDebugMessageCallback((GLDEBUGPROC)MessageCallback, 0);
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);
ImGui_ImplSdlGL3_Init(window);
@ -156,22 +177,10 @@ bool Renderer::Init(std::string title, int width, int height) {
glBindBuffer(GL_ARRAY_BUFFER, spriteVBuf);
glBufferData(GL_ARRAY_BUFFER, sizeof(rectVertData), rectVertData, GL_STATIC_DRAW);
GLuint frag = LoadShader("assets/main.frag", GL_FRAGMENT_SHADER);
GLuint vert = LoadShader("assets/main.vert", GL_VERTEX_SHADER);
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);
mainshader = Shader("assets/main.vert", "assets/main.frag");
mainshader.print_values();
glUseProgram(shaderProg);
colorUniform = glGetUniformLocation(shaderProg, "colortint");
bgUniform = glGetUniformLocation(shaderProg, "colorbackground");
mvpUniform = glGetUniformLocation(shaderProg, "MVP");
wireshader = Shader("assets/wireframe.vert", "assets/wireframe.frag");
set_window_size(width, height);
@ -193,7 +202,7 @@ void Renderer::set_window_size(int width, int height) {
heightmult = 1. / windowheight * 2;
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;
SDL_LogDebug(SDL_LOG_CATEGORY_RENDER, "Window size set to %dx%d.\n", windowwidth, windowheight);
@ -237,54 +246,51 @@ bool Renderer::ImguiProcessEvents(SDL_Event *e) {
void Renderer::ImguiNewFrame() {
ImGui_ImplSdlGL3_NewFrame(window);
}
Texture * Renderer::LoadTexture(std::string path) {
auto it = textures.find(path);
if (it == textures.end()) {
SDL_LogVerbose(SDL_LOG_CATEGORY_RENDER, "Loading texture: %s\n", path.c_str());
// Texture not loaded, let's load it.
SDL_Surface* surface = SDL_LoadBMP(path.c_str());
SDL_LogVerbose(SDL_LOG_CATEGORY_RENDER, "Loaded surface.");
if (surface != NULL) {
GLuint textureId;
glGenTextures(1, &textureId);
glBindTexture(GL_TEXTURE_2D, textureId);
if (it != textures.end()) return &it->second; // Texture already loaded
GLenum mode = GL_RGB;
if (surface->format->BytesPerPixel == 4) {
mode = GL_RGBA;
}
SDL_LogVerbose(SDL_LOG_CATEGORY_RENDER, "Loading texture: %s\n", path.c_str());
// Texture not loaded, let's load it.
SDL_Surface* surface = SDL_LoadBMP(path.c_str());
SDL_LogVerbose(SDL_LOG_CATEGORY_RENDER, "Loaded surface.");
if (surface != NULL) {
GLuint textureId;
glGenTextures(1, &textureId);
glBindTexture(GL_TEXTURE_2D, textureId);
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
SDL_LogVerbose(SDL_LOG_CATEGORY_RENDER, "Sending %dx%d texture to GPU...", surface->w, surface->h);
glTexImage2D(GL_TEXTURE_2D, 0, mode, surface->w, surface->h, 0, mode, GL_UNSIGNED_BYTE, surface->pixels);
SDL_LogVerbose(SDL_LOG_CATEGORY_RENDER, "Loaded texture to GPU.");
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
Texture t{};
t.id = textureId;
t.w = surface->w;
t.h = surface->h;
SDL_FreeSurface(surface);
SDL_LogVerbose(SDL_LOG_CATEGORY_RENDER, "Freed surface.");
textures.insert(std::pair<std::string, Texture>(path, t));
SDL_LogDebug(SDL_LOG_CATEGORY_RENDER, "Loaded texture \"%s\"\n", path.c_str());
return &textures[path];
}
else {
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "Could not load texture \"%s\"\n\t%s\n", path.c_str(), SDL_GetError());
return nullptr;
GLenum mode = GL_RGB;
if (surface->format->BytesPerPixel == 4) {
mode = GL_RGBA;
}
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
SDL_LogVerbose(SDL_LOG_CATEGORY_RENDER, "Sending %dx%d texture to GPU...", surface->w, surface->h);
glTexImage2D(GL_TEXTURE_2D, 0, mode, surface->w, surface->h, 0, mode, GL_UNSIGNED_BYTE, surface->pixels);
SDL_LogVerbose(SDL_LOG_CATEGORY_RENDER, "Loaded texture to GPU.");
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
Texture t{};
t.id = textureId;
t.w = surface->w;
t.h = surface->h;
SDL_FreeSurface(surface);
SDL_LogVerbose(SDL_LOG_CATEGORY_RENDER, "Freed surface.");
textures.insert(std::pair<std::string, Texture>(path, t));
SDL_LogDebug(SDL_LOG_CATEGORY_RENDER, "Loaded texture \"%s\"\n", path.c_str());
return &textures[path];
}
else {
// Texture already loaded, no need to load it again
return &it->second;
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "Could not load texture \"%s\"\n\t%s\n", path.c_str(), SDL_GetError());
return nullptr;
}
}
@ -305,7 +311,6 @@ Sprite Renderer::CreateSprite(std::string path, int x, int y, int w, int h) {
x / tw, (y + h) / th,
(x + w) / tw, (y + h) / th,
};
glCreateBuffers(1, &sprite.uvBuf);
glBindBuffer(GL_ARRAY_BUFFER, sprite.uvBuf);
@ -326,12 +331,11 @@ void Renderer::draw_sprite(Sprite *sprite, Color fg, Color bg, int x, int y, flo
glEnable(GL_BLEND);
glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD);
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);
glUseProgram(shaderProg);
glUniform4f(colorUniform, fg.r, fg.g, fg.b, fg.a);
glUniform4f(bgUniform, bg.r, bg.g, bg.b, bg.a);
glUniformMatrix4fv(mvpUniform, 1, GL_FALSE, &mvp[0][0]);
mainshader.use();
mainshader.set_mvp(mvp);
mainshader.set_color_tint(fg);
mainshader.set_aux_uniform("colorbackground", bg);
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);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
if (wireframe) {
wireshader.use();
wireshader.set_mvp(mvp);
Color white = Color(1.0f,1.0f,1.0f,1.0f);
wireshader.set_color_tint(white);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glUseProgram(wireShaderProg);
glUniform4f(colorUniform, 1, 1, 1, 1);
glUniformMatrix4fv(mvpUniform, 1, GL_FALSE, &mvp[0][0]);
glBindVertexArray(spriteVertArrayId);
glEnableVertexAttribArray(0);
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);
}
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(1);
}
void Renderer::Clear() {

View file

@ -12,13 +12,15 @@ gl::GLint Shader::get_uniform_location(std::string name) {
auto it = uniforms.find(name);
if (it == uniforms.end()) {
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 it->second;
}
Shader::Shader(std::ifstream vert, std::ifstream frag) {
void Shader::init_streams(std::ifstream vert, std::ifstream frag) {
std::string vsource;
if (vert.is_open()) {
std::string line;
@ -27,6 +29,9 @@ Shader::Shader(std::ifstream vert, std::ifstream frag) {
}
vert.close();
}
else {
SDL_LogWarn(SDL_LOG_CATEGORY_RENDER, "Could not load vert shader!");
}
std::string fsource;
if (frag.is_open()) {
@ -36,13 +41,16 @@ Shader::Shader(std::ifstream vert, std::ifstream frag) {
}
frag.close();
}
else {
SDL_LogWarn(SDL_LOG_CATEGORY_RENDER, "Could not load frag shader!");
}
Shader(vsource, fsource);
init_source(vsource, fsource);
}
Shader::Shader(std::string vertsource, std::string fragsource) {
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();
glShaderSource(vert_id, 1, &vs, nullptr);
@ -79,39 +87,73 @@ Shader::Shader(std::string vertsource, std::string fragsource) {
result = GL_FALSE;
infologlength = 0;
glGetShaderiv(program_id, GL_LINK_STATUS, &result);
glGetShaderiv(program_id, GL_INFO_LOG_LENGTH, &infologlength);
glGetProgramiv(program_id, GL_LINK_STATUS, &result);
glGetProgramiv(program_id, GL_INFO_LOG_LENGTH, &infologlength);
if (infologlength > 0) {
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]);
}
glDetachShader(program_id, vert_id);
glDetachShader(program_id, frag_id);
glDeleteShader(vert_id);
glDeleteShader(frag_id);
// glDeleteShader(vert_id);
// glDeleteShader(frag_id);
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");
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::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);
}
Shader::~Shader() {}
void Shader::erase() {
if (program_id) {
glDeleteShader(program_id);
if (frag_id != 0)
{
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 <map>
#include <fstream>
#include <glbinding/gl/types.h>
#include <glm/common.hpp>
#include "Renderer.h"
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_mvp;
std::map<std::string, gl::GLint> uniforms;
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:
Shader(std::ifstream vert, std::ifstream frag);
Shader();
Shader(const char* vertpath, const char* fragpath);
Shader(std::string vert, std::string frag);
void use();
void set_color_tint(Color col);
void set_mvp(glm::mat4x4 mvp);
void set_aux_uniform(std::string name, glm::fvec4 val);
void set_aux_uniform(std::string name, float val);
~Shader();
void set_color_tint(Color &col);
void set_mvp(glm::mat4x4 &mvp);
void set_aux_uniform(std::string name, Color &val);
void set_aux_uniform(std::string name, glm::fvec4 &val);
void set_aux_uniform(std::string name, float &val);
~Shader() = default;
void erase();
void print_values();
};