Dengine/src/dengine.c

239 lines
6.2 KiB
C
Raw Normal View History

2016-06-28 06:00:03 +00:00
#include "Dengine/AssetManager.h"
#include "Dengine/Common.h"
#include "Dengine/Debug.h"
#include "Dengine/Math.h"
#include "Dengine/OpenGL.h"
#include "Dengine/WorldTraveller.h"
INTERNAL inline void processKey(KeyState *state, int action)
{
// TODO(doyle): Handle GLFW_REPEAT, and probably remove this function
if (action == GLFW_PRESS || action == GLFW_RELEASE)
{
state->newHalfTransitionCount++;
}
}
INTERNAL void keyCallback(GLFWwindow *window, int key, int scancode, int action,
int mode)
2016-06-03 05:07:40 +00:00
{
2016-06-17 14:40:40 +00:00
GameState *game = CAST(GameState *)(glfwGetWindowUserPointer(window));
2016-06-03 05:07:40 +00:00
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
{
glfwSetWindowShouldClose(window, GL_TRUE);
}
switch (key)
{
case GLFW_KEY_UP:
processKey(&game->input.keys[keycode_up], action);
break;
case GLFW_KEY_DOWN:
processKey(&game->input.keys[keycode_down], action);
break;
case GLFW_KEY_LEFT:
processKey(&game->input.keys[keycode_left], action);
break;
case GLFW_KEY_RIGHT:
processKey(&game->input.keys[keycode_right], action);
break;
case GLFW_KEY_LEFT_SHIFT:
processKey(&game->input.keys[keycode_leftShift], action);
2016-08-10 11:52:05 +00:00
break;
case GLFW_KEY_ENTER:
processKey(&game->input.keys[keycode_enter], action);
2016-08-10 11:52:05 +00:00
break;
case GLFW_KEY_BACKSPACE:
processKey(&game->input.keys[keycode_backspace], action);
break;
default:
2016-08-10 11:52:05 +00:00
if (key >= ' ' && key <= '~')
{
i32 offset = 0;
if (key >= 'A' && key <= 'Z')
{
if (!game->input.keys[keycode_leftShift].endedDown)
offset = 'a' - 'A';
}
i32 glfwCodeToPlatformCode = (key - ' ') + offset;
processKey(&game->input.keys[glfwCodeToPlatformCode], action);
2016-08-10 11:52:05 +00:00
}
break;
}
}
INTERNAL void mouseCallback(GLFWwindow *window, double xPos, double yPos)
{
GameState *game = CAST(GameState *)(glfwGetWindowUserPointer(window));
// NOTE(doyle): x(0), y(0) of mouse starts from the top left of window
v2 windowSize = game->renderer.size;
f32 flipYPos = windowSize.h - CAST(f32) yPos;
game->input.mouseP = V2(CAST(f32) xPos, flipYPos);
}
INTERNAL void mouseButtonCallback(GLFWwindow *window, int button, int action,
int mods)
{
GameState *game = CAST(GameState *)(glfwGetWindowUserPointer(window));
switch(button)
{
case GLFW_MOUSE_BUTTON_LEFT:
processKey(&game->input.keys[keycode_mouseLeft], action);
break;
default:
break;
}
}
2016-06-03 05:07:40 +00:00
INTERNAL void scrollCallback(GLFWwindow *window, double xOffset, double yOffset)
{
}
i32 main(void)
2016-06-03 05:07:40 +00:00
{
/*
**************************
* INIT APPLICATION WINDOW
**************************
*/
2016-06-03 05:07:40 +00:00
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
i32 windowWidth = 1600;
i32 windowHeight = 900;
GLFWwindow *window =
glfwCreateWindow(windowWidth, windowHeight, "Dengine", NULL, NULL);
2016-06-03 05:07:40 +00:00
if (!window)
{
2016-06-17 14:40:40 +00:00
printf("glfwCreateWindow() failed: Failed to create window\n");
2016-06-03 05:07:40 +00:00
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
/*
**************************
* INITIALISE OPENGL STATE
**************************
*/
2016-06-03 05:07:40 +00:00
/* Make GLEW use more modern technies for OGL on core profile*/
glewExperimental = GL_TRUE;
if (glewInit() != GLEW_OK)
{
2016-06-17 14:40:40 +00:00
printf("glewInit() failed: Failed to initialise GLEW\n");
2016-06-03 05:07:40 +00:00
return -1;
}
// NOTE(doyle): glewInit() bug that sets the gl error flag after init
// regardless of success. Catch it once by calling glGetError
glGetError();
2016-06-03 05:07:40 +00:00
i32 frameBufferWidth, frameBufferHeight;
glfwGetFramebufferSize(window, &frameBufferWidth, &frameBufferHeight);
glViewport(0, 0, frameBufferWidth, frameBufferHeight);
2016-06-03 05:07:40 +00:00
glfwSetKeyCallback(window, keyCallback);
glfwSetCursorPosCallback(window, mouseCallback);
glfwSetMouseButtonCallback(window, mouseButtonCallback);
glfwSetScrollCallback(window, scrollCallback);
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
2016-06-09 05:49:03 +00:00
glEnable(GL_BLEND);
glEnable(GL_CULL_FACE);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glCullFace(GL_BACK);
2016-06-03 05:07:40 +00:00
/*
*******************
* INITIALISE GAME
*******************
*/
GameState worldTraveller = {0};
worldTraveller_gameInit(&worldTraveller,
V2i(frameBufferWidth, frameBufferHeight));
#ifdef DENGINE_DEBUG
debug_init(&worldTraveller.arena, V2i(windowWidth, windowHeight),
worldTraveller.assetManager.font);
#endif
glfwSetWindowUserPointer(window, CAST(void *)(&worldTraveller));
/*
*******************
* GAME LOOP
*******************
*/
2016-06-17 14:40:40 +00:00
f32 startTime = CAST(f32)(glfwGetTime());
2016-06-16 17:00:11 +00:00
f32 secondsElapsed = 0.0f; // Time between current frame and last frame
#if 0
2016-06-16 17:00:11 +00:00
// TODO(doyle): Get actual monitor refresh rate
i32 monitorRefreshHz = 60;
f32 targetSecondsPerFrame = 1.0f / CAST(f32)(monitorRefreshHz);
#else
// TODO(doyle): http://gafferongames.com/game-physics/fix-your-timestep/
// NOTE(doyle): Prevent glfwSwapBuffer until a vertical retrace has
// occurred, i.e. limit framerate to monitor refresh rate
glfwSwapInterval(1);
#endif
2016-06-03 07:05:28 +00:00
2016-06-03 05:07:40 +00:00
while (!glfwWindowShouldClose(window))
{
/* Check and call events */
glfwPollEvents();
2016-06-03 05:07:40 +00:00
/* Rendering commands here*/
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
2016-06-03 07:05:28 +00:00
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
2016-06-03 05:07:40 +00:00
2016-06-17 14:40:40 +00:00
worldTraveller_gameUpdateAndRender(&worldTraveller, secondsElapsed);
GL_CHECK_ERROR();
2016-06-03 05:07:40 +00:00
/* Swap the buffers */
glfwSwapBuffers(window);
2016-06-16 17:00:11 +00:00
f32 endTime = CAST(f32)glfwGetTime();
2016-06-16 17:00:11 +00:00
secondsElapsed = endTime - startTime;
#if 0
2016-06-16 17:00:11 +00:00
// TODO(doyle): Busy waiting, should sleep
while (secondsElapsed < targetSecondsPerFrame)
{
endTime = CAST(f32)(glfwGetTime());
2016-06-16 17:00:11 +00:00
secondsElapsed = endTime - startTime;
}
#endif
2016-06-16 17:00:11 +00:00
LOCAL_PERSIST f32 titleUpdateFrequencyInSeconds = 0.5f;
titleUpdateFrequencyInSeconds -= secondsElapsed;
if (titleUpdateFrequencyInSeconds <= 0)
{
f32 msPerFrame = secondsElapsed * 1000.0f;
f32 framesPerSecond = 1.0f / secondsElapsed;
2016-06-17 14:40:40 +00:00
char textBuffer[256];
snprintf(textBuffer, ARRAY_COUNT(textBuffer),
"Dengine | %f ms/f | %f fps", msPerFrame, framesPerSecond);
2016-06-17 14:40:40 +00:00
glfwSetWindowTitle(window, textBuffer);
2016-06-16 17:00:11 +00:00
titleUpdateFrequencyInSeconds = 0.5f;
}
startTime = endTime;
2016-06-03 05:07:40 +00:00
}
glfwTerminate();
return 0;
}