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-10-19 15:51:07 +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-10-19 15:51:39 +02:00
return drawTriangle ( constants : : TRIANGLE_VERTICES , constants : : TRIANGLE_VERTICES_SIZE , constants : : VERTEX_SHADER_SOURCE , constants : : FRAGMENT_SHADER_SOURCE , false ) ;
2022-09-10 13:40:58 +02:00
case 1 :
2022-10-19 15:51:39 +02:00
return drawSquare ( constants : : VERTEX_SHADER_SOURCE , constants : : FRAGMENT_SHADER_SOURCE ) ;
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-10-19 15:51:39 +02:00
return drawTriangle ( constants : : TRIANGLES_VERTICES , constants : : TRIANGLES_VERTICES_SIZE , constants : : VERTEX_SHADER_SOURCE , constants : : FRAGMENT_SHADER_SOURCE , 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-10-19 15:51:39 +02:00
return ( drawTriangle ( constants : : TRIANGLE_ONE , constants : : TRIANGLE_ONE_SIZE , constants : : VERTEX_SHADER_SOURCE , constants : : FRAGMENT_SHADER_SOURCE , false ) = = - 1 | | drawTriangle ( constants : : TRIANGLE_TWO , constants : : TRIANGLE_TWO_SIZE , constants : : VERTEX_SHADER_SOURCE , constants : : FRAGMENT_SHADER_SOURCE , false ) = = - 1 ) ;
2022-10-19 15:51:07 +02:00
case 4 :
2022-10-19 15:46:29 +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-10-19 15:51:39 +02:00
return ( drawTriangle ( constants : : TRIANGLE_ONE , constants : : TRIANGLE_ONE_SIZE , constants : : VERTEX_SHADER_SOURCE , constants : : FRAGMENT_SHADER_SOURCE , false ) = = - 1 | | drawTriangle ( constants : : TRIANGLE_TWO , constants : : TRIANGLE_TWO_SIZE , constants : : VERTEX_SHADER_SOURCE , constants : : FRAGMENT_SHADER_SOURCE_YELLOW , false ) = = - 1 ) ;
2022-10-19 15:51:07 +02:00
case 5 :
// Get color from vertex shader to fragment shader
2022-10-19 15:51:39 +02:00
return drawTriangle ( constants : : TRIANGLE_VERTICES , constants : : TRIANGLE_VERTICES_SIZE , constants : : VERTEX_SHADER_COLOR , constants : : FRAGMENT_SHADER_COLOR_FROM_VERTEX , false ) ;
2022-10-19 15:51:07 +02:00
case 6 :
// set color from opengl code to uniform value in fragment shader
2022-10-19 15:51:39 +02:00
return drawTriangle ( constants : : TRIANGLE_VERTICES , constants : : TRIANGLE_VERTICES_SIZE , constants : : VERTEX_SHADER_COLOR , constants : : FRAGMENT_SHADER_UNIFORMS , false ) ;
2022-10-19 15:51:07 +02:00
case constants : : MAX_DRAW_CALL :
// set color from opengl code to uniform value in fragment shader
2022-10-19 15:51:39 +02:00
return drawTriangle ( constants : : TRIANGLE_COLORS , constants : : TRIANGLE_COLORS_SIZE , constants : : VERTEX_SHADER_VERTICE_COLOR , constants : : FRAGMENT_SHADER_COLOR_FROM_VERTEX , 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-10-19 15:51:39 +02:00
int drawSquare ( const char * vertexShaderSource , const char * fragmentShaderSource )
2022-09-05 20:17:25 +02:00
{
2022-10-19 15:51:39 +02:00
const std : : pair < unsigned int , unsigned int > shaders = compileShaders ( vertexShaderSource , fragmentShaderSource ) ;
if ( shaders . first = = 0 | | shaders . second = = 0 )
return - 1 ;
const unsigned int shaderProgram = linkShaderObjectsShaderProgram ( shaders . first , shaders . second ) ;
if ( shaderProgram = = 0 )
return - 1 ;
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-10-19 15:51:07 +02:00
configureVertexAttribute ( false ) ;
2022-09-05 20:17:25 +02:00
2022-10-19 15:51:39 +02:00
doDrawElements ( shaderProgram , VAO , GL_TRIANGLES , GL_UNSIGNED_INT , std : : size ( constants : : SQUARE_INDICES ) ) ;
2022-09-05 20:17:25 +02:00
return 0 ;
}
2022-10-19 15:51:39 +02:00
void doDrawElements ( const unsigned int shaderProgram , const unsigned int vertexArrayObject , const GLenum drawArrayMode , const GLenum drawType , const int numberOfElementsToDraw )
2022-09-05 20:17:25 +02:00
{
2022-10-19 15:51:39 +02:00
glUseProgram ( shaderProgram ) ;
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-10-19 15:51:39 +02:00
int drawTriangle ( const float triangleVertices [ ] , const size_t triangleVerticesSize , const char * vertexShaderSource , const char * 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-10-19 15:51:39 +02:00
const std : : pair < unsigned int , unsigned int > shaders = compileShaders ( vertexShaderSource , fragmentShaderSource ) ;
if ( shaders . first = = 0 | | shaders . second = = 0 )
return - 1 ;
const unsigned int shaderProgram = linkShaderObjectsShaderProgram ( shaders . first , shaders . second ) ;
if ( shaderProgram = = 0 )
return - 1 ;
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-10-19 15:51:07 +02:00
configureVertexAttribute ( colorIncluded ) ;
2022-10-19 15:51:39 +02:00
doDrawArrays ( shaderProgram , vertexArrayObject , GL_TRIANGLES , 0 , triangleVerticesSize ) ;
2022-09-05 20:17:25 +02:00
return 0 ;
}
2022-10-19 15:51:39 +02:00
void updateUniformColor ( const unsigned int shaderProgram , const GLchar * uniformName )
2022-10-19 15:51:07 +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-10-19 15:51:39 +02:00
const int vertexColorLocation = glGetUniformLocation ( shaderProgram , uniformName ) ; // query the location of our uniform
if ( vertexColorLocation ! = - 1 ) // if glGetUniformLocation returns -1 it could not find the location
{
glUniform4f ( vertexColorLocation , 0.0f , greenValue , 0.0f , 1.0f ) ; /* we set the uniform value using glUniform4f
4f means that it expects 4 floats
few of possible postfixes :
f : the function expects a float as its value .
i : the function expects an int as its value .
ui : the function expects an unsigned int as its value .
3f : the function expects 3 floats as its value .
fv : the function expects a float vector / array as its value .
*/
}
2022-10-19 15:51:07 +02:00
}
2022-10-19 15:51:39 +02:00
void doDrawArrays ( const unsigned int shaderProgram , 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-10-19 15:51:39 +02:00
glUseProgram ( shaderProgram ) ;
updateUniformColor ( shaderProgram , " ourColor " ) ;
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