sdfps/sdfps.c

218 lines
6.0 KiB
C
Raw Normal View History

2022-03-21 17:58:17 +00:00
// sdfps.c
#include <SDL2/SDL.h>
#include <glad/glad.h>
#include "types.h"
GLuint create_shader(GLenum shader_type, const char *src) {
GLuint s = glCreateShader(shader_type);
glShaderSource(s, 1, &src, NULL);
glCompileShader(s);
GLint s_compiled;
glGetShaderiv(s, GL_COMPILE_STATUS, &s_compiled);
if (s_compiled != GL_TRUE) {
GLsizei log_length = 0;
GLchar msg[1024] = { 0 };
glGetShaderInfoLog(s, sizeof(msg), &log_length, msg);
puts(msg);
}
return s;
}
void init(Sdfps* s) { /* TODO: Error checks */
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
/* these 2 are required on macos [https://www.glfw.org/faq.html#41---how-do-i-create-an-opengl-30-context] */
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
//SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
//SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
s -> window = SDL_CreateWindow("sdfps",
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
800, 600,
SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
s -> context = SDL_GL_CreateContext(s -> window);
SDL_GL_MakeCurrent(s -> window, s -> context);
SDL_GL_SetSwapInterval(1);
if (!gladLoadGLES2Loader(SDL_GL_GetProcAddress)) printf("FUCK, gl loading failed\n");
puts(glGetString(GL_VERSION));
s -> vert_shader = create_shader(GL_VERTEX_SHADER,
"#version 330\n"
"in vec4 a_pos;\n"
"void main() {\n"
"gl_Position = a_pos;\n"
"}\n");
s -> frag_shader = create_shader(GL_FRAGMENT_SHADER,
"#version 330\n"
"precision highp float;\n"
"out vec4 out_color;\n"
"void main() {\n"
"vec2 xy = mod(gl_FragCoord.xy, vec2(200.0, 200.0));\n"
"out_color = vec4(xy.x / 100.0, xy.x / 200.0, xy.y / 200.0, 1);\n"
"}\n");
s -> shader_program = glCreateProgram();
glAttachShader(s -> shader_program, s -> vert_shader);
glAttachShader(s -> shader_program, s -> frag_shader);
glLinkProgram(s -> shader_program);
GLint program_linked;
glGetProgramiv(s -> shader_program, GL_LINK_STATUS, &program_linked);
if (program_linked != GL_TRUE) {
GLsizei log_length = 0;
GLchar msg[1024];
glGetProgramInfoLog(s -> shader_program, sizeof(msg), &log_length, msg);
puts(msg);
}
}
void deinit(Sdfps *s) {
SDL_GL_DeleteContext(s -> context);
SDL_DestroyWindow(s -> window);
}
void render(Sdfps *s) {
// setup render texture
const s32 fb_w = 512, fb_h = 512;
GLuint render_tex;
glGenTextures(1, &render_tex);
glBindTexture(GL_TEXTURE_2D, render_tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
fb_w, fb_h, // width height
0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
GLuint framebuf;
glGenFramebuffers(1, &framebuf);
glBindFramebuffer(GL_FRAMEBUFFER, framebuf);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, render_tex, 0);
GLenum fb_status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (fb_status != GL_FRAMEBUFFER_COMPLETE)
puts("FRAME BUFFER FUCKED UP SOMEWHERE");
glViewport(0, 0, fb_w, fb_h);
glClearColor(0.1f, 0.25f, 0.24f, 1);
glClear(GL_COLOR_BUFFER_BIT);
GLint pos_attr_loc = glGetAttribLocation(s -> shader_program, "a_pos");
GLuint vertex_buffer;
glGenBuffers(1, &vertex_buffer);
GLfloat data[] = {
-1, 1,
4, 1,
-1, -4,
};
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
GLuint vert_array;
glGenVertexArrays(1, &vert_array);
glBindVertexArray(vert_array);
glEnableVertexAttribArray(pos_attr_loc);
glVertexAttribPointer(
pos_attr_loc,
2, // components per iteration, 2 = vec2
GL_FLOAT, // data type of each component
GL_FALSE, // data should/shouldnt be normalized
0, // stride, e.g. space between components (in bytes)
0 // pointer/start, 0 is gur location of gur first position
);
glUseProgram(s -> shader_program);
glBindVertexArray(vert_array);
glDrawArrays(GL_TRIANGLES,
0, // first in array
3 // count
);
#if 1
// just here to check that it works, since it can be used as an easy way to
// get data back out of a shader, there's probs a more proper way to do it
// that we could change to later
f32 pixels[16 * 16 * 4] = { 0.0f };
glReadPixels(
10, // x pixel starting bottom left,
10, // y pixel
16, // width in pixels, 1 = reading a single pixel
16, // height
GL_RGBA, // format, can also be GL_RGBA_INTEGER
GL_FLOAT, // type
pixels // data
);
#endif
// show it
glBindFramebuffer(GL_FRAMEBUFFER, 0); // not technically needed
s32 win_w, win_h;
SDL_GL_GetDrawableSize(s -> window, &win_w, &win_h);
glViewport(0, 0, win_w, win_h); // not technically needed
// copy framebuf to window?
glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuf);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glBlitFramebuffer(0, 0, fb_w, fb_h, 0, 0, win_w, win_h, GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT, GL_NEAREST);
// deletes
glDeleteBuffers(1, &vertex_buffer);
glDeleteVertexArrays(1, &vert_array);
glDeleteFramebuffers(1, &framebuf);
glDeleteTextures(1, &render_tex);
SDL_GL_SwapWindow(s -> window);
}
/*
* so entry point, return non zero to quit program
* return 0 to reload so
*/
int sdfps_main(int argc, char **argv, Sdfps **u_data) {
/* TODO: actually copy gur data over from gur kv store */
if (*u_data == NULL) {
*u_data = malloc(1024);
init(*u_data);
}
if (!gladLoadGLES2Loader(SDL_GL_GetProcAddress)) printf("FUCK, gl loading failed\n");
Sdfps *sdfps = *u_data;
while (1) {
SDL_Event e;
while (SDL_PollEvent(&e))
if (e.type == SDL_QUIT)
goto quit;
render(sdfps);
SDL_Delay(1);
if (!remove("reload-trigger")) {
// do some cleanup before reloading,
// pause your audio devices etc
//deinit(sdfps);
puts("removed reload-trigger, reloading...");
return 0;
}
}
quit:
// do what ever you got to before process dies
deinit(sdfps);
return 1;
}