From 06535ccf013696d96dec389b29e050c21a4481bf Mon Sep 17 00:00:00 2001 From: var Date: Wed, 1 Apr 2026 22:07:55 -0500 Subject: [PATCH] Camera follows object in 3rd person --- res/tex/texture.png | Bin 1107 -> 1170 bytes src/camera.c | 2 +- src/game.c | 10 +++++-- src/game.h | 3 +- src/render.c | 71 ++++++++++++++++++++++++++++---------------- src/shape.c | 52 ++++++++++++++++++++++++++++++-- src/shape.h | 2 +- 7 files changed, 107 insertions(+), 33 deletions(-) diff --git a/res/tex/texture.png b/res/tex/texture.png index 9d6e08ad17fced7a25d75051a88b959ac461d320..5ece0b538b0585f21f3b3673506d11beade6478f 100644 GIT binary patch delta 286 zcmcc2F^O|RcRiCapUKsPFa`$Z7oIMTAr-gY-q^@_$U&sxp-a$C7mH0z+8q{slW*MS zXzJSAdhMK`lh$zy^NypULifLa?SH)Y)$>=`UOTyRwpY5x?T@nSU-;c#_S?em`}40a z{9eCS&h>NdtFC9q7yf_w`}yg$O6yvM85$TE7+4q>6o3>X1H delta 197 zcmbQld6{EEcNil#d&GrX0SpYxD?MEtLn>~)y|IzkAwi(+;rvTtZGwhposition[0] = 5.0f; - c->position[1] = 0.0f; + c->position[1] = 8.0f; c->position[2] = 0.0f; c->width[0] = 0.6f; c->width[1] = 5.8f; diff --git a/src/game.c b/src/game.c index 58cb6f4..d0b4edb 100644 --- a/src/game.c +++ b/src/game.c @@ -7,7 +7,8 @@ GameState *Game_New() { - GameState *gs = calloc(1, sizeof(GameState)); + GameState *gs = calloc(1, sizeof(GameState) + (2 * sizeof(Shape**))); + gs->shapes = (void*)(gs + 1); if (!Render_Init(gs)) return NULL; @@ -26,7 +27,12 @@ void Game_Update(GameState *gs) else if (gs->input.d) move[1] = -speed; if (gs->input.q) move[2] = speed; else if (gs->input.e) move[2] = -speed; - glm_vec3_add(gs->camera.position, move, gs->camera.position); + + ShapeInstance *target = &(gs->shapes[0]->instances[2]); + vec3 displacement; + glm_vec3_scale(gs->camera.front, -10.0, displacement); + glm_vec3_add(target->position, move, target->position); + glm_vec3_add(target->position, displacement, gs->camera.position); Camera_UpdateVectors(&gs->camera); SDL_Delay(5); diff --git a/src/game.h b/src/game.h index 052c80d..c1af1ea 100644 --- a/src/game.h +++ b/src/game.h @@ -25,7 +25,8 @@ typedef struct GLuint textureId; int shaderProgramId; Camera camera; - Shape *testShape; + Shape **shapes; + int numShapes; mat4 projMatrix; mat4 viewMatrix; } GameState; diff --git a/src/render.c b/src/render.c index d20a92c..d9c6a30 100644 --- a/src/render.c +++ b/src/render.c @@ -227,6 +227,7 @@ bool Render_Init(GameState *gs) if (gs->shaderProgramId < 0) { printf("Failed to load shaders.\n"); + return false; } glEnable(GL_DEPTH_TEST); @@ -236,17 +237,32 @@ bool Render_Init(GameState *gs) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); printf("Initialized OpenGL.\n"); + gs->numShapes = 2; + Shape *shape = Shape_MakePyramid(5); - gs->testShape = shape; + gs->shapes[0] = shape; glGenVertexArrays(1, &shape->VAO); glGenBuffers(1, &shape->VBO); glGenBuffers(1, &shape->IBO); glGenBuffers(1, &shape->EBO); + printf("Created shape 0.\n"); + + shape = Shape_MakePlane(); + gs->shapes[1] = shape; + glGenVertexArrays(1, &shape->VAO); + glGenBuffers(1, &shape->VBO); + glGenBuffers(1, &shape->IBO); + glGenBuffers(1, &shape->EBO); + printf("Created shape 1.\n"); LoadTexture(gs); + printf("Loaded textures.\n"); Camera_Init(&gs->camera); - InitShapeBuffers(gs->testShape); + InitShapeBuffers(gs->shapes[0]); + InitShapeBuffers(gs->shapes[1]); + printf("Initialized buffers.\n"); + return true; } void Render_Destroy(GameState *gs) @@ -302,35 +318,38 @@ void Render_Draw(GameState *gs) glBindTexture(GL_TEXTURE_2D, gs->textureId); vec3 scale = { 0, 0, 0 }; - Shape *shape = gs->testShape; - glBindVertexArray(shape->VAO); - - // apply transformations to each instance - for (int j = 0; j < shape->numInstances; j++) + for (int i = 0; i < gs->numShapes; i++) { - ShapeInstance* instance = shape->instances + j; - mat4* matrix = (void*)(shape->instanceData + (j * 17) + 1); - mat4 tempMat; - glm_mat4_identity(tempMat); + Shape *shape = gs->shapes[i]; + glBindVertexArray(shape->VAO); - glm_translate(tempMat, instance->position); - glm_rotate_x(tempMat, instance->rotation[0], tempMat); - glm_rotate_y(tempMat, instance->rotation[1], tempMat); - glm_rotate_z(tempMat, instance->rotation[2], tempMat); + // apply transformations to each instance + for (int j = 0; j < shape->numInstances; j++) + { + ShapeInstance* instance = shape->instances + j; + mat4* matrix = (void*)(shape->instanceData + (j * 17) + 1); + mat4 tempMat; + glm_mat4_identity(tempMat); + + glm_translate(tempMat, instance->position); + glm_rotate_x(tempMat, instance->rotation[0], tempMat); + glm_rotate_y(tempMat, instance->rotation[1], tempMat); + glm_rotate_z(tempMat, instance->rotation[2], tempMat); + + scale[0] = instance->scale; + scale[1] = instance->scale; + scale[2] = instance->scale; + glm_scale(tempMat, scale); + + memcpy(matrix, tempMat, sizeof(mat4)); + } - scale[0] = instance->scale; - scale[1] = instance->scale; - scale[2] = instance->scale; - glm_scale(tempMat, scale); + // re-buffer the instance data because transformations may have changed + glBindBuffer(GL_ARRAY_BUFFER, shape->IBO); + glBufferData(GL_ARRAY_BUFFER, shape->numInstances * SHAPE_INSTANCE_SIZE, shape->instanceData, GL_DYNAMIC_DRAW); - memcpy(matrix, tempMat, sizeof(mat4)); + glDrawElementsInstanced(GL_TRIANGLES, shape->numIndices, GL_UNSIGNED_SHORT, 0, shape->numInstances); } - // re-buffer the instance data because transformations may have changed - glBindBuffer(GL_ARRAY_BUFFER, shape->IBO); - glBufferData(GL_ARRAY_BUFFER, shape->numInstances * SHAPE_INSTANCE_SIZE, shape->instanceData, GL_DYNAMIC_DRAW); - - glDrawElementsInstanced(GL_TRIANGLES, shape->numIndices, GL_UNSIGNED_SHORT, 0, shape->numInstances); - SDL_GL_SwapWindow(gs->window); } diff --git a/src/shape.c b/src/shape.c index 170b9ef..10c5a50 100644 --- a/src/shape.c +++ b/src/shape.c @@ -63,8 +63,8 @@ Shape *Shape_MakePyramid(int numInstances) { ShapeInstance *instance = shape->instances + i; instance->position[0] = 0.0f; - instance->position[0] = 0.0f; - instance->position[0] = (5.0f * i) - 10.0; + instance->position[1] = 3.0f; + instance->position[2] = (5.0f * i) - 10.0f; instance->scale = 1.0f; instance->collisionRadius = 1.0f; glm_vec3_zero(instance->velocity); @@ -77,6 +77,54 @@ Shape *Shape_MakePyramid(int numInstances) return shape; } +Shape *Shape_MakePlane() +{ + GLfloat vertices[] = + { + -30.0f, 0.0f, -30.0f, 0.0f, 0.0f, + -30.0f, 0.0f, 30.0f, 0.0f, 1.0f, + 30.0f, 0.0f, 30.0f, 1.0f, 1.0f, + 30.0f, 0.0f, -30.0f, 1.0f, 0.0f, + }; + + GLushort indices[] = + { + 1, 2, 0, + 2, 3, 0 + }; + + size_t numBytesVertices = sizeof(vertices); + size_t numBytesIndices = sizeof(indices); + + Shape *shape = malloc(sizeof(Shape) + numBytesVertices + numBytesIndices); + void *tempPtr = (void*)(shape + 1); + shape->vertices = tempPtr; + shape->numVertices = numBytesVertices / sizeof(vertices[0]); + shape->indices = tempPtr + numBytesVertices; + shape->numIndices = numBytesIndices / sizeof(indices[0]); + + memcpy(shape->vertices, vertices, numBytesVertices); + memcpy(shape->indices, indices, numBytesIndices); + + shape->instances = calloc(1, sizeof(ShapeInstance) + SHAPE_INSTANCE_SIZE); + shape->instanceData = (void*)(shape->instances + 1); + shape->numInstances = 1; + + ShapeInstance *instance = shape->instances; + instance->position[0] = 0.0f; + instance->position[1] = 0.0f; + instance->position[2] = 0.0f; + instance->scale = 1.0f; + instance->collisionRadius = 1.0f; + glm_vec3_zero(instance->velocity); + glm_vec3_zero(instance->rotation); + float *textureId = shape->instanceData + (0 * 17); + *textureId = 5; + mat4 *matrix = (void*)(textureId + 1); + + return shape; +} + void *Shape_Destroy(Shape *shape) { free(shape); diff --git a/src/shape.h b/src/shape.h index 6291584..e9e09fc 100644 --- a/src/shape.h +++ b/src/shape.h @@ -15,7 +15,6 @@ typedef struct vec3 velocity; float scale; float collisionRadius; - } ShapeInstance; typedef struct @@ -35,3 +34,4 @@ typedef struct } Shape; Shape *Shape_MakePyramid(int numInstances); +Shape *Shape_MakePlane();