#define GL_GLEXT_PROTOTYPES #include #include #include #include #include #include #include #include #include #include //int main() { // struct wl_display *display = wl_display_connect(NULL); // if (!display) { // fprintf(stderr, "Failed to connect to Wayland display.\n"); // return 1; // } // fprintf(stderr, "Connection established!\n"); // // while (wl_display_dispatch(display) != -1) { // } // // wl_display_disconnect(display); //} //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; //} 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; } const char *vertex_shader_src = //"attribute vec4 vPosition; \n" //"void main() \n" //"{ \n" //" gl_Position = vPosition; \n" //"} \n"; "#version 320 es\n" "\n" "layout(location = 0) in vec2 aPos;\n" "\n" "void main() {\n" " gl_Position = vec4(aPos, 0.0, 1.0);\n" "}\n"; /// 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); // buffers // Load the vertex data GLfloat vertices[] = { -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, }; GLuint vao, vbo; glGenVertexArrays(1, &vao); glBindVertexArray(vao); glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glEnableVertexAttribArray(0); glVertexAttribPointer( 0, // location 2, // vec2 GL_FLOAT, GL_FALSE, 0, (void *)0 ); 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); //glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vVertices); //glEnableVertexAttribArray(0); //glDrawArrays(GL_TRIANGLES, 0, 6); glBindVertexArray(vao); glDrawArrays(GL_TRIANGLES, 0, 6); SDL_GL_SwapWindow(window); checkGlError(); } checkGlError(); }