diff --git a/.vscode/settings.json b/.vscode/settings.json index 6512136..b0ed660 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -27,6 +27,7 @@ "**/.vscode/**" ], "files.associations": { + "*.ejs": "html", "array": "cpp", "atomic": "cpp", "bit": "cpp", @@ -75,7 +76,10 @@ "typeinfo": "cpp", "chrono": "cpp", "ctime": "cpp", - "ratio": "cpp" + "ratio": "cpp", + "compare": "cpp", + "concepts": "cpp", + "numbers": "cpp" }, "C_Cpp.errorSquiggles": "Disabled", "cSpell.words": [ diff --git a/Engine/engine/Shaders/fragmentShaderSource.frag b/Engine/engine/Shaders/fragmentShaderSource.frag new file mode 100644 index 0000000..e973e8d --- /dev/null +++ b/Engine/engine/Shaders/fragmentShaderSource.frag @@ -0,0 +1,5 @@ +out vec4 FragColor; +void main() +{ + FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f); +} \ No newline at end of file diff --git a/Engine/engine/Shaders/vertexShaderSource.vert b/Engine/engine/Shaders/vertexShaderSource.vert new file mode 100644 index 0000000..36f9d90 --- /dev/null +++ b/Engine/engine/Shaders/vertexShaderSource.vert @@ -0,0 +1,5 @@ +layout (location = 0) in vec3 aPos; +void main() +{ + gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0); +} \ No newline at end of file diff --git a/Engine/engine/constants.hpp b/Engine/engine/constants.hpp index adca746..6874b1e 100644 --- a/Engine/engine/constants.hpp +++ b/Engine/engine/constants.hpp @@ -53,6 +53,10 @@ namespace constants " gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n" "}\0" } ; + inline const std::string VERTEX_SHADER_SOURCE_FILENAME { + "Engine/engine/Shaders/vertexShaderSource.vert" + }; + inline const char *VERTEX_SHADER_VERTICE_COLOR { "#version 330 core\n" "layout (location = 0) in vec3 aPos;\n" // position has attribute position 0 "layout (location = 1) in vec3 aColor;\n" // color has attribute position 1 @@ -96,6 +100,12 @@ namespace constants "}\0" }; + inline const std::string FRAGMENT_SHADER_SOURCE_FILENAME { + "Engine/engine/Shaders/fragmentShaderSource.frag" + }; + + + inline const char *FRAGMENT_SHADER_SOURCE_YELLOW { "#version 330 core\n" "out vec4 FragColor;\n" @@ -174,20 +184,20 @@ namespace constants 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 + -0.25f, -0.5f, 0.0f, // bottom left + -0.25f, 0.5f, 0.0f // top left }; inline constexpr unsigned int SQUARE_INDICES[] { 0, 1, 3, // first triangle - 1, 2, 3 // second 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) }; - inline constexpr int MAX_DRAW_CALL = { 7 }; + inline constexpr int MAX_DRAW_CALL = { 8 }; } diff --git a/Engine/engine/draw.cpp b/Engine/engine/draw.cpp index 0daccb6..8c3c2d9 100644 --- a/Engine/engine/draw.cpp +++ b/Engine/engine/draw.cpp @@ -9,6 +9,7 @@ #include "shaders.hpp" #include "constants.hpp" #include "misc.hpp" +#include "shader.hpp" int drawFigure(const int whatToDraw) { @@ -33,24 +34,48 @@ int drawFigure(const int whatToDraw) case 6: // set color from opengl code to uniform value in fragment shader return drawTriangle(constants::TRIANGLE_VERTICES, constants::TRIANGLE_VERTICES_SIZE, constants::VERTEX_SHADER_COLOR, constants::FRAGMENT_SHADER_UNIFORMS, false); - case constants::MAX_DRAW_CALL: + case 7: // set color from opengl code to uniform value in fragment shader return drawTriangle(constants::TRIANGLE_COLORS, constants::TRIANGLE_COLORS_SIZE, constants::VERTEX_SHADER_VERTICE_COLOR, constants::FRAGMENT_SHADER_COLOR_FROM_VERTEX, true); + case constants::MAX_DRAW_CALL: + // set color from opengl code to uniform value in fragment shader + return drawTriangleClass(constants::TRIANGLE_VERTICES, constants::TRIANGLE_VERTICES_SIZE, constants::VERTEX_SHADER_SOURCE_FILENAME, constants::FRAGMENT_SHADER_SOURCE_FILENAME, false); default: throw "No function for this draw call"; } } -int drawSquare(const char* vertexShaderSource, const char* fragmentShaderSource) +int drawTriangleClass(const float triangleVertices[], const size_t triangleVerticesSize, const std::string vertexPath, const std::string fragmentPath, const bool colorIncluded) +{ + Shader ourShader(vertexPath, fragmentPath); + ourShader.use(); + 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; +} + +unsigned int getShaderProgram(const char* vertexShaderSource, const char* fragmentShaderSource) { const std::pair shaders = compileShaders(vertexShaderSource, fragmentShaderSource); if (shaders.first == 0 || shaders.second == 0) - return -1; + return 0; const unsigned int shaderProgram = linkShaderObjectsShaderProgram(shaders.first, shaders.second); if (shaderProgram == 0) - return -1; + return 0; + return shaderProgram; +} +int drawSquare(const char* vertexShaderSource, const char* fragmentShaderSource) +{ + const unsigned int shaderProgram = getShaderProgram(vertexShaderSource, fragmentShaderSource); + if (shaderProgram == 0) + return -1; const 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); @@ -72,16 +97,12 @@ void doDrawElements(const unsigned int shaderProgram, const unsigned int vertexA int drawTriangle(const float triangleVertices[], const size_t triangleVerticesSize, const char* vertexShaderSource, const char* fragmentShaderSource, const bool colorIncluded) { - const unsigned int vertexBufferObject = copyVerticesMemory(triangleVertices, triangleVerticesSize, GL_ARRAY_BUFFER); - - const std::pair shaders = compileShaders(vertexShaderSource, fragmentShaderSource); - if (shaders.first == 0 || shaders.second == 0) - return -1; - - const unsigned int shaderProgram = linkShaderObjectsShaderProgram(shaders.first, shaders.second); + + const unsigned int shaderProgram = getShaderProgram(vertexShaderSource, fragmentShaderSource); if (shaderProgram == 0) - return -1; - + return -1; + + const unsigned int vertexBufferObject = copyVerticesMemory(triangleVertices, triangleVerticesSize, GL_ARRAY_BUFFER); const unsigned int vertexArrayObject = generateBindVAO(); copyVerticesArray(vertexBufferObject, triangleVertices, triangleVerticesSize, GL_ARRAY_BUFFER); diff --git a/Engine/engine/draw.hpp b/Engine/engine/draw.hpp index a4e4bc6..b1f587f 100644 --- a/Engine/engine/draw.hpp +++ b/Engine/engine/draw.hpp @@ -2,12 +2,15 @@ #define DRAW_HPP #include #include +#include int drawFigure(const int whatToDraw); int drawSquare(const char* vertexShaderSource, const char* fragmentShaderSource); void doDrawElements(const unsigned int shaderProgram, const unsigned int vertexArrayObject, const GLenum drawArrayMode, const GLenum drawType, const int numberOfElementsToDraw); int drawTriangle(const float triangleVertices[], const size_t triangleVerticesSize, const char* vertexShaderSource, const char* fragmentShaderSource, const bool colorIncluded); +int drawTriangleClass(const float triangleVertices[], const size_t triangleVerticesSize, const std::string vertexPath, const std::string fragmentPath, const bool colorIncluded); void updateUniformColor(const unsigned int shaderProgram, const GLchar* uniformName); void doDrawArrays(const unsigned int shaderProgram, const unsigned int vertexArrayObject, const GLenum drawArrayMode, const int firstIndex, const unsigned int numberOfIndicesToBeRendered ); +unsigned int drawSquareShaderProgram(const char* vertexShaderSource, const char* fragmentShaderSource); #endif \ No newline at end of file diff --git a/Engine/engine/match b/Engine/engine/match index f73c15a..ccbc9d0 100755 Binary files a/Engine/engine/match and b/Engine/engine/match differ diff --git a/Engine/engine/shader.cpp b/Engine/engine/shader.cpp new file mode 100644 index 0000000..c4130f2 --- /dev/null +++ b/Engine/engine/shader.cpp @@ -0,0 +1,158 @@ +#ifndef SHADER_CPP +#define SHADER_CPP +#include "shader.hpp" +#include "misc.hpp" +#include // include glad to get all the required OpenGL headers + +#include +#include +#include +#include + + Shader::Shader(const std::string vertexPath, const std::string fragmentPath) + { + const char* vertexSource = this->readFile(vertexPath); + const char* shaderSource = this->readFile(fragmentPath); + const std::pair shaders = this->compileShaders(vertexSource, shaderSource); + + this->ID = this->linkShaderObjectsShaderProgram(shaders.first, shaders.second); + } + // use/activate the shader + void Shader::use() + { + glUseProgram(ID); + } + // utility uniform functions + void Shader::setBool(const std::string &name, bool value) const + { + glUniform1i(glGetUniformLocation(ID, name.c_str()), (int)value); + } + void Shader::setInt(const std::string &name, int value) const + { + glUniform1i(glGetUniformLocation(ID, name.c_str()), value); + } + void Shader::setFloat(const std::string &name, float value) const + { + glUniform1f(glGetUniformLocation(ID, name.c_str()), value); + } + + void Shader::shaderFailedMessage(const unsigned int shader, const bool compilation) const + { + char infoLog[512]; + const size_t sizeOfInfoLog = sizeof(infoLog) / sizeof(infoLog[0]); + compilation ? glGetShaderInfoLog(shader, sizeOfInfoLog, NULL, infoLog) + : glGetProgramInfoLog(shader, sizeOfInfoLog, NULL, infoLog); + std::cout << "ERROR vertex shader compilation failed \n" + << infoLog << std::endl; + } + + int Shader::shaderSuccessful(const unsigned int shader, const bool compilation) const + { + // check if compilation was successful + // int because glGetShaderiv requires int + int success; + // here we store info about compilation + // check if compilation was successful + compilation ? glGetShaderiv(shader, GL_COMPILE_STATUS, &success) + : glGetProgramiv(shader, GL_LINK_STATUS, &success); + // if not display compilation log + if (!success) + { + shaderFailedMessage(shader, compilation); + } + return success; + } + + unsigned int Shader::compileShader(const GLenum shaderType, const char *shaderSource) const + { + // we create vertex shader and assign its id to shader variable + const unsigned int 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) + glShaderSource(shaderID, 1, &shaderSource, NULL); + // compile shader + glCompileShader(shaderID); + if (!shaderSuccessful(shaderID, true)) + return 0; + return shaderID; + } + + const char* Shader::readFile(const std::string fileName) const + { + // 1. retrieve the vertex/fragment source code from filePath + std::string shaderCode; + std::ifstream shaderFile; + // ensure ifstream objects can throw exceptions: + shaderFile.exceptions (std::ifstream::failbit | std::ifstream::badbit); + try + { + // open file + shaderFile.open(fileName); + std::stringstream shaderStream; + // read file buffer contents into streams + shaderStream << shaderFile.rdbuf(); + // close file handlers + shaderFile.close(); + // convert stream into string + shaderCode = shaderStream.str(); + } + catch(std::ifstream::failure const& e) + { + std::cout << "ERROR::SHADER::FILE_NOT_SUCCESSFULLY_READ" << std::endl; + } + const char* vShaderCode = shaderCode.c_str(); + return vShaderCode; + } + + unsigned int Shader::linkShaderObjectsShaderProgram(const unsigned int vertexShaders, const unsigned int fragmentShader) const + { + // link shader objects into shader program + // will store shader program id + // creates program + const unsigned int programID = glCreateProgram(); + + // attachShaders + glAttachShader(programID, vertexShaders); + glAttachShader(programID, fragmentShader); + + // link shaders + glLinkProgram(programID); + if (!shaderSuccessful(programID, false)) + return 0; + + // activate program + // after that every shader and rendering call will use this program object + glUseProgram(programID); + + // delete shaders (they are linked into shaderProgram and we do not need them anymore) + glDeleteShader(vertexShaders); + glDeleteShader(fragmentShader); + if (programID == 0) + print("Shader Program Linking Failed"); + + return programID; + } + + std::pair Shader::compileShaders(const char* vertexShaderSource, const char* fragmentShaderSource) const + { + const unsigned int vertexShader = compileShader(GL_VERTEX_SHADER, vertexShaderSource); + if (vertexShader == 0) + { + print("Vertex Shader Compilation Failed"); + return std::make_pair(0, 0); + } + + const unsigned int fragmentShader = compileShader(GL_FRAGMENT_SHADER, fragmentShaderSource); + if (fragmentShader == 0) + { + print("Fragment Shader Compilation Failed"); + return std::make_pair(0, 0); + } + return std::make_pair(vertexShader, fragmentShader); + } + + + + +#endif \ No newline at end of file diff --git a/Engine/engine/shader.hpp b/Engine/engine/shader.hpp new file mode 100644 index 0000000..798aff5 --- /dev/null +++ b/Engine/engine/shader.hpp @@ -0,0 +1,36 @@ +#ifndef SHADER_HPP +#define SHADER_HPP + +#include // include glad to get all the required OpenGL headers + +#include +#include +#include +#include + + +class Shader +{ +public: + // the program ID + unsigned int ID; + + // constructor reads and builds the shader + Shader(const std::string vertexPath, const std::string fragmentPath); + // use/activate the shader + void use(); + // utility uniform functions + void setBool(const std::string &name, bool value) const; + void setInt(const std::string &name, int value) const; + void setFloat(const std::string &name, float value) const; + // +private: + unsigned int linkShaderObjectsShaderProgram(const unsigned int vertexShaders, const unsigned int fragmentShader) const; + const char* readFile(const std::string fileName) const; + std::pair compileShaders(const char* vertexShaderSource, const char* fragmentShaderSource) const; + unsigned int compileShader(const GLenum shaderType, const char *shaderSource) const; + int shaderSuccessful(const unsigned int shader, const bool compilation) const; + void shaderFailedMessage(const unsigned int shader, const bool compilation) const; +}; + +#endif \ No newline at end of file