diff --git a/Makefile b/Makefile index 468dd07..f41bbb1 100644 --- a/Makefile +++ b/Makefile @@ -6,4 +6,4 @@ all: $(CC) $(CFLAGS) $(LDFLAGS) -o glonkers main.c run: all - ./glonkers + SDL_VIDEODRIVER="wayland,x11" ./glonkers diff --git a/fragment.glsl b/fragment.glsl index 0f45d62..6d58328 100644 --- a/fragment.glsl +++ b/fragment.glsl @@ -1,69 +1,76 @@ -#version 330 core -out vec4 FragColor; -uniform vec2 WindowSize; -uniform float time; - -float rand(ivec2 co) { - return fract(sin(dot(co, vec2(12.9898, 78.233))) * 43758.5453); -} - -float cell_size = 0.01; - -#define PI 3.1415926538 - -// whatever that corner contributes -float c_dot(vec2 point, vec2 corner) { - ivec2 c = ivec2(round(corner * 100)); - float angle = rand(c) * 2*PI; - vec2 random_corner_vec = vec2(cos(angle), sin(angle)); - vec2 offset = (point - corner) / cell_size; - float dot_product = dot(random_corner_vec, offset); - // for now just return something - return dot_product; -} - -float lerp(float a, float b, float x) { - return a + x*(b-a); -} - -// better than built in smoothstep. -float fade(float t) { - return ((6*t - 15)*t + 10)*t*t*t; -} +precision mediump float; void main() { - // We'll make origin in the top-left. - vec2 uv = gl_FragCoord.xy / WindowSize; - uv.y = 1.0 - uv.y; - vec2 grid_edge_offset = mod(uv, cell_size); - // c: corner - vec2 c_tl = uv - grid_edge_offset; - vec2 c_tr = uv - grid_edge_offset + vec2(cell_size, 0); - vec2 c_bl = uv - grid_edge_offset + vec2(0, cell_size); - vec2 c_br = uv - grid_edge_offset + vec2(cell_size, cell_size); - float c_tl_dot = c_dot(uv, c_tl); - float c_tr_dot = c_dot(uv, c_tr); - float c_bl_dot = c_dot(uv, c_bl); - float c_br_dot = c_dot(uv, c_br); + gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); +} - // the uv within the tile (0 to 1) - vec2 tile_uv = (uv - c_tl) / cell_size; - // lerp index - float u = fade(tile_uv.x); - float v = fade(tile_uv.y); - //float u = tile_uv.x; - //float v = tile_uv.y; - //float u = smoothstep(0, 1, tile_uv.x); - //float v = smoothstep(0, 1, tile_uv.y); - //float val = smoothstep(tile_uv.x, smoothstep(tile_uv.y, c_bl_dot, c_tl_dot), smoothstep(tile_uv.y, c_br_dot, c_tr_dot)); - float val = lerp(lerp(c_tl_dot, c_bl_dot, v), lerp(c_tr_dot, c_br_dot, v), u); - //float val = tile_uv.y; - //float val = c_bl_dot*2 + 0.5; - //val = val * 20; - float out_val = val /2 + 0.5; - FragColor = vec4(out_val, out_val, out_val, 1); - - //float yes = 0.5 + (c_dot(uv, c_tl) + c_dot(uv, c_tr) + c_dot(uv, c_bl) + c_dot(uv, c_br)) / 2; - //FragColor = vec4(yes, yes, yes, 1); -} +//#version 330 core +//out vec4 FragColor; +//uniform vec2 WindowSize; +//uniform float time; +// +//float rand(ivec2 co) { +// return fract(sin(dot(co, vec2(12.9898, 78.233))) * 43758.5453); +//} +// +//float cell_size = 0.01; +// +//#define PI 3.1415926538 +// +//// whatever that corner contributes +//float c_dot(vec2 point, vec2 corner) { +// ivec2 c = ivec2(round(corner * 100)); +// float angle = rand(c) * 2*PI; +// vec2 random_corner_vec = vec2(cos(angle), sin(angle)); +// vec2 offset = (point - corner) / cell_size; +// float dot_product = dot(random_corner_vec, offset); +// // for now just return something +// return dot_product; +//} +// +//float lerp(float a, float b, float x) { +// return a + x*(b-a); +//} +// +//// better than built in smoothstep. +//float fade(float t) { +// return ((6*t - 15)*t + 10)*t*t*t; +//} +// +//void main() { +// // We'll make origin in the top-left. +// vec2 uv = gl_FragCoord.xy / WindowSize; +// uv.y = 1.0 - uv.y; +// vec2 grid_edge_offset = mod(uv, cell_size); +// // c: corner +// vec2 c_tl = uv - grid_edge_offset; +// vec2 c_tr = uv - grid_edge_offset + vec2(cell_size, 0); +// vec2 c_bl = uv - grid_edge_offset + vec2(0, cell_size); +// vec2 c_br = uv - grid_edge_offset + vec2(cell_size, cell_size); +// float c_tl_dot = c_dot(uv, c_tl); +// float c_tr_dot = c_dot(uv, c_tr); +// float c_bl_dot = c_dot(uv, c_bl); +// float c_br_dot = c_dot(uv, c_br); +// +// // the uv within the tile (0 to 1) +// vec2 tile_uv = (uv - c_tl) / cell_size; +// +// // lerp index +// float u = fade(tile_uv.x); +// float v = fade(tile_uv.y); +// //float u = tile_uv.x; +// //float v = tile_uv.y; +// //float u = smoothstep(0, 1, tile_uv.x); +// //float v = smoothstep(0, 1, tile_uv.y); +// //float val = smoothstep(tile_uv.x, smoothstep(tile_uv.y, c_bl_dot, c_tl_dot), smoothstep(tile_uv.y, c_br_dot, c_tr_dot)); +// float val = lerp(lerp(c_tl_dot, c_bl_dot, v), lerp(c_tr_dot, c_br_dot, v), u); +// //float val = tile_uv.y; +// //float val = c_bl_dot*2 + 0.5; +// //val = val * 20; +// float out_val = val /2 + 0.5; +// FragColor = vec4(out_val, out_val, out_val, 1); +// +// //float yes = 0.5 + (c_dot(uv, c_tl) + c_dot(uv, c_tr) + c_dot(uv, c_bl) + c_dot(uv, c_br)) / 2; +// //FragColor = vec4(yes, yes, yes, 1); +//} diff --git a/main.c b/main.c index a56c8cd..56868eb 100644 --- a/main.c +++ b/main.c @@ -5,10 +5,11 @@ #include #include #include +#include #include #include #include -//#include +#include //int main() { // struct wl_display *display = wl_display_connect(NULL); @@ -23,208 +24,231 @@ // // wl_display_disconnect(display); //} -struct our_state { - // ... - struct wl_compositor *compositor; - // ... -}; +//struct our_state { +// // ... +// struct wl_compositor *compositor; +// // ... +//}; +// +//static void +//registry_handle_global(void *data, struct wl_registry *registry, +// uint32_t name, const char *interface, uint32_t version) +//{ +// printf("interface: '%s', version: %d, name: %d\n", +// interface, version, name); +// +// struct our_state *state = data; +// +// if (strcmp(interface, wl_compositor_interface.name) == 0) { +// state->compositor = wl_registry_bind( +// registry, name, &wl_compositor_interface, 4); +// } +//} +// +//static void +//registry_handle_global_remove(void *data, struct wl_registry *registry, +// uint32_t name) +//{ +// // This space deliberately left blank +//} +// +//static const struct wl_registry_listener +//registry_listener = { +// .global = registry_handle_global, +// .global_remove = registry_handle_global_remove, +//}; +// +//int +//main(int argc, char *argv[]) +//{ +// struct our_state state = { 0 }; +// struct wl_display *display = wl_display_connect(NULL); +// struct wl_registry *registry = wl_display_get_registry(display); +// wl_registry_add_listener(registry, ®istry_listener, &state); +// wl_display_roundtrip(display); +// return 0; +//} -static void -registry_handle_global(void *data, struct wl_registry *registry, - uint32_t name, const char *interface, uint32_t version) -{ - printf("interface: '%s', version: %d, name: %d\n", - interface, version, name); - - struct our_state *state = data; - - if (strcmp(interface, wl_compositor_interface.name) == 0) { - state->compositor = wl_registry_bind( - registry, name, &wl_compositor_interface, 4); +void checkGlError() { + const char *err = SDL_GetError(); + if (*err != 0) { + printf("OpenGL error: %s", err); } } -static void -registry_handle_global_remove(void *data, struct wl_registry *registry, - uint32_t name) -{ - // This space deliberately left blank +/// returns 0 if failed. +GLuint compile_shader(GLuint type, const char *src) { + GLuint id = glCreateShader(type); + glShaderSource(id, 1, &src, 0); + glCompileShader(id); + + int result; + glGetShaderiv(id, GL_COMPILE_STATUS, &result); + if (result == GL_FALSE) { + int length; + glGetShaderiv(id, GL_INFO_LOG_LENGTH, &result); + char *message = alloca(length * sizeof(char)); + glGetShaderInfoLog(id, length, &length, message); + printf("failed to compile %s shader\n", type == GL_VERTEX_SHADER ? "vertex" : "fragment"); + printf("%s\n", message); + glDeleteShader(id); + return 0; + } + + return id; } -static const struct wl_registry_listener -registry_listener = { - .global = registry_handle_global, - .global_remove = registry_handle_global_remove, -}; +const char *vertex_shader_src = +"attribute vec4 vPosition; \n" +"void main() \n" +"{ \n" +" gl_Position = vPosition; \n" +"} \n"; -int -main(int argc, char *argv[]) -{ - struct our_state state = { 0 }; - struct wl_display *display = wl_display_connect(NULL); - struct wl_registry *registry = wl_display_get_registry(display); - wl_registry_add_listener(registry, ®istry_listener, &state); - wl_display_roundtrip(display); - return 0; +/// returns 0 if failed. +GLuint create_shader(const char *fragment_src) { + GLuint program = glCreateProgram(); + GLuint vertex_shader = compile_shader(GL_VERTEX_SHADER, vertex_shader_src); + GLuint fragment_shader = compile_shader(GL_FRAGMENT_SHADER, fragment_src); + if (!((fragment_shader == 0) || (vertex_shader == 0))) { + glAttachShader(program, vertex_shader); + glAttachShader(program, fragment_shader); + glLinkProgram(program); + glValidateProgram(program); + glDeleteShader(vertex_shader); + glDeleteShader(fragment_shader); + return program; + } else { + return 0; + } +} + +GLuint load_shader(const char *path) { + FILE *handle = fopen(path, "r"); + fseek(handle, 0L, SEEK_END); + long length = ftell(handle); + fseek(handle, 0L, SEEK_SET); + char *string = malloc(length * sizeof(char)); + if (!fread(string, sizeof(char), length, handle)) { + printf("failed to read shader file"); + exit(1); + } + fclose(handle); + + GLuint shader = create_shader(string); + + if (shader == 0) { + // print file + int line_count = 1; + printf("%i\t", line_count); + line_count++; + for (int i = 0; i < length; i++) { + printf("%c", string[i]); + if (string[i] == '\n') { + printf("%i\t", line_count); + line_count++; + } + } + printf("\n"); + } + + free(string); + return shader; +} + +struct timespec program_start; + +void init_timer() { + clock_gettime(CLOCK_MONOTONIC, &program_start); +} + +double time_since_start() { + struct timespec now; + clock_gettime(CLOCK_MONOTONIC, &now); + + return (now.tv_sec - program_start.tv_sec) + + (now.tv_nsec - program_start.tv_nsec) / 1e9; +} + +int main() { + init_timer(); + + printf("Good Morning 🍵\n"); + SDL_Init(SDL_INIT_VIDEO); + SDL_SetHint(SDL_HINT_OPENGL_ES_DRIVER, "1"); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, + SDL_GL_CONTEXT_PROFILE_ES); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); + SDL_Window* window = SDL_CreateWindow("SDL3 OpenGL Cube", + 800, 600, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE); + if (!window) { + printf("CreateWindow Error: %s\n", SDL_GetError()); + SDL_Quit(); + return 1; + } + + SDL_GLContext glContext = SDL_GL_CreateContext(window); +const char *version = (const char *)glGetString(GL_VERSION); +const char *renderer = (const char *)glGetString(GL_RENDERER); + +SDL_Log("GL_VERSION: %s", version); +SDL_Log("GL_RENDERER: %s", renderer); + + if (!glContext) { + printf("GL Context Error: %s\n", SDL_GetError()); + SDL_DestroyWindow(window); + SDL_Quit(); + return 1; + } + glEnable(GL_DEPTH_TEST); + + SDL_Event e; + int running = 1; + + GLuint shader = load_shader("fragment.glsl"); //create_shader(fragment_shader_source); + + int w, h; + double time; + while (running) { + while (SDL_PollEvent(&e)) { + if (e.type == SDL_EVENT_QUIT) running = false; + if (e.type == SDL_EVENT_WINDOW_RESIZED) { + SDL_GetWindowSize(window, &w, &h); + } + } + checkGlError(); + + // Rendorrrr + glViewport(0, 0, w, h); + + glClearColor(0.1f, 0.1f, 0.1f, 1.0f); // Dark gray background + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + // Shader parameters. + glUseProgram(shader); + + //int uniform_WindowSize = glGetUniformLocation(shader, "WindowSize"); + //glUniform2f(uniform_WindowSize, w, h); + + //time = time_since_start(); + //int uniform_time = glGetUniformLocation(shader, "time"); + //glUniform1f(uniform_time, (float)time); + + // Load the vertex data + GLfloat vVertices[] = { + 0.0f, 0.5f, 0.0f, + -0.5f, -0.5f, 0.0f, + 0.5f, -0.5f, 0.0f + }; + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vVertices); + glEnableVertexAttribArray(0); + glDrawArrays(GL_TRIANGLES, 0, 3); + + SDL_GL_SwapWindow(window); + checkGlError(); + } + + checkGlError(); } -//void checkGlError() { -// const char *err = SDL_GetError(); -// if (*err != 0) { -// printf("OpenGL error: %s", err); -// } -//} -// -///// returns 0 if failed. -//GLuint compile_shader(GLuint type, const char *src) { -// GLuint id = glCreateShader(type); -// glShaderSource(id, 1, &src, 0); -// glCompileShader(id); -// -// int result; -// glGetShaderiv(id, GL_COMPILE_STATUS, &result); -// if (result == GL_FALSE) { -// int length; -// glGetShaderiv(id, GL_INFO_LOG_LENGTH, &result); -// char *message = alloca(length * sizeof(char)); -// glGetShaderInfoLog(id, length, &length, message); -// printf("failed to compile %s shader\n", type == GL_VERTEX_SHADER ? "vertex" : "fragment"); -// printf("%s\n", message); -// glDeleteShader(id); -// return 0; -// } -// -// return id; -//} -// -///// returns 0 if failed. -//GLuint create_shader(const char *fragment_src) { -// GLuint program = glCreateProgram(); -// GLuint fragment_shader = compile_shader(GL_FRAGMENT_SHADER, fragment_src); -// if (!(fragment_shader == 0)) { -// glAttachShader(program, fragment_shader); -// glLinkProgram(program); -// glValidateProgram(program); -// glDeleteShader(fragment_shader); -// return program; -// } else { -// return 0; -// } -//} -// -//GLuint load_shader(const char *path) { -// FILE *handle = fopen(path, "r"); -// fseek(handle, 0L, SEEK_END); -// long length = ftell(handle); -// fseek(handle, 0L, SEEK_SET); -// char *string = malloc(length * sizeof(char)); -// if (!fread(string, sizeof(char), length, handle)) { -// printf("failed to read shader file"); -// exit(1); -// } -// fclose(handle); -// -// GLuint shader = create_shader(string); -// -// if (shader == 0) { -// // print file -// int line_count = 1; -// printf("%i\t", line_count); -// line_count++; -// for (int i = 0; i < length; i++) { -// printf("%c", string[i]); -// if (string[i] == '\n') { -// printf("%i\t", line_count); -// line_count++; -// } -// } -// printf("\n"); -// } -// -// free(string); -// return shader; -//} -// -//struct timespec program_start; -// -//void init_timer() { -// clock_gettime(CLOCK_MONOTONIC, &program_start); -//} -// -//double time_since_start() { -// struct timespec now; -// clock_gettime(CLOCK_MONOTONIC, &now); -// -// return (now.tv_sec - program_start.tv_sec) + -// (now.tv_nsec - program_start.tv_nsec) / 1e9; -//} -// -//int main() { -// init_timer(); -// -// printf("Good Morning 🍵\n"); -// SDL_Init(SDL_INIT_VIDEO); -// SDL_Window* window = SDL_CreateWindow("SDL3 OpenGL Cube", -// 800, 600, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE); -// if (!window) { -// printf("CreateWindow Error: %s\n", SDL_GetError()); -// SDL_Quit(); -// return 1; -// } -// -// SDL_GLContext glContext = SDL_GL_CreateContext(window); -// if (!glContext) { -// printf("GL Context Error: %s\n", SDL_GetError()); -// SDL_DestroyWindow(window); -// SDL_Quit(); -// return 1; -// } -// glEnable(GL_DEPTH_TEST); -// -// SDL_Event e; -// int running = 1; -// -// GLuint shader = load_shader("fragment.glsl"); //create_shader(fragment_shader_source); -// -// int w, h; -// double time; -// while (running) { -// while (SDL_PollEvent(&e)) { -// if (e.type == SDL_EVENT_QUIT) running = false; -// if (e.type == SDL_EVENT_WINDOW_RESIZED) { -// SDL_GetWindowSize(window, &w, &h); -// } -// } -// checkGlError(); -// -// // Rendorrrr -// glViewport(0, 0, w, h); -// -// glClearColor(0.1f, 0.1f, 0.1f, 1.0f); // Dark gray background -// glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); -// -// // Shader parameters. -// glUseProgram(shader); -// -// int uniform_WindowSize = glGetUniformLocation(shader, "WindowSize"); -// glUniform2f(uniform_WindowSize, w, h); -// -// time = time_since_start(); -// int uniform_time = glGetUniformLocation(shader, "time"); -// glUniform1f(uniform_time, (float)time); -// -// // Draw quad. -// glBegin(GL_QUADS); -// glVertex2f(-1, 1); -// glVertex2f(-1,-1); -// glVertex2f( 1,-1); -// glVertex2f( 1, 1); -// -// glEnd(); -// -// SDL_GL_SwapWindow(window); -// } -// -// checkGlError(); -//} -//