Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .clang-format
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,4 @@ AllowShortBlocksOnASingleLine: 'Never'
AlignArrayOfStructures: Left
IndentCaseLabels: true
AllowShortEnumsOnASingleLine: false

24 changes: 24 additions & 0 deletions shaders/remap.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#version 330 core

// In
in vec2 tex_coord;

uniform sampler2D framebuffer;
uniform sampler2D remaps;

// Out
layout (location = 0) out vec4 color;

void main() {
vec4 texel = texture(framebuffer, tex_coord);
int remap_count = int(texel.b * 255.0);
float remap_index = clamp(texel.g * 255.0, 0, 18.0) / 18.0;
texel.r += texel.a;

// TODO: precalculate palette to 2d texture for required remappings later.
for (int i = 0; i < remap_count; i++) {
texel = texture(remaps, vec2(texel.r, remap_index));
}

color = vec4(texel.r, 0, 0, 0);
}
12 changes: 12 additions & 0 deletions shaders/remap.vert
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#version 330 core

const vec2 posCoord[4] = vec2[](vec2(320.0, 200.0), vec2(0.0, 200.0), vec2(0.0, 0.0), vec2(320.0, 0.0));
const vec2 texCoord[4] = vec2[](vec2(1.0, 0.0), vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0));

out vec2 tex_coord;
uniform mat4 projection;

void main() {
tex_coord = texCoord[gl_VertexID].xy;
gl_Position = projection * vec4(posCoord[gl_VertexID].xy, 0.0, 1.0);
}
12 changes: 1 addition & 11 deletions shaders/rgba.frag
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,11 @@ layout (std140) uniform palette {
};

uniform sampler2D framebuffer;
uniform sampler2D remaps;

// Out
layout (location = 0) out vec4 color;

void main() {
vec4 texel = texture(framebuffer, tex_coord);
int remap_count = int(texel.b * 255.0);
float remap_index = clamp(texel.g * 255.0, 0, 18.0) / 18.0;
texel.r += texel.a;

// TODO: precalculate palette to 2d texture for required remappings later.
for (int i = 0; i < remap_count; i++) {
texel = texture(remaps, vec2(texel.r, remap_index));
}

color = colors[int(255.0 * texel.r)];
}
}
49 changes: 34 additions & 15 deletions src/video/renderers/opengl3/gl3_renderer.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@
#include "video/vga_state.h"

