added framebuffer; also opengl debugging

This commit is contained in:
DaniTheSkunk 2023-01-12 05:10:47 +00:00
parent 75f83bf3f6
commit 35d6299688
9 changed files with 240 additions and 8 deletions

BIN
gfx.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

20
include/framebuffer.h Normal file
View File

@ -0,0 +1,20 @@
#ifndef GUARD_4770FE04EA612B028DF68960A453BD0B
#define GUARD_4770FE04EA612B028DF68960A453BD0B
#include "types.h"
#include "vec2i.h"
struct sw_framebuffer {
struct sw_vec2i size;
u32 _fb, _fbtex, _fbdepth;
};
struct sw_framebuffer *sw_framebuffer_create(struct sw_vec2i size);
void sw_framebuffer_destroy(struct sw_framebuffer *fb);
void sw_framebuffer_static_init();
void sw_framebuffer_copy_to_screen(struct sw_framebuffer *fb);
void sw_framebuffer_resize(struct sw_framebuffer *fb, struct sw_vec2i new_size);
#endif /* GUARD_4770FE04EA612B028DF68960A453BD0B */

8
include/scaler.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef GUARD_D3B2B8EAB7F3D9A513B3C06FAAF6357E
#define GUARD_D3B2B8EAB7F3D9A513B3C06FAAF6357E
#define SW_SCALE_STRETCH 0
#define SW_SCALE_ASPECT 1
#define SW_SCALE_INTEGER 2
#endif /* GUARD_D3B2B8EAB7F3D9A513B3C06FAAF6357E */

View File

@ -1,14 +1,19 @@
#ifndef GUARD_F247452E0BF1EC9CD9131C2A6FD281CA
#define GUARD_F247452E0BF1EC9CD9131C2A6FD281CA
#include "framebuffer.h"
#include "types.h"
#include "vec2i.h"
struct GLFWwindow;
struct sw_window {
struct sw_vec2i size;
struct sw_vec2i real_size;
i32 scaler;
struct GLFWwindow *_window;
struct sw_framebuffer *_scaler_fb;
};
struct sw_window *sw_window_create(struct sw_vec2i size, char *title);

View File

