engine/logger.c \
engine/performance.c \
engine/render.c \
+ engine/scene.c \
engine/tga.c \
engine/ui.c \
game/level.c \
#include "geometry.h"
#include "performance.h"
+#include "scene.h"
const float AXIS_RADIUS = 5.0f;
float viewportAspectRatio = 1.0f;
-
-
void initRender() {
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
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);
#ifndef RENDER_H_
#define RENDER_H_
+#include "scene.h"
+
float viewportAspectRatio;
void initRender();
+void renderFrame();
void renderScene();
#endif
--- /dev/null
+#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;
+}
--- /dev/null
+#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_
#include <stdlib.h>
#include "engine/logger.h"
+#include "engine/scene.h"
#include "level.h"
#include "player.h"
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) {
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);