From edfc39dc5ca88d91ab6a27121321fc1b719d1ad7 Mon Sep 17 00:00:00 2001 From: outfrost Date: Wed, 27 May 2020 01:10:23 +0200 Subject: [PATCH] Finish moving to scene tree implementation; clean up unused code --- src/engine/render.c | 88 ++++++++++----------------------------------- src/engine/render.h | 2 +- src/engine/scene.c | 49 ++++++++++++++++++++++--- src/engine/scene.h | 4 +++ src/game/level.c | 35 +++++++++--------- src/game/level.h | 2 +- src/game/player.c | 15 ++++---- src/game/player.h | 12 +++---- src/main.c | 1 + 9 files changed, 101 insertions(+), 107 deletions(-) diff --git a/src/engine/render.c b/src/engine/render.c index 3b88d44..a26cfab 100644 --- a/src/engine/render.c +++ b/src/engine/render.c @@ -1,23 +1,22 @@ #include #include -#include "game/level.h" -#include "game/player.h" - #include "geometry.h" #include "performance.h" #include "scene.h" -const float AXIS_RADIUS = 5.0f; +float viewportAspectRatio = 1.0f; +const Scene* cameraAnchor; + +static const float AXIS_RADIUS = 5.0f; +static void renderScene(const Scene*); static void setupCamera(); -static void moveCameraTo(const Vector3D pos); +static void moveCameraTo(const Scene* scene); static void drawAxes(); -static void renderBlockGrid(const BlockGrid grid); -static void renderCharacter(const Character* character, const Vector3D pos); static void drawSolid(const Solid* solid); -float viewportAspectRatio = 1.0f; + void initRender() { glClearColor(0.0f, 0.0f, 0.0f, 1.0f); @@ -37,29 +36,25 @@ void initRender() { glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 0.005f); } - - -void renderSceneNew(const Scene*); - void renderFrame() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - + glEnable(GL_NORMALIZE); glEnable(GL_CULL_FACE); glEnable(GL_DEPTH_TEST); - + setupCamera(); - moveCameraTo(playerPos); - - renderSceneNew(currentScene); - + moveCameraTo(cameraAnchor); + + renderScene(currentScene); + glFlush(); glutSwapBuffers(); frameRendered(); glutPostRedisplay(); } -void renderSceneNew(const Scene* scene) { +void renderScene(const Scene* scene) { if (!scene) { return; } @@ -80,39 +75,10 @@ void renderSceneNew(const Scene* scene) { } for (size_t i = 0; i < scene->numChildren; ++i) { - renderSceneNew(scene->children[i]); + renderScene(scene->children[i]); } } - - -void renderScene() { - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glEnable(GL_NORMALIZE); - glEnable(GL_CULL_FACE); - glEnable(GL_DEPTH_TEST); - - setupCamera(); - moveCameraTo(playerPos); - - glDisable(GL_LIGHTING); - drawAxes(); - glEnable(GL_LIGHTING); - - glEnable(GL_LIGHT0); - glEnable(GL_TEXTURE_2D); - renderBlockGrid(levelGrid); - renderCharacter(&playerCharacter, playerPos); - glDisable(GL_TEXTURE_2D); - glDisable(GL_LIGHT0); - - glFlush(); - glutSwapBuffers(); - frameRendered(); - glutPostRedisplay(); -} - static void setupCamera() { glMatrixMode(GL_PROJECTION); glLoadIdentity(); @@ -126,8 +92,10 @@ static void setupCamera() { glRotatef(45.0f, 0.0f, 1.0f, 0.0f); } -static void moveCameraTo(const Vector3D pos) { +static void moveCameraTo(const Scene* anchor) { glMatrixMode(GL_PROJECTION); + // TODO This needs to account for parent nodes as well + Vector3D pos = translationOf(anchor->transform); glTranslatef(-pos.x, -pos.y, -pos.z); } @@ -153,26 +121,6 @@ static void drawAxes() { glEnd(); } -static void renderBlockGrid(const BlockGrid grid) { - glMatrixMode(GL_MODELVIEW); - for (size_t z = 0; z < grid.depth; ++z) { - glLoadIdentity(); - glTranslatef(0.0f, 0.0f, z * BLOCKGRID_CELL_SIZE); - for (size_t x = 0; x < grid.width; ++x) { - drawSolid(getBlockFromGrid(grid, x, z)->solid); - glTranslatef(BLOCKGRID_CELL_SIZE, 0.0f, 0.0f); - } - } - glLoadIdentity(); -} - -static void renderCharacter(const Character* character, const Vector3D pos) { - glMatrixMode(GL_MODELVIEW); - glTranslatef(pos.x, pos.y, pos.z); - drawSolid(character->solid); - glLoadIdentity(); -} - static void drawSolid(const Solid* solid) { if (solid == NULL) { return; diff --git a/src/engine/render.h b/src/engine/render.h index 2aea882..df18281 100644 --- a/src/engine/render.h +++ b/src/engine/render.h @@ -4,9 +4,9 @@ #include "scene.h" float viewportAspectRatio; +const Scene* cameraAnchor; void initRender(); void renderFrame(); -void renderScene(); #endif diff --git a/src/engine/scene.c b/src/engine/scene.c index e1a4cee..5cbe405 100644 --- a/src/engine/scene.c +++ b/src/engine/scene.c @@ -6,10 +6,14 @@ Scene* currentScene = NULL; -static Transform identity = { .a1 = 1.0f, .a2 = 0.0f, .a3 = 0.0f, .a4 = 0.0f, - .b1 = 0.0f, .b2 = 1.0f, .b3 = 0.0f, .b4 = 0.0f, - .c1 = 0.0f, .c2 = 0.0f, .c3 = 1.0f, .c4 = 0.0f, - .d1 = 0.0f, .d2 = 0.0f, .d3 = 0.0f, .d4 = 1.0f }; + + +Transform identity() { + return (Transform) { .a1 = 1.0f, .a2 = 0.0f, .a3 = 0.0f, .a4 = 0.0f, + .b1 = 0.0f, .b2 = 1.0f, .b3 = 0.0f, .b4 = 0.0f, + .c1 = 0.0f, .c2 = 0.0f, .c3 = 1.0f, .c4 = 0.0f, + .d1 = 0.0f, .d2 = 0.0f, .d3 = 0.0f, .d4 = 1.0f }; +} void multiply(Transform* transform, Transform by) { GLfloat* a = (GLfloat*) &by; @@ -33,12 +37,16 @@ void translate(Transform* transform, Vector3D vec) { .d1 = 0.0f, .d2 = 0.0f, .d3 = 0.0f, .d4 = 1.0f }); } +Vector3D translationOf(Transform transform) { + return (Vector3D) { transform.a4, transform.b4, transform.c4 }; +} + Scene* newScene() { Scene* scene = malloc(sizeof(Scene)); *scene = (Scene) { .parent = NULL, .numChildren = 0u, .children = NULL, - .transform = identity, + .transform = identity(), .solid = NULL }; return scene; } @@ -61,3 +69,34 @@ void insertChildScene(Scene* scene, Scene* newChild) { newChild->parent = scene; } + +void reparentScene(Scene* scene, Scene* newParent) { + if (!scene) { + return; + } + + if (scene->parent) { + Scene* parent = scene->parent; + size_t indexInParent = parent->numChildren; + for (size_t i = 0; i < parent->numChildren; ++i) { + if (parent->children[i] == scene) { + indexInParent = i; + break; + } + } + // This includes the hopefully impossible case where parent->numChildren == 0 + if (indexInParent == parent->numChildren) { + logError("Scene %p not found in children of parent %p", scene, parent); + } + else { + for (size_t i = indexInParent; i < parent->numChildren - 1; ++i) { + parent->children[i] = parent->children[i + 1]; + } + parent->children = realloc(parent->children, --(parent->numChildren) * sizeof(Scene*)); + } + } + + scene->parent = NULL; + + insertChildScene(newParent, scene); +} diff --git a/src/engine/scene.h b/src/engine/scene.h index 1abc11c..24b308a 100644 --- a/src/engine/scene.h +++ b/src/engine/scene.h @@ -23,8 +23,12 @@ struct Scene { Scene* currentScene; +Transform identity(); void translate(Transform* transform, Vector3D vec); +Vector3D translationOf(Transform transform); + Scene* newScene(); void insertChildScene(Scene* scene, Scene* newChild); +void reparentScene(Scene* scene, Scene* newParent); #endif // SCENE_H_ diff --git a/src/game/level.c b/src/game/level.c index 0dd1d61..ad1158e 100644 --- a/src/game/level.c +++ b/src/game/level.c @@ -7,31 +7,29 @@ #include "level.h" #include "player.h" +BlockGrid levelGrid; + static Block blockEmpty = { .type = BLOCKTYPE_SPACE, .solid = NULL }; static Block blockWall01 = { .type = BLOCKTYPE_OBSTACLE, .solid = NULL }; -static Block* testBlocks[9] = { &blockWall01, &blockWall01, &blockWall01, - &blockEmpty, &blockEmpty, &blockEmpty, - &blockWall01, &blockEmpty, &blockWall01 }; - -BlockGrid levelGrid = { .width = 3, - .depth = 3, - .blocks = testBlocks }; - -#define DEFAULT_PLAYER_SPAWN_POS { -BLOCKGRID_CELL_SIZE, 0.0f, -BLOCKGRID_CELL_SIZE } -Vector3D playerSpawnPos = DEFAULT_PLAYER_SPAWN_POS; +static Transform playerSpawnTransform; void initLevel() { + playerSpawnTransform = identity(); + translate(&playerSpawnTransform, (Vector3D) { .x = -BLOCKGRID_CELL_SIZE, + .y = 0.0f, + .z = -BLOCKGRID_CELL_SIZE }); + blockWall01.solid = importSolid("assets/wall01.3ds"); - + buildLevelFromImage(readTga("assets/level01.tga")); - + Scene* levelScene = newScene(); - + for (size_t z = 0; z < levelGrid.depth; ++z) { for (size_t x = 0; x < levelGrid.width; ++x) { Scene* blockScene = newScene(); @@ -46,6 +44,10 @@ void initLevel() { currentScene = levelScene; } +void startLevel() { + spawnPlayer(playerSpawnTransform); +} + void buildLevelFromImage(TgaImage* image) { if (image == NULL) { logError("Null image received, cannot build level"); @@ -62,7 +64,6 @@ void buildLevelFromImage(TgaImage* image) { .blocks = malloc(image->header.imageWidth * image->header.imageHeight * sizeof(Block*)) }; - playerSpawnPos = (Vector3D) DEFAULT_PLAYER_SPAWN_POS; for (size_t row = 0; row < newGrid.depth; ++row) { for (size_t x = 0; x < newGrid.width; ++x) { @@ -77,7 +78,10 @@ void buildLevelFromImage(TgaImage* image) { break; case 0xFF00FFFF: block = &blockEmpty; - playerSpawnPos = (Vector3D) { x * BLOCKGRID_CELL_SIZE, 0.0f, z * BLOCKGRID_CELL_SIZE }; + playerSpawnTransform = identity(); + translate(&playerSpawnTransform, (Vector3D) { .x = x * BLOCKGRID_CELL_SIZE, + .y = 0.0f, + .z = z * BLOCKGRID_CELL_SIZE }); break; default: block = &blockEmpty; @@ -88,5 +92,4 @@ void buildLevelFromImage(TgaImage* image) { } levelGrid = newGrid; - spawnPlayer(); } diff --git a/src/game/level.h b/src/game/level.h index ccde120..4795d5d 100644 --- a/src/game/level.h +++ b/src/game/level.h @@ -27,9 +27,9 @@ typedef struct { #define BLOCKGRID_CELL_SIZE 2.5f BlockGrid levelGrid; -Vector3D playerSpawnPos; void initLevel(); +void startLevel(); void buildLevelFromImage(TgaImage* image); static inline Block* getBlockFromGrid(BlockGrid grid, size_t x, size_t z) { diff --git a/src/game/player.c b/src/game/player.c index 6aafb24..144d0cf 100644 --- a/src/game/player.c +++ b/src/game/player.c @@ -1,16 +1,19 @@ -#include "engine/logger.h" +#include "engine/asset.h" +#include "engine/render.h" -#include "level.h" #include "player.h" -Character playerCharacter = { .solid = NULL }; +Scene* playerCharacter; void initPlayer() { - playerCharacter.solid = importSolid("assets/playercharacter.3ds"); + playerCharacter = newScene(); + cameraAnchor = playerCharacter; + playerCharacter->solid = importSolid("assets/playercharacter.3ds"); } -void spawnPlayer() { - playerPos = playerSpawnPos; +void spawnPlayer(Transform transform) { + playerCharacter->transform = transform; + reparentScene(playerCharacter, currentScene); } diff --git a/src/game/player.h b/src/game/player.h index aeeabc4..9a7c250 100644 --- a/src/game/player.h +++ b/src/game/player.h @@ -3,16 +3,12 @@ #include -#include "engine/asset.h" +#include "engine/geometry.h" +#include "engine/scene.h" -typedef struct { - const Solid* solid; -} Character; - -Character playerCharacter; -Vector3D playerPos; +Scene* playerCharacter; void initPlayer(); -void spawnPlayer(); +void spawnPlayer(Transform transform); #endif diff --git a/src/main.c b/src/main.c index ed887da..fa9ed02 100644 --- a/src/main.c +++ b/src/main.c @@ -62,6 +62,7 @@ int main(int argc, char** argv) { //initPerformanceMetering(); initLevel(); initPlayer(); + startLevel(); glutMainLoop(); return 0; -- 2.44.0