]> git.lizzy.rs Git - shadowclad.git/blob - src/engine/engine.c
1e7849f7a33dc45cf85d5409406de78a005bd8d7
[shadowclad.git] / src / engine / engine.c
1 #include "engine.h"
2
3 #include <stdlib.h>
4 #include <assimp/version.h>
5 #include <GL/glxew.h>
6 #include <GLFW/glfw3.h>
7
8 #include "_prelude.h"
9 #include "input.h"
10 #include "logger.h"
11 #include "performance.h"
12 #include "render.h"
13 #include "ui.h"
14
15 // static const int EXIT_OK = 0;
16 static const int EXIT_LIB_FAIL = 1;
17 static const int EXIT_CTX_FAIL = 2;
18
19 static GLFWwindow* window;
20
21 static void onGlfwError(int error, const char* description);
22
23
24
25 void init(EngineConfig config) {
26         if (window) {
27                 logError("init called more than once");
28                 return;
29         }
30
31         logInfo("Assimp %u.%u", aiGetVersionMajor(), aiGetVersionMinor());
32         logInfo("GLEW %s", (const char*) glewGetString(GLEW_VERSION));
33         logInfo("GLFW %s", glfwGetVersionString());
34
35         glfwSetErrorCallback(onGlfwError);
36
37         if (!glfwInit()) {
38                 logError("GLFW init failed");
39                 exit(EXIT_LIB_FAIL);
40         }
41         // glutInitContextVersion(4,5); TODO establish correct context
42         // glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
43         // glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 5);
44
45         window = glfwCreateWindow(config.windowWidth,
46                                   config.windowHeight,
47                                   config.windowTitle.cstr,
48                                   NULL,
49                                   NULL);
50
51         if (!window) {
52                 logError("Window or context creation failed");
53                 glfwTerminate();
54                 exit(EXIT_CTX_FAIL);
55         }
56
57         glfwMakeContextCurrent(window);
58
59         logInfo("OpenGL %s", (const char*) glGetString(GL_VERSION));
60         logInfo("GLSL %s", (const char*) glGetString(GL_SHADING_LANGUAGE_VERSION));
61         logInfo("Renderer: %s", (const char*) glGetString(GL_RENDERER));
62
63         GLenum glewInitStatus = glewInit();
64         if (glewInitStatus != GLEW_OK) {
65                 logError("GLEW init failed: %s", (const char*) glewGetErrorString(glewInitStatus));
66                 exit(EXIT_LIB_FAIL);
67         }
68
69         logInfo("Setting swap interval: %d", config.swapInterval);
70         glfwSwapInterval(config.swapInterval);
71
72         int width, height;
73         glfwGetFramebufferSize(window, &width, &height);
74         resizeStage(window, width, height);
75
76         glfwSetFramebufferSizeCallback(window, resizeStage);
77         glfwSetKeyCallback(window, onKeyboardEvent);
78
79         initRender();
80         //initPerformanceMetering();
81 }
82
83 void run(void (*updateFn) (float)) {
84         if (!updateFn) {
85                 logError("No update function provided");
86                 return;
87         }
88
89         float lastTime = glfwGetTime();
90         float delta = 0.0f;
91
92         while (!glfwWindowShouldClose(window)) {
93                 float time = glfwGetTime();
94                 delta = time - lastTime;
95                 lastTime = time;
96
97                 updateFn(delta);
98
99                 renderFrame(window);
100                 glfwPollEvents();
101         }
102 }
103
104 void terminate() {
105         glfwTerminate();
106 }
107
108 EngineConfig defaultConfig() {
109         return (EngineConfig) { .windowWidth = 800,
110                                 .windowHeight = 600,
111                                 .windowTitle = newString(NULL),
112                                 .swapInterval = 1 };
113 }
114
115 static void onGlfwError(int error UNUSED, const char* description) {
116         logError("GLFW error: %s", description);
117 }