diff options
| author | Aaditya Dhruv <[email protected]> | 2026-01-25 18:06:13 -0600 |
|---|---|---|
| committer | Aaditya Dhruv <[email protected]> | 2026-01-25 18:06:13 -0600 |
| commit | 955ffb0d4a0235532fdb9b808745bcf571735122 (patch) | |
| tree | 7b6dce22f1af65411ba27cfae88a4e4d9927d862 | |
| parent | 118980e02e59ff31871df59dce257075394f3533 (diff) | |
rotating cube
| -rw-r--r-- | CMakeLists.txt | 2 | ||||
| -rw-r--r-- | shaders/fragment.glsl | 2 | ||||
| -rw-r--r-- | shaders/vertex.glsl | 7 | ||||
| -rw-r--r-- | src/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/block.c | 88 | ||||
| -rw-r--r-- | src/block.h | 11 | ||||
| -rw-r--r-- | src/engine.c | 62 | ||||
| -rw-r--r-- | src/engine.h | 26 | ||||
| -rw-r--r-- | src/junkcraft.c | 43 | ||||
| -rw-r--r-- | src/shader.c | 23 | ||||
| -rw-r--r-- | src/shader.h | 16 | ||||
| -rw-r--r-- | src/window.h | 1 |
12 files changed, 216 insertions, 66 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 160b3df..5cff1d8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,4 +9,4 @@ message("Compiler: ${CMAKE_CXX_COMPILER_ID}") add_subdirectory(src) target_include_directories(junkcraft PRIVATE include) find_package(SDL2) -target_link_libraries(junkcraft PRIVATE SDL2) +target_link_libraries(junkcraft PRIVATE SDL2 junk m) diff --git a/shaders/fragment.glsl b/shaders/fragment.glsl index cdaf24f..2b1879f 100644 --- a/shaders/fragment.glsl +++ b/shaders/fragment.glsl @@ -1,6 +1,6 @@ #version 410 core out vec4 frag_colour; -in vec3 color; +flat in vec3 color; void main() { frag_colour = vec4( color, 1.0 ); }; diff --git a/shaders/vertex.glsl b/shaders/vertex.glsl index d6a5091..7d99479 100644 --- a/shaders/vertex.glsl +++ b/shaders/vertex.glsl @@ -2,8 +2,11 @@ layout(location=0) in vec3 pos; layout(location=1) in vec3 col; -out vec3 color; +flat out vec3 color; +uniform mat4 model; +uniform mat4 view; +uniform mat4 perspective; void main() { - gl_Position = vec4( pos, 1.0 ); + gl_Position = perspective * model * vec4( pos, 1.0 ); color = col; }; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2286d1a..7b88ab5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -5,4 +5,5 @@ add_executable(junkcraft block.c util.c window.c + engine.c ) diff --git a/src/block.c b/src/block.c index e93ae6c..3679892 100644 --- a/src/block.c +++ b/src/block.c @@ -1,37 +1,62 @@ -#include "cglm/types.h" +#include "cglm/cglm.h" +#include "cglm/io.h" +#include "cglm/util.h" +#include "math.h" #include "glad/glad.h" #include "block.h" +#include "shader.h" #include "util.h" -#include "cglm/cglm.h" #include "block.h" +#include <math.h> #include <string.h> +#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0])) + int block_init(vec3 pos, struct block* blk) { // Store buffer data into struct // Initialize vbo and ebo for block memcpy(blk->coords, pos, sizeof(vec3)); + // ========== Constants of a block ================ + // Local world coordinates float vertices[] = { 0.5f, 0.5f, 0.0f, // top-right -0.5f, 0.5f, 0.0f, // top-left -0.5f, -0.5f, 0.0f, // bottom-left 0.5f, -0.5f, 0.0f, // bottom-right + + 0.5f, 0.5f, -0.5f, // top-right (back plane) + -0.5f, 0.5f, -0.5f, // top-left (back plane) + -0.5f, -0.5f, -0.5f, // bottom-left (back plane) + 0.5f, -0.5f, -0.5f, // bottom-right (back plane) }; float colors[] = { - 1.0f, 0.0f, 0.0f, // r,g,b of first point. - 0.0f, 1.0f, 0.0f, // r,g,b of second point. - 0.0f, 0.0f, 1.0f, // r,g,b of third point. - 1.0f, 1.0f, 1.0f // r,g,b of fourth point. + 1.0f, 0.0f, 0.0f, + 1.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, + 0.0f, 1.0f, 0.0f, + + 0.0f, 0.0f, 1.0f, + 0.0f, 0.0f, 1.0f, + 1.0f, 1.0f, 0.0f, + 1.0f, 1.0f, 0.0f, + }; - int vertex_order[] = { 1, 2, 3, 3, 0, 1 }; - - //TODO: - //1. Create VAO for mesh - //2. Create VBOs for vertices and colors - //3. Set EBO for index order - create_vbo(&blk->_vbo1, (void*)vertices, sizeof(float) * 12); - create_vbo(&blk->_vbo2, (void*)colors, sizeof(float) * 12); - create_ebo(&blk->_ebo, (void*)vertex_order, sizeof(int) * 6); + int vertex_order[] = { + 1, 2, 3, 3, 0, 1, // Front + 5, 6, 7, 7, 4, 5, // Back + 0, 3, 7, 7, 4, 0, // Right + 1, 2, 6, 6, 5, 1, // Left + 5, 1, 0, 0, 4, 5, // Top + 6, 2, 3, 3, 7, 6, // Bottom + }; + + // ================ OpenGL work ================ + create_vbo(&blk->_vbo1, (void*)vertices, sizeof(float) * ARRAY_SIZE(vertices)); + create_vbo(&blk->_vbo2, (void*)colors, sizeof(float) * ARRAY_SIZE(colors)); + create_ebo(&blk->_ebo, (void*)vertex_order, sizeof(int) * ARRAY_SIZE(vertex_order)); + + blk->_vertex_count = ARRAY_SIZE(vertex_order); glGenVertexArrays(1, &blk->_vao); glBindVertexArray(blk->_vao); // Enable 2 attribs - position and color @@ -44,12 +69,41 @@ int block_init(vec3 pos, struct block* blk) { glBindBuffer(GL_ARRAY_BUFFER, blk->_vbo2); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, blk->_ebo); + return 0; } +void block_update(struct block* blk) { + //=============== Matrix Work ============== + + // RTS matrix - rotate, translate, scale + glm_mat4_identity(blk->model); + float angle = glm_rad(blk->angle); + vec3 axis_y = { 0.0f, 1.0f, 0.0f }; + vec3 pivot = { 0.0f, 0.0f, -0.25f }; + vec3 translation = { 0.0f, 0, -2.0f }; + glm_translate(blk->model, translation); + glm_rotate_at(blk->model, pivot, angle, axis_y); + glm_mat4_print(blk->model, stderr); + // View matrix (camera) + vec3 camera = { 0.0f, 0.0f, -2.0f }; + vec3 camera_direction = { 0.0f, 0.0f, 1.0f }; + glm_look(camera, camera_direction, axis_y, blk->view); + + // Projection (perspective) matrix + + glm_perspective(glm_rad(45.0f), 800.0f / 600.0f, 0.1f, -10.0f, blk->perspective); + + blk->angle = fmodf(blk->angle + 0.01f, 360.0f); +} + // Register block vbos and ebos to context -int block_draw(struct block* blk) { +int block_draw(struct block* blk, struct shader* shader) { glBindVertexArray(blk->_vao); - glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); + set_uniform_mat4("model", shader, blk->model); +// set_uniform_mat4("view", shader, blk->view); + set_uniform_mat4("perspective", shader, blk->perspective); + glDrawElements(GL_TRIANGLES, blk->_vertex_count, GL_UNSIGNED_INT, 0); + block_update(blk); return 0; } diff --git a/src/block.h b/src/block.h index 46607b4..00668f6 100644 --- a/src/block.h +++ b/src/block.h @@ -1,13 +1,20 @@ #pragma once #include "cglm/types.h" #include "glad/glad.h" +#include "shader.h" + struct block { - vec3 coords; + vec3 coords; int type; GLuint _vao; GLuint _vbo1; GLuint _vbo2; GLuint _ebo; + int _vertex_count; + mat4 model; + mat4 view; + mat4 perspective; + float angle; }; int block_init(vec3 pos, struct block* blk); -int block_draw(struct block* blk); +int block_draw(struct block* blk, struct shader* shader); diff --git a/src/engine.c b/src/engine.c new file mode 100644 index 0000000..9e007ca --- /dev/null +++ b/src/engine.c @@ -0,0 +1,62 @@ +#include "engine.h" +#include "block.h" +#include "window.h" +#include <junk/vector.h> + +int engine_init(struct engine *engine) { + // Setup the Window + struct window* window = malloc(sizeof(struct window)); + memset(window, 0, sizeof(struct window)); + if (window_init(window) != 0) { + free(window); + return -1; + } + engine->window = window; + + // Setup Shader pipeline + struct shader* shader = malloc(sizeof(struct shader)); + memset(shader, 0, sizeof(struct shader)); + if (shader_init(shader)) { + free(window); + free(shader); + return -1; + }; + engine->shader = shader; + + // Setup Objects to draw + struct block* blk = malloc(sizeof(struct block)); + memset(blk, 0, sizeof(struct block)); + vec3 pos = { 0, 0, 0 }; + if (block_init(pos, blk) != 0) { + free(window); + free(shader); + free(blk); + return -1; + } + vector_init(&engine->objects); + VECTOR_INSERT(engine->objects, (void*)blk); + + engine->game_loop = 1; + return 0; +} + +void engine_draw(struct engine* engine) { + while (engine->game_loop) { + SDL_Event event; + while (SDL_PollEvent(&event)) { + // Quit game + if (event.type == SDL_QUIT) { + engine->game_loop = 0; + } + } + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glEnable(GL_DEPTH_TEST); + //glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); + glUseProgram(engine->shader->program); + for (int i = 0; i < engine->objects->len; i++) { + struct block* block = vector_get(engine->objects, i); + block_draw(block, engine->shader); + } + SDL_RenderPresent(engine->window->renderer); + } +} diff --git a/src/engine.h b/src/engine.h new file mode 100644 index 0000000..7fde16f --- /dev/null +++ b/src/engine.h @@ -0,0 +1,26 @@ +#pragma once +#include "window.h" +#include "shader.h" +#include "junk/vector.h" +struct engine { + struct window* window; + struct shader* shader; + struct vector* objects; + int game_loop; +}; + +/** + * Initalize the Engine, a struct that oversees the rest of the components in the game + * @param @out engine The engine struct to store data in + * @return 0 on success + */ +int engine_init(struct engine* engine); + + +/** + * Take all objects in the engine, apply the shader pipeline and draw on the window + * Event handling is also processed here, though should maybe moved to a separate thread + * + * @param engine The target engine + */ +void engine_draw(struct engine* engine); diff --git a/src/junkcraft.c b/src/junkcraft.c index d914973..e96b942 100644 --- a/src/junkcraft.c +++ b/src/junkcraft.c @@ -1,44 +1,11 @@ -#include <SDL2/SDL_events.h> -#include <SDL2/SDL_pixels.h> -#include <SDL2/SDL_rect.h> -#include <signal.h> -#include <stdio.h> -#include "SDL2/SDL_render.h" -#include "glad/glad.h" -#include "shader.h" -#include "block.h" -#include "window.h" - -// Global OpenGL Context -GLuint shader_program; -int game_loop = 1; - -void draw(struct window* window, struct block* block) { - while (game_loop) { - SDL_Event event; - while (SDL_PollEvent(&event)) { - // Quit game - if (event.type == SDL_QUIT) { - game_loop = 0; - } - } - glClear(GL_COLOR_BUFFER_BIT); - glUseProgram(shader_program); - block_draw(block); - SDL_RenderPresent(window->renderer); - } -} +#include "engine.h" int main() { - struct window window = {0}; - if (window_init(&window) != 0) { + struct engine engine = { 0 }; + if (engine_init(&engine) != 0) { return -1; } - struct block blk = {0}; - vec3 pos = { 0, 0, 0 }; - block_init(pos, &blk); - shader_program = shader_init(); - draw(&window, &blk); - window_cleanup(&window); + engine_draw(&engine); + window_cleanup(engine.window); return 0; } diff --git a/src/shader.c b/src/shader.c index c78a7e5..339b76f 100644 --- a/src/shader.c +++ b/src/shader.c @@ -1,3 +1,4 @@ +#include "glad/glad.h" #include "shader.h" #include <stdio.h> #include <stdlib.h> @@ -31,6 +32,12 @@ GLuint compile_shader(GLuint type, const char* code) { GLuint shader = glCreateShader(type); glShaderSource(shader, 1, &code, NULL); glCompileShader(shader); + GLint out; + glGetShaderiv(shader, GL_COMPILE_STATUS, &out); + if (out == GL_FALSE) { + fprintf(stderr, "Failed to compile shader: %s", code); + exit(1); + } return shader; } @@ -52,12 +59,24 @@ GLuint create_shader_program(const char* vs, const char* fs) { } -GLuint shader_init() { +int shader_init(struct shader* shader) { char* shaders[2] = { "shaders/fragment.glsl", "shaders/vertex.glsl" }; char* fragment_shader = read_shader(shaders[0]); char* vertex_shader = read_shader(shaders[1]); GLuint shader_program = create_shader_program(vertex_shader, fragment_shader); free(vertex_shader); free(fragment_shader); - return shader_program; + shader->program = shader_program; + return 0; +} + +int set_uniform_mat4(char* var, struct shader* shader, mat4 matrix) { + GLuint loc = glGetUniformLocation(shader->program, var); + if (loc == -1) { + fprintf(stderr, "Invalid var %s for get_uniform_mat4: Does not exist\n", var); + exit(1); + return -1; + } + glUniformMatrix4fv(loc, 1, GL_FALSE, (void*)matrix); + return 0; } diff --git a/src/shader.h b/src/shader.h index c613708..78b4a26 100644 --- a/src/shader.h +++ b/src/shader.h @@ -1,5 +1,15 @@ +#pragma once +#include "cglm/types.h" #include "glad/glad.h" -//Load a vertex and framgent shader defined in -//the shaders/ directory. -GLuint shader_init(); +struct shader { + GLuint program; +}; +/* + *Load a vertex and framgent shader defined in the shaders/ directory. + @param shader The shader struct to store the compiled program pointer in + @return zero on success + */ +int shader_init(struct shader* shader); + +int set_uniform_mat4(char* var, struct shader* shader, mat4 matrix); diff --git a/src/window.h b/src/window.h index 9a8c942..0c3680b 100644 --- a/src/window.h +++ b/src/window.h @@ -1,3 +1,4 @@ +#pragma once #include "SDL2/SDL.h" #include "SDL2/SDL_video.h" #include "SDL2/SDL_render.h" |
