From 0d997bc08b95cd70c792587fbf88dc1f24de06bb Mon Sep 17 00:00:00 2001 From: Dominic Masters Date: Wed, 5 May 2021 07:37:25 -0700 Subject: [PATCH] Added frame buffer support. --- assets/shaders/{test.frag => textured.frag} | 3 +- assets/shaders/{test.vert => textured.vert} | 0 include/dawn/dawn.h | 1 + include/dawn/display/framebuffer.h | 16 +++++ include/dawn/display/texture.h | 2 +- src/display/framebuffer.c | 68 +++++++++++++++++++++ src/display/framebuffer.h | 34 +++++++++++ src/display/gui/font.h | 21 +++++++ src/display/render.c | 1 - src/display/texture.c | 2 + src/game/game.c | 57 +++++++---------- src/game/game.h | 10 ++- 12 files changed, 170 insertions(+), 45 deletions(-) rename assets/shaders/{test.frag => textured.frag} (62%) rename assets/shaders/{test.vert => textured.vert} (100%) create mode 100644 include/dawn/display/framebuffer.h create mode 100644 src/display/framebuffer.c create mode 100644 src/display/framebuffer.h diff --git a/assets/shaders/test.frag b/assets/shaders/textured.frag similarity index 62% rename from assets/shaders/test.frag rename to assets/shaders/textured.frag index 945dbdd6..a19c1548 100644 --- a/assets/shaders/test.frag +++ b/assets/shaders/textured.frag @@ -8,5 +8,6 @@ out vec4 FragColor; void main() { vec4 color = texture(u_Text, TexCoord); - FragColor = color; + FragColor = color + vec4(0.25, 0.25, 0.25, 1); + // FragColor = vec4(1, 0, 0, 1); } \ No newline at end of file diff --git a/assets/shaders/test.vert b/assets/shaders/textured.vert similarity index 100% rename from assets/shaders/test.vert rename to assets/shaders/textured.vert diff --git a/include/dawn/dawn.h b/include/dawn/dawn.h index 66e70503..4ff6f2fa 100644 --- a/include/dawn/dawn.h +++ b/include/dawn/dawn.h @@ -8,6 +8,7 @@ // Display / Rendering #include "display/camera.h" +#include "display/framebuffer.h" #include "display/primitive.h" #include "display/render.h" #include "display/shader.h" diff --git a/include/dawn/display/framebuffer.h b/include/dawn/display/framebuffer.h new file mode 100644 index 00000000..89cc9af8 --- /dev/null +++ b/include/dawn/display/framebuffer.h @@ -0,0 +1,16 @@ +/** + * Copyright (c) 2021 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#pragma once +#include "../libs.h" +#include "texture.h" + +typedef struct { + GLuint fboId; + GLuint rboId; + texture_t *texture; +} framebuffer_t; \ No newline at end of file diff --git a/include/dawn/display/texture.h b/include/dawn/display/texture.h index 595c0b81..885d1767 100644 --- a/include/dawn/display/texture.h +++ b/include/dawn/display/texture.h @@ -19,5 +19,5 @@ typedef struct { /** Information about a single pixel. */ typedef struct { - uint8_t r, g, b, a ; + uint8_t r, g, b, a; } pixel_t; diff --git a/src/display/framebuffer.c b/src/display/framebuffer.c new file mode 100644 index 00000000..90b26b98 --- /dev/null +++ b/src/display/framebuffer.c @@ -0,0 +1,68 @@ +/** + * Copyright (c) 2021 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#include "framebuffer.h" + +framebuffer_t * frameBufferCreate(int32_t w, int32_t h) { + framebuffer_t *fb = malloc(sizeof(framebuffer_t)); + if(fb == NULL) return NULL; + + // Create Color Attachment texture. + fb->texture = textureCreate(w, h, NULL); + if(fb->texture == NULL) { + free(fb); + return NULL; + } + + // Create Frame Buffer + glGenFramebuffers(1, &fb->fboId); + glBindFramebuffer(GL_FRAMEBUFFER, fb->fboId); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + GL_TEXTURE_2D, fb->texture->id, 0 + ); + + // Render Buffer + glGenRenderbuffers(1, &fb->rboId); + glBindRenderbuffer(GL_RENDERBUFFER, fb->rboId); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, w, h); + glBindRenderbuffer(GL_RENDERBUFFER, 0); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, + GL_RENDERBUFFER, fb->rboId + ); + + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { + uint32_t error; + error = 0; + } + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + return fb; +} + +void frameBufferUse(framebuffer_t *frameBuffer, bool clear) { + if(frameBuffer == NULL) { + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glViewport(0, 0, RENDER_STATE.width, RENDER_STATE.height); + } else { + glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer->fboId); + glViewport(0, 0, frameBuffer->texture->width, frameBuffer->texture->height); + } + + if(clear) { + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + } +} + +void frameBufferDispose(framebuffer_t *frameBuffer) { + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glBindRenderbuffer(GL_RENDERBUFFER, 0); + glDeleteRenderbuffers(1, &frameBuffer->rboId); + glDeleteFramebuffers(1, &frameBuffer->fboId); + textureDispose(frameBuffer->texture); + free(frameBuffer); +} \ No newline at end of file diff --git a/src/display/framebuffer.h b/src/display/framebuffer.h new file mode 100644 index 00000000..2bb93ef5 --- /dev/null +++ b/src/display/framebuffer.h @@ -0,0 +1,34 @@ +/** + * Copyright (c) 2021 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#pragma once +#include +#include "texture.h" + +/** + * Creates a new frame buffer that can be rendered to. + * + * @param width Width of the frame buffer (in pixels). + * @param height Height of the frame buffer (in pixels). + * @return A renderable frame buffer. + */ +framebuffer_t * frameBufferCreate(int32_t width, int32_t height); + +/** + * Use a given frame buffer as the current rendering context. + * + * @param frameBuffer Frame buffer to use, or NULL to not use any. + * @param clear Whether or not to clear the frame buffer prior to rendering. + */ +void frameBufferUse(framebuffer_t *frameBuffer, bool clear); + +/** + * Dispose/cleanup a previously created frame buffer. + * + * @param frameBuffer Frame Buffer to clean. + */ +void frameBufferDispose(framebuffer_t *frameBuffer); \ No newline at end of file diff --git a/src/display/gui/font.h b/src/display/gui/font.h index d4a0040c..552c89c0 100644 --- a/src/display/gui/font.h +++ b/src/display/gui/font.h @@ -11,7 +11,28 @@ #define FONT_CHAR_START 33 +/** + * Get the division for a given character. + * + * @param tileset Tileset to get the division from. + * @param character Character to get the division for. + * @return The division from the tileset for the character. + */ tilesetdiv_t * fontGetCharacterDivision(tileset_t *tileset, char character); + +/** + * Renders a set of font characters to the sprite. Coordinates are anchored to + * the top left (0,0) origin. + * + * @param batch Sprite Batch to render to. + * @param tileset Tileset for the font. + * @param string String to render. + * @param x Position in X space. + * @param y Position in Y space. + * @param z Position in Z space. + * @param charWidth Width of each character. + * @param charHeight Height of each character. + */ void fontSpriteBatchBuffer(spritebatch_t *batch, tileset_t *tileset, char *string, float x, float y, float z, float charWidth, float charHeight ); \ No newline at end of file diff --git a/src/display/render.c b/src/display/render.c index b060ddfd..445ea457 100644 --- a/src/display/render.c +++ b/src/display/render.c @@ -32,5 +32,4 @@ void renderDispose() { void renderSetResolution(int32_t width, int32_t height) { RENDER_STATE.width = width; RENDER_STATE.height = height; - glViewport(0, 0, width, height); } \ No newline at end of file diff --git a/src/display/texture.c b/src/display/texture.c index 0f98ea40..5476a4a9 100644 --- a/src/display/texture.c +++ b/src/display/texture.c @@ -41,6 +41,8 @@ texture_t * textureCreate(int32_t width, int32_t height, pixel_t *pixels) { GL_RGBA, GL_UNSIGNED_BYTE, pixels ); } + + glBindTexture(GL_TEXTURE_2D, 0); return texture; } diff --git a/src/game/game.c b/src/game/game.c index 12fddaaa..cc4063f5 100644 --- a/src/game/game.c +++ b/src/game/game.c @@ -9,11 +9,9 @@ game_t GAME_STATE; -holdemgame_t holdem; -holdemrender_t render; - -texture_t *fontTexture; -spritebatch_t *fontBatch; +primitive_t *prim; +framebuffer_t *fbo; +texture_t *text; bool gameInit() { // Init the game @@ -25,29 +23,14 @@ bool gameInit() { inputInit(); worldInit(); - holdemGameInit(&holdem); - holdemRenderInit(&render); + prim = cubeCreate(1, 1, 1); + text = assetTextureLoad("bruh.png"); - holdemRoundInit(&holdem); - cardShuffle(holdem.deck, holdem.deckSize); - - // Deal Card - holdemDealAll(&holdem, 2); - holdemFlop(&holdem); - - fontTexture = assetTextureLoad("font.png"); - fontBatch = spriteBatchCreate(100); - tileset_t *tileset = tilesetCreate(20, 20, - fontTexture->width, fontTexture->height, - 1, 1, 1, 1 - ); - - char *buffer = "!\"#$%"; - fontSpriteBatchBuffer(fontBatch, tileset, buffer, 0, 0, 0, 1.1, 1.5); + fbo = frameBufferCreate(128, 128); // Load the world shader. GAME_STATE.shaderWorld = assetShaderLoad( - "shaders/test.vert", "shaders/test.frag" + "shaders/textured.vert", "shaders/textured.frag" ); // Init the input manger. @@ -59,25 +42,27 @@ bool gameUpdate(float platformDelta) { renderFrameStart(); inputUpdate(); - // Attach the world shader + // Set up the camera and shader. shaderUse(GAME_STATE.shaderWorld); + frameBufferUse(fbo, true); + cameraLookAt(&GAME_STATE.cameraWorld, 2, 2, 2, 0, 0, 0); + cameraPerspective(&GAME_STATE.cameraWorld, 45.0f, + ((float)fbo->texture->width) / ((float)fbo->texture->height), + 0.5f, 500.0f + ); + shaderUseCamera(GAME_STATE.shaderWorld, &GAME_STATE.cameraWorld); + shaderUsePosition(GAME_STATE.shaderWorld, 0, 0, 0, TIME_STATE.current, TIME_STATE.current, 0); + shaderUseTexture(GAME_STATE.shaderWorld, text); + primitiveDraw(prim, 0, prim->indiceCount); - // Set up the camera. - int x = 10; - cameraLookAt(&GAME_STATE.cameraWorld, x, 2.5f, 50, x, 2, 0); + frameBufferUse(NULL, true); + shaderUseTexture(GAME_STATE.shaderWorld, fbo->texture); cameraPerspective(&GAME_STATE.cameraWorld, 45.0f, ((float)RENDER_STATE.width) / ((float)RENDER_STATE.height), 0.5f, 500.0f ); shaderUseCamera(GAME_STATE.shaderWorld, &GAME_STATE.cameraWorld); - - - shaderUseTexture(GAME_STATE.shaderWorld, fontTexture); - spriteBatchDraw(fontBatch, 0, -1); - - // holdemRender(&render, &holdem); - // Render the game scene. - // worldRender(); + primitiveDraw(prim, 0, prim->indiceCount); if(inputIsPressed(INPUT_NULL)) return false; return true; diff --git a/src/game/game.h b/src/game/game.h index 0952d038..df389c37 100644 --- a/src/game/game.h +++ b/src/game/game.h @@ -11,13 +11,11 @@ #include "../display/shader.h" #include "../file/asset.h" #include "../input/input.h" -#include "../world/world.h" -#include "../world/entity/entity.h" -#include "../card/poker/holdem.h" -#include "../display/gui/font.h" -#include "../display/spritebatch.h" -#include "../display/tileset.h" +#include "../display/primitive.h" +#include "../display/framebuffer.h" +#include "../display/primitives/cube.h" +#include "../display/primitives/quad.h" /** * Initialize the game context.