Last active
September 15, 2020 17:27
-
-
Save wareya/5fe9c1227346bae74d235732956111b8 to your computer and use it in GitHub Desktop.
DCT compression artefacts as a multipass GLSL post processing shader
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <GL/gl3w.h> | |
#include <GLFW/glfw3.h> | |
#include <stdio.h> | |
#define STB_IMAGE_IMPLEMENTATION | |
#define STBI_ONLY_PNG | |
#include "include/stb_image.h" | |
struct vertex { | |
float x, y, z, u, v; | |
}; | |
void checkerr(int line) | |
{ | |
GLenum err; | |
while((err = glGetError()) != GL_NO_ERROR) | |
{ | |
printf("GL error %04X from line %d\n", err, line); | |
} | |
} | |
struct renderer { | |
struct texture { | |
int x, y, n; | |
GLuint texid; | |
texture(const char * filename) | |
{ | |
unsigned char * data = stbi_load(filename, &x, &y, &n, 4); | |
if(!data) puts("failed to open texture"); | |
checkerr(__LINE__); | |
glActiveTexture(GL_TEXTURE0); | |
checkerr(__LINE__); | |
glGenTextures(1, &texid); | |
glBindTexture(GL_TEXTURE_2D, texid); | |
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); | |
stbi_image_free(data); | |
checkerr(__LINE__); | |
glGenerateMipmap(GL_TEXTURE_2D); | |
checkerr(__LINE__); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR); | |
checkerr(__LINE__); | |
} | |
}; | |
texture * load_texture(const char * filename) | |
{ | |
return new texture(filename); | |
} | |
struct postprogram { | |
unsigned int program; | |
unsigned int fshader; | |
unsigned int vshader; | |
postprogram(const char * name, const char * fshadersource) | |
{ | |
const char * vshadersource = | |
"#version 330 core\n\ | |
layout (location = 0) in vec3 aPos;\n\ | |
layout (location = 1) in vec2 aTex;\n\ | |
varying out vec2 myTexCoord;\n\ | |
void main()\n\ | |
{\n\ | |
gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n\ | |
myTexCoord = aTex;\n\ | |
}\n" | |
; | |
checkerr(__LINE__); | |
vshader = glCreateShader(GL_VERTEX_SHADER); | |
glShaderSource(vshader, 1, &vshadersource, NULL); | |
glCompileShader(vshader); | |
checkerr(__LINE__); | |
fshader = glCreateShader(GL_FRAGMENT_SHADER); | |
glShaderSource(fshader, 1, &fshadersource, NULL); | |
glCompileShader(fshader); | |
checkerr(__LINE__); | |
program = glCreateProgram(); | |
glAttachShader(program, vshader); | |
glAttachShader(program, fshader); | |
glLinkProgram(program); | |
checkerr(__LINE__); | |
int v,f,p; | |
glGetShaderiv(vshader, GL_COMPILE_STATUS, &v); | |
glGetShaderiv(fshader, GL_COMPILE_STATUS, &f); | |
glGetProgramiv(program, GL_LINK_STATUS, &p); | |
checkerr(__LINE__); | |
if(!v or !f or !p) | |
{ | |
char info[512]; | |
puts("Failed to compile shader:"); | |
puts(name); | |
if(!v) | |
{ | |
glGetShaderInfoLog(vshader, 512, NULL, info); | |
puts(info); | |
} | |
if(!f) | |
{ | |
glGetShaderInfoLog(fshader, 512, NULL, info); | |
puts(info); | |
} | |
if(!p) | |
{ | |
glGetProgramInfoLog(program, 512, NULL, info); | |
puts(info); | |
} | |
exit(0); | |
} | |
checkerr(__LINE__); | |
glDeleteShader(vshader); | |
glDeleteShader(fshader); | |
} | |
}; | |
unsigned int VAO, VBO, FBO, FBOtexture1, FBOtexture2; | |
int w, h; | |
unsigned int vshader; | |
unsigned int fshader; | |
unsigned int program; | |
GLFWwindow * win; | |
postprogram * dctpre, * dctx, * dcty, * dctdiscard, * dctxi, * dctyi, * dctpost; | |
renderer() | |
{ | |
if(!glfwInit()) puts("glfw failed to init"), exit(0); | |
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); | |
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); | |
win = glfwCreateWindow(800, 600, "Hello, World!", NULL, NULL); | |
glfwSwapInterval(0); | |
if(!win) puts("glfw failed to init"), exit(0); | |
glfwMakeContextCurrent(win); | |
if(gl3wInit()) puts("glfw failed to init"), exit(0); | |
glfwSwapBuffers(win); | |
glfwGetFramebufferSize(win, &w, &h); | |
glEnable(GL_DEBUG_OUTPUT); | |
glDebugMessageCallback([](GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void* userParam) | |
{ | |
puts(message); | |
}, nullptr); | |
glEnable(GL_DEPTH_TEST); | |
glDepthFunc(GL_LEQUAL); | |
glGenVertexArrays(1, &VAO); | |
glGenBuffers(1, &VBO); | |
glBindVertexArray(VAO); | |
glPrimitiveRestartIndex(65535); | |
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | |
glBindBuffer(GL_ARRAY_BUFFER, VBO); | |
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(vertex), (void*)0); | |
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(vertex), (void*)offsetof(vertex, u)); | |
glEnableVertexAttribArray(0); | |
glEnableVertexAttribArray(1); | |
checkerr(__LINE__); | |
const char * vshadersource = | |
"#version 330 core\n\ | |
uniform mat4 projection;\n\ | |
uniform mat4 translation;\n\ | |
layout (location = 0) in vec3 aPos;\n\ | |
layout (location = 1) in vec2 aTex;\n\ | |
varying out vec2 myTexCoord;\n\ | |
void main()\n\ | |
{\n\ | |
gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0) * translation * projection;\n\ | |
myTexCoord = aTex;\n\ | |
}\n" | |
; | |
const char * fshadersource = | |
"#version 330 core\n\ | |
uniform sampler2D mytexture;\n\ | |
varying vec2 myTexCoord;\n\ | |
void main()\n\ | |
{\n\ | |
gl_FragColor = texture2D(mytexture, myTexCoord);\n\ | |
if(gl_FragColor.a == 0) discard;\n\ | |
}\n" | |
; | |
checkerr(__LINE__); | |
vshader = glCreateShader(GL_VERTEX_SHADER); | |
glShaderSource(vshader, 1, &vshadersource, NULL); | |
glCompileShader(vshader); | |
fshader = glCreateShader(GL_FRAGMENT_SHADER); | |
glShaderSource(fshader, 1, &fshadersource, NULL); | |
glCompileShader(fshader); | |
program = glCreateProgram(); | |
glAttachShader(program, vshader); | |
glAttachShader(program, fshader); | |
glLinkProgram(program); | |
checkerr(__LINE__); | |
int vsuccess, fsuccess, psuccess; | |
glGetShaderiv(vshader, GL_COMPILE_STATUS, &vsuccess); | |
glGetShaderiv(fshader, GL_COMPILE_STATUS, &fsuccess); | |
glGetProgramiv(program, GL_LINK_STATUS, &psuccess); | |
if(!vsuccess or !fsuccess or !psuccess) | |
{ | |
char info[512]; | |
puts("Failed to compile shader"); | |
if(!vsuccess) | |
{ | |
glGetShaderInfoLog(vshader, 512, NULL, info); | |
puts(info); | |
} | |
if(!fsuccess) | |
{ | |
glGetShaderInfoLog(fshader, 512, NULL, info); | |
puts(info); | |
} | |
if(!psuccess) | |
{ | |
glGetProgramInfoLog(program, 512, NULL, info); | |
puts(info); | |
} | |
exit(0); | |
} | |
checkerr(__LINE__); | |
glUseProgram(program); | |
glUniform1i(glGetUniformLocation(program, "mytexture"), 0); | |
checkerr(__LINE__); | |
glDeleteShader(fshader); | |
glDeleteShader(vshader); | |
checkerr(__LINE__); | |
// FBO program | |
dctpre = new postprogram("dctpre", | |
"#version 330 core\n\ | |
uniform sampler2D mytexture;\n\ | |
varying vec2 myTexCoord;\n\ | |
void main()\n\ | |
{\n\ | |
gl_FragColor = texture2D(mytexture, myTexCoord)*0.5+0.5;\n\ | |
}\n"); | |
glUseProgram(dctpre->program); | |
checkerr(__LINE__); | |
glUniform1i(glGetUniformLocation(dctpre->program, "mytexture"), 0); | |
checkerr(__LINE__); | |
dctx = new postprogram("dctx", | |
"#version 330 core\n\ | |
uniform sampler2D mytexture;\n\ | |
uniform ivec2 myTexSize;\n\ | |
varying vec2 myTexCoord;\n\ | |
#define M_PI 3.1415926535897932384626433832795\n\ | |
void main()\n\ | |
{\n\ | |
ivec2 size = myTexSize;\n\ | |
int intx = int(myTexCoord.x*size.x);\n\ | |
int j = int(mod(intx, 8));\n\ | |
float x = intx - j;\n\ | |
x /= size.x;\n\ | |
vec4 array1[8];\n\ | |
for(int i = 0; i < 8; i++)\n\ | |
array1[i] = texture2D(mytexture, vec2(x+(float(i)+0.5)/size.x, myTexCoord.y))*2-1;\n\ | |
vec4 color = vec4(0);\n\ | |
color.a = 1;\n\ | |
for(int i = 0; i < 8; i++)\n\ | |
{\n\ | |
color.r += array1[i].r*cos(M_PI/8.0*(i+1/2.0)*j);\n\ | |
color.g += array1[i].g*cos(M_PI/8.0*(i+1/2.0)*j);\n\ | |
color.b += array1[i].b*cos(M_PI/8.0*(i+1/2.0)*j);\n\ | |
}\n\ | |
color *= sqrt(2.0/8);\n\ | |
gl_FragColor = color*0.5+0.5;\n\ | |
}\n"); | |
glUseProgram(dctx->program); | |
checkerr(__LINE__); | |
glUniform1i(glGetUniformLocation(dctx->program, "mytexture"), 0); | |
glUniform2i(glGetUniformLocation(dctx->program, "myTexSize"), w, h); | |
checkerr(__LINE__); | |
dcty = new postprogram("dcty", | |
"#version 330 core\n\ | |
uniform sampler2D mytexture;\n\ | |
uniform ivec2 myTexSize;\n\ | |
varying vec2 myTexCoord;\n\ | |
#define M_PI 3.1415926535897932384626433832795\n\ | |
void main()\n\ | |
{\n\ | |
ivec2 size = myTexSize;\n\ | |
int inty = int(myTexCoord.y*size.y);\n\ | |
int j = int(mod(inty, 8));\n\ | |
float y = inty - j;\n\ | |
y /= size.y;\n\ | |
vec4 array1[8];\n\ | |
for(int i = 0; i < 8; i++)\n\ | |
array1[i] = texture2D(mytexture, vec2(myTexCoord.x, y+(float(i)+0.5)/size.y))*2-1;\n\ | |
vec4 color = vec4(0);\n\ | |
color.a = 1;\n\ | |
for(int i = 0; i < 8; i++)\n\ | |
{\n\ | |
color.r += array1[i].r*cos(M_PI/8.0*(i+1/2.0)*j);\n\ | |
color.g += array1[i].g*cos(M_PI/8.0*(i+1/2.0)*j);\n\ | |
color.b += array1[i].b*cos(M_PI/8.0*(i+1/2.0)*j);\n\ | |
}\n\ | |
color *= sqrt(2.0/8);\n\ | |
gl_FragColor = color*0.5+0.5;\n\ | |
}\n"); | |
glUseProgram(dcty->program); | |
checkerr(__LINE__); | |
glUniform1i(glGetUniformLocation(dcty->program, "mytexture"), 0); | |
glUniform2i(glGetUniformLocation(dcty->program, "myTexSize"), w, h); | |
checkerr(__LINE__); | |
dctdiscard = new postprogram("dctdiscard", | |
"#version 330 core\n\ | |
uniform sampler2D mytexture;\n\ | |
uniform ivec2 myTexSize;\n\ | |
varying vec2 myTexCoord;\n\ | |
void main()\n\ | |
{\n\ | |
ivec2 size = myTexSize;\n\ | |
int intx = int(myTexCoord.x*size.x);\n\ | |
int inty = int(myTexCoord.y*size.y);\n\ | |
int xj = int(mod(intx, 8));\n\ | |
int yj = int(mod(inty, 8));\n\ | |
float dist = xj+yj+1;\n\ | |
vec4 color = texture2D(mytexture, myTexCoord)*2-1;\n\ | |
color *= 32;\n\ | |
color /= dist;\n\ | |
color = round(color);\n\ | |
color *= dist;\n\ | |
color /= 32;\n\ | |
gl_FragColor = color*0.5+0.5;\n\ | |
}\n"); | |
glUseProgram(dctdiscard->program); | |
checkerr(__LINE__); | |
glUniform1i(glGetUniformLocation(dctdiscard->program, "mytexture"), 0); | |
glUniform2i(glGetUniformLocation(dctdiscard->program, "myTexSize"), w, h); | |
checkerr(__LINE__); | |
dctxi = new postprogram("dctxi", | |
"#version 330 core\n\ | |
uniform sampler2D mytexture;\n\ | |
uniform ivec2 myTexSize;\n\ | |
varying vec2 myTexCoord;\n\ | |
#define M_PI 3.1415926535897932384626433832795\n\ | |
void main()\n\ | |
{\n\ | |
ivec2 size = myTexSize;\n\ | |
int intx = int(myTexCoord.x*size.x);\n\ | |
int j = int(mod(intx, 8));\n\ | |
float x = intx - j;\n\ | |
x /= size.x;\n\ | |
vec4 array1[8];\n\ | |
for(int i = 0; i < 8; i++)\n\ | |
array1[i] = texture2D(mytexture, vec2(x+(float(i)+0.5)/size.x, myTexCoord.y))*2-1;\n\ | |
vec4 color = vec4(0);\n\ | |
color += array1[0]/2;\n\ | |
for(int i = 1; i < 8; i++)\n\ | |
{\n\ | |
color.r += array1[i].r*cos(M_PI/8.0*i*(j+1/2.0));\n\ | |
color.g += array1[i].g*cos(M_PI/8.0*i*(j+1/2.0));\n\ | |
color.b += array1[i].b*cos(M_PI/8.0*i*(j+1/2.0));\n\ | |
}\n\ | |
color *= sqrt(2.0/8);\n\ | |
gl_FragColor = color*0.5+0.5;\n\ | |
}\n"); | |
glUseProgram(dctxi->program); | |
checkerr(__LINE__); | |
glUniform1i(glGetUniformLocation(dctxi->program, "mytexture"), 0); | |
glUniform2i(glGetUniformLocation(dctxi->program, "myTexSize"), w, h); | |
checkerr(__LINE__); | |
dctyi = new postprogram("dctyi", | |
"#version 330 core\n\ | |
uniform sampler2D mytexture;\n\ | |
uniform ivec2 myTexSize;\n\ | |
varying vec2 myTexCoord;\n\ | |
#define M_PI 3.1415926535897932384626433832795\n\ | |
void main()\n\ | |
{\n\ | |
ivec2 size = myTexSize;\n\ | |
int inty = int(myTexCoord.y*size.y);\n\ | |
int j = int(mod(inty, 8));\n\ | |
float y = inty - j;\n\ | |
y /= size.y;\n\ | |
vec4 array1[8];\n\ | |
for(int i = 0; i < 8; i++)\n\ | |
array1[i] = texture2D(mytexture, vec2(myTexCoord.x, y+(float(i)+0.5)/size.y))*2-1;\n\ | |
vec4 color = vec4(0);\n\ | |
color += array1[0]/2;\n\ | |
for(int i = 1; i < 8; i++)\n\ | |
{\n\ | |
color.r += array1[i].r*cos(M_PI/8.0*i*(j+1/2.0));\n\ | |
color.g += array1[i].g*cos(M_PI/8.0*i*(j+1/2.0));\n\ | |
color.b += array1[i].b*cos(M_PI/8.0*i*(j+1/2.0));\n\ | |
}\n\ | |
color *= sqrt(2.0/8);\n\ | |
gl_FragColor = color*0.5+0.5;\n\ | |
}\n"); | |
glUseProgram(dctyi->program); | |
checkerr(__LINE__); | |
glUniform1i(glGetUniformLocation(dctyi->program, "mytexture"), 0); | |
glUniform2i(glGetUniformLocation(dctyi->program, "myTexSize"), w, h); | |
checkerr(__LINE__); | |
dctpost = new postprogram("dctpost", | |
"#version 330 core\n\ | |
uniform sampler2D mytexture;\n\ | |
varying vec2 myTexCoord;\n\ | |
void main()\n\ | |
{\n\ | |
gl_FragColor = texture2D(mytexture, myTexCoord)*2-1;\n\ | |
}\n"); | |
glUseProgram(dctpost->program); | |
checkerr(__LINE__); | |
glUniform1i(glGetUniformLocation(dctpost->program, "mytexture"), 0); | |
checkerr(__LINE__); | |
glGenFramebuffers(1, &FBO); | |
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, FBO); | |
checkerr(__LINE__); | |
glActiveTexture(GL_TEXTURE0); | |
glGenTextures(1, &FBOtexture1); | |
glGenTextures(1, &FBOtexture2); | |
glBindTexture(GL_TEXTURE_2D, FBOtexture1); | |
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, w, h, 0, GL_RGB, GL_FLOAT, NULL); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | |
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, FBOtexture1, 0); | |
checkerr(__LINE__); | |
glBindTexture(GL_TEXTURE_2D, FBOtexture2); | |
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, w, h, 0, GL_RGB, GL_FLOAT, NULL); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | |
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, FBOtexture2, 0); | |
checkerr(__LINE__); | |
checkerr(__LINE__); | |
} | |
void cycle_start() | |
{ | |
checkerr(__LINE__); | |
int w2, h2; | |
glfwGetFramebufferSize(win, &w2, &h2); | |
checkerr(__LINE__); | |
if(w2 != w or h2 != h) | |
{ | |
w = w2; | |
h = h2; | |
glViewport(0, 0, w, h); | |
checkerr(__LINE__); | |
glActiveTexture(GL_TEXTURE0); | |
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, FBO); | |
glBindTexture(GL_TEXTURE_2D, FBOtexture1); | |
checkerr(__LINE__); | |
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, w, h, 0, GL_RGB, GL_FLOAT, NULL); | |
checkerr(__LINE__); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | |
checkerr(__LINE__); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | |
checkerr(__LINE__); | |
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, FBOtexture1, 0); | |
checkerr(__LINE__); | |
glBindTexture(GL_TEXTURE_2D, FBOtexture2); | |
checkerr(__LINE__); | |
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, w, h, 0, GL_RGB, GL_FLOAT, NULL); | |
checkerr(__LINE__); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | |
checkerr(__LINE__); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | |
checkerr(__LINE__); | |
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, FBOtexture2, 0); | |
checkerr(__LINE__); | |
glUseProgram(dctx->program); | |
glUniform2i(glGetUniformLocation(dctx->program, "myTexSize"), w, h); | |
checkerr(__LINE__); | |
glUseProgram(dctxi->program); | |
glUniform2i(glGetUniformLocation(dctxi->program, "myTexSize"), w, h); | |
checkerr(__LINE__); | |
glUseProgram(dctdiscard->program); | |
glUniform2i(glGetUniformLocation(dctdiscard->program, "myTexSize"), w, h); | |
checkerr(__LINE__); | |
glUseProgram(dcty->program); | |
glUniform2i(glGetUniformLocation(dcty->program, "myTexSize"), w, h); | |
checkerr(__LINE__); | |
glUseProgram(dctyi->program); | |
glUniform2i(glGetUniformLocation(dctyi->program, "myTexSize"), w, h); | |
checkerr(__LINE__); | |
} | |
glUseProgram(program); | |
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, FBO); | |
glDrawBuffer(GL_COLOR_ATTACHMENT0); | |
glEnable(GL_DEPTH_TEST); | |
glEnable(GL_BLEND); | |
float projection[16] = { | |
1.0f/w, 0.0f, 0.0f, 0.0f, | |
0.0f, -1.0f/h, 0.0f, 0.0f, | |
0.0f, 0.0f, 1.0f, 0.0f, | |
0.0f, 0.0f, 0.0f, 1.0f | |
}; | |
glUniformMatrix4fv(glGetUniformLocation(program, "projection"), 1, 0, projection); | |
glClearColor(0,0,0,1); | |
glDepthMask(true); | |
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | |
checkerr(__LINE__); | |
} | |
void cycle_end() | |
{ | |
glDisable(GL_DEPTH_TEST); | |
glDisable(GL_BLEND); | |
const vertex vertices[] = { | |
{-1.f, -1.f, 0.6f, 0.0f, 0.0f}, | |
{ 1.f, -1.f, 0.5f, 1.0f, 0.0f}, | |
{-1.f, 1.f, 0.5f, 0.0f, 1.0f}, | |
{ 1.f, 1.f, 0.5f, 1.0f, 1.0f} | |
}; | |
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_DYNAMIC_DRAW); | |
checkerr(__LINE__); | |
int currtex = 0; | |
auto BUFFER_A = [&]() | |
{ | |
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, FBO); | |
glDrawBuffer(GL_COLOR_ATTACHMENT1); | |
}; | |
auto BUFFER_B = [&]() | |
{ | |
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, FBO); | |
glDrawBuffer(GL_COLOR_ATTACHMENT0); | |
}; | |
auto BUFFER_DONE = [&]() | |
{ | |
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); | |
glDrawBuffer(GL_BACK); | |
}; | |
auto FLIP_SOURCE = [&]() | |
{ | |
if(currtex == 1) | |
{ | |
glBindTexture(GL_TEXTURE_2D, FBOtexture2); | |
currtex = 2; | |
BUFFER_B(); | |
} | |
else | |
{ | |
glBindTexture(GL_TEXTURE_2D, FBOtexture1); | |
currtex = 1; | |
BUFFER_A(); | |
} | |
}; | |
FLIP_SOURCE(); | |
glUseProgram(dctpre->program); | |
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); | |
FLIP_SOURCE(); | |
glUseProgram(dctx->program); | |
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); | |
FLIP_SOURCE(); | |
glUseProgram(dcty->program); | |
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); | |
FLIP_SOURCE(); | |
glUseProgram(dctdiscard->program); | |
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); | |
FLIP_SOURCE(); | |
glUseProgram(dctxi->program); | |
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); | |
FLIP_SOURCE(); | |
glUseProgram(dctyi->program); | |
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); | |
FLIP_SOURCE(); | |
BUFFER_DONE(); | |
glUseProgram(dctpost->program); | |
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); | |
glfwSwapBuffers(win); | |
} | |
void draw_texture(texture * texture, float x, float y, float z, float xscale, float yscale) | |
{ | |
const vertex vertices[] = { | |
{-float(texture->x),-float(texture->y), 0.0f, 0.0f, 0.0f}, | |
{ float(texture->x),-float(texture->y), 0.0f, 1.0f, 0.0f}, | |
{-float(texture->x), float(texture->y), 0.0f, 0.0f, 1.0f}, | |
{ float(texture->x), float(texture->y), 0.0f, 1.0f, 1.0f} | |
}; | |
float translation[16] = { | |
xscale, 0.0f, 0.0f, x, | |
0.0f, yscale, 0.0f, y, | |
0.0f, 0.0f, 1.0f, z, | |
0.0f, 0.0f, 0.0f, 1.0f | |
}; | |
glUniformMatrix4fv(glGetUniformLocation(program, "translation"), 1, 0, translation); | |
glBindTexture(GL_TEXTURE_2D, texture->texid); | |
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_DYNAMIC_DRAW); | |
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); | |
} | |
}; | |
int main() | |
{ | |
float x = 0; | |
float y = 0; | |
renderer myrenderer; | |
auto & win = myrenderer.win; | |
auto mychar = myrenderer.load_texture("me.png"); | |
auto mymap = myrenderer.load_texture("dkoth_gg2isdead.png"); | |
float oldtime = glfwGetTime(); | |
while (!glfwWindowShouldClose(win)) | |
{ | |
glfwPollEvents(); | |
float newtime = glfwGetTime(); | |
float delta = newtime-oldtime; | |
oldtime = newtime; | |
if(glfwGetKey(win, GLFW_KEY_E)) y -= 1000*delta; | |
if(glfwGetKey(win, GLFW_KEY_D)) y += 1000*delta; | |
if(glfwGetKey(win, GLFW_KEY_W)) x -= 1000*delta; | |
if(glfwGetKey(win, GLFW_KEY_F)) x += 1000*delta; | |
myrenderer.cycle_start(); | |
myrenderer.draw_texture(mymap, -x/2, -y/2, 0.5, 6, 6); | |
myrenderer.draw_texture(mychar, x/2, y/2, 0.2, 1, 1); | |
myrenderer.cycle_end(); | |
} | |
glfwDestroyWindow(win); | |
puts("init worked"); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment