feat: draw triangle, refactor code

This commit is contained in:
Krzysztof Rudnicki 2022-09-02 19:57:09 +02:00
parent 69f4e802a1
commit 47e24fcedb
4 changed files with 107 additions and 23 deletions

View File

@ -72,7 +72,10 @@
"stdexcept": "cpp",
"streambuf": "cpp",
"cinttypes": "cpp",
"typeinfo": "cpp"
"typeinfo": "cpp",
"chrono": "cpp",
"ctime": "cpp",
"ratio": "cpp"
},
"C_Cpp.errorSquiggles": "Disabled"
}

View File

@ -51,6 +51,17 @@ namespace constants
"}\0"
};
// we specify three vertices
// each of them with position in 3d space
// x y z
inline constexpr float TRIANGLE_VERTICES[] {
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f
};
inline constexpr size_t TRIANGLE_VERTICES_SIZE = { sizeof(TRIANGLE_VERTICES) };
}
#endif

Binary file not shown.

View File

@ -102,8 +102,6 @@ int shaderProgramLinkingSuccessful(const unsigned int shaderProgram)
int shaderCompilationSuccessful(const unsigned int shader)
{
// check if compilation was successful
// int because glGetShaderiv requires int
int successfulCompilation;
@ -124,7 +122,7 @@ unsigned int compileShader(const GLenum shaderType, const char * shaderSource)
{
// we create vertex shader and assign its id to shader variable
unsigned int shaderID;
shaderID = glCreateShader(GL_VERTEX_SHADER);
shaderID = glCreateShader(shaderType);
// attach shader source code to shader object
// from left: shader object to compile, how many strings as source code, actual source code (we leave the 4th as NULL)
@ -135,17 +133,9 @@ unsigned int compileShader(const GLenum shaderType, const char * shaderSource)
return shaderID;
}
void drawTriangle()
// https://stackoverflow.com/a/25680092
unsigned int copyVerticesMemory(const float vertices[], const size_t sizeOfVertices)
{
// we specify three vertices
// each of them with position in 3d space
// x y z
const float triangleVertices[] = {
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f
};
// 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
@ -160,15 +150,22 @@ void drawTriangle()
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(GL_ARRAY_BUFFER, sizeof(triangleVertices), triangleVertices, GL_STATIC_DRAW);
glBufferData(GL_ARRAY_BUFFER, sizeOfVertices, vertices, GL_STATIC_DRAW);
return vertexBufferObject;
}
std::pair<unsigned int, unsigned int> compileShaders()
{
unsigned int vertexShader = compileShader(GL_VERTEX_SHADER, constants::vertexShaderSource);
if(vertexShader == 0) return;
if(vertexShader == 0) return std::make_pair(0, 0);
unsigned int fragmentShader = compileShader(GL_FRAGMENT_SHADER, constants::fragmentShaderSource);
if(fragmentShader == 0) return;
if(fragmentShader == 0) return std::make_pair(0, 0);
return std::make_pair(vertexShader, fragmentShader);
}
unsigned int linkShaderObjectsShaderProgram(unsigned int vertexShaders, unsigned int fragmentShader)
{
// link shader objects into shader program
// will store shader program id
unsigned int shaderProgram;
@ -176,20 +173,92 @@ void drawTriangle()
shaderProgram = glCreateProgram();
// attachShaders
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, vertexShaders);
glAttachShader(shaderProgram, fragmentShader);
// link shaders
glLinkProgram(shaderProgram);
if(!shaderProgramLinkingSuccessful(shaderProgram)) return;
if(!shaderProgramLinkingSuccessful(shaderProgram)) return 0;
// activate program
// after that every shader and rendering call will use this program object
glUseProgram(shaderProgram);
// delete shaders (they are linked into shaderProgram and we do not need them anymore)
glDeleteShader(vertexShader);
glDeleteShader(vertexShaders);
glDeleteShader(fragmentShader);
return shaderProgram;
}
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
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
// 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);
// bind vao
glBindVertexArray(vertexArrayObject);
return vertexArrayObject;
}
void copyVerticesArray(unsigned int vertexBufferObject, const float vertices[], const size_t sizeOfVertices)
{
// copy vertices array in array useful for OGL
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);
glBufferData(GL_ARRAY_BUFFER, sizeOfVertices, vertices, GL_STATIC_DRAW);
}
void drawTriangle()
{
try {
unsigned int vertexBufferObject = copyVerticesMemory(constants::TRIANGLE_VERTICES, sizeof(constants::TRIANGLE_VERTICES));
std::pair<unsigned int, unsigned int> shaders = compileShaders();
if(shaders.first == 0 || shaders.second == 0) throw "Shader Compilation Failed";
unsigned int shaderProgram = linkShaderObjectsShaderProgram(shaders.first, shaders.second);
if(shaderProgram == 0) throw "Shader Program Linking Failed";;
configureVertexAttribute();
unsigned int vertexArrayObject = generateBindVAO();
copyVerticesArray(vertexBufferObject, constants::TRIANGLE_VERTICES, sizeof(constants::TRIANGLE_VERTICES));
// set vertex attribute pointers
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
// use shader program to render an object
glUseProgram(shaderProgram);
glBindVertexArray(vertexArrayObject);
// From left:
// primitive type we want to draw
// starting index of vertex array
// how many vertices we want to draw
glDrawArrays(GL_TRIANGLES, 0, 3);
}
catch (const char* error)
{
std::cerr << "Error: " << error << '\n';
}
}
@ -206,7 +275,7 @@ void renderLoop(GLFWwindow* window)
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);
drawTriangle();
// 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)
@ -215,7 +284,7 @@ void renderLoop(GLFWwindow* window)
// glfwPollEvents checks if any event (like mouse/keyboard input was triggered), updates window state and calls functions (which we register via callback methods)
glfwPollEvents();
drawTriangle();
}
}
@ -238,6 +307,7 @@ int main()
if(initializeGLAD() == -1) return -1;
viewPort(window);
renderLoop(window);
// clean GLFW resources