diff --git a/.vscode/settings.json b/.vscode/settings.json index 78ee1fa..f3822df 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -72,7 +72,10 @@ "stdexcept": "cpp", "streambuf": "cpp", "cinttypes": "cpp", - "typeinfo": "cpp" + "typeinfo": "cpp", + "chrono": "cpp", + "ctime": "cpp", + "ratio": "cpp" }, "C_Cpp.errorSquiggles": "Disabled" } \ No newline at end of file diff --git a/Engine/engine/constants.hpp b/Engine/engine/constants.hpp index 0c4fa69..305f2f0 100644 --- a/Engine/engine/constants.hpp +++ b/Engine/engine/constants.hpp @@ -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 \ No newline at end of file diff --git a/Engine/engine/match b/Engine/engine/match index 35a2000..129a8be 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 46f7c8c..cdf165b 100644 --- a/Engine/engine/match.cpp +++ b/Engine/engine/match.cpp @@ -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 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 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