2018-02-12 21:35:44 +01:00
# include <GL/gl3w.h> // This example is using gl3w to access OpenGL functions (because it is small). You may use glew/glad/glLoadGen/etc. whatever already works for you.
2016-08-31 19:30:31 +02:00
# include <GLFW/glfw3.h>
# include <GLFW/glfw3native.h>
2018-02-13 12:05:07 +01:00
# include "Globals.h"
2016-08-29 22:31:11 +02:00
# include <X11/Xlib.h>
# include <stdlib.h>
# include <stdio.h>
2016-09-16 17:29:17 +02:00
# include <unistd.h>
2016-08-29 22:31:11 +02:00
# include <iostream>
2018-02-12 13:05:19 +01:00
# include <sstream>
2016-08-29 22:31:11 +02:00
2017-01-30 22:39:55 +01:00
# include "Timer.h"
2016-09-16 17:29:17 +02:00
# include "RuntimeModuleManager.h"
2016-09-23 09:06:46 +02:00
# include "imgui/imgui.h"
2017-07-02 20:18:34 +02:00
# include "imgui_dock.h"
2018-02-12 21:35:44 +01:00
# include "imgui_impl_glfw_gl3.h"
2016-08-29 22:31:11 +02:00
2018-03-10 08:48:41 +01:00
# include "FileModificationObserver.h"
2016-11-25 22:27:37 +01:00
# include "Serializer.h"
2017-01-30 22:39:55 +01:00
Timer * gTimer = nullptr ;
2016-09-19 22:55:42 +02:00
Renderer * gRenderer = nullptr ;
GLFWwindow * gWindow = nullptr ;
2016-11-06 11:34:51 +01:00
RuntimeModuleManager * gModuleManager = nullptr ;
2016-11-25 22:27:37 +01:00
WriteSerializer * gWriteSerializer = nullptr ;
ReadSerializer * gReadSerializer = nullptr ;
2017-02-05 14:37:58 +01:00
GuiInputState * gGuiInputState = nullptr ;
2018-03-10 08:48:41 +01:00
FileModificationObserver * gFileModificationObserver = nullptr ;
2017-02-05 10:36:37 +01:00
double gTimeAtStart = 0 ;
2016-08-29 22:31:11 +02:00
2017-02-05 14:37:58 +01:00
double mouse_scroll_x = 0. ;
double mouse_scroll_y = 0. ;
2018-03-04 12:31:05 +01:00
bool show_dock_1 = true ;
bool show_dock_2 = true ;
bool show_dock_3 = true ;
2016-08-31 19:30:31 +02:00
2018-03-04 12:31:05 +01:00
using namespace std ;
2016-08-31 19:30:31 +02:00
2016-08-29 22:31:11 +02:00
static void error_callback ( int error , const char * description )
{
fprintf ( stderr , " Error (%d): %s \n " , error , description ) ;
}
2018-02-27 23:31:13 +01:00
static void opengl_error_callback (
GLenum source ,
GLenum type ,
GLuint id ,
GLenum severity ,
GLsizei length ,
const GLchar * message ,
const void * userParam )
{
gLog ( " OpenGL Error: %s type %0x%x, severity = 0x%x, message = %s " ,
( type = = GL_DEBUG_TYPE_ERROR ? " ** GL ERROR ** " : " " ) ,
type , severity , message ) ;
}
2016-08-29 22:31:11 +02:00
static void key_callback ( GLFWwindow * window , int key , int scancode , int action , int mods )
{
if ( key = = GLFW_KEY_ESCAPE & & action = = GLFW_PRESS )
glfwSetWindowShouldClose ( window , GLFW_TRUE ) ;
}
2017-02-05 14:37:58 +01:00
void mouse_scroll_callback ( GLFWwindow * window , double xoffset , double yoffset ) {
mouse_scroll_x + = xoffset ;
mouse_scroll_y + = yoffset ;
}
void handle_mouse ( ) {
if ( ! glfwGetWindowAttrib ( gWindow , GLFW_FOCUSED ) ) {
return ;
}
if ( glfwGetMouseButton ( gWindow , 1 ) ) {
glfwSetInputMode ( gWindow , GLFW_CURSOR , GLFW_CURSOR_DISABLED ) ;
} else {
glfwSetInputMode ( gWindow , GLFW_CURSOR , GLFW_CURSOR_NORMAL ) ;
}
double mouse_x , mouse_y ;
glfwGetCursorPos ( gWindow , & mouse_x , & mouse_y ) ;
gGuiInputState - > mousedX = mouse_x - gGuiInputState - > mouseX ;
gGuiInputState - > mousedY = mouse_y - gGuiInputState - > mouseY ;
gGuiInputState - > mouseX = mouse_x ;
gGuiInputState - > mouseY = mouse_y ;
gGuiInputState - > mouseScroll = mouse_scroll_y ;
gGuiInputState - > mouseButton =
glfwGetMouseButton ( gWindow , 0 )
+ ( glfwGetMouseButton ( gWindow , 1 ) < < 1 )
+ ( glfwGetMouseButton ( gWindow , 2 ) < < 2 ) ;
}
2016-08-29 22:31:11 +02:00
int main ( void )
{
2017-02-05 10:36:37 +01:00
gTimeAtStart = gGetCurrentTime ( ) ;
std : : cout < < " Time at start: " < < gTimeAtStart < < std : : endl ;
2018-02-12 13:05:19 +01:00
LoggingInit ( ) ;
2016-11-25 22:27:37 +01:00
WriteSerializer out_serializer ;
ReadSerializer in_serializer ;
2016-09-23 09:06:46 +02:00
// Initialize GLFW
2016-08-29 22:31:11 +02:00
glfwSetErrorCallback ( error_callback ) ;
glfwInit ( ) ;
glfwWindowHint ( GLFW_CLIENT_API , GLFW_OPENGL_API ) ;
glfwWindowHint ( GLFW_CONTEXT_VERSION_MAJOR , 3 ) ;
2018-02-13 12:05:07 +01:00
glfwWindowHint ( GLFW_CONTEXT_VERSION_MINOR , 3 ) ;
2017-03-26 14:19:09 +02:00
glfwWindowHint ( GLFW_SAMPLES , 16 ) ;
2018-02-12 21:35:44 +01:00
glfwWindowHint ( GLFW_OPENGL_PROFILE , GLFW_OPENGL_CORE_PROFILE ) ;
# if __APPLE__
glfwWindowHint ( GLFW_OPENGL_FORWARD_COMPAT , GL_TRUE ) ;
# endif
2016-08-29 22:31:11 +02:00
2016-09-19 22:55:42 +02:00
gWindow = glfwCreateWindow ( 800 , 600 , " ProtoT " , NULL , NULL ) ;
glfwMakeContextCurrent ( gWindow ) ;
2018-02-12 21:35:44 +01:00
glfwSwapInterval ( 1 ) ;
gl3wInit ( ) ;
2016-08-31 19:30:31 +02:00
int width , height ;
2016-09-19 22:55:42 +02:00
glfwGetWindowSize ( gWindow , & width , & height ) ;
2016-08-29 22:31:11 +02:00
2017-02-05 14:37:58 +01:00
glfwSetKeyCallback ( gWindow , key_callback ) ;
glfwSetScrollCallback ( gWindow , mouse_scroll_callback ) ;
2017-01-14 17:14:23 +01:00
std : : cout < < " OpenGL Version: " < < glGetString ( GL_VERSION ) < < endl ;
std : : cout < < " GLSL Version : " < < glGetString ( GL_SHADING_LANGUAGE_VERSION ) < < endl ;
2018-02-27 23:31:13 +01:00
// During init, enable debug output
glEnable ( GL_DEBUG_OUTPUT ) ;
glDebugMessageCallback ( ( GLDEBUGPROC ) opengl_error_callback , 0 ) ;
2016-09-23 09:06:46 +02:00
// imgui initialization.
2018-02-12 21:35:44 +01:00
ImGui : : CreateContext ( ) ;
ImGuiIO & io = ImGui : : GetIO ( ) ; ( void ) io ;
2017-02-05 14:37:58 +01:00
GuiInputState gui_input_state ;
gGuiInputState = & gui_input_state ;
2018-02-28 21:11:51 +01:00
ImGui_ImplGlfwGL3_Init ( gWindow , true ) ;
2018-03-04 21:10:57 +01:00
ImGui : : LoadDock ( ) ;
2016-08-29 22:31:11 +02:00
2018-03-10 08:48:41 +01:00
// FileModificationObserver
FileModificationObserver file_modification_observer ;
gFileModificationObserver = & file_modification_observer ;
2017-01-30 22:39:55 +01:00
// Timer
Timer timer ;
gTimer = & timer ;
timer . mCurrentTime = 0.0f ;
timer . mDeltaTime = 0.0f ;
2016-09-03 16:18:51 +02:00
printf ( " Initializing ModuleManager... \n " ) ;
2016-09-16 17:29:17 +02:00
RuntimeModuleManager module_manager ;
2016-09-23 09:06:46 +02:00
module_manager . RegisterModule ( " src/modules/libRenderModule.so " ) ;
2018-03-09 16:44:40 +01:00
module_manager . RegisterModule ( " src/modules/libTestModule.so " ) ;
2018-02-12 21:35:44 +01:00
// module_manager.RegisterModule("src/modules/libCharacterModule.so");
2016-09-03 16:18:51 +02:00
2016-11-06 11:34:51 +01:00
// Setup global variables
gModuleManager = & module_manager ;
2016-11-25 22:27:37 +01:00
gWriteSerializer = & out_serializer ;
gReadSerializer = & in_serializer ;
// Load modules
module_manager . LoadModules ( ) ;
2018-02-12 21:35:44 +01:00
double frame_time_last = glfwGetTime ( ) ;
double frame_time_current = frame_time_last ;
double frame_delta_time = 0.0 ;
2018-02-12 13:05:19 +01:00
uint64_t frame_counter = 0 ;
2016-08-31 19:30:31 +02:00
2018-02-16 22:43:40 +01:00
bool draw_imgui_demo = false ;
2016-09-19 22:55:42 +02:00
while ( ! glfwWindowShouldClose ( gWindow ) ) {
2018-02-12 13:05:19 +01:00
frame_counter + + ;
2017-02-05 14:37:58 +01:00
// Start the imgui frame such that widgets can be submitted
handle_mouse ( ) ;
glfwGetWindowSize ( gWindow , & width , & height ) ;
2018-02-28 21:11:51 +01:00
glViewport ( 0 , 0 , width , height ) ;
2018-02-12 21:35:44 +01:00
glfwPollEvents ( ) ;
2018-02-16 22:43:40 +01:00
ImGui_ImplGlfwGL3_NewFrame ( ) ;
2018-02-12 21:35:44 +01:00
if ( module_manager . CheckModulesChanged ( ) ) {
gLog ( " Detected module update at frame %d. Unloading all modules. " , frame_counter ) ;
module_manager . UnloadModules ( ) ;
// We need to sleep to make sure we load the new files
module_manager . LoadModules ( ) ;
}
frame_time_last = frame_time_current ;
frame_time_current = glfwGetTime ( ) ;
frame_delta_time = frame_time_current - frame_time_last ;
gTimer - > mFrameTime = ( float ) ( frame_delta_time ) ;
2017-01-30 22:39:55 +01:00
if ( ! gTimer - > mPaused ) {
gTimer - > mDeltaTime = gTimer - > mFrameTime ;
gTimer - > mCurrentTime = gTimer - > mCurrentTime + gTimer - > mDeltaTime ;
} else {
gTimer - > mDeltaTime = 0.0f ;
}
2017-01-14 16:21:47 +01:00
2017-03-11 22:16:12 +01:00
assert ( gTimer - > mDeltaTime > = 0.0f ) ;
2018-02-12 13:05:19 +01:00
int width , height ;
glfwGetWindowSize ( gWindow , & width , & height ) ;
2018-02-16 22:43:40 +01:00
ImGui : : BeginMainMenuBar ( ) ;
if ( ImGui : : BeginMenu ( " Dialogs " ) )
{
ImGui : : Checkbox ( " ImGui Demo " , & draw_imgui_demo ) ;
ImGui : : EndMenu ( ) ;
}
2018-03-04 12:31:05 +01:00
float menu_bar_height = ImGui : : GetWindowHeight ( ) ;
2018-02-16 22:43:40 +01:00
ImGui : : EndMainMenuBar ( ) ;
if ( draw_imgui_demo )
ImGui : : ShowDemoWindow ( ) ;
2018-03-04 21:10:57 +01:00
ImGui : : RootDock ( ImVec2 ( 0.0f , menu_bar_height ) , ImVec2 ( width , height - menu_bar_height ) ) ;
2018-02-12 13:05:19 +01:00
2018-03-04 12:31:05 +01:00
module_manager . Update ( gTimer - > mDeltaTime ) ;
2018-02-12 13:05:19 +01:00
2018-03-04 21:10:57 +01:00
ImGui : : Render ( ) ;
2018-02-12 13:05:19 +01:00
2018-07-08 14:00:30 +02:00
// Send the application to sleep if we have some time left for this frame
double frame_target_time = 1.0 / module_manager . mTargetFPS ;
if ( frame_delta_time < frame_target_time ) {
usleep ( ( frame_target_time - frame_delta_time ) * 1000000 * 0.98 ) ;
}
2018-02-12 13:05:19 +01:00
2018-03-10 08:48:41 +01:00
if ( glfwGetKey ( gWindow , GLFW_KEY_F5 ) = = GLFW_PRESS ) {
gFileModificationObserver - > Update ( ) ;
}
2018-02-12 21:35:44 +01:00
glfwSwapBuffers ( gWindow ) ;
2016-08-29 22:31:11 +02:00
}
2016-09-16 17:29:17 +02:00
2018-03-04 21:10:57 +01:00
ImGui : : SaveDock ( ) ;
2016-11-25 22:27:37 +01:00
module_manager . UnregisterModules ( ) ;
2016-09-19 22:55:42 +02:00
gRenderer = nullptr ;
2016-09-23 09:06:46 +02:00
2017-07-02 20:18:34 +02:00
ImGui : : ShutdownDock ( ) ;
2018-02-12 21:35:44 +01:00
ImGui_ImplGlfwGL3_Shutdown ( ) ;
ImGui : : DestroyContext ( ) ;
glfwTerminate ( ) ;
2016-08-29 22:31:11 +02:00
}