2022-09-05 20:17:25 +02:00
# ifndef DRAW_CPP
# define DRAW_CPP
# include <glad/glad.h>
# include <GLFW/glfw3.h>
# include <iostream>
2022-09-17 16:32:48 +02:00
# include <cmath>
2022-09-05 20:17:25 +02:00
# include "draw.hpp"
# include "renderLoop.hpp"
# include "shaders.hpp"
# include "constants.hpp"
# include "misc.hpp"
2022-09-10 13:40:58 +02:00
int drawFigure ( const int whatToDraw )
2022-09-05 20:17:25 +02:00
{
2022-09-10 13:40:58 +02:00
switch ( whatToDraw )
2022-09-05 20:17:25 +02:00
{
2022-09-10 13:40:58 +02:00
case 0 :
2022-09-18 18:10:03 +02:00
return drawTriangle ( constants : : TRIANGLE_VERTICES , constants : : TRIANGLE_VERTICES_SIZE , constants : : VERTEX_FIRST_SHADER , constants : : FRAGMENT_ORANGE , false ) ;
2022-09-10 13:40:58 +02:00
case 1 :
2022-09-18 18:10:03 +02:00
return drawSquare ( constants : : VERTEX_FIRST_SHADER , constants : : FRAGMENT_ORANGE ) ;
2022-09-17 14:14:08 +02:00
case 2 :
// Try to draw 2 triangles next to each other using glDrawArrays by adding more vertices to your data.
2022-09-18 18:10:03 +02:00
return drawTriangle ( constants : : TRIANGLES_VERTICES , constants : : TRIANGLES_VERTICES_SIZE , constants : : VERTEX_FIRST_SHADER , constants : : FRAGMENT_ORANGE , false ) ;
2022-09-17 14:14:08 +02:00
case 3 :
// Now create the same 2 triangles using two different VAOs and VBOs for their data
2022-09-18 18:10:03 +02:00
return ( drawTriangle ( constants : : TRIANGLE_ONE , constants : : TRIANGLE_ONE_SIZE , constants : : VERTEX_FIRST_SHADER , constants : : FRAGMENT_ORANGE , false ) = = - 1 | | drawTriangle ( constants : : TRIANGLE_TWO , constants : : TRIANGLE_TWO_SIZE , constants : : VERTEX_FIRST_SHADER , constants : : FRAGMENT_ORANGE , false ) = = - 1 ) ;
2022-09-17 16:32:48 +02:00
case 4 :
2022-09-17 14:14:08 +02:00
// Create two shader programs where the second program uses a different fragment shader that outputs the color yellow; draw both triangles again where one outputs the color yellow
2022-09-18 18:10:03 +02:00
return ( drawTriangle ( constants : : TRIANGLE_ONE , constants : : TRIANGLE_ONE_SIZE , constants : : VERTEX_FIRST_SHADER , constants : : FRAGMENT_ORANGE , false ) = = - 1 | | drawTriangle ( constants : : TRIANGLE_TWO , constants : : TRIANGLE_TWO_SIZE , constants : : VERTEX_FIRST_SHADER , constants : : FRAGMENT_YELLOW , false ) = = - 1 ) ;
2022-09-17 16:32:48 +02:00
case 5 :
// Get color from vertex shader to fragment shader
2022-09-18 18:10:03 +02:00
return drawTriangle ( constants : : TRIANGLE_VERTICES , constants : : TRIANGLE_VERTICES_SIZE , constants : : VERTEX_WITH_COLOR , constants : : FRAGMENT_COLOR_INPUT , false ) ;
2022-09-17 16:32:48 +02:00
case 6 :
// set color from opengl code to uniform value in fragment shader
2022-09-18 18:10:03 +02:00
return drawTriangle ( constants : : TRIANGLE_VERTICES , constants : : TRIANGLE_VERTICES_SIZE , constants : : VERTEX_WITH_COLOR , constants : : FRAGMENT_UNIFORMS , false ) ;
2022-09-17 16:32:48 +02:00
case constants : : MAX_DRAW_CALL :
// set color from opengl code to uniform value in fragment shader
2022-09-18 18:10:03 +02:00
return drawTriangle ( constants : : TRIANGLE_COLORS , constants : : TRIANGLE_COLORS_SIZE , constants : : VERTEX_WITH_COLOR , constants : : FRAGMENT_COLOR_INPUT , true ) ;
2022-09-10 13:40:58 +02:00
default :
throw " No function for this draw call " ;
2022-09-07 18:54:59 +02:00
}
2022-09-05 20:17:25 +02:00
}
2022-09-18 18:10:03 +02:00
int drawSquare ( const std : : string_view vertexShaderSource , const std : : string_view fragmentShaderSource )
2022-09-05 20:17:25 +02:00
{
2022-09-18 18:10:03 +02:00
Shader ourShader ( vertexShaderSource , fragmentShaderSource ) ;
2022-09-05 20:17:25 +02:00
2022-09-07 18:54:59 +02:00
const unsigned int VAO = generateBindVAO ( ) ;
2022-09-06 21:52:06 +02:00
copyVerticesMemory ( constants : : SQUARE_VERTICES , constants : : SQUARE_VERTICES_SIZE , GL_ARRAY_BUFFER ) ;
copyVerticesMemory ( constants : : SQUARE_INDICES , constants : : SQUARE_INDICES_SIZE , GL_ELEMENT_ARRAY_BUFFER ) ;
2022-09-05 20:17:25 +02:00
2022-09-07 18:54:59 +02:00
// set vertex attribute pointers
2022-09-17 16:32:48 +02:00
configureVertexAttribute ( false ) ;
2022-09-05 20:17:25 +02:00
2022-09-18 18:10:03 +02:00
doDrawElements ( ourShader , VAO , GL_TRIANGLES , GL_UNSIGNED_INT , std : : size ( constants : : SQUARE_INDICES ) ) ;
2022-09-05 20:17:25 +02:00
return 0 ;
}
2022-09-18 18:10:03 +02:00
void doDrawElements ( const Shader Shader , const unsigned int vertexArrayObject , const GLenum drawArrayMode , const GLenum drawType , const int numberOfElementsToDraw )
2022-09-05 20:17:25 +02:00
{
2022-09-18 18:10:03 +02:00
Shader . use ( ) ;
2022-09-05 20:17:25 +02:00
glBindVertexArray ( vertexArrayObject ) ;
glDrawElements ( drawArrayMode , numberOfElementsToDraw , drawType , 0 ) ;
glBindVertexArray ( 0 ) ;
2022-09-07 18:54:59 +02:00
}
2022-09-05 20:17:25 +02:00
2022-09-18 18:10:03 +02:00
int drawTriangle ( const float triangleVertices [ ] , const size_t triangleVerticesSize , const std : : string_view vertexShaderSource , const std : : string_view fragmentShaderSource , const bool colorIncluded )
2022-09-07 18:54:59 +02:00
{
2022-09-17 14:14:08 +02:00
const unsigned int vertexBufferObject = copyVerticesMemory ( triangleVertices , triangleVerticesSize , GL_ARRAY_BUFFER ) ;
2022-09-07 18:54:59 +02:00
2022-09-18 18:10:03 +02:00
Shader ourShader ( vertexShaderSource , fragmentShaderSource ) ;
2022-09-05 20:17:25 +02:00
2022-09-07 18:54:59 +02:00
const unsigned int vertexArrayObject = generateBindVAO ( ) ;
2022-09-17 14:14:08 +02:00
copyVerticesArray ( vertexBufferObject , triangleVertices , triangleVerticesSize , GL_ARRAY_BUFFER ) ;
2022-09-05 20:17:25 +02:00
2022-09-07 18:54:59 +02:00
// set vertex attribute pointers
2022-09-17 16:32:48 +02:00
configureVertexAttribute ( colorIncluded ) ;
2022-09-18 18:10:03 +02:00
doDrawArrays ( ourShader , vertexArrayObject , GL_TRIANGLES , 0 , triangleVerticesSize ) ;
2022-09-05 20:17:25 +02:00
return 0 ;
}
2022-09-18 18:10:03 +02:00
GLfloat updateUniformColor ( )
2022-09-17 16:32:48 +02:00
{
// update the uniform color
const float timeValue = glfwGetTime ( ) ; // retrieve running time
const float greenValue = sin ( timeValue ) / 2.0f + 0.5f ; // vary the color from 0.0 to 1.0 using sin
2022-09-18 18:10:03 +02:00
return greenValue ;
2022-09-17 16:32:48 +02:00
}
2022-09-18 18:10:03 +02:00
void doDrawArrays ( const Shader Shader , const unsigned int vertexArrayObject , const GLenum drawArrayMode , const int firstIndex , const unsigned int numberOfIndicesToBeRendered )
2022-09-05 20:17:25 +02:00
{
// use shader program to render an object
2022-09-18 18:10:03 +02:00
Shader . use ( ) ;
Shader . setFloat ( " ourColor " , updateUniformColor ( ) ) ;
2022-09-05 20:17:25 +02:00
glBindVertexArray ( vertexArrayObject ) ;
// From left:
// primitive type we want to draw
2022-09-07 18:54:59 +02:00
// starting index of vertex array
2022-09-05 20:17:25 +02:00
// how many vertices we want to draw
glDrawArrays ( drawArrayMode , firstIndex , numberOfIndicesToBeRendered ) ;
}
2022-09-07 18:54:59 +02:00
# endif