From f6da8751bf7a64f3a325b1bf8264d2ca99624360 Mon Sep 17 00:00:00 2001 From: Michal Idziorek Date: Sun, 4 Sep 2022 14:15:53 +0200 Subject: shader --- src/Shader.h | 122 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/tutorial.cpp | 54 ++++++++++++++++++------ 2 files changed, 163 insertions(+), 13 deletions(-) create mode 100644 src/Shader.h diff --git a/src/Shader.h b/src/Shader.h new file mode 100644 index 0000000..1a8b484 --- /dev/null +++ b/src/Shader.h @@ -0,0 +1,122 @@ +#ifndef SHADER_H +#define SHADER_H + +#include + +#include +#include +#include +#include + +class Shader +{ +public: + unsigned int ID; + // constructor generates the shader on the fly + // ------------------------------------------------------------------------ + Shader(const char* vertexPath, const char* fragmentPath) + { + // 1. retrieve the vertex/fragment source code from filePath + std::string vertexCode; + std::string fragmentCode; + std::ifstream vShaderFile; + std::ifstream fShaderFile; + // ensure ifstream objects can throw exceptions: + vShaderFile.exceptions (std::ifstream::failbit | std::ifstream::badbit); + fShaderFile.exceptions (std::ifstream::failbit | std::ifstream::badbit); + try + { + // open files + vShaderFile.open(vertexPath); + fShaderFile.open(fragmentPath); + std::stringstream vShaderStream, fShaderStream; + // read file's buffer contents into streams + vShaderStream << vShaderFile.rdbuf(); + fShaderStream << fShaderFile.rdbuf(); + // close file handlers + vShaderFile.close(); + fShaderFile.close(); + // convert stream into string + vertexCode = vShaderStream.str(); + fragmentCode = fShaderStream.str(); + } + catch (std::ifstream::failure& e) + { + std::cout << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ: " << e.what() << std::endl; + } + const char* vShaderCode = vertexCode.c_str(); + const char * fShaderCode = fragmentCode.c_str(); + // 2. compile shaders + unsigned int vertex, fragment; + // vertex shader + vertex = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vertex, 1, &vShaderCode, NULL); + glCompileShader(vertex); + checkCompileErrors(vertex, "VERTEX"); + // fragment Shader + fragment = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fragment, 1, &fShaderCode, NULL); + glCompileShader(fragment); + checkCompileErrors(fragment, "FRAGMENT"); + // shader Program + ID = glCreateProgram(); + glAttachShader(ID, vertex); + glAttachShader(ID, fragment); + glLinkProgram(ID); + checkCompileErrors(ID, "PROGRAM"); + // delete the shaders as they're linked into our program now and no longer necessary + glDeleteShader(vertex); + glDeleteShader(fragment); + } + // activate the shader + // ------------------------------------------------------------------------ + void use() + { + glUseProgram(ID); + } + // utility uniform functions + // ------------------------------------------------------------------------ + void setBool(const std::string &name, bool value) const + { + glUniform1i(glGetUniformLocation(ID, name.c_str()), (int)value); + } + // ------------------------------------------------------------------------ + void setInt(const std::string &name, int value) const + { + glUniform1i(glGetUniformLocation(ID, name.c_str()), value); + } + // ------------------------------------------------------------------------ + void setFloat(const std::string &name, float value) const + { + glUniform1f(glGetUniformLocation(ID, name.c_str()), value); + } + +private: + // utility function for checking shader compilation/linking errors. + // ------------------------------------------------------------------------ + void checkCompileErrors(unsigned int shader, std::string type) + { + int success; + char infoLog[1024]; + if (type != "PROGRAM") + { + glGetShaderiv(shader, GL_COMPILE_STATUS, &success); + if (!success) + { + glGetShaderInfoLog(shader, 1024, NULL, infoLog); + std::cout << "ERROR::SHADER_COMPILATION_ERROR of type: " << type << "\n" << infoLog << "\n -- --------------------------------------------------- -- " << std::endl; + } + } + else + { + glGetProgramiv(shader, GL_LINK_STATUS, &success); + if (!success) + { + glGetProgramInfoLog(shader, 1024, NULL, infoLog); + std::cout << "ERROR::PROGRAM_LINKING_ERROR of type: " << type << "\n" << infoLog << "\n -- --------------------------------------------------- -- " << std::endl; + } + } + } +}; + +#endif diff --git a/src/tutorial.cpp b/src/tutorial.cpp index e3f7a9d..aa9baef 100644 --- a/src/tutorial.cpp +++ b/src/tutorial.cpp @@ -1,9 +1,12 @@ // https://learnopengl.com/Getting-started/OpenGL +// seriously consider GLFW et al. + #include #include -#include +//#include +#include #include "TutorialConfig.h" @@ -16,6 +19,9 @@ GLuint VAO1_glob; void renderScene(void) { + float seconds = glutGet(GLUT_ELAPSED_TIME) / 1000.0; + float greenValue = sin(seconds) / 2.0 + 0.5; + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); @@ -26,6 +32,8 @@ void renderScene(void) { glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); glUseProgram(shaderProgram_glob); + glUniform4f(glGetUniformLocation (shaderProgram_glob, "ourColor") , 0,greenValue,0,1); + glBindVertexArray(VAO_glob); glDrawArrays(GL_TRIANGLES, 0, 3); @@ -81,8 +89,9 @@ int main(int argc, char **argv) { // init GLUT and create Window glutInit(&argc, argv); + glutSetOption(GLUT_ALLOW_NEGATIVE_WINDOW_POSITION,true); glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA); - glutInitWindowPosition(100,100); + glutInitWindowPosition(-500,600); glutInitWindowSize(320,320); glutCreateWindow("Lighthouse3D - GLUT Tutorial"); glutIdleFunc(idle); @@ -122,20 +131,39 @@ int main(int argc, char **argv) { exit(1); // or handle the error in a nicer way } + int nrAttributes; + glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &nrAttributes); + std::cout << "Maximum nr of vertex attributes supported: " << nrAttributes << std::endl; + int success; char infoLog[512]; - const char *vertexShaderSource = "#version 330 core\n" - "layout (location = 0) in vec3 aPos;\n" - "void main()\n" - "{\n" - " gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n" - "}\0"; - const char *fragmentShaderSource = "#version 330 core\n" - "out vec4 FragColor; void main() { FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f); } \0"; - - const char *fragmentShader1Source = "#version 330 core\n" - "out vec4 FragColor; void main() { FragColor = vec4(1.0f, 0.0f, 0.0f, 1.0f); } \0"; + const char *vertexShaderSource = + "#version 330 core\n" + "layout (location = 0) in vec3 aPos;\n" + "out vec4 vertexColor;\n" + "uniform vec4 ourColor;" + "void main(){" + "gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);" + "vertexColor = vec4(aPos.y,aPos.x,ourColor.y,1.0);" + "vertexColor = ourColor;" + "}\0"; + + const char *fragmentShaderSource = + "#version 330 core\n" + "out vec4 FragColor;" + "in vec4 vertexColor;" + "void main(){" + "FragColor = vertexColor;" + "}\0"; + + const char *fragmentShader1Source = + "#version 330 core\n" + "out vec4 FragColor;" + "in vec4 vertexColor;" + "void main(){" + "FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);" + "}\0"; GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertexShader, 1, &vertexShaderSource, NULL); -- cgit v1.2.3