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-12-11 19:52:49 +01:00
# include "shader.hpp"
2022-09-05 20:17:25 +02:00
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 :
2023-01-27 21:29:04 +01:00
return drawTriangleClass ( constants : : TRIANGLE_VERTICES , constants : : TRIANGLE_VERTICES_SIZE , constants : : VERTEX_SHADER_SOURCE_FILENAME , constants : : FRAGMENT_SHADER_SOURCE_FILENAME ) ;
2022-09-10 13:40:58 +02:00
case 1 :
2023-03-05 18:12:48 +01: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.
2023-01-27 21:29:04 +01:00
return drawTriangleClass ( constants : : TRIANGLES_VERTICES , constants : : TRIANGLES_VERTICES_SIZE , constants : : VERTEX_SHADER_SOURCE_FILENAME , constants : : FRAGMENT_SHADER_SOURCE_FILENAME ) ;
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
2023-01-27 21:29:04 +01:00
return ( drawTriangleClass ( constants : : TRIANGLE_ONE , constants : : TRIANGLE_ONE_SIZE , constants : : VERTEX_SHADER_SOURCE_FILENAME , constants : : FRAGMENT_SHADER_SOURCE_FILENAME ) = = - 1 | | drawTriangleClass ( constants : : TRIANGLE_TWO , constants : : TRIANGLE_TWO_SIZE , constants : : VERTEX_SHADER_SOURCE_FILENAME , constants : : FRAGMENT_SHADER_SOURCE_FILENAME ) = = - 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
2023-01-27 21:29:04 +01:00
return ( drawTriangleClass ( constants : : TRIANGLE_ONE , constants : : TRIANGLE_ONE_SIZE , constants : : VERTEX_SHADER_SOURCE_FILENAME , constants : : FRAGMENT_SHADER_SOURCE_FILENAME ) = = - 1 | | drawTriangleClass ( constants : : TRIANGLE_TWO , constants : : TRIANGLE_TWO_SIZE , constants : : VERTEX_SHADER_SOURCE_FILENAME , constants : : FRAGMENT_SHADER_SOURCE_YELLOW_FILENAME ) = = - 1 ) ;
2022-10-19 15:51:07 +02:00
case 5 :
// Get color from vertex shader to fragment shader
2023-01-27 21:29:04 +01:00
return drawTriangleClass ( constants : : TRIANGLE_VERTICES , constants : : TRIANGLE_VERTICES_SIZE , constants : : VERTEX_SHADER_COLOR_FILENAME , constants : : FRAGMENT_SHADER_COLOR_FROM_VERTEX_FILENAME ) ;
2022-10-19 15:51:07 +02:00
case 6 :
// set color from opengl code to uniform value in fragment shader
2023-01-27 21:29:04 +01:00
return drawTriangleClass ( constants : : TRIANGLE_VERTICES , constants : : TRIANGLE_VERTICES_SIZE , constants : : VERTEX_SHADER_COLOR_FILENAME , constants : : FRAGMENT_SHADER_UNIFORMS_FILENAME ) ;
2022-11-20 23:14:59 +01:00
case 7 :
2022-10-19 15:51:07 +02:00
// set color from opengl code to uniform value in fragment shader
2023-01-18 17:51:24 +01:00
return drawTriangleClass ( constants : : TRIANGLE_COLORS , constants : : TRIANGLE_COLORS_SIZE , constants : : VERTEX_SHADER_VERTICE_COLOR_FILENAME , constants : : FRAGMENT_SHADER_COLOR_FROM_VERTEX_FILENAME , true ) ;
2023-01-27 21:29:04 +01:00
case 8 :
// upside down triangle
return drawTriangleClass ( constants : : TRIANGLE_VERTICES , constants : : TRIANGLE_VERTICES_SIZE , constants : : VERTEX_SHADER_UPSIDE_DOWN_FILENAME , constants : : FRAGMENT_SHADER_SOURCE_FILENAME ) ;
case 9 :
{
// offset triangle
offsetsStruct offsets = offsetsStruct ( ) ;
offsets . xOffset = 0.5f ;
return drawTriangleClass ( constants : : TRIANGLE_VERTICES , constants : : TRIANGLE_VERTICES_SIZE , constants : : VERTEX_SHADER_OFFSET_FILENAME , constants : : FRAGMENT_SHADER_SOURCE_FILENAME , false , offsets ) ;
}
2022-11-20 23:14:59 +01:00
case constants : : MAX_DRAW_CALL :
2023-01-27 21:29:04 +01:00
return drawTriangleClass ( constants : : TRIANGLE_VERTICES , constants : : TRIANGLE_VERTICES_SIZE , constants : : VERTEX_SHADER_TASK_THREE_FILENAME , constants : : FRAGMENT_SHADER_TASK_THREE_FILENAME ) ;
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-12-11 18:49:16 +01:00
unsigned int getShaderProgram ( const char * vertexShaderSource , const char * fragmentShaderSource )
{
const std : : pair < unsigned int , unsigned int > shaders = compileShaders ( vertexShaderSource , fragmentShaderSource ) ;
if ( shaders . first = = 0 | | shaders . second = = 0 )
return 0 ;
const unsigned int shaderProgram = linkShaderObjectsShaderProgram ( shaders . first , shaders . second ) ;
if ( shaderProgram = = 0 )
return 0 ;
return shaderProgram ;
}
2023-01-27 21:29:04 +01:00
void setOffsets ( Shader shader , const offsetsStruct offsets ) {
shader . setFloat ( " xOffset " , offsets . xOffset ) ;
shader . setFloat ( " yOffset " , offsets . yOffset ) ;
shader . setFloat ( " zOffset " , offsets . zOffset ) ;
}
int drawTriangleClass ( const float triangleVertices [ ] , const size_t triangleVerticesSize , const char * vertexPath , const char * fragmentPath , const bool colorIncluded , const offsetsStruct offsets )
2022-11-20 23:14:59 +01:00
{
2023-01-27 21:29:04 +01:00
// In your CPP file:
// ======================
// float offset = 0.5f;
2022-11-20 23:14:59 +01:00
Shader ourShader ( vertexPath , fragmentPath ) ;
ourShader . use ( ) ;
2023-01-27 21:29:04 +01:00
setOffsets ( ourShader , offsets ) ;
2022-11-20 23:14:59 +01:00
const unsigned int vertexBufferObject = copyVerticesMemory ( triangleVertices , triangleVerticesSize , GL_ARRAY_BUFFER ) ;
const unsigned int vertexArrayObject = generateBindVAO ( ) ;
copyVerticesArray ( vertexBufferObject , triangleVertices , triangleVerticesSize , GL_ARRAY_BUFFER ) ;
// set vertex attribute pointers
configureVertexAttribute ( colorIncluded ) ;
doDrawArrays ( ourShader . ID , vertexArrayObject , GL_TRIANGLES , 0 , triangleVerticesSize ) ;
return 0 ;
}
2022-12-11 18:49:16 +01:00
int drawTriangle ( const float triangleVertices [ ] , const size_t triangleVerticesSize , const char * vertexShaderSource , const char * fragmentShaderSource , const bool colorIncluded )
2022-09-05 20:17:25 +02:00
{
2022-12-11 18:49:16 +01:00
const unsigned int shaderProgram = getShaderProgram ( vertexShaderSource , fragmentShaderSource ) ;
2022-10-19 15:51:39 +02:00
if ( shaderProgram = = 0 )
2022-12-11 18:49:16 +01:00
return - 1 ;
const unsigned int vertexBufferObject = copyVerticesMemory ( triangleVertices , triangleVerticesSize , GL_ARRAY_BUFFER ) ;
const unsigned int vertexArrayObject = generateBindVAO ( ) ;
copyVerticesArray ( vertexBufferObject , triangleVertices , triangleVerticesSize , GL_ARRAY_BUFFER ) ;
// set vertex attribute pointers
configureVertexAttribute ( colorIncluded ) ;
doDrawArrays ( shaderProgram , vertexArrayObject , GL_TRIANGLES , 0 , triangleVerticesSize ) ;
return 0 ;
2022-11-20 23:14:59 +01:00
}
2022-09-05 20:17:25 +02:00
2022-11-20 23:14:59 +01:00
int drawSquare ( const char * vertexShaderSource , const char * fragmentShaderSource )
{
const unsigned int shaderProgram = getShaderProgram ( vertexShaderSource , fragmentShaderSource ) ;
if ( shaderProgram = = 0 )
return - 1 ;
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 ;
}
2023-01-18 17:51:24 +01:00
int drawSquareClass ( const char * vertexPath , const char * fragmentPath )
{
Shader ourShader ( vertexPath , fragmentPath ) ;
ourShader . use ( ) ;
const unsigned int vertexBufferObject = copyVerticesMemory ( constants : : SQUARE_VERTICES , constants : : SQUARE_VERTICES_SIZE , GL_ARRAY_BUFFER ) ;
const unsigned int vertexArrayObject = generateBindVAO ( ) ;
copyVerticesArray ( vertexBufferObject , constants : : SQUARE_VERTICES , constants : : SQUARE_VERTICES_SIZE , GL_ARRAY_BUFFER ) ;
// set vertex attribute pointers
configureVertexAttribute ( false ) ;
doDrawArrays ( ourShader . ID , vertexArrayObject , GL_TRIANGLES , 0 , constants : : SQUARE_VERTICES_SIZE ) ;
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
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