Skip to content

Instantly share code, notes, and snippets.

@wareya
Last active September 15, 2020 17:27
Show Gist options
  • Save wareya/5fe9c1227346bae74d235732956111b8 to your computer and use it in GitHub Desktop.
Save wareya/5fe9c1227346bae74d235732956111b8 to your computer and use it in GitHub Desktop.
DCT compression artefacts as a multipass GLSL post processing shader
#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