move from sdl textures to opengl, add byuu color correction shaders :D

This commit is contained in:
Matthew Berry 2020-11-10 00:00:06 -08:00
parent 717965c400
commit b6ddfcf424
4 changed files with 103 additions and 20 deletions

View file

@ -16,5 +16,7 @@ dependencies:
version: 0.1.3
sdl:
git: git@github.com:ysbaddaden/sdl.cr.git
lib_gl:
github: nulldotpro/LibGL
license: MIT

View file

@ -1,31 +1,22 @@
require "lib_gl"
class Display
WIDTH = 240
HEIGHT = 160
SCALE = 4
PIXELFORMAT_RGB24 = (1 << 28) | (7 << 24) | (1 << 20) | (0 << 16) | (24 << 8) | (3 << 0)
PIXELFORMAT_BGR555 = (1 << 28) | (5 << 24) | (5 << 20) | (3 << 16) | (15 << 8) | (2 << 0)
TEXTUREACCESS_STREAMING = 1
def initialize
@window = SDL::Window.new("crab", WIDTH * SCALE, HEIGHT * SCALE)
@renderer = SDL::Renderer.new @window
@renderer.logical_size = {WIDTH, HEIGHT}
@texture = LibSDL.create_texture @renderer, PIXELFORMAT_BGR555, TEXTUREACCESS_STREAMING, WIDTH, HEIGHT
end
def window_title : String
"crab - #{@fps} fps"
end
@fps = 30
@seconds : Int32 = Time.utc.second
def initialize
@window = SDL::Window.new(window_title, WIDTH * SCALE, HEIGHT * SCALE, flags: SDL::Window::Flags::OPENGL)
setup_gl
end
def draw(framebuffer : Bytes) : Nil
LibSDL.update_texture @texture, nil, framebuffer, WIDTH * 2
@renderer.clear
@renderer.copy @texture
@renderer.present
LibGL.tex_image_2d(LibGL::TEXTURE_2D, 0, LibGL::RGB5, 240, 160, 0, LibGL::RGBA, LibGL::UNSIGNED_SHORT_1_5_5_5_REV, framebuffer)
LibGL.draw_arrays(LibGL::TRIANGLE_STRIP, 0, 4)
LibSDL.gl_swap_window @window
@fps += 1
if Time.utc.second != @seconds
@window.title = window_title
@ -33,4 +24,65 @@ class Display
@seconds = Time.utc.second
end
end
private def window_title : String
"crab - #{@fps} fps"
end
private def compile_shader(source : String, type : UInt32) : UInt32
source_ptr = source.to_unsafe
shader = LibGL.create_shader(type)
LibGL.shader_source(shader, 1, pointerof(source_ptr), nil)
LibGL.compile_shader shader
shader_compiled = 0
LibGL.get_shader_iv(shader, LibGL::COMPILE_STATUS, pointerof(shader_compiled))
if shader_compiled != LibGL::TRUE
log_length = 0
LibGL.get_shader_iv(shader, LibGL::INFO_LOG_LENGTH, pointerof(log_length))
s = " " * log_length
if log_length > 0
LibGL.get_shader_info_log(shader, log_length, pointerof(log_length), s)
end
puts source
abort "Error compiling shader: #{s}"
end
shader
end
protected def self.callback(source : UInt32, type : UInt32, id : UInt32, severity : UInt32, length : Int32, message : Pointer(UInt8), userParam : Pointer(Void)) : Nil
puts String.new message
end
private def setup_gl : Nil
glcontext = LibSDL.gl_create_context @window
shader_program = LibGL.create_program
LibSDL.gl_set_attribute LibSDL::GLattr::SDL_GL_CONTEXT_MAJOR_VERSION, 4
LibSDL.gl_set_attribute LibSDL::GLattr::SDL_GL_CONTEXT_MINOR_VERSION, 5
LibSDL.gl_set_swap_interval 1
LibGL.enable(LibGL::DEBUG_OUTPUT)
LibGL.enable(LibGL::DEBUG_OUTPUT_SYNCHRONOUS)
LibGL.debug_message_callback(->Display.callback, nil)
vtx_shader_id = compile_shader(File.read("src/crab/shaders/gba_colors.vert"), LibGL::VERTEX_SHADER)
frag_shader_id = compile_shader(File.read("src/crab/shaders/gba_colors.frag"), LibGL::FRAGMENT_SHADER)
frame_buffer = 0_u32
LibGL.gen_textures(1, pointerof(frame_buffer))
LibGL.active_texture(LibGL::TEXTURE0)
LibGL.bind_texture(LibGL::TEXTURE_2D, frame_buffer)
LibGL.attach_shader shader_program, vtx_shader_id
LibGL.attach_shader shader_program, frag_shader_id
LibGL.link_program shader_program
LibGL.validate_program shader_program
a = [LibGL::BLUE, LibGL::GREEN, LibGL::RED, LibGL::ONE] # flip the rgba to bgra where a is always 1
a_ptr = pointerof(a).as(Int32*)
LibGL.tex_parameter_iv(LibGL::TEXTURE_2D, LibGL::TEXTURE_SWIZZLE_RGBA, a_ptr)
LibGL.tex_parameter_i(LibGL::TEXTURE_2D, LibGL::TEXTURE_MIN_FILTER, LibGL::NEAREST)
LibGL.tex_parameter_i(LibGL::TEXTURE_2D, LibGL::TEXTURE_MAG_FILTER, LibGL::NEAREST)
LibGL.use_program shader_program
vao = 0_u32 # required even if not used
LibGL.gen_vertex_arrays(1, pointerof(vao))
LibGL.bind_vertex_array(vao)
end
end

View file

@ -0,0 +1,19 @@
#version 330
in vec2 tex_coord;
out vec4 frag_color;
uniform sampler2D input_texture;
void main() {
// Credits to Talarubi and Near for this color-correction algorithm.
// https://byuu.net/video/color-emulation
vec4 color = texture(input_texture, tex_coord);
float lcdGamma = 4.0, outGamma = 2.2;
color.rgb = pow(color.rgb, vec3(lcdGamma));
frag_color.rgb = pow(vec3( 0 * color.b + 50 * color.g + 255 * color.r,
30 * color.b + 230 * color.g + 10 * color.r,
220 * color.b + 10 * color.g + 50 * color.r) / 255,
vec3(1.0 / outGamma));
frag_color.a = 1.0;
}

View file

@ -0,0 +1,10 @@
#version 330
out vec2 tex_coord;
const vec2 vertices[4] = vec2[4](vec2(-1.0, -1.0), vec2(1.0, -1.0), vec2(-1.0, 1.0), vec2(1.0, 1.0));
void main() {
gl_Position = vec4(vertices[gl_VertexID], 0.0, 1.0);
tex_coord = (vertices[gl_VertexID] + 1.0) / vec2(2.0, -2.0);
}