Add minimal, wonky scene tree system

master
outfrost 2020-05-24 06:46:47 +02:00
parent bdd49b5cfe
commit 9eb2826dc0
7 changed files with 168 additions and 3 deletions

View File

@ -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 \

View File

@ -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);

View File

@ -1,9 +1,12 @@
#ifndef RENDER_H_
#define RENDER_H_
#include "scene.h"
float viewportAspectRatio;
void initRender();
void renderFrame();
void renderScene();
#endif

63
src/engine/scene.c Normal file
View File

@ -0,0 +1,63 @@
#include <stdlib.h>
#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;
}

30
src/engine/scene.h Normal file
View File

@ -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_

View File

@ -2,6 +2,7 @@
#include <stdlib.h>
#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) {

View File

@ -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);