diff --git a/Engine/engine/constants.hpp b/Engine/engine/constants.hpp index 305f2f0..6d0d3f7 100644 --- a/Engine/engine/constants.hpp +++ b/Engine/engine/constants.hpp @@ -62,6 +62,36 @@ namespace constants 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 \ No newline at end of file diff --git a/Engine/engine/match b/Engine/engine/match index 129a8be..d786d84 100755 Binary files a/Engine/engine/match and b/Engine/engine/match differ diff --git a/Engine/engine/match.cpp b/Engine/engine/match.cpp index cdf165b..9114656 100644 --- a/Engine/engine/match.cpp +++ b/Engine/engine/match.cpp @@ -71,7 +71,7 @@ void viewPort(GLFWwindow* window) // 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 // if the user pressed escape we close window @@ -79,6 +79,8 @@ void processInput(GLFWwindow *window) glfwSetWindowShouldClose(window, true); if(glfwGetKey(window, GLFW_KEY_C) == GLFW_PRESS) 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) @@ -133,16 +135,16 @@ unsigned int compileShader(const GLenum shaderType, const char * shaderSource) return shaderID; } +template // 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 unsigned int vertexBufferObject; // this is open gl object so we refer it by its ID generated here and stored in vertexBufferObject variable glGenBuffers(1, &vertexBufferObject); - // 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 /* 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_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; } std::pair compileShaders() { 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); - 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); } @@ -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) glDeleteShader(vertexShaders); glDeleteShader(fragmentShader); + if(shaderProgram == 0) std::cout << "Shader Program Linking Failed" << std::endl; return shaderProgram; } @@ -218,34 +229,15 @@ unsigned int generateBindVAO() 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 - glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject); - glBufferData(GL_ARRAY_BUFFER, sizeOfVertices, vertices, GL_STATIC_DRAW); + glBindBuffer(boundBufferTarget, vertexBufferObject); + glBufferData(boundBufferTarget, sizeOfVertices, vertices, GL_STATIC_DRAW); } -void drawTriangle() -{ - try { - unsigned int vertexBufferObject = copyVerticesMemory(constants::TRIANGLE_VERTICES, sizeof(constants::TRIANGLE_VERTICES)); - - std::pair 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); +void doDrawArrays(const unsigned int shaderProgram, const unsigned int vertexArrayObject, const GLenum drawArrayMode, const int firstIndex, const unsigned int numberOfIndicesToBeRendered ) +{ // use shader program to render an object glUseProgram(shaderProgram); glBindVertexArray(vertexArrayObject); @@ -253,29 +245,101 @@ void drawTriangle() // 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) + glDrawArrays(drawArrayMode, firstIndex, numberOfIndicesToBeRendered); +} + +int drawTriangle() +{ + unsigned int vertexBufferObject = copyVerticesMemory(constants::TRIANGLE_VERTICES, constants::TRIANGLE_VERTICES_SIZE, GL_ARRAY_BUFFER); + + std::pair 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 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(constants::SQUARE_VERTICES, constants::SQUARE_VERTICES_SIZE, GL_ARRAY_BUFFER); + copyVerticesMemory(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) { + bool whatToDraw = true; // glfwWindowShouldClose checks if GLFW was instructed to close while(!glfwWindowShouldClose(window)) { // input - processInput(window); + whatToDraw = processInput(window, whatToDraw); // We specify the color to clear the screen with // 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); // There is GL_COLOR_BUFFER_BIT, GL_DEPTH_BUFFER_BIT and GL_STENCIL_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 // 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(); - - } }