feat: draw square

This commit is contained in:
Krzysztof Rudnicki 2022-09-04 21:25:01 +02:00
parent 47e24fcedb
commit c8e6f37165
3 changed files with 131 additions and 39 deletions

View File

@ -62,6 +62,36 @@ namespace constants
inline constexpr size_t TRIANGLE_VERTICES_SIZE = { sizeof(TRIANGLE_VERTICES) }; inline constexpr size_t TRIANGLE_VERTICES_SIZE = { sizeof(TRIANGLE_VERTICES) };
// compare with square done with only vertices:
/*
float vertices[] = {
// first triangle
0.5f, 0.5f, 0.0f, // top right
0.5f, -0.5f, 0.0f, // bottom right
-0.5f, 0.5f, 0.0f, // top left
// second triangle
0.5f, -0.5f, 0.0f, // bottom right
-0.5f, -0.5f, 0.0f, // bottom left
-0.5f, 0.5f, 0.0f // top left
};
bottom right and top left is specified twice !
*/
inline constexpr float SQUARE_VERTICES[] {
0.5f, 0.5f, 0.0f, // top right
0.5f, -0.5f, 0.0f, // bottom right
-0.5f, -0.5f, 0.0f, // bottom left
-0.5f, 0.5f, 0.0f // top left
};
inline constexpr unsigned int SQUARE_INDICES[] {
0, 1, 3, // first triangle
1, 2, 3 // second triangle
};
inline constexpr size_t SQUARE_INDICES_SIZE = { sizeof(SQUARE_INDICES) };
inline constexpr size_t SQUARE_VERTICES_SIZE = { sizeof(SQUARE_VERTICES) };
} }
#endif #endif

Binary file not shown.

View File

