2022-09-05 20:17:25 +02:00
# ifndef RENDER_LOOP_CPP
# define RENDER_LOOP_CPP
# include <glad/glad.h>
# include <GLFW/glfw3.h>
# include <iostream>
# include "renderLoop.hpp"
# include "draw.hpp"
# include "shaders.hpp"
# include "constants.hpp"
# include "misc.hpp"
2022-09-07 18:54:59 +02:00
bool processInput ( GLFWwindow * window , const bool whatToDraw )
2022-09-05 20:17:25 +02:00
{
2022-09-07 18:54:59 +02:00
// glfwGetKey takes window and key as an input and checks is currently being pressed
2022-09-05 20:17:25 +02:00
// if the user pressed escape we close window
2022-09-07 18:54:59 +02:00
if ( glfwGetKey ( window , GLFW_KEY_ESCAPE ) = = GLFW_PRESS )
2022-09-05 20:17:25 +02:00
glfwSetWindowShouldClose ( window , true ) ;
2022-09-07 18:54:59 +02:00
if ( glfwGetKey ( window , GLFW_KEY_C ) = = GLFW_PRESS )
2022-09-05 20:17:25 +02:00
glfwSetWindowShouldClose ( window , true ) ;
2022-09-07 18:54:59 +02:00
if ( glfwGetKey ( window , GLFW_KEY_LEFT ) = = GLFW_PRESS | | glfwGetKey ( window , GLFW_KEY_RIGHT ) = = GLFW_PRESS )
return ! whatToDraw ;
2022-09-05 20:17:25 +02:00
return whatToDraw ;
}
2022-09-06 21:52:06 +02:00
// https://stackoverflow.com/a/25680092
unsigned int copyVerticesMemory ( const float vertices [ ] , const size_t sizeOfVertices , const GLenum boundBufferTarget )
2022-09-05 20:17:25 +02:00
{
2022-09-06 21:52:06 +02:00
// stores vertices in gpu memory
unsigned int vertexBufferObject ;
// this is open gl object so we refer it by its ID generated here and stored in vertexBufferObject variable
glGenBuffers ( 1 , & vertexBufferObject ) ;
// buffer type of vertex buffer object is GL_ARRAY_BUFFER
glBindBuffer ( boundBufferTarget , vertexBufferObject ) ;
// now whenever we change GL_ARRAY_BUFFER we change bound buffer vertexBufferObject
/* we copy vertex data into buffer memory
GL_STREAM_DRAW : the data is set only once and used by the GPU at most a few times .
GL_STATIC_DRAW : the data is set only once and used many times .
GL_DYNAMIC_DRAW : the data is changed a lot and used many times .
*/
glBufferData ( boundBufferTarget , sizeOfVertices , vertices , GL_STATIC_DRAW ) ;
return vertexBufferObject ;
2022-09-05 20:17:25 +02:00
}
2022-09-06 21:52:06 +02:00
unsigned int copyVerticesMemory ( const unsigned int vertices [ ] , const size_t sizeOfVertices , const GLenum boundBufferTarget )
2022-09-05 20:17:25 +02:00
{
// stores vertices in gpu memory
unsigned int vertexBufferObject ;
// this is open gl object so we refer it by its ID generated here and stored in vertexBufferObject variable
glGenBuffers ( 1 , & vertexBufferObject ) ;
// buffer type of vertex buffer object is GL_ARRAY_BUFFER
glBindBuffer ( boundBufferTarget , vertexBufferObject ) ;
// now whenever we change GL_ARRAY_BUFFER we change bound buffer vertexBufferObject
/* we copy vertex data into buffer memory
GL_STREAM_DRAW : the data is set only once and used by the GPU at most a few times .
GL_STATIC_DRAW : the data is set only once and used many times .
GL_DYNAMIC_DRAW : the data is changed a lot and used many times .
*/
glBufferData ( boundBufferTarget , sizeOfVertices , vertices , GL_STATIC_DRAW ) ;
return vertexBufferObject ;
}
void configureVertexAttribute ( )
{
// specify how OGL interprets vertex data
// From left:
// which vertex attribute we configure (from shader source code layout (location = 0))
// size of vertex attribute (we use vec3 so it contains 3 values)
// type of data of which vec consists of
// should data be normalized, (useful when we use integer data)
// space between vertex attributes, each position data is 3 times the size of float
// offset of where position data begins in buffer
// see: https://learnopengl.com/img/getting-started/vertex_attribute_pointer.png
// vertex attribute data take data from memory managed by VBO bound to GL_ARRAY_BUFFER
2022-09-07 18:54:59 +02:00
glVertexAttribPointer ( 0 , 3 , GL_FLOAT , GL_FALSE , 3 * sizeof ( float ) , ( void * ) 0 ) ;
2022-09-05 20:17:25 +02:00
// enable vertex attribute
glEnableVertexAttribArray ( 0 ) ;
}
unsigned int generateBindVAO ( )
{
// vertex array object is used to draw objects by binding them to vao
// generate vao
unsigned int vertexArrayObject ;
glGenVertexArrays ( 1 , & vertexArrayObject ) ;
2022-09-07 18:54:59 +02:00
// bind vao
2022-09-05 20:17:25 +02:00
glBindVertexArray ( vertexArrayObject ) ;
return vertexArrayObject ;
}
void copyVerticesArray ( unsigned int vertexBufferObject , const float vertices [ ] , const size_t sizeOfVertices , const GLenum boundBufferTarget )
{
// copy vertices array in array useful for OGL
glBindBuffer ( boundBufferTarget , vertexBufferObject ) ;
glBufferData ( boundBufferTarget , sizeOfVertices , vertices , GL_STATIC_DRAW ) ;
}
2022-09-07 18:54:59 +02:00
bool renderLoopInside ( GLFWwindow * window , bool whatToDraw )
2022-09-05 20:17:25 +02:00
{
2022-09-07 18:54:59 +02:00
// input
whatToDraw = processInput ( window , whatToDraw ) ;
// We specify the color to clear the screen with
// RGB and alpha value
glClearColor ( constants : : LEARN_OPEN_GL_COLOR . red , constants : : LEARN_OPEN_GL_COLOR . green , constants : : LEARN_OPEN_GL_COLOR . blue , constants : : LEARN_OPEN_GL_COLOR . alpha ) ;
// There is GL_COLOR_BUFFER_BIT, GL_DEPTH_BUFFER_BIT and GL_STENCIL_BUFFER_BIT
glClear ( GL_COLOR_BUFFER_BIT ) ;
if ( drawFigure ( whatToDraw ) = = - 1 )
{
print ( " error with drawing! " ) ;
glfwSetWindowShouldClose ( window , true ) ;
} ;
2022-09-05 20:17:25 +02:00
2022-09-07 18:54:59 +02:00
// swaps buffer containing color values of each pixel in window
// there is front buffer (final image) and back buffer (where all rendering commands draw to)
// when back buffer is ready we swap it with front buffer to eliminate flickering
glfwSwapBuffers ( window ) ;
2022-09-05 20:17:25 +02:00
2022-09-07 18:54:59 +02:00
// glfwPollEvents checks if any event (like mouse/keyboard input was triggered), updates window state and calls functions (which we register via callback methods)
glfwPollEvents ( ) ;
return whatToDraw ;
2022-09-05 20:17:25 +02:00
}
2022-09-07 18:54:59 +02:00
void renderLoop ( GLFWwindow * window )
2022-09-05 20:17:25 +02:00
{
bool whatToDraw = true ;
// glfwWindowShouldClose checks if GLFW was instructed to close
2022-09-07 18:54:59 +02:00
while ( ! glfwWindowShouldClose ( window ) )
2022-09-05 20:17:25 +02:00
{
whatToDraw = renderLoopInside ( window , whatToDraw ) ;
}
}
2022-09-07 18:54:59 +02:00
# endif