#include "shader.c" #include "shader.h" #include "fragment_shader.h" #include "vertex_shader.h" /* [=]===^=[ compile_shader ]==============================================================^===[=] */ static GLuint compile_shader(GLenum shader_type, const char *shader_source) { GLuint shader = glCreateShader(shader_type); glShaderSource(shader, 1, &shader_source, 0); glCompileShader(shader); GLint success; GLchar info_log[512]; glGetShaderiv(shader, GL_COMPILE_STATUS, &success); if(!success) { glGetShaderInfoLog(shader, sizeof(info_log), 0, info_log); printf("%s shader compilation failed:\n%s\n", (shader_type == GL_VERTEX_SHADER) ? "Vertex" : "Fragment", info_log); } return shader; } /* [=]===^=[ opengl_setup ]================================================================^===[=] */ static void opengl_setup(void) { gl_loader(); glEnable(GL_FRAMEBUFFER_SRGB); glDisable(GL_DEPTH_TEST); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDisable(GL_CULL_FACE); // Compile shaders GLuint vertex_shader = compile_shader(GL_VERTEX_SHADER, vertex_shader_start); GLuint fragment_shader = compile_shader(GL_FRAGMENT_SHADER, fragment_shader_start); printf("%d %d\n", vertex_shader, fragment_shader); state.shader_program = glCreateProgram(); glAttachShader(state.shader_program, vertex_shader); glAttachShader(state.shader_program, fragment_shader); glBindAttribLocation(state.shader_program, 0, "position"); glBindAttribLocation(state.shader_program, 1, "texture_coord"); glLinkProgram(state.shader_program); GLint success; glGetProgramiv(state.shader_program, GL_LINK_STATUS, &success); if(!success) { GLchar log[512]; glGetProgramInfoLog(state.shader_program, sizeof(log), 0, log); printf("Shader Linking Failed:\n%s\n", log); } glDeleteShader(vertex_shader); glDeleteShader(fragment_shader); glUseProgram(state.shader_program); state.contrast = 1.0f; state.saturation = 0.0f; state.brightness = 1.0f; CrtsTone(state.tone_data, state.contrast, state.saturation, INPUT_THIN, INPUT_MASK); state.uniform_resolution = glGetUniformLocation(state.shader_program, "resolution"); state.uniform_src_image_size = glGetUniformLocation(state.shader_program, "src_image_size"); state.uniform_brightness = glGetUniformLocation(state.shader_program, "brightness"); state.uniform_tone = glGetUniformLocation(state.shader_program, "tone_data"); state.uniform_crt_emulation = glGetUniformLocation(state.shader_program, "crt_emulation"); state.uniform_sampler_location = glGetUniformLocation(state.shader_program, "iChannel0"); glGenVertexArrays(1, &state.vao); glBindVertexArray(state.vao); glGenBuffers(1, &state.vbo); glGenBuffers(1, &state.ebo); glBindBuffer(GL_ARRAY_BUFFER, state.vbo); const float vertices[] = { -1.0f, -1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 1.0f }; glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, state.ebo); static const unsigned int indices[] = { 0, 1, 2, 2, 3, 0 }; glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2 * sizeof(float))); glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); // Setup texture glDeleteTextures(1, &state.texture); glGenTextures(1, &state.texture); glBindTexture(GL_TEXTURE_2D, state.texture); glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB8_ALPHA8, BUFFER_WIDTH, BUFFER_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, buffer); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glBindTexture(GL_TEXTURE_2D, 0); } /* [=]===^=[ render_frame ]=================================================================^===[=] */ __attribute__((always_inline)) static inline void render_frame(void) { glClearColor(.0f, 0.f, 0.f, 1.f); glClear(GL_COLOR_BUFFER_BIT); glUseProgram(state.shader_program); glBindVertexArray(state.vao); glBindBuffer(GL_ARRAY_BUFFER, state.vbo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, state.ebo); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, state.texture); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, BUFFER_WIDTH, BUFFER_HEIGHT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, display_buffer); glUniform2f(state.uniform_src_image_size, (float)BUFFER_WIDTH, (float)BUFFER_HEIGHT); glUniform2f(state.uniform_resolution, (float)state.viewport.w, (float)state.viewport.h); glUniform1f(state.uniform_brightness, state.brightness); glUniform4f(state.uniform_tone, state.tone_data[0], state.tone_data[1], state.tone_data[2], state.tone_data[3]); glUniform1i(state.uniform_crt_emulation, state.toggle_crt_emulation); glUniform1i(state.uniform_sampler_location, 0); glViewport(state.viewport.x, state.viewport.y, state.viewport.w, state.viewport.h); glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); }