#define TEX_UNIT_ATLAS 0
#define TEX_UNIT_FBO 1
#define TEX_UNIT_REMAPS 2
#define TEX_UNIT_REMAP_FBO 1
#define TEX_UNIT_FINAL_FBO 2
#define TEX_UNIT_REMAPS 3
#define PAL_BLOCK_BINDING 0
#define NATIVE_W 320
#define NATIVE_H 200
Expand All @@ -25,7 +26,8 @@ typedef struct gl3_context {
texture_atlas *atlas;
object_array *objects;
shared *shared;
render_target *target;
render_target *remap_target;
render_target *final_target;
remaps *remaps;

int viewport_w;
Expand All @@ -42,6 +44,7 @@ typedef struct gl3_context {

object_array_blend_mode current_blend_mode;
GLuint palette_prog_id;
GLuint remap_prog_id;
GLuint rgba_prog_id;

video_screenshot_signal screenshot_cb;
Expand Down Expand Up @@ -82,9 +85,12 @@ static bool setup_context(void *userdata, int window_w, int window_h, bool fulls
if(!create_program(&ctx->palette_prog_id, "palette.vert", "palette.frag")) {
goto error_2;
}
if(!create_program(&ctx->rgba_prog_id, "rgba.vert", "rgba.frag")) {
if(!create_program(&ctx->remap_prog_id, "remap.vert", "remap.frag")) {
goto error_3;
}
if(!create_program(&ctx->rgba_prog_id, "rgba.vert", "rgba.frag")) {
goto error_4;
}

// Fetch viewport size which may be different from window size.
SDL_GL_GetDrawableSize(ctx->window, &ctx->viewport_w, &ctx->viewport_h);
Expand All @@ -100,7 +106,8 @@ static bool setup_context(void *userdata, int window_w, int window_h, bool fulls
ctx->atlas = atlas_create(TEX_UNIT_ATLAS, 2048, 2048);
ctx->objects = object_array_create(2048.0f, 2048.0f);
ctx->shared = shared_create();
ctx->target = render_target_create(TEX_UNIT_FBO, NATIVE_W, NATIVE_H, GL_RGBA8, GL_RGBA);
ctx->remap_target = render_target_create(TEX_UNIT_REMAP_FBO, NATIVE_W, NATIVE_H, GL_RGBA8, GL_RGBA);
ctx->final_target = render_target_create(TEX_UNIT_FINAL_FBO, NATIVE_W, NATIVE_H, GL_R8, GL_RED);
ctx->remaps = remaps_create(TEX_UNIT_REMAPS);

vga_state_mark_dirty();
Expand All @@ -115,26 +122,30 @@ static bool setup_context(void *userdata, int window_w, int window_h, bool fulls
bind_uniform_1i(ctx->palette_prog_id, "atlas", TEX_UNIT_ATLAS);
bind_uniform_1i(ctx->palette_prog_id, "remaps", TEX_UNIT_REMAPS);

// Activate RGBA conversion program, and bind palette etc.
// Activate remapping program, and bind remaps etc.
activate_program(ctx->remap_prog_id);
bind_uniform_4fv(ctx->remap_prog_id, "projection", projection_matrix);
bind_uniform_1i(ctx->remap_prog_id, "framebuffer", TEX_UNIT_REMAP_FBO);
bind_uniform_1i(ctx->remap_prog_id, "remaps", TEX_UNIT_REMAPS);

// Activate RGBA conversion program and bind palette
activate_program(ctx->rgba_prog_id);
bind_uniform_4fv(ctx->rgba_prog_id, "projection", projection_matrix);
GLuint pal_ubo_id = shared_get_block(ctx->shared);
bind_uniform_block(ctx->rgba_prog_id, "palette", PAL_BLOCK_BINDING, pal_ubo_id);
bind_uniform_1i(ctx->rgba_prog_id, "framebuffer", TEX_UNIT_FBO);
bind_uniform_1i(ctx->rgba_prog_id, "remaps", TEX_UNIT_REMAPS);
bind_uniform_4fv(ctx->rgba_prog_id, "projection", projection_matrix);
bind_uniform_1i(ctx->rgba_prog_id, "framebuffer", TEX_UNIT_FINAL_FBO);

log_info("OpenGL3 Renderer initialized!");
return true;

error_4:
delete_program(ctx->remap_prog_id);
error_3:
delete_program(ctx->palette_prog_id);

error_2:
SDL_GL_DeleteContext(ctx->gl_context);

error_1:
SDL_DestroyWindow(ctx->window);

error_0:
return false;
}
Expand Down Expand Up @@ -179,11 +190,13 @@ static void reset_context(void *userdata) {
static void close_context(void *userdata) {
gl3_context *ctx = userdata;
remaps_free(&ctx->remaps);
render_target_free(&ctx->target);
render_target_free(&ctx->remap_target);
render_target_free(&ctx->final_target);
shared_free(&ctx->shared);
object_array_free(&ctx->objects);
atlas_free(&ctx->atlas);
delete_program(ctx->palette_prog_id);
delete_program(ctx->remap_prog_id);
delete_program(ctx->rgba_prog_id);
SDL_GL_DeleteContext(ctx->gl_context);
SDL_DestroyWindow(ctx->window);
Expand Down Expand Up @@ -296,13 +309,19 @@ static inline void finish_offscreen(gl3_context *ctx) {
object_array_batch batch;
object_array_begin(ctx->objects, &batch);
activate_program(ctx->palette_prog_id);
render_target_activate(ctx->target);
render_target_activate(ctx->remap_target);

object_array_blend_mode mode;
while(object_array_get_batch(ctx->objects, &batch, &mode)) {
video_set_blend_mode(ctx, mode);
object_array_draw(ctx->objects, &batch);
}

// Set remapping target and run the second pass.
video_set_blend_mode(ctx, MODE_SET);
activate_program(ctx->remap_prog_id);
render_target_activate(ctx->final_target);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
}

/**
Expand All @@ -316,7 +335,7 @@ static inline void finish_onscreen(gl3_context *ctx) {
if(ctx->draw_atlas) {
bind_uniform_1i(ctx->rgba_prog_id, "framebuffer", TEX_UNIT_ATLAS);
} else {
bind_uniform_1i(ctx->rgba_prog_id, "framebuffer", TEX_UNIT_FBO);
bind_uniform_1i(ctx->rgba_prog_id, "framebuffer", TEX_UNIT_FINAL_FBO);
}
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
Expand Down
Loading