2020-01-03 21:41:23 +01:00
# include <glad/glad.h>
2019-12-13 13:40:41 +01:00
# include <GLFW/glfw3.h>
2020-01-04 17:48:15 +01:00
# include <iostream>
2020-01-04 18:19:18 +01:00
# include "Rendering/Shader.h"
# include "ECS/ECS.h"
2020-01-04 18:25:47 +01:00
# include "ECS/Events/InputEvent.h"
# include "ECS/Systems/GravitySystem.h"
# include "ECS/Systems/PositionDebugSystem.h"
# include "ECS/Systems/KeyboardMovementSystem.h"
2019-12-13 13:26:18 +01:00
using namespace ECS ;
2020-01-03 21:41:23 +01:00
World * world = World : : createWorld ( ) ;
static void key_callback ( GLFWwindow * window , int key , int scancode , int action , int mods ) {
2019-12-13 13:50:02 +01:00
if ( key = = GLFW_KEY_ESCAPE & & action = = GLFW_PRESS )
glfwSetWindowShouldClose ( window , GLFW_TRUE ) ;
2020-01-03 21:41:23 +01:00
world - > emit < InputEvent > ( { key , action } ) ;
2019-12-13 13:50:02 +01:00
}
2019-12-13 13:26:18 +01:00
int main ( ) {
2020-01-07 13:10:23 +01:00
// TODO: Could be automated by getting all classes within 'ECS/Systems'
2019-12-13 13:26:18 +01:00
world - > registerSystem ( new GravitySystem ( - 9.8f ) ) ;
2020-01-03 21:41:23 +01:00
world - > registerSystem ( new PositionDebugOutputSystem ( ) ) ;
world - > registerSystem ( new KeyboardMovementSystem ( ) ) ;
2019-12-13 13:26:18 +01:00
2019-12-13 13:40:41 +01:00
Entity * ent = world - > create ( ) ;
2020-01-07 13:10:23 +01:00
ent - > assign < Transform > ( ) ;
ent - > assign < Movement > ( glm : : vec3 ( 1.f , 1.f , 1.f ) ) ;
2019-12-13 13:26:18 +01:00
2020-01-07 13:10:23 +01:00
ComponentHandle < Transform > pos = ent - > get < Transform > ( ) ;
2019-12-13 13:26:18 +01:00
2019-12-13 13:40:41 +01:00
GLFWwindow * window ;
/* Initialize the library */
if ( ! glfwInit ( ) )
return - 1 ;
/* Create a windowed mode window and its OpenGL context */
window = glfwCreateWindow ( 640 , 480 , " Hello World " , NULL , NULL ) ;
if ( ! window ) {
glfwTerminate ( ) ;
return - 1 ;
}
/* Make the window's context current */
glfwMakeContextCurrent ( window ) ;
2019-12-13 13:50:02 +01:00
glfwSetKeyCallback ( window , key_callback ) ;
2020-01-03 21:41:23 +01:00
// glad: load all OpenGL function pointers
// ---------------------------------------
if ( ! gladLoadGLLoader ( ( GLADloadproc ) glfwGetProcAddress ) )
{
std : : cout < < " Failed to initialize GLAD " < < std : : endl ;
return - 1 ;
}
2020-01-04 17:48:15 +01:00
Shader defaultShader ( " Shaders/default-vertex.vs " , " Shaders/default-fragment.fs " ) ;
2020-01-03 21:41:23 +01:00
// set up vertex data (and buffer(s)) and configure vertex attributes
// ------------------------------------------------------------------
float vertices [ ] = {
2020-01-04 17:48:15 +01:00
// positions // colors
0.5f , - 0.5f , 0.0f , 1.0f , 0.0f , 0.0f , // bottom right
- 0.5f , - 0.5f , 0.0f , 0.0f , 1.0f , 0.0f , // bottom left
0.0f , 0.5f , 0.0f , 0.0f , 0.0f , 1.0f // top
2020-01-03 21:41:23 +01:00
} ;
unsigned int indices [ ] = { // note that we start from 0!
2020-01-04 17:48:15 +01:00
0 , 1 , 2 // first Triangle
2020-01-03 21:41:23 +01:00
} ;
unsigned int VBO , VAO , EBO ;
glGenVertexArrays ( 1 , & VAO ) ;
glGenBuffers ( 1 , & VBO ) ;
glGenBuffers ( 1 , & EBO ) ;
// bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s).
glBindVertexArray ( VAO ) ;
glBindBuffer ( GL_ARRAY_BUFFER , VBO ) ;
glBufferData ( GL_ARRAY_BUFFER , sizeof ( vertices ) , vertices , GL_STATIC_DRAW ) ;
glBindBuffer ( GL_ELEMENT_ARRAY_BUFFER , EBO ) ;
glBufferData ( GL_ELEMENT_ARRAY_BUFFER , sizeof ( indices ) , indices , GL_STATIC_DRAW ) ;
2020-01-04 17:48:15 +01:00
// position attribute
glVertexAttribPointer ( 0 , 3 , GL_FLOAT , GL_FALSE , 6 * sizeof ( float ) , ( void * ) 0 ) ;
glEnableVertexAttribArray ( 0 ) ;
// color attribute
glVertexAttribPointer ( 1 , 3 , GL_FLOAT , GL_FALSE , 6 * sizeof ( float ) , ( void * ) ( 3 * sizeof ( float ) ) ) ;
glEnableVertexAttribArray ( 1 ) ;
2020-01-03 21:41:23 +01:00
glEnableVertexAttribArray ( 0 ) ;
// note that this is allowed, the call to glVertexAttribPointer registered VBO as the vertex attribute's bound vertex buffer object so afterwards we can safely unbind
glBindBuffer ( GL_ARRAY_BUFFER , 0 ) ;
// remember: do NOT unbind the EBO while a VAO is active as the bound element buffer object IS stored in the VAO; keep the EBO bound.
//glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
// You can unbind the VAO afterwards so other VAO calls won't accidentally modify this VAO, but this rarely happens. Modifying other
// VAOs requires a call to glBindVertexArray anyways so we generally don't unbind VAOs (nor VBOs) when it's not directly necessary.
glBindVertexArray ( 0 ) ;
double timeInLastFrame = glfwGetTime ( ) ;
double elapsed_time = 0.0 ;
2019-12-13 13:40:41 +01:00
/* Loop until the user closes the window */
while ( ! glfwWindowShouldClose ( window ) ) {
2020-01-03 21:41:23 +01:00
// Delta time handling
double delta = glfwGetTime ( ) - timeInLastFrame ;
timeInLastFrame = glfwGetTime ( ) ;
elapsed_time + = delta ;
std : : cout < < " Elapsed time: " < < elapsed_time < < std : : endl ;
world - > tick ( delta ) ;
2019-12-13 13:40:41 +01:00
/* Render here */
2020-01-03 21:41:23 +01:00
// render
// ------
glClearColor ( 0.2f , 0.3f , 0.3f , 1.0f ) ;
2019-12-13 13:40:41 +01:00
glClear ( GL_COLOR_BUFFER_BIT ) ;
2020-01-03 21:41:23 +01:00
// draw our first triangle
2020-01-04 17:48:15 +01:00
defaultShader . use ( ) ;
2020-01-03 21:41:23 +01:00
glBindVertexArray ( VAO ) ; // seeing as we only have a single VAO there's no need to bind it every time, but we'll do so to keep things a bit more organized
2020-01-04 17:48:15 +01:00
glDrawArrays ( GL_TRIANGLES , 0 , 3 ) ;
2020-01-03 21:41:23 +01:00
// glBindVertexArray(0); // no need to unbind it every time
2019-12-13 13:40:41 +01:00
/* Swap front and back buffers */
glfwSwapBuffers ( window ) ;
/* Poll for and process events */
glfwPollEvents ( ) ;
}
glfwTerminate ( ) ;
2019-12-13 13:26:18 +01:00
return 0 ;
}