/* * Copyright (C) 2018 Tomasz Kramkowski * SPDX-License-Identifier: MIT */ #include #include #include "assets.h" #include "eprintf.h" #include "gl.h" #include "glprog.h" #include "linmath.h" #include "nelem.h" enum { WIDTH = 800, HEIGHT = 600, }; int main(int argc, char **argv) { bool running = true; SDL_Window *win; SDL_GLContext *glc; GLuint ebo, vbo, vao, prog; GLint ucolor; struct vertex { vec3 pos; vec3 col; vec2 uv; } verts[] = { {{ 0.5, 0.5, 0.0 }, { 1.0, 0.0, 0.0 }, { 1.0, 1.0 }}, {{ 0.5, -0.5, 0.0 }, { 0.0, 1.0, 0.0 }, { 1.0, 0.0 }}, {{ -0.5, -0.5, 0.0 }, { 0.0, 0.0, 1.0 }, { 0.0, 0.0 }}, {{ -0.5, 0.5, 0.0 }, { 1.0, 1.0, 0.0 }, { 0.0, 1.0 }}, }; GLuint idxs[] = { 0, 1, 3, 1, 2, 3, }; setprogname(argc >= 1 && argv[0] != NULL ? argv[0] : "faqe"); if (SDL_Init(SDL_INIT_VIDEO) != 0) eprintf("Failed to initialise SDL: %s", SDL_GetError()); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); win = SDL_CreateWindow("faqe", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WIDTH, HEIGHT, SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE); if (win == NULL) eprintf("Failed to create window: %s", SDL_GetError()); glc = SDL_GL_CreateContext(win); if (glc == NULL) eprintf("Failed to create OpenGL context: %s", SDL_GetError()); gl_load((gl_loadfunc *)SDL_GL_GetProcAddress); gl_viewport(0, 0, WIDTH, HEIGHT); gl_buf_gen(1, &vbo); gl_buf_gen(1, &ebo); gl_va_gen(1, &vao); gl_va_bind(vao); gl_buf_bind(GL_ARRAY_BUFFER, vbo); gl_buf_data(GL_ARRAY_BUFFER, sizeof verts, verts, GL_STATIC_DRAW); gl_buf_bind(GL_ELEMENT_ARRAY_BUFFER, ebo); gl_buf_data(GL_ELEMENT_ARRAY_BUFFER, sizeof idxs, idxs, GL_STATIC_DRAW); gl_va_define(0, NELEM(verts[0].pos), GL_FLOAT, GL_FALSE, sizeof *verts, (void *)offsetof(struct vertex, pos)); gl_va_enable(0); gl_va_define(1, NELEM(verts[0].col), GL_FLOAT, GL_FALSE, sizeof *verts, (void *)offsetof(struct vertex, col)); gl_va_enable(1); gl_va_define(2, NELEM(verts[0].uv), GL_FLOAT, GL_FALSE, sizeof *verts, (void *)offsetof(struct vertex, uv)); gl_va_enable(2); prog = glprog_load(2, (struct shdrdat []){ { GL_VERTEX_SHADER, vert_glsl.data, vert_glsl.size }, { GL_FRAGMENT_SHADER, frag_glsl.data, frag_glsl.size }, }, 1, &(struct unidat){ "ucolor", &ucolor }); gl_poly_mode(GL_FRONT_AND_BACK, GL_LINE); while (running) { SDL_Event ev; while (SDL_PollEvent(&ev)) { switch (ev.type) { case SDL_KEYDOWN: case SDL_KEYUP: if (ev.key.state != SDL_RELEASED || ev.key.keysym.sym != SDLK_ESCAPE) break; /* fallthrough */ case SDL_QUIT: running = false; break; case SDL_WINDOWEVENT: switch (ev.window.event) { case SDL_WINDOWEVENT_SIZE_CHANGED: gl_viewport(0, 0, ev.window.data1, ev.window.data2); } break; } } gl_clearcolor(0.2, 0.3, 0.3, 1.0); gl_clear(GL_COLOR_BUFFER_BIT); gl_prog_use(prog); gl_va_bind(vao); gl_draw_elems(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); gl_va_bind(0); SDL_GL_SwapWindow(win); } SDL_GL_DeleteContext(glc); SDL_DestroyWindow(win); SDL_Quit(); }