@ -71,7 +71,7 @@ void viewPort(GLFWwindow* window)
// we call framebuffer_size_callback on every window resize // we call framebuffer_size_callback on every window resize
} }
void processInput(GLFWwindow *window) bool processInput(GLFWwindow *window, bool whatToDraw)
{ {
// glfwGetKey takes window and key as an input and checks is currently being pressed // glfwGetKey takes window and key as an input and checks is currently being pressed
// if the user pressed escape we close window // if the user pressed escape we close window
@ -79,6 +79,8 @@ void processInput(GLFWwindow *window)
glfwSetWindowShouldClose(window, true); glfwSetWindowShouldClose(window, true);
if(glfwGetKey(window, GLFW_KEY_C) == GLFW_PRESS) if(glfwGetKey(window, GLFW_KEY_C) == GLFW_PRESS)
glfwSetWindowShouldClose(window, true); glfwSetWindowShouldClose(window, true);
if(glfwGetKey(window, GLFW_KEY_LEFT) == GLFW_PRESS || glfwGetKey(window, GLFW_KEY_RIGHT) == GLFW_PRESS ) return !whatToDraw;
return whatToDraw;
} }
int shaderProgramLinkingSuccessful(const unsigned int shaderProgram) int shaderProgramLinkingSuccessful(const unsigned int shaderProgram)
@ -133,16 +135,16 @@ unsigned int compileShader(const GLenum shaderType, const char * shaderSource)
return shaderID; return shaderID;
} }
template <typename T>
// https://stackoverflow.com/a/25680092 // https://stackoverflow.com/a/25680092
unsigned int copyVerticesMemory(const float vertices[], const size_t sizeOfVertices) unsigned int copyVerticesMemory(const T vertices[], const size_t sizeOfVertices, const GLenum boundBufferTarget)
{ {
// stores vertices in gpu memory // stores vertices in gpu memory
unsigned int vertexBufferObject; unsigned int vertexBufferObject;
// this is open gl object so we refer it by its ID generated here and stored in vertexBufferObject variable // this is open gl object so we refer it by its ID generated here and stored in vertexBufferObject variable
glGenBuffers(1, &vertexBufferObject); glGenBuffers(1, &vertexBufferObject);
// buffer type of vertex buffer object is GL_ARRAY_BUFFER // buffer type of vertex buffer object is GL_ARRAY_BUFFER
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject); glBindBuffer(boundBufferTarget, vertexBufferObject);
// now whenever we change GL_ARRAY_BUFFER we change bound buffer vertexBufferObject // now whenever we change GL_ARRAY_BUFFER we change bound buffer vertexBufferObject
/* we copy vertex data into buffer memory /* we copy vertex data into buffer memory
@ -150,17 +152,25 @@ unsigned int copyVerticesMemory(const float vertices[], const size_t sizeOfVerti
GL_STATIC_DRAW: the data is set only once and used many 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. GL_DYNAMIC_DRAW: the data is changed a lot and used many times.
*/ */
glBufferData(GL_ARRAY_BUFFER, sizeOfVertices, vertices, GL_STATIC_DRAW); glBufferData(boundBufferTarget, sizeOfVertices, vertices, GL_STATIC_DRAW);
return vertexBufferObject; return vertexBufferObject;
} }
std::pair<unsigned int, unsigned int> compileShaders() std::pair<unsigned int, unsigned int> compileShaders()
{ {
unsigned int vertexShader = compileShader(GL_VERTEX_SHADER, constants::vertexShaderSource); unsigned int vertexShader = compileShader(GL_VERTEX_SHADER, constants::vertexShaderSource);
if(vertexShader == 0) return std::make_pair(0, 0); if(vertexShader == 0)
{
std::cout << "Vertex Shader Compilation Failed" << std::endl;
return std::make_pair(0, 0);
}
unsigned int fragmentShader = compileShader(GL_FRAGMENT_SHADER, constants::fragmentShaderSource); unsigned int fragmentShader = compileShader(GL_FRAGMENT_SHADER, constants::fragmentShaderSource);
if(fragmentShader == 0) return std::make_pair(0, 0); if(fragmentShader == 0)
{
std::cout << "Fragment Shader Compilation Failed" << std::endl;
return std::make_pair(0, 0);
}
return std::make_pair(vertexShader, fragmentShader); return std::make_pair(vertexShader, fragmentShader);
} }
@ -187,6 +197,7 @@ unsigned int linkShaderObjectsShaderProgram(unsigned int vertexShaders, unsigned
// delete shaders (they are linked into shaderProgram and we do not need them anymore) // delete shaders (they are linked into shaderProgram and we do not need them anymore)
glDeleteShader(vertexShaders); glDeleteShader(vertexShaders);
glDeleteShader(fragmentShader); glDeleteShader(fragmentShader);
if(shaderProgram == 0) std::cout << "Shader Program Linking Failed" << std::endl;
return shaderProgram; return shaderProgram;
} }
@ -218,34 +229,15 @@ unsigned int generateBindVAO()
return vertexArrayObject; return vertexArrayObject;
} }
void copyVerticesArray(unsigned int vertexBufferObject, const float vertices[], const size_t sizeOfVertices) void copyVerticesArray(unsigned int vertexBufferObject, const float vertices[], const size_t sizeOfVertices, const GLenum boundBufferTarget)
{ {
// copy vertices array in array useful for OGL // copy vertices array in array useful for OGL
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject); glBindBuffer(boundBufferTarget, vertexBufferObject);
glBufferData(GL_ARRAY_BUFFER, sizeOfVertices, vertices, GL_STATIC_DRAW); glBufferData(boundBufferTarget, sizeOfVertices, vertices, GL_STATIC_DRAW);
} }
void drawTriangle() void doDrawArrays(const unsigned int shaderProgram, const unsigned int vertexArrayObject, const GLenum drawArrayMode, const int firstIndex, const unsigned int numberOfIndicesToBeRendered )
{ {
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 // use shader program to render an object
glUseProgram(shaderProgram); glUseProgram(shaderProgram);
glBindVertexArray(vertexArrayObject); glBindVertexArray(vertexArrayObject);
@ -253,29 +245,101 @@ void drawTriangle()
// primitive type we want to draw // primitive type we want to draw
// starting index of vertex array // starting index of vertex array
// how many vertices we want to draw // how many vertices we want to draw
glDrawArrays(GL_TRIANGLES, 0, 3); glDrawArrays(drawArrayMode, firstIndex, numberOfIndicesToBeRendered);
} }
catch (const char* error)
int drawTriangle()
{
unsigned int vertexBufferObject = copyVerticesMemory(constants::TRIANGLE_VERTICES, constants::TRIANGLE_VERTICES_SIZE, GL_ARRAY_BUFFER);
std::pair<unsigned int, unsigned int> shaders = compileShaders();
if(shaders.first == 0 || shaders.second == 0) return -1;
unsigned int shaderProgram = linkShaderObjectsShaderProgram(shaders.first, shaders.second);
if(shaderProgram == 0) return -1;
configureVertexAttribute();
unsigned int vertexArrayObject = generateBindVAO();
copyVerticesArray(vertexBufferObject, constants::TRIANGLE_VERTICES, constants::TRIANGLE_VERTICES_SIZE, GL_ARRAY_BUFFER);
// set vertex attribute pointers
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
doDrawArrays(shaderProgram, vertexArrayObject, GL_TRIANGLES, 0, 3);
return 0;
}
void doDrawElements(const unsigned int shaderProgram, const unsigned int vertexArrayObject, const GLenum drawArrayMode, const GLenum drawType, const int numberOfElementsToDraw)
{
glUseProgram(shaderProgram);
glBindVertexArray(vertexArrayObject);
glDrawElements(drawArrayMode, numberOfElementsToDraw, drawType, 0);
glBindVertexArray(0);
}
int drawSquare()
{
std::pair<unsigned int, unsigned int> shaders = compileShaders();
if(shaders.first == 0 || shaders.second == 0) return -1;
unsigned int shaderProgram = linkShaderObjectsShaderProgram(shaders.first, shaders.second);
if(shaderProgram == 0) return -1;
unsigned int VAO = generateBindVAO();
copyVerticesMemory<float>(constants::SQUARE_VERTICES, constants::SQUARE_VERTICES_SIZE, GL_ARRAY_BUFFER);
copyVerticesMemory<unsigned int>(constants::SQUARE_INDICES, constants::SQUARE_INDICES_SIZE, GL_ELEMENT_ARRAY_BUFFER);
// set vertex attribute pointers
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
doDrawElements(shaderProgram, VAO, GL_TRIANGLES, GL_UNSIGNED_INT, std::size(constants::SQUARE_INDICES));
return 0;
}
int drawFigure(const bool whatToDraw)
{
if(whatToDraw)
{ {
std::cerr << "Error: " << error << '\n'; if(drawTriangle() == -1)
{
std::cout << "Error with drawing triangle! " << std::endl;
return -1;
}
}else
{
if(drawSquare() == -1)
{
std::cout << "Error with drawing square! " << std::endl;
return -1;
}
} }
return 0;
} }
void renderLoop(GLFWwindow* window) void renderLoop(GLFWwindow* window)
{ {
bool whatToDraw = true;
// glfwWindowShouldClose checks if GLFW was instructed to close // glfwWindowShouldClose checks if GLFW was instructed to close
while(!glfwWindowShouldClose(window)) while(!glfwWindowShouldClose(window))
{ {
// input // input
processInput(window); whatToDraw = processInput(window, whatToDraw);
// We specify the color to clear the screen with // We specify the color to clear the screen with
// RGB and alpha value // 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); 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 // There is GL_COLOR_BUFFER_BIT, GL_DEPTH_BUFFER_BIT and GL_STENCIL_BUFFER_BIT
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
drawTriangle();
if(drawFigure(whatToDraw) == -1)
{
std::cout << "error with drawing!" << std::endl;
glfwSetWindowShouldClose(window, true);
};
// swaps buffer containing color values of each pixel in window // 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) // there is front buffer (final image) and back buffer (where all rendering commands draw to)
@ -284,8 +348,6 @@ 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 checks if any event (like mouse/keyboard input was triggered), updates window state and calls functions (which we register via callback methods)
glfwPollEvents(); glfwPollEvents();
} }
} }