@ -43,6 +43,7 @@ skunk_sources = [
'src/color32.c',
'src/error.c',
'src/file.c',
'src/framebuffer.c',
'src/gsa.c',
'src/image32.c',
'src/image8.c',

134
src/framebuffer.c Normal file
View File

@ -0,0 +1,134 @@
#include "framebuffer.h"
#include "error.h"
#include "gl.h"
#include "shader.h"
#include <stdlib.h>
static struct sw_shaderprogram program_copy;
static char *vert_copy = "#version 300 es\n\
precision highp float;\
in vec2 pos;\
out vec2 out_tex_coord;\
void main() {\
gl_Position = vec4(pos, 0.0f, 1.0f);\
out_tex_coord = vec2(pos.x * 0.5 + 0.5, pos.y * 0.5 + 0.5);\
}";
static char *frag_copy = "#version 300 es\n\
precision highp float;\
in vec2 out_tex_coord;\
uniform sampler2D tex;\
out vec4 color;\
void main() {\
vec4 col = texture(tex, out_tex_coord);\
if(col.a > 0.0) {\
color = col;\
}\
}";
static f32 screen_rect[12] = {
-1.f, -1.f, 1.f, -1.f, -1.f, 1.f, 1.f, -1.f, -1.f, 1.f, 1.f, 1.f};
static u32 vao, vbo;
struct sw_framebuffer *sw_framebuffer_create(struct sw_vec2i size) {
struct sw_framebuffer *fb;
sw_log("init framebuffer");
fb = malloc(sizeof(struct sw_framebuffer));
glGenFramebuffers(1, &fb->_fb);
glGenTextures(1, &fb->_fbtex);
glGenTextures(1, &fb->_fbdepth);
sw_framebuffer_resize(fb, size);
return fb;
}
void sw_framebuffer_destroy(struct sw_framebuffer *fb) {
glDeleteTextures(1, &fb->_fbtex);
glDeleteFramebuffers(1, &fb->_fb);
}
void sw_framebuffer_static_init() {
sw_log("init static framebuffer");
program_copy = sw_shaderprogram_create(vert_copy, frag_copy);
sw_log("init static framebuffer vao");
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
sw_log("init static framebuffer vbo");
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(
GL_ARRAY_BUFFER, sizeof(f32) * 12, screen_rect, GL_STATIC_DRAW
);
glGetAttribLocation(program_copy._program, "pos");
glVertexAttribPointer(
glGetAttribLocation(program_copy._program, "pos"),
2,
GL_FLOAT,
GL_FALSE,
0,
0
);
glEnableVertexAttribArray(glGetAttribLocation(program_copy._program, "pos")
);
glBindVertexArray(0);
sw_log("init static framebuffer done");
}
void sw_framebuffer_copy_to_screen(struct sw_framebuffer *fb) {
glBindVertexArray(vao);
sw_shaderprogram_use(program_copy);
glBindTexture(GL_TEXTURE_2D, fb->_fbtex);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDrawArrays(GL_TRIANGLES, 0, 12);
glBindVertexArray(0);
}
void sw_framebuffer_resize(
struct sw_framebuffer *fb, struct sw_vec2i new_size
) {
sw_log("resize framebuffer to %ix%i", new_size.x, new_size.y);
fb->size = new_size;
glBindFramebuffer(GL_FRAMEBUFFER, fb->_fb);
glBindTexture(GL_TEXTURE_2D, fb->_fbtex);
glTexImage2D(
GL_TEXTURE_2D,
0,
GL_RGBA8,
new_size.x,
new_size.y,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
0
);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, fb->_fbtex, 0);
glBindTexture(GL_TEXTURE_2D, fb->_fbdepth);
glTexImage2D(
GL_TEXTURE_2D,
0,
GL_DEPTH_COMPONENT,
new_size.x,
new_size.y,
0,
GL_DEPTH_COMPONENT,
GL_UNSIGNED_SHORT,
0
);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, fb->_fbdepth, 0);
}

View File

@ -54,18 +54,17 @@ static i32 next_render_vert;
static struct render_vert render_verts[MAX_RENDER_VERTS * 4];
static sw_color32 palette[256];
static f32 palette_gl[1024];
static u32 tex;
int gsa_main(int argc, char *argv[]) {
(void)argc;
(void)argv;
u32 tex;
i32 max_components;
sw_log("Initialising GameSkunkAdvance v0.0");
_win = sw_window_create(sw_vec2i(304, 176), "Game Skunk Advance v0.0");
program = sw_shaderprogram_create(vert_source, frag_source);
sw_shaderprogram_use(program);
glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS, &max_components);
sw_log("GL_MAX_VERTEX_UNIFORM_COMPONENTS: %i", max_components);
@ -88,9 +87,11 @@ int gsa_main(int argc, char *argv[]) {
_gfx->_data
);
glGenBuffers(1, &vao);
sw_log("setup gsa vao");
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
sw_log("setup gsa vbo");
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glVertexAttribPointer(
@ -112,7 +113,9 @@ int gsa_main(int argc, char *argv[]) {
glEnableVertexAttribArray(glGetAttribLocation(program._program, "pos"));
glEnableVertexAttribArray(glGetAttribLocation(program._program, "tex_coord")
);
glBindVertexArray(0);
sw_log("gsa setup done");
init();
sw_window_run(_win, _gsa_tick);
@ -202,8 +205,11 @@ void _gsa_tick() {
sw_color32_get_bf(palette[0]),
sw_color32_get_af(palette[0])
);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindVertexArray(vao);
sw_shaderprogram_use(program);
glBindTexture(GL_TEXTURE_2D, tex);
/* TODO: only do when palette changed */
update_palette_gl();
glUniform4fv(
@ -216,5 +222,6 @@ void _gsa_tick() {
GL_DYNAMIC_DRAW
);
glDrawArrays(GL_TRIANGLES, 0, next_render_vert);
glBindVertexArray(0);
/* glEnd(); */
}

View File

@ -11,6 +11,8 @@ struct sw_shader sw_shader_create(char const *source, i32 type) {
i32 length;
i32 ret;
sw_log("create shader");
switch(type) {
case SW_SHADER_VERTEX:
gltype = GL_VERTEX_SHADER;
@ -44,14 +46,24 @@ struct sw_shaderprogram
sw_shaderprogram_create(char const *vertex, char const *fragment) {
struct sw_shaderprogram program;
struct sw_shader v, f;
i32 ret;
sw_log("create shader program");
v = sw_shader_create(vertex, SW_SHADER_VERTEX);
f = sw_shader_create(fragment, SW_SHADER_FRAGMENT);
program._program = glCreateProgram();
glAttachShader(program._program, v._shader);
glAttachShader(program._program, f._shader);
sw_log("link shader");
glLinkProgram(program._program);
glGetProgramiv(program._program, GL_LINK_STATUS, &ret);
if(!ret) {
char str[256];
i32 len;
glGetProgramInfoLog(program._program, 256, &len, str);
sw_error("Shader Link Error: %s", str);
}
return program;
}

View File

@ -2,11 +2,22 @@
#include <stdlib.h>
#include "error.h"
#include "framebuffer.h"
#include "gl.h"
void _tick();
struct sw_window *_tick_window;
void (*_tick_fn)();
static void _tick();
static struct sw_window *_tick_window;
static void (*_tick_fn)();
static void GLAPIENTRY gldebug(
GLenum source,
GLenum type,
GLuint id,
GLenum severity,
GLsizei length,
const char *msg,
const void *user
);
struct sw_window *sw_window_create(struct sw_vec2i size, char *title) {
struct sw_window *win;
@ -14,6 +25,7 @@ struct sw_window *sw_window_create(struct sw_vec2i size, char *title) {
win = malloc(sizeof(struct sw_window));
win->size = size;
sw_log("init glfw");
glfwInit();
glfwDefaultWindowHints();
@ -21,16 +33,24 @@ struct sw_window *sw_window_create(struct sw_vec2i size, char *title) {
glfwShowWindow(win->_window);
glfwMakeContextCurrent(win->_window);
glewInit();
glEnable(GL_DEBUG_OUTPUT);
glDebugMessageCallback(gldebug, 0);
glfwSwapInterval(1);
sw_log("setup ogl defaults");
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glEnable(GL_DEPTH_TEST);
sw_framebuffer_static_init(); /* TODO: move elsewhere */
win->_scaler_fb = sw_framebuffer_create(size);
glClearColor(0.1f, 0.2f, 0.3f, 1.f);
sw_log("window setup complete");
return win;
}
void sw_window_run(struct sw_window *window, void (*callback)()) {
sw_log("run window");
_tick_window = window;
_tick_fn = callback;
#ifdef __EMSCRIPTEN__
@ -45,8 +65,33 @@ void sw_window_run(struct sw_window *window, void (*callback)()) {
/* private functions */
void _tick() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindFramebuffer(GL_FRAMEBUFFER, _tick_window->_scaler_fb->_fb);
_tick_fn();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
sw_framebuffer_copy_to_screen(_tick_window->_scaler_fb);
glfwSwapBuffers(_tick_window->_window);
glfwPollEvents();
}
void GLAPIENTRY gldebug(
GLenum source,
GLenum type,
GLuint id,
GLenum severity,
GLsizei length,
const char *msg,
const void *user
) {
(void)source;
(void)id;
(void)severity;
(void)length;
(void)user;
if(type == GL_DEBUG_TYPE_ERROR) {
sw_error("%s", msg);
} else {
sw_log("%s", msg);
}
}