From 9182cabf799ea084ea5dd2c802020d816a2ff582 Mon Sep 17 00:00:00 2001 From: Sebastian Krzyszkowiak Date: Wed, 30 May 2018 21:11:46 +0200 Subject: [PATCH] Add abstraction for GPU shaders --- src/CMakeLists.txt | 1 + src/internal.c | 9 ++++++- src/internal.h | 2 +- src/libsuperderpy.c | 1 + src/libsuperderpy.h | 3 ++- src/shader.c | 60 +++++++++++++++++++++++++++++++++++++++++++++ src/shader.h | 29 ++++++++++++++++++++++ src/utils.c | 2 ++ 8 files changed, 104 insertions(+), 3 deletions(-) create mode 100644 src/shader.c create mode 100644 src/shader.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4210432..5d64d3e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -7,6 +7,7 @@ SET(SRC_LIST character.c internal.c tween.c + shader.c ) if (EMSCRIPTEN) list(APPEND SRC_LIST emscripten-audio-stream.c) diff --git a/src/internal.c b/src/internal.c index a223e4d..c202b8b 100644 --- a/src/internal.c +++ b/src/internal.c @@ -351,9 +351,16 @@ SYMBOL_INTERNAL struct libsuperderpy_list* AddToList(struct libsuperderpy_list* return list; } -SYMBOL_INTERNAL struct libsuperderpy_list* RemoveFromList(struct libsuperderpy_list** list, bool (*identity)(struct libsuperderpy_list* elem, void* data), void* data) { +static bool Identity(struct libsuperderpy_list* elem, void* data) { + return elem->data == data; +} + +SYMBOL_INTERNAL struct libsuperderpy_list* RemoveFromList(struct libsuperderpy_list** list, void* data, bool (*identity)(struct libsuperderpy_list* elem, void* data)) { struct libsuperderpy_list *prev = NULL, *tmp = *list, *start; void* d = NULL; + if (!identity) { + identity = Identity; + } while (tmp) { if (identity(tmp, data)) { if (prev) { diff --git a/src/internal.h b/src/internal.h index 8ff57cb..c6959b3 100644 --- a/src/internal.h +++ b/src/internal.h @@ -80,7 +80,7 @@ void* AddGarbage(struct Game* game, void* data); void ClearGarbage(struct Game* game); void ClearScreen(struct Game* game); struct libsuperderpy_list* AddToList(struct libsuperderpy_list* list, void* data); -struct libsuperderpy_list* RemoveFromList(struct libsuperderpy_list** list, bool (*identity)(struct libsuperderpy_list* elem, void* data), void* data); +struct libsuperderpy_list* RemoveFromList(struct libsuperderpy_list** list, void* data, bool (*identity)(struct libsuperderpy_list* elem, void* data)); void AddTimeline(struct Game* game, struct Timeline* timeline); void RemoveTimeline(struct Game* game, struct Timeline* timeline); void DrawTimelines(struct Game* game); diff --git a/src/libsuperderpy.c b/src/libsuperderpy.c index e1b5c04..53cd1d5 100644 --- a/src/libsuperderpy.c +++ b/src/libsuperderpy.c @@ -73,6 +73,7 @@ SYMBOL_EXPORT struct Game* libsuperderpy_init(int argc, char** argv, const char* game->_priv.garbage = NULL; game->_priv.timelines = NULL; + game->_priv.shaders = NULL; game->_priv.paused = false; diff --git a/src/libsuperderpy.h b/src/libsuperderpy.h index 5859991..7a5708f 100644 --- a/src/libsuperderpy.h +++ b/src/libsuperderpy.h @@ -43,6 +43,7 @@ struct Game; #include "character.h" #include "config.h" #include "gamestate.h" +#include "shader.h" #include "timeline.h" #include "tween.h" #include "utils.h" @@ -123,7 +124,7 @@ struct Game { struct Gamestate* current_gamestate; - struct libsuperderpy_list *garbage, *timelines; + struct libsuperderpy_list *garbage, *timelines, *shaders; bool draw; diff --git a/src/shader.c b/src/shader.c new file mode 100644 index 0000000..db4eb04 --- /dev/null +++ b/src/shader.c @@ -0,0 +1,60 @@ +/*! \file shader.c + * \brief GPU shaders abstraction. + */ +/* + * Copyright (c) Sebastian Krzyszkowiak + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include "shader.h" +#include "internal.h" +#include +#include + +ALLEGRO_SHADER* CreateShader(struct Game* game, const char* vertex, const char* fragment) { + const char* log; + + PrintConsole(game, "Creating shader V:%s F:%s...", vertex, fragment); + + ALLEGRO_SHADER* shader = al_create_shader(ALLEGRO_SHADER_GLSL); + if (!al_attach_shader_source_file(shader, ALLEGRO_VERTEX_SHADER, vertex)) { + log = al_get_shader_log(shader); + if (log) { + PrintConsole(game, "%s", log); + } + } + if (!al_attach_shader_source_file(shader, ALLEGRO_PIXEL_SHADER, fragment)) { + log = al_get_shader_log(shader); + if (log) { + PrintConsole(game, "%s", log); + } + } + if (!al_build_shader(shader)) { + log = al_get_shader_log(shader); + if (log) { + PrintConsole(game, "%s", log); + } + } + + game->_priv.shaders = AddToList(game->_priv.shaders, shader); + + PrintConsole(game, "Shader compiled successfully."); + + return shader; +} + +void DestroyShader(struct Game* game, ALLEGRO_SHADER* shader) { + RemoveFromList(&game->_priv.shaders, shader, NULL); + al_destroy_shader(shader); +} diff --git a/src/shader.h b/src/shader.h new file mode 100644 index 0000000..4205f1a --- /dev/null +++ b/src/shader.h @@ -0,0 +1,29 @@ +/*! \file shader.h + * \brief GPU shaders abstraction. + */ +/* + * Copyright (c) Sebastian Krzyszkowiak + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LIBSUPERDERPY_SHADER_H +#define LIBSUPERDERPY_SHADER_H + +#include "libsuperderpy.h" + +ALLEGRO_SHADER *CreateShader(struct Game *game, const char* vertex, const char* fragment); +void DestroyShader(struct Game *game, ALLEGRO_SHADER *shader); + +#endif diff --git a/src/utils.c b/src/utils.c index ea237a8..939ecdd 100644 --- a/src/utils.c +++ b/src/utils.c @@ -27,6 +27,8 @@ #include #include +// TODO: split to separate files + SYMBOL_EXPORT void DrawVerticalGradientRect(float x, float y, float w, float h, ALLEGRO_COLOR top, ALLEGRO_COLOR bottom) { ALLEGRO_VERTEX v[] = { {.x = x, .y = y, .z = 0, .color = top},