diff --git a/headers/mesh.hpp b/headers/mesh.hpp index 59f9474..bbe3b80 100644 --- a/headers/mesh.hpp +++ b/headers/mesh.hpp @@ -13,11 +13,13 @@ public: void setPosition(glm::vec3 p); void setScale(glm::vec3 s); void setRotation(glm::quat r); - void setOwned(bool o); + void setOwnedBuffers(bool o); + void setOwnedShader(bool o); Shader *getShader(); private: bool buffersOwned; + bool shaderOwned; int count; unsigned int VAO; Shader *shader; diff --git a/headers/shader.hpp b/headers/shader.hpp index 7271488..9f8198c 100644 --- a/headers/shader.hpp +++ b/headers/shader.hpp @@ -11,6 +11,7 @@ public: void use(); void setInt(const std::string &name, int value); void setFloat(const std::string &name, float value); + void setVec3(const std::string &name, glm::vec3 value); void setMat4(const std::string &name, glm::mat4 value); private: diff --git a/headers/shapes.h b/headers/shapes.h index eb00edd..1994b39 100644 --- a/headers/shapes.h +++ b/headers/shapes.h @@ -75,6 +75,50 @@ float cube_vertices[] = { -0.5f, 0.5f, -0.5f, 0.0f, 1.0f /**/ }; +float uvcube[] = { + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + + -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f +}; + const char *basicVertexShaderSource = "#version 330 core\n" "layout (location = 0) in vec3 aPos;\n" diff --git a/shaders/lighting/Frag.glsl b/shaders/lighting/Frag.glsl new file mode 100644 index 0000000..a3d7ace --- /dev/null +++ b/shaders/lighting/Frag.glsl @@ -0,0 +1,42 @@ +#version 330 core +struct Material { + vec3 ambient; + vec3 diffuse; + vec3 specular; + float shininess; +}; + +out vec4 FragColor; + +in vec3 FragPos; +in vec3 Normal; + +uniform vec3 ourColor; +uniform vec3 lightColor; +uniform vec3 lightPos; +uniform vec3 viewPos; +uniform Material material; + +void main() +{ + //misc + vec3 norm = normalize(Normal); + vec3 lightDir = normalize(lightPos - FragPos); + + // ambient + vec3 ambient = vec3(0.2) * (lightColor * material.ambient); + + // diffuse + float diff = max(dot(norm, lightDir), 0.0); + vec3 diffuse = lightColor * (diff * material.diffuse); + + // specular + vec3 viewDir = normalize(viewPos - FragPos); + vec3 reflectDir = reflect(-lightDir, norm); + float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); + vec3 specular = vec3(0.5) * (lightColor * (spec * material.specular)); + + //out + vec3 result = ambient + diffuse + specular; + FragColor = vec4(result, 1.0); +} diff --git a/shaders/lighting/LightFrag.glsl b/shaders/lighting/LightFrag.glsl new file mode 100644 index 0000000..c958e8c --- /dev/null +++ b/shaders/lighting/LightFrag.glsl @@ -0,0 +1,9 @@ +#version 330 core +out vec4 FragColor; + +uniform vec3 ourColor; + +void main() +{ + FragColor = vec4(ourColor, 1.0); +} diff --git a/shaders/lighting/Vert.glsl b/shaders/lighting/Vert.glsl new file mode 100644 index 0000000..2be9792 --- /dev/null +++ b/shaders/lighting/Vert.glsl @@ -0,0 +1,18 @@ +#version 330 core +layout (location = 0) in vec3 aPos; +layout (location = 1) in vec3 aNormal; + +out vec3 FragPos; +out vec3 Normal; + +uniform mat4 model; +uniform mat4 view; +uniform mat4 projection; + +void main() +{ + gl_Position = projection * view * model * vec4(aPos, 1.0); + FragPos = vec3(model * vec4(aPos, 1.0)); + Normal = aNormal; + //Normal = mat3(transpose(inverse(model))) * aNormal;//if non unifrom scale +} diff --git a/src/main.cpp b/src/main.cpp index 1b19898..454c0a4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2,7 +2,6 @@ #include /*Must be before GLFW*/ #include #include -#include #include #include #include @@ -13,15 +12,7 @@ void processInput(GLFWwindow *window); void framebuffer_size_callback(GLFWwindow *window, int width, int height); - -glm::vec3 cubePositions[] = { - glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(2.0f, 5.0f, -15.0f), - glm::vec3(-1.5f, -2.2f, -2.5f), glm::vec3(-3.8f, -2.0f, -12.3f), - glm::vec3(2.4f, -0.4f, -3.5f), glm::vec3(-1.7f, 3.0f, -7.5f), - glm::vec3(1.3f, -2.0f, -2.5f), glm::vec3(1.5f, 2.0f, -2.5f), - glm::vec3(1.5f, 0.2f, -1.5f), glm::vec3(-1.3f, 1.0f, -1.5f)}; - -int main(void) { +GLFWwindow *init() { glfwInit(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); @@ -37,65 +28,82 @@ int main(void) { glViewport(0, 0, 800, 600); glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); + return window; +} +unsigned int meshInit() { unsigned int VBO, VAO; glGenVertexArrays(1, &VAO); glBindVertexArray(VAO); glGenBuffers(1, &VBO); glBindBuffer(GL_ARRAY_BUFFER, VBO); - glBufferData(GL_ARRAY_BUFFER, sizeof(cube_vertices), cube_vertices, - GL_STATIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, sizeof(uvcube), uvcube, GL_STATIC_DRAW); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void *)0); - glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void *)0); + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void *)(3 * sizeof(float))); + glEnableVertexAttribArray(0); + glEnableVertexAttribArray(1); + return VAO; +} - glEnableVertexAttribArray(0); /*pos*/ - glEnableVertexAttribArray(1); /*tex_cord*/ +int main(void) { + glm::vec3 lightPos = glm::vec3(1, 2.0f, 1); + glm::vec3 cameraPos = glm::vec3(2.3, 3, 5); + glm::vec3 lightColor = glm::vec3(1); - Shader *shaderProgram = new Shader("./shaders/MVPTexNoRGBVert.glsl", - "./shaders/TexNoRGBFrag.glsl"); - - Mesh *mesh = new Mesh(shaderProgram, VAO, 36); - mesh->setOwned(true); - - Texture *texture = new Texture(GL_TEXTURE_2D, "./texture/container.jpg"); - Texture *texture2 = new Texture(GL_TEXTURE_2D, "./texture/brick.jpg"); - - Camera *cam = - new Camera(glm::vec3(0.0, 0.0, 5.0), -90.0f, 0.0f, 45.0, 800.0 / 600); + GLFWwindow *window = init(); + Camera *cam = new Camera(cameraPos, -115.0f, -25.0f, 45, 800.0 / 600); glfwSetWindowUserPointer(window, cam); + Shader *cubeShader = new Shader("./shaders/lighting/Vert.glsl", + "./shaders/lighting/Frag.glsl"); + Shader *lightShader = new Shader("./shaders/lighting/Vert.glsl", + "./shaders/lighting/LightFrag.glsl"); + + uint VAO = meshInit(); + Mesh *cube = new Mesh(cubeShader, VAO, 36); + Mesh *light = new Mesh(lightShader, VAO, 36); + cube->setOwnedShader(true); + light->setOwnedShader(true); + + light->setPosition(lightPos); + light->setScale(glm::vec3(.3)); + glEnable(GL_DEPTH_TEST); while (!glfwWindowShouldClose(window)) { - glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - texture->bind(GL_TEXTURE0); - texture2->bind(GL_TEXTURE1); - glActiveTexture(GL_TEXTURE0); - for (unsigned int i = 0; i < 10; i++) { - mesh->setPosition(cubePositions[i]); - mesh->getShader()->setInt("tex0", i % 2); + Shader *s = cube->getShader(); + s->use(); + s->setVec3("lightColor", lightColor); + s->setVec3("ourColor", glm::vec3(0.24725, 0.1995, 0.0745)); + s->setVec3("lightPos", lightPos); + s->setVec3("viewPos", glm::vec3(0.0, 0.0, 5.0)); - glm::mat4 rotate = glm::mat4(1); - float angle = 20.0f * i; - rotate = - glm::rotate(rotate, glm::radians(angle), glm::vec3(1.0f, 0.3f, 0.5f)); - rotate = glm::rotate(rotate, (float)glfwGetTime() * glm::radians(55.0f), - glm::vec3(1.0f, 0.5f, 0.0f)); - mesh->setRotation(glm::quat_cast(rotate)); - mesh->draw(cam); - } + /*mat taken from*/ + /*http://devernay.free.fr/cours/opengl/materials.html*/ + s->setVec3("material.ambient", glm::vec3(0.24725, 0.1995, 0.0745)); + s->setVec3("material.diffuse", glm::vec3(0.75164, 0.60648, 0.22648)); + s->setVec3("material.specular", glm::vec3(0.628281, 0.555802, 0.366065)); + s->setFloat("material.shininess", 0.4 * 128); + cube->draw(cam); + + s = light->getShader(); + s->use(); + s->setVec3("ourColor", lightColor); + light->draw(cam); glfwSwapBuffers(window); glfwPollEvents(); processInput(window); } - delete (shaderProgram); + delete cam; + delete cube; + delete light; glfwTerminate(); return 0; } diff --git a/src/mesh.cpp b/src/mesh.cpp index a0da980..3aeba9d 100644 --- a/src/mesh.cpp +++ b/src/mesh.cpp @@ -3,11 +3,18 @@ #include Mesh::Mesh(Shader *s, unsigned int VAO, int count) - : buffersOwned(false), count(count), VAO(VAO), shader(s), - position(glm::vec3(0)), scale(glm::vec3(1)), + : buffersOwned(false), shaderOwned(false), count(count), VAO(VAO), + shader(s), position(glm::vec3(0)), scale(glm::vec3(1)), rotation(glm::quat(1.0f, 0.0f, 0.0f, 0.0f)) {} -Mesh::~Mesh() {} +Mesh::~Mesh() { + if (shaderOwned) + delete shader; + if (buffersOwned){ + glDeleteVertexArrays(1, &VAO); + // TODO vbo, ibo + } +} void Mesh::draw(Camera *c) { glm::mat4 model = glm::mat4(1); @@ -28,6 +35,8 @@ void Mesh::setScale(glm::vec3 s) { scale = s; } void Mesh::setRotation(glm::quat r) { rotation = r; } -void Mesh::setOwned(bool o) { buffersOwned = o; } +void Mesh::setOwnedBuffers(bool o) { buffersOwned = o; } + +void Mesh::setOwnedShader(bool o) { shaderOwned = o; } Shader *Mesh::getShader() { return shader; } diff --git a/src/shader.cpp b/src/shader.cpp index 86e65c4..b39ec19 100644 --- a/src/shader.cpp +++ b/src/shader.cpp @@ -45,6 +45,11 @@ void Shader::setFloat(const std::string &name, float value) { glUniform1f(glGetUniformLocation(ID, name.c_str()), value); } +void Shader::setVec3(const std::string &name, glm::vec3 value) { + glUniform3fv(glGetUniformLocation(ID, name.c_str()), 1, + glm::value_ptr(value)); +} + void Shader::setMat4(const std::string &name, glm::mat4 value) { glUniformMatrix4fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, glm::value_ptr(value));