From 9eb2826dc033c146f75113a80b9ab2113534f478 Mon Sep 17 00:00:00 2001 From: outfrost Date: Sun, 24 May 2020 06:46:47 +0200 Subject: [PATCH] Add minimal, wonky scene tree system --- Makefile | 1 + src/engine/render.c | 52 +++++++++++++++++++++++++++++++++++-- src/engine/render.h | 3 +++ src/engine/scene.c | 63 +++++++++++++++++++++++++++++++++++++++++++++ src/engine/scene.h | 30 +++++++++++++++++++++ src/game/level.c | 16 ++++++++++++ src/main.c | 6 ++++- 7 files changed, 168 insertions(+), 3 deletions(-) create mode 100644 src/engine/scene.c create mode 100644 src/engine/scene.h diff --git a/Makefile b/Makefile index af858fd..4184930 100644 --- a/Makefile +++ b/Makefile @@ -17,6 +17,7 @@ sources ::= main.c \ engine/logger.c \ engine/performance.c \ engine/render.c \ + engine/scene.c \ engine/tga.c \ engine/ui.c \ game/level.c \ diff --git a/src/engine/render.c b/src/engine/render.c index 68385b0..99586f5 100644 --- a/src/engine/render.c +++ b/src/engine/render.c @@ -6,6 +6,7 @@ #include "geometry.h" #include "performance.h" +#include "scene.h" const float AXIS_RADIUS = 5.0f; @@ -18,8 +19,6 @@ static void drawSolid(const Solid* solid); float viewportAspectRatio = 1.0f; - - void initRender() { glClearColor(0.0f, 0.0f, 0.0f, 1.0f); @@ -38,6 +37,55 @@ 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); + + glFlush(); + glutSwapBuffers(); + frameRendered(); + glutPostRedisplay(); +} + +void renderSceneNew(const Scene* scene) { + if (!scene) { + return; + } + + glMatrixMode(GL_MODELVIEW); + glLoadMatrixf((const GLfloat*) &scene->transform); + + glDisable(GL_LIGHTING); + drawAxes(); + glEnable(GL_LIGHTING); + + if (scene->solid) { + glEnable(GL_LIGHT0); + glEnable(GL_TEXTURE_2D); + drawSolid(scene->solid); + glDisable(GL_TEXTURE_2D); + glDisable(GL_LIGHT0); + } + + for (size_t i = 0; i < scene->numChildren; ++i) { + renderSceneNew(scene->children[i]); + } +} + + + void renderScene() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); diff --git a/src/engine/render.h b/src/engine/render.h index 9251b16..2aea882 100644 --- a/src/engine/render.h +++ b/src/engine/render.h @@ -1,9 +1,12 @@ #ifndef RENDER_H_ #define RENDER_H_ +#include "scene.h" + float viewportAspectRatio; void initRender(); +void renderFrame(); void renderScene(); #endif diff --git a/src/engine/scene.c b/src/engine/scene.c new file mode 100644 index 0000000..e1a4cee --- /dev/null +++ b/src/engine/scene.c @@ -0,0 +1,63 @@ +#include + +#include "engine/logger.h" + +#include "scene.h" + +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 }; + +void multiply(Transform* transform, Transform by) { + GLfloat* a = (GLfloat*) &by; + GLfloat* b = (GLfloat*) transform; + + for (size_t row = 0; row < 4; ++row) { + for (size_t col = 0; col < 4; ++col) { + b[(row * 4) + col] = + a[(row * 4) + 0] * b[(0 * 4) + col] + + a[(row * 4) + 1] * b[(1 * 4) + col] + + a[(row * 4) + 2] * b[(2 * 4) + col] + + a[(row * 4) + 3] * b[(3 * 4) + col]; + } + } +} + +void translate(Transform* transform, Vector3D vec) { + multiply(transform, (Transform) { .a1 = 1.0f, .a2 = 0.0f, .a3 = 0.0f, .a4 = vec.x, + .b1 = 0.0f, .b2 = 1.0f, .b3 = 0.0f, .b4 = vec.y, + .c1 = 0.0f, .c2 = 0.0f, .c3 = 1.0f, .c4 = vec.z, + .d1 = 0.0f, .d2 = 0.0f, .d3 = 0.0f, .d4 = 1.0f }); +} + +Scene* newScene() { + Scene* scene = malloc(sizeof(Scene)); + *scene = (Scene) { .parent = NULL, + .numChildren = 0u, + .children = NULL, + .transform = identity, + .solid = NULL }; + return scene; +} + +void insertChildScene(Scene* scene, Scene* newChild) { + if (!scene || !newChild) { + return; + } + if (newChild->parent) { + logError( + "Cannot insert scene 0x%p as child of 0x%p, because it is already child of 0x%p", + newChild, + scene, + newChild->parent); + return; + } + + scene->children = realloc(scene->children, ++(scene->numChildren) * sizeof(Scene*)); + scene->children[scene->numChildren - 1] = newChild; + + newChild->parent = scene; +} diff --git a/src/engine/scene.h b/src/engine/scene.h new file mode 100644 index 0000000..1abc11c --- /dev/null +++ b/src/engine/scene.h @@ -0,0 +1,30 @@ +#ifndef SCENE_H_ +#define SCENE_H_ + +#include "asset.h" + +typedef struct Scene Scene; +typedef struct Transform Transform; + +struct Transform { + GLfloat a1, a2, a3, a4; + GLfloat b1, b2, b3, b4; + GLfloat c1, c2, c3, c4; + GLfloat d1, d2, d3, d4; +}; + +struct Scene { + Scene* parent; + size_t numChildren; + Scene** children; + Transform transform; + const Solid* solid; +}; + +Scene* currentScene; + +void translate(Transform* transform, Vector3D vec); +Scene* newScene(); +void insertChildScene(Scene* scene, Scene* newChild); + +#endif // SCENE_H_ diff --git a/src/game/level.c b/src/game/level.c index 219b2e9..a92e9b7 100644 --- a/src/game/level.c +++ b/src/game/level.c @@ -2,6 +2,7 @@ #include #include "engine/logger.h" +#include "engine/scene.h" #include "level.h" #include "player.h" @@ -28,6 +29,21 @@ void initLevel() { 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.depth; ++x) { + Scene* blockScene = newScene(); + translate(&blockScene->transform, (Vector3D) { .x = x * BLOCKGRID_CELL_SIZE, + .y = 0.0f, + .z = z * BLOCKGRID_CELL_SIZE }); + blockScene->solid = getBlockFromGrid(levelGrid, x, z)->solid; + insertChildScene(levelScene, blockScene); + } + } + + currentScene = levelScene; } void buildLevelFromImage(TgaImage* image) { diff --git a/src/main.c b/src/main.c index 144f54a..ed887da 100644 --- a/src/main.c +++ b/src/main.c @@ -48,7 +48,11 @@ int main(int argc, char** argv) { logWarning("Could not enable vsync (extensions not supported)"); } - glutDisplayFunc(renderScene); + GLint maxModelviewStackDepth; + glGetIntegerv(GL_MAX_MODELVIEW_STACK_DEPTH, &maxModelviewStackDepth); + logDebug("GL_MAX_MODELVIEW_STACK_DEPTH: %d", maxModelviewStackDepth); + + glutDisplayFunc(renderFrame); glutReshapeFunc(resizeStage); //glutKeyboardFunc(key_pressed); //glutMouseFunc(mouse_button_event); -- 2.44.0