diff --git a/BaseGLProject/BaseGLProject.vcxproj b/BaseGLProject/BaseGLProject.vcxproj index 4e88a62..c69e076 100644 --- a/BaseGLProject/BaseGLProject.vcxproj +++ b/BaseGLProject/BaseGLProject.vcxproj @@ -89,13 +89,13 @@ true WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) true - C:\Graphics\Tools\glew\include;C:\Graphics\Tools\glm;C:\Graphics\Tools\glfw\include;%(AdditionalIncludeDirectories) + C:\Graphics\Tools\SOIL\include;C:\Graphics\Tools\Assimp\include;C:\Graphics\Tools\glew\include;C:\Graphics\Tools\glm;C:\Graphics\Tools\glfw\include;%(AdditionalIncludeDirectories) true Console - C:\Graphics\Tools\glfw\lib\x86;C:\Graphics\Tools\glew\lib;%(AdditionalLibraryDirectories) - glfw3.lib;glew32.lib;opengl32.lib;%(AdditionalDependencies) + C:\Graphics\Tools\SOIL\lib;C:\Graphics\Tools\Assimp\lib\x86;C:\Graphics\Tools\glfw\lib\x86;C:\Graphics\Tools\glew\lib;%(AdditionalLibraryDirectories) + assimp.lib;SOIL.lib;glfw3.lib;glew32.lib;opengl32.lib;%(AdditionalDependencies) @@ -155,7 +155,9 @@ + + @@ -166,6 +168,7 @@ + @@ -177,8 +180,10 @@ + + @@ -186,6 +191,7 @@ + Geometry 4.0 @@ -197,7 +203,9 @@ 4.0 Document + + diff --git a/BaseGLProject/BaseGLProject.vcxproj.filters b/BaseGLProject/BaseGLProject.vcxproj.filters index c1fdb2a..437c922 100644 --- a/BaseGLProject/BaseGLProject.vcxproj.filters +++ b/BaseGLProject/BaseGLProject.vcxproj.filters @@ -19,6 +19,9 @@ {4ea3f893-d13b-4d3c-a496-f05d5b3aeeb4} + + {af32f844-b061-4424-a685-e3f537232cf8} + @@ -66,6 +69,12 @@ Source Files + + Models + + + Source Files + @@ -131,6 +140,15 @@ Header Files + + Models + + + Header Files + + + Header Files + @@ -142,5 +160,14 @@ Shaders + + Shaders + + + Shaders + + + Shaders + \ No newline at end of file diff --git a/BaseGLProject/CheckeredFloor.cpp b/BaseGLProject/CheckeredFloor.cpp index 98d2bd9..6fb8cbb 100644 --- a/BaseGLProject/CheckeredFloor.cpp +++ b/BaseGLProject/CheckeredFloor.cpp @@ -15,13 +15,15 @@ void CheckeredFloor::genVertices(std::vector &vertices, color *= -1; glm::vec3 tile_color = (color > 0) ? _light_color : _dark_color; //gen 1 carré - vertices.emplace_back(x, 0, y, 1); //upleft - vertices.emplace_back(x + side_size, 0, y, 1); //upright - vertices.emplace_back(x, 0, y + side_size, 1); //downleft - - vertices.emplace_back(x + side_size, 0, y, 1); //upright + vertices.emplace_back(x, 0, y, 1); //upleft vertices.emplace_back(x, 0, y + side_size, 1); //downleft vertices.emplace_back(x + side_size, 0, y + side_size, 1); //downright + + vertices.emplace_back(x + side_size, 0, y + side_size, 1); //downright + vertices.emplace_back(x + side_size, 0, y, 1); //upright + vertices.emplace_back(x, 0, y, 1); //upleft + + for (int z = 0; z < 6; z++) colors.push_back(tile_color); diff --git a/BaseGLProject/Global.h b/BaseGLProject/Global.h new file mode 100644 index 0000000..1456acd --- /dev/null +++ b/BaseGLProject/Global.h @@ -0,0 +1,8 @@ +#pragma once +#include "glm/glm.hpp" + +namespace global +{ + static glm::vec4 LightLocation(50, 50, 50, 1); + static glm::vec3 LightIntensity(0.9, 0.9, 0.9); +} diff --git a/BaseGLProject/IDrawable.h b/BaseGLProject/IDrawable.h index 2b20bc6..bb904e8 100644 --- a/BaseGLProject/IDrawable.h +++ b/BaseGLProject/IDrawable.h @@ -12,7 +12,9 @@ enum DrawableType WIRE_CUBE, LINE_SEGMENT, SPHERE, - TEAPOT + TEAPOT, + LOADED_MESH, + LIGHTED_PLANE }; class IDrawable { diff --git a/BaseGLProject/Models/Mesh.cpp b/BaseGLProject/Models/Mesh.cpp new file mode 100644 index 0000000..a74684d --- /dev/null +++ b/BaseGLProject/Models/Mesh.cpp @@ -0,0 +1,296 @@ + +#define GLM_ENABLE_EXPERIMENTAL + +#include +#include +#include "Mesh.h" +#include "../Global.h" + +#include +#include +#include +#include +#include +#include + +#include + +/** +* Constructor, loading the specified aiMesh +**/ + + + + +Mesh::MeshEntry::MeshEntry(aiMesh *mesh, const aiScene* scene, Mesh * m) +{ + parent = m; + + vbo[VERTEX_BUFFER] = NULL; + vbo[TEXCOORD_BUFFER] = NULL; + vbo[NORMAL_BUFFER] = NULL; + vbo[INDEX_BUFFER] = NULL; + + glGenVertexArrays(1, &vao); + glBindVertexArray(vao); + + elementCount = mesh->mNumFaces * 3; + + if (mesh->HasPositions()) { + float *vertices = new float[mesh->mNumVertices * 3]; + for (int i = 0; i < mesh->mNumVertices; ++i) { + vertices[i * 3] = mesh->mVertices[i].x; + vertices[i * 3 + 1] = mesh->mVertices[i].y; + vertices[i * 3 + 2] = mesh->mVertices[i].z; + } + + glGenBuffers(1, &vbo[VERTEX_BUFFER]); + glBindBuffer(GL_ARRAY_BUFFER, vbo[VERTEX_BUFFER]); + glBufferData(GL_ARRAY_BUFFER, 3 * mesh->mNumVertices * sizeof(GLfloat), vertices, GL_STATIC_DRAW); + + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL); + glEnableVertexAttribArray(0); + + delete[] vertices; + } + + + if (mesh->HasTextureCoords(0)) { + float *texCoords = new float[mesh->mNumVertices * 2]; + for (int i = 0; i < mesh->mNumVertices; ++i) { + texCoords[i * 2] = mesh->mTextureCoords[0][i].x; + texCoords[i * 2 + 1] = mesh->mTextureCoords[0][i].y; + } + + glGenBuffers(1, &vbo[TEXCOORD_BUFFER]); + glBindBuffer(GL_ARRAY_BUFFER, vbo[TEXCOORD_BUFFER]); + glBufferData(GL_ARRAY_BUFFER, 2 * mesh->mNumVertices * sizeof(GLfloat), texCoords, GL_STATIC_DRAW); + + glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, NULL); + glEnableVertexAttribArray(2); + + delete[] texCoords; + } + + + if (mesh->HasNormals()) { + float *normals = new float[mesh->mNumVertices * 3]; + for (int i = 0; i < mesh->mNumVertices; ++i) { + normals[i * 3] = mesh->mNormals[i].x; + normals[i * 3 + 1] = mesh->mNormals[i].y; + normals[i * 3 + 2] = mesh->mNormals[i].z; + } + + glGenBuffers(1, &vbo[NORMAL_BUFFER]); + glBindBuffer(GL_ARRAY_BUFFER, vbo[NORMAL_BUFFER]); + glBufferData(GL_ARRAY_BUFFER, 3 * mesh->mNumVertices * sizeof(GLfloat), normals, GL_STATIC_DRAW); + + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, NULL); + glEnableVertexAttribArray(1); + + delete[] normals; + } + + + if (mesh->HasFaces()) { + unsigned int *indices = new unsigned int[mesh->mNumFaces * 3]; + for (int i = 0; i < mesh->mNumFaces; ++i) { + indices[i * 3] = mesh->mFaces[i].mIndices[0]; + indices[i * 3 + 1] = mesh->mFaces[i].mIndices[1]; + indices[i * 3 + 2] = mesh->mFaces[i].mIndices[2]; + } + + glGenBuffers(1, &vbo[INDEX_BUFFER]); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo[INDEX_BUFFER]); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, 3 * mesh->mNumFaces * sizeof(GLuint), indices, GL_STATIC_DRAW); + + glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, 0, NULL); + glEnableVertexAttribArray(3); + + delete[] indices; + } + + if (mesh->mMaterialIndex >= 0) { + aiMaterial* material = scene->mMaterials[mesh->mMaterialIndex]; + + material->Get(AI_MATKEY_SHININESS, shininessStrength); + material->Get(AI_MATKEY_COLOR_DIFFUSE, dcolor); + material->Get(AI_MATKEY_COLOR_AMBIENT, acolor); + material->Get(AI_MATKEY_COLOR_SPECULAR, scolor); + + + } + + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindVertexArray(0); + + +} + +/** +* Deletes the allocated OpenGL buffers +**/ +Mesh::MeshEntry::~MeshEntry() { + if (vbo[VERTEX_BUFFER]) { + glDeleteBuffers(1, &vbo[VERTEX_BUFFER]); + } + + if (vbo[TEXCOORD_BUFFER]) { + glDeleteBuffers(1, &vbo[TEXCOORD_BUFFER]); + } + + if (vbo[NORMAL_BUFFER]) { + glDeleteBuffers(1, &vbo[NORMAL_BUFFER]); + } + + if (vbo[INDEX_BUFFER]) { + glDeleteBuffers(1, &vbo[INDEX_BUFFER]); + } + + glDeleteVertexArrays(1, &vao); + + +} + +/** +* Renders this MeshEntry +**/ +void Mesh::MeshEntry::render() { + + + glBindVertexArray(vao); + int size; + glGetBufferParameteriv(GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_SIZE, &size); + glDrawElements(GL_TRIANGLES, size/ sizeof(unsigned int), GL_UNSIGNED_INT, NULL); + glBindVertexArray(0); +} + +/** +* Mesh constructor, loads the specified filename if supported by Assimp +**/ +Mesh::Mesh(const char *filename, ShaderProgram * sh) +{ + shader = sh; + + std::string fullname; + fullname = std::string("./Models/")+ std::string(filename); + + Assimp::Importer importer; //aiProcessPreset_TargetRealtime_Fast + const aiScene* scene = importer.ReadFile(fullname.c_str(), aiProcess_Triangulate | aiProcess_FlipUVs | aiProcess_GenSmoothNormals | aiProcess_OptimizeMeshes); + + // Check for errors + if (!scene || scene->mFlags == AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) // if is Not Zero + { + std::cout << "ERROR::ASSIMP:: " << importer.GetErrorString() << std::endl; + return; + } + + for (int i = 0; i < scene->mNumMeshes; ++i) { + meshEntries.push_back(new Mesh::MeshEntry(scene->mMeshes[i], scene, this)); + } + + +} + +/** +* Clears all loaded MeshEntries +**/ +Mesh::~Mesh(void) +{ + for (int i = 0; i < meshEntries.size(); ++i) { + + delete meshEntries.at(i); + } + meshEntries.clear(); +} + +/** +* Renders all loaded MeshEntries +**/ +DrawableType Mesh::getType() +{ + return DrawableType::LOADED_MESH; +} + +void Mesh::draw(ShaderProgram *, glm::mat4x4 proj_matrix, glm::mat4x4 view_matrix) { + + shader->use(); + for (int i = 0; i < meshEntries.size(); ++i) { + + MeshEntry * m = meshEntries[i]; + + + float shiness = meshEntries.at(i)->shininessStrength; + + + _model.glPushMatrix(); + effectTransformations(); + shader->addUniform("mvp"); + + + shader->addUniform("NormalMatrix"); //Refer next slide : mat3 + shader->addUniform("ModelViewMatrix"); //View*Model : mat4 + + glm::vec4 light_center(0, 10, 0, 0); + float radius = 10.0f; + float angle = 0; + static bool first_draw = true; + for (int i = 0; i < 5; i++) + { + std::string name = "Light[" + std::to_string(i) + "].Position"; + shader->addUniform(name); + glm::vec4 position = glm::vec4(radius * cos(glm::radians(angle)), 10 ,radius * sin(glm::radians(angle)), 1); + glUniform4fv(shader->uniform(name), 1, glm::value_ptr(view_matrix * position)); + angle += 360 / 5; + } + first_draw = false; + shader->addUniform("Light[0].Intensity"); + glUniform3fv(shader->uniform("Light[0].Intensity"), 1, glm::value_ptr(glm::vec3(0.0f, 0.5f, 0.5f))); + shader->addUniform("Light[1].Intensity"); + glUniform3fv(shader->uniform("Light[1].Intensity"), 1, glm::value_ptr(glm::vec3(0.0f, 0.0f, 0.5f))); + shader->addUniform("Light[2].Intensity"); + glUniform3fv(shader->uniform("Light[2].Intensity"), 1, glm::value_ptr(glm::vec3(0.5f, 0.0f, 0.0f))); + shader->addUniform("Light[3].Intensity"); + glUniform3fv(shader->uniform("Light[3].Intensity"), 1, glm::value_ptr(glm::vec3(0.0f, 0.5f, 0.0f))); + shader->addUniform("Light[4].Intensity"); + glUniform3fv(shader->uniform("Light[4].Intensity"), 1, glm::value_ptr(glm::vec3(0.5f, 0.5f, 0.5f))); + + glm::mat4 mvpMatrix = proj_matrix * view_matrix * _model.getMatrix(); + glUniformMatrix4fv(shader->uniform("mvp"), 1, GL_FALSE, glm::value_ptr(mvpMatrix)); + glm::mat4 modelview = view_matrix * _model.getMatrix(); + glUniformMatrix4fv(shader->uniform("ModelViewMatrix"), 1, GL_FALSE, glm::value_ptr(modelview)); + glm::mat4 inverseModelView = glm::inverse(modelview); + glm::mat3 normalMatrix = glm::mat3(glm::transpose(inverseModelView)); + glUniformMatrix3fv(shader->uniform("NormalMatrix"), 1, GL_FALSE, glm::value_ptr(normalMatrix)); + + + glm::vec3 diffuse = glm::vec3(meshEntries.at(i)->dcolor.r, meshEntries.at(i)->dcolor.g, meshEntries.at(i)->dcolor.b); + glm::vec3 specular = glm::vec3(meshEntries.at(i)->scolor.r, meshEntries.at(i)->scolor.g, meshEntries.at(i)->scolor.b); + glm::vec3 ambient = glm::vec3(meshEntries.at(i)->acolor.r, meshEntries.at(i)->acolor.g, meshEntries.at(i)->acolor.b); + + if (glm::length(ambient) == 0) { + ambient = glm::vec3(0.1, 0.1, 0.1); + } + + if (glm::length(diffuse) == 0) { + diffuse = glm::vec3(0.9, 0.9, 0.9); + } + + if (glm::length(specular) == 0) { + specular = glm::vec3(0.4, 0.4, 0.4); + } + + if (shiness == 0) + shiness = 150.0f; + + glUniform3fv(shader->uniform("Ka"), 1, glm::value_ptr(ambient)); + glUniform3fv(shader->uniform("Kd"), 1, glm::value_ptr(diffuse)); + glUniform3fv(shader->uniform("Ks"), 1, glm::value_ptr(specular)); + glUniform1f(shader->uniform("Shininess"), shiness); + + meshEntries.at(i)->render(); + _model.glPopMatrix(); + } + + shader->disable(); +} diff --git a/BaseGLProject/Models/Mesh.h b/BaseGLProject/Models/Mesh.h new file mode 100644 index 0000000..ac923e1 --- /dev/null +++ b/BaseGLProject/Models/Mesh.h @@ -0,0 +1,45 @@ +#pragma once + +#include "GL/glew.h" +#include + +#include + +#include "assimp\scene.h" +#include "assimp\mesh.h" +#include "../Loader.h" +#include "../ADrawable.h" + + +class Mesh : public ADrawable +{ +public: + struct MeshEntry { + static enum BUFFERS { + VERTEX_BUFFER, TEXCOORD_BUFFER, NORMAL_BUFFER, INDEX_BUFFER + }; + GLuint vao; + GLuint vbo[4]; + + unsigned int elementCount; + aiColor3D dcolor; + aiColor3D acolor; + aiColor3D scolor; + float shininessStrength; + MeshEntry(aiMesh *mesh, const aiScene* scene, Mesh * m); + ~MeshEntry(); + Mesh * parent; + void render(); + }; + +public: + Mesh(const char *filename, ShaderProgram * sh); + ~Mesh(void); + + + std::vector meshEntries; + + ShaderProgram * shader; + void draw(ShaderProgram *shader, glm::mat4x4 proj_matrix, glm::mat4x4 view_matrix); + DrawableType getType(); +}; \ No newline at end of file diff --git a/BaseGLProject/MyGLWindow.cpp b/BaseGLProject/MyGLWindow.cpp index 0c1cd40..0328f84 100644 --- a/BaseGLProject/MyGLWindow.cpp +++ b/BaseGLProject/MyGLWindow.cpp @@ -58,26 +58,37 @@ void MyGlWindow::setBgColor(float bgColor[3]) void MyGlWindow::setup() { _staticShader = new ShaderProgram(); - _staticShader->initFromFiles("simple.vert", "simple.frag"); + _staticShader->initFromFiles("light.vert", "onelight.frag"); _lightShader = new ShaderProgram(); - _lightShader->initFromFiles("light.vert", "simple.frag"); + _lightShader->initFromFiles("light.vert", "toon.frag"); - _static_drawables.emplace_back(new CheckeredFloor(50, 16)); + _static_drawables.push_back(new Plane(50, 16)); + + /*_static_drawables.emplace_back(new CheckeredFloor(50, 16)); _light_drawables.push_back(new ColorCube(false)); _light_drawables.back()->addTranslation(glm::vec4(2, 1.1f, 0, 0)); - _light_drawables.push_back(new Sphere(1, 100, 100)); + _light_drawables.push_back(new Sphere(1, 50, 50)); _light_drawables.back()->addTranslation(glm::vec4(-2, 1.1f, 0, 0)); _light_drawables.push_back(new VBOTeapot(64, glm::identity())); - _light_drawables.back()->addTranslation(glm::vec4(2, 3, -7, 0)); - _light_drawables.back()->addRotation(glm::vec4(1, 0, 0, -90)); + _light_drawables.back()->addTranslation(glm::vec4(2, 0, -7, 0)); + _light_drawables.back()->addRotation(glm::vec4(1, 0, 0, -90)); + _light_drawables.push_back(new Mesh("bunny.obj", _lightShader)); + _light_drawables.push_back(new Mesh("buddha.obj", _lightShader)); + _light_drawables.back()->addTranslation(glm::vec4(0, 13, -15, 0)); + _light_drawables.back()->addRotation(glm::vec4(0, 1, 0, -180)); + _light_drawables.back()->addScaling(glm::vec4(30, 30, 30, 0));*/ + _light_drawables.push_back(new Mesh("teapot.obj", _lightShader)); + _light_drawables.back()->addTranslation(glm::vec4(0, 1, 0, 0)); + _light_drawables.back()->addScaling(glm::vec4(1, 1, 1, 1)); } void MyGlWindow::draw() { - glClearColor(_bgColor[0], _bgColor[1], _bgColor[2], 1); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glClearColor(_bgColor[0], _bgColor[1], _bgColor[2], 1); glViewport(0, 0, m_width, m_height); glEnable(GL_DEPTH_TEST); + glEnable(GL_DEPTH_BUFFER); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glm::vec3 eye(viewer.getViewPoint().x, viewer.getViewPoint().y, viewer.getViewPoint().z); glm::vec3 look(viewer.getViewCenter().x, viewer.getViewCenter().y, viewer.getViewCenter().z); @@ -87,33 +98,63 @@ void MyGlWindow::draw() _staticShader->use(); - _staticShader->addUniform("mvp"); - + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + _staticShader->addUniform("mvp"); + + _staticShader->addUniform("Ka"); //Ambient Object Color :vec3 + glUniform3fv(_staticShader->uniform("Ka"), 1, glm::value_ptr(glm::vec3(0.19225, 0.19225, 0.19225))); + + _staticShader->addUniform("Kd"); //Diffuse Object Color :vec3 + glUniform3fv(_staticShader->uniform("Kd"), 1, glm::value_ptr(glm::vec3(0.50754, 0.50754, 0.50754))); + + _staticShader->addUniform("Ks"); //Specular Object Color :vec3 + glUniform3fv(_staticShader->uniform("Ks"), 1, glm::value_ptr(glm::vec3(0.508273, 0.508273, 0.508273))); + + _staticShader->addUniform("Shininess"); + glUniform1f(_staticShader->uniform("Shininess"), 51.2); + + _staticShader->addUniform("NormalMatrix"); //Refer next slide : mat3 + _staticShader->addUniform("ModelViewMatrix"); //View*Model : mat4 + + /* Variable set for spot lighting */ + + _staticShader->addUniform("LightDirection"); + _staticShader->addUniform("Exponent"); + glUniform1f(_staticShader->uniform("Exponent"), 10); + _staticShader->addUniform("Cutoff"); + glUniform1f(_staticShader->uniform("Cutoff"), 30); + _staticShader->addUniform("InnerCutoff"); + glUniform1f(_staticShader->uniform("InnerCutoff"), 25); + + /* END set */ + for (ADrawable *drawable : _static_drawables) drawable->draw(_staticShader, projection, view); _staticShader->disable(); - _lightShader->use(); + _lightShader->use(); + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + _lightShader->addUniform("mvp"); - _lightShader->addUniform("mvp"); - _lightShader->addUniform("LightLocation"); //Light Position to camera coordinates : vec4 + _lightShader->addUniform("Ka"); //Ambient Object Color :vec3 + glUniform3fv(_lightShader->uniform("Ka"), 1, glm::value_ptr(glm::vec3(0.19225, 0.19225, 0.19225))); _lightShader->addUniform("Kd"); //Diffuse Object Color :vec3 - glUniform3fv(_lightShader->uniform("Kd"), 1, glm::value_ptr(glm::vec3(1, 1, 0))); - _lightShader->addUniform("Ld"); //Diffuse Light Color : vec3 - glUniform3fv(_lightShader->uniform("Ld"), 1, glm::value_ptr(glm::vec3(1, 1, 1))); - - _lightShader->addUniform("Ka"); //Diffuse Object Color :vec3 - glUniform3fv(_lightShader->uniform("Ka"), 1, glm::value_ptr(glm::vec3(0.2, 0.2, 0))); - _lightShader->addUniform("La"); //Diffuse Light Color : vec3 - glUniform3fv(_lightShader->uniform("La"), 1, glm::value_ptr(glm::vec3(1, 1, 1))); - - _lightShader->addUniform("Ks"); //Diffuse Object Color :vec3 - glUniform3fv(_lightShader->uniform("Ks"), 1, glm::value_ptr(glm::vec3(0.3, 0.3, 0))); - _lightShader->addUniform("Ls"); //Diffuse Light Color : vec3 - glUniform3fv(_lightShader->uniform("Ls"), 1, glm::value_ptr(glm::vec3(1, 1, 1))); + glUniform3fv(_lightShader->uniform("Kd"), 1, glm::value_ptr(glm::vec3(0.50754, 0.50754, 0.50754))); + + _lightShader->addUniform("Ks"); //Specular Object Color :vec3 + glUniform3fv(_lightShader->uniform("Ks"), 1, glm::value_ptr(glm::vec3(0.508273, 0.508273, 0.508273))); + _lightShader->addUniform("Shininess"); + glUniform1f(_lightShader->uniform("Shininess"), 51.2); + _lightShader->addUniform("NormalMatrix"); //Refer next slide : mat3 _lightShader->addUniform("ModelViewMatrix"); //View*Model : mat4 diff --git a/BaseGLProject/MyGLWindow.h b/BaseGLProject/MyGLWindow.h index 7962781..f6ea5be 100644 --- a/BaseGLProject/MyGLWindow.h +++ b/BaseGLProject/MyGLWindow.h @@ -14,6 +14,8 @@ #include "LineSegment.h" #include "Sphere.h" #include "vboteapot.h" +#include "Plane.h" +#include "Models/Mesh.h" struct vertexAttr { GLfloat posX, posY, posZ; diff --git a/BaseGLProject/Plane.cpp b/BaseGLProject/Plane.cpp new file mode 100644 index 0000000..8a61de6 --- /dev/null +++ b/BaseGLProject/Plane.cpp @@ -0,0 +1,129 @@ +#include "Plane.h" + + +Plane::Plane(int size, int numcell) +{ + this->size = size; + this->ncell = numcell; + + setup(size, numcell); +} + +int nvert2; + +void Plane::setup(float size, int nSquares) +{ + std::vector vlists; + std::vector clists; + + + // parameters: + float maxX = size / 2, maxY = size / 2; + float minX = -size / 2, minY = -size / 2; + + int x, y, v[3], i; + float xp, yp, xd, yd; + v[2] = 0; + xd = (maxX - minX) / ((float)nSquares); + yd = (maxY - minY) / ((float)nSquares); + + + for (x = 0, xp = minX; x < nSquares; x++, xp += xd) { + for (y = 0, yp = minY, i = x; y < nSquares; y++, i++, yp += yd) { + + clists.push_back(glm::vec3(0, 1, 0)); + clists.push_back(glm::vec3(0, 1, 0)); + clists.push_back(glm::vec3(0, 1, 0)); + clists.push_back(glm::vec3(0, 1, 0)); + clists.push_back(glm::vec3(0, 1, 0)); + clists.push_back(glm::vec3(0, 1, 0)); + + + vlists.push_back(glm::vec3(xp, -0.1, yp)); + vlists.push_back(glm::vec3(xp, -0.1, yp + yd)); + vlists.push_back(glm::vec3(xp + xd, -0.1, yp + yd)); + + vlists.push_back(glm::vec3(xp, -0.1, yp)); + vlists.push_back(glm::vec3(xp + xd, -0.1, yp + yd)); + vlists.push_back(glm::vec3(xp + xd, -0.1, yp)); + + + + } // end of for j + }// end of for i + + nvert2 = vlists.size(); + + //create vao + glGenVertexArrays(1, &vaoHandle); + glBindVertexArray(vaoHandle); + + //create vbo for vertices + glGenBuffers(1, &vbo_cube_vertices); + glBindBuffer(GL_ARRAY_BUFFER, vbo_cube_vertices); + glBufferData(GL_ARRAY_BUFFER, sizeof(float)*vlists.size() * 3, vlists.data(), GL_STATIC_DRAW); + glVertexAttribPointer( + 0, // attribute + 3, // number of elements per vertex, here (x,y,z,1) + GL_FLOAT, // the type of each element + GL_FALSE, // take our values as-is + 0, // no extra data between each position + 0 // offset of first element + ); + glEnableVertexAttribArray(0); + + + //create vbo for colors + glGenBuffers(1, &vbo_cube_colors); + glBindBuffer(GL_ARRAY_BUFFER, vbo_cube_colors); + glBufferData(GL_ARRAY_BUFFER, sizeof(float)*clists.size() * 3, clists.data(), GL_STATIC_DRAW); + glVertexAttribPointer( + 1, // attribute + 3, // number of elements per vertex, here (R,G,B) + GL_FLOAT, // the type of each element + GL_FALSE, // take our values as-is + 0, // no extra data between each position + 0 // offset of first element + ); + glEnableVertexAttribArray(1); + + vlists.clear(); + clists.clear(); + + glBindVertexArray(0); +} + +void Plane::resize(int size, int numcell) +{ + setup(size, numcell); +} + +void Plane::draw(ShaderProgram * shader, glm::mat4x4 proj_matrix, glm::mat4x4 view_matrix) +{ + + _model.glPushMatrix(); + effectTransformations(); + glBindVertexArray(vaoHandle); + glm::mat4 mvpMatrix = proj_matrix * view_matrix * _model.getMatrix(); + glUniformMatrix4fv(shader->uniform("mvp"), 1, GL_FALSE, glm::value_ptr(mvpMatrix)); + glm::mat4 modelview = view_matrix * _model.getMatrix(); + shader->addUniform("LightLocation"); + glUniform4fv(shader->uniform("LightLocation"), 1, glm::value_ptr(view_matrix * glm::vec4(0, 15, 0, 1))); + shader->addUniform("LightIntensity"); + glUniform3fv(shader->uniform("LightIntensity"), 1, glm::value_ptr(glm::vec3(0.7, 0.7, 0.7))); + glUniformMatrix4fv(shader->uniform("ModelViewMatrix"), 1, GL_FALSE, glm::value_ptr(modelview)); + glUniform4fv(shader->uniform("LightDirection"), 1, glm::value_ptr(view_matrix * glm::vec4(0, -15, 0, 1))); + glm::mat4 inverseModelView = glm::inverse(modelview); + glm::mat3 normalMatrix = glm::mat3(glm::transpose(inverseModelView)); + glUniformMatrix3fv(shader->uniform("NormalMatrix"), 1, GL_FALSE, glm::value_ptr(normalMatrix)); + + glDrawArrays(GL_TRIANGLES, 0, nvert2 * 3); + glBindVertexArray(0); + + _model.glPopMatrix(); + +} +DrawableType Plane::getType() +{ + return DrawableType::LIGHTED_PLANE; +} \ No newline at end of file diff --git a/BaseGLProject/Plane.h b/BaseGLProject/Plane.h new file mode 100644 index 0000000..f42a1f9 --- /dev/null +++ b/BaseGLProject/Plane.h @@ -0,0 +1,25 @@ +#pragma once + +#include +#include +#include +#include +#include "ADrawable.h" +#include "Loader.h" + +class Plane : public ADrawable +{ +public: + Plane(int size, int numcell); + + virtual void draw(ShaderProgram * shader, glm::mat4x4 proj_matrix, glm::mat4x4 view_matrix) override; + virtual DrawableType getType() override; + + void setup(float size, int nSquares); + void resize(int size, int numcell); + GLuint vaoHandle; + GLuint vbo_cube_vertices, vbo_cube_colors; + + int size; + int ncell; +}; diff --git a/BaseGLProject/Sphere.cpp b/BaseGLProject/Sphere.cpp index 33ca388..396ee17 100644 --- a/BaseGLProject/Sphere.cpp +++ b/BaseGLProject/Sphere.cpp @@ -100,7 +100,7 @@ radius(rad), slices(sl), stacks(st) void Sphere::draw(ShaderProgram *shader, glm::mat4x4 proj_matrix, glm::mat4x4 view_matrix) { - _model.glPushMatrix(); + _model.glPushMatrix(); effectTransformations(); glBindVertexArray(VAO); glm::mat4 mvpMatrix = proj_matrix * view_matrix * _model.getMatrix(); diff --git a/BaseGLProject/light.frag b/BaseGLProject/light.frag new file mode 100644 index 0000000..bc7e5bf --- /dev/null +++ b/BaseGLProject/light.frag @@ -0,0 +1,43 @@ +#version 430 + +in vec3 f_color; +out vec4 FragColors; + +uniform vec3 Kd; +uniform vec3 Ka; +uniform vec3 Ks; +uniform float Shininess; + +struct LightInfo { + vec4 Position; + vec3 Intensity; +}; + +uniform LightInfo Light[5]; + + +in vec3 fNormal; +in vec3 pos; + +void main() +{ + + vec3 finalColor; + vec3 ambient; + + ambient = Ka * Light[0].Intensity; + for (int i=0; i<5; i++) + { + vec3 L = normalize(Light[i].Position.xyz - pos); + vec3 N = fNormal; + vec3 V = normalize(-pos); + //vec3 R = normalize(reflect(-L, N)); + vec3 H = normalize(V + L); + + vec3 diffuse = Kd * Light[i].Intensity * max(dot(L, N), 0.0); + vec3 specular = Ks * Light[i].Intensity * pow(max(dot(H, N), 0.0), Shininess); + finalColor = finalColor + diffuse + specular; + } + + FragColors = vec4(finalColor + ambient, 1); +} diff --git a/BaseGLProject/light.vert b/BaseGLProject/light.vert index 3b9bb93..045956b 100644 --- a/BaseGLProject/light.vert +++ b/BaseGLProject/light.vert @@ -4,39 +4,18 @@ layout(location=0) in vec3 coord3d; layout(location=1) in vec3 v_normal; layout(location=2) in vec3 v_color; -out vec3 f_color; - uniform mat4 mvp; -uniform vec4 LightLocation; - -uniform vec3 Kd; -uniform vec3 Ld; - -uniform vec3 Ka; -uniform vec3 La; - -uniform vec3 Ks; -uniform vec3 Ls; - - uniform mat3 NormalMatrix; uniform mat4 ModelViewMatrix; +out vec3 fNormal; +out vec3 pos; + void main(void) { - vec3 fNormal = normalize(NormalMatrix * v_normal); - vec4 pos = ModelViewMatrix * vec4(coord3d, 1.0); + fNormal = normalize(NormalMatrix * v_normal); + pos = (ModelViewMatrix * vec4(coord3d, 1.0)).xyz; - vec3 L = normalize(LightLocation.xyz - pos.xyz); - vec3 N = fNormal; - vec3 V = normalize(-pos.xyz); - vec3 R = reflect(-L, N); - - vec3 diffuse = Kd * Ld * max(dot(L, N), 0.0); - vec3 ambient = Ka * La; - vec3 specular = Ks * Ls * pow(max(dot(R, V), 0.0), 50.0); - - f_color = diffuse + ambient + specular; gl_Position = mvp * vec4(coord3d, 1.0f); } diff --git a/BaseGLProject/onelight.frag b/BaseGLProject/onelight.frag new file mode 100644 index 0000000..c8a5db9 --- /dev/null +++ b/BaseGLProject/onelight.frag @@ -0,0 +1,62 @@ +#version 430 + +in vec3 f_color; +out vec4 FragColors; + +uniform vec3 Kd; +uniform vec3 Ka; +uniform vec3 Ks; +uniform float Shininess; + +uniform vec4 LightLocation; +uniform vec3 LightIntensity; + +uniform vec4 LightDirection; +uniform float Exponent; +uniform float Cutoff; +uniform float InnerCutoff; + +in vec3 fNormal; +in vec3 pos; + +const float a = 1.0f; +const float b = 0.01f; +const float c = 0.001f; + +void main() +{ + + vec3 LightDir = LightDirection.xyz - LightLocation.xyz; + + vec3 L = LightLocation.xyz - pos; + float d = length(L); + L = normalize(L); + + float attenuation = 1.0f / (a + b * d + c * pow(d, 2)); + float angle = acos(dot(-L, normalize(LightDir))); // radian + float spotAttenuation = 1.0f; + if (angle < radians(InnerCutoff)) + spotAttenuation = 1.0f; + else + { + // pos is outside the spot's inner cutoff + float SpotDot = dot(-L, normalize(LightDir)); + float spotValue = smoothstep(cos(radians(Cutoff)), cos(radians(InnerCutoff)), SpotDot); + spotAttenuation = pow(spotValue, Exponent); + } + attenuation *= spotAttenuation; + + vec3 N = normalize(fNormal); + vec3 V = normalize(-pos); + vec3 H = normalize(V + L); + + float dotNL = max(dot(L, N), 0.0); // for diffuse + float dotHN = max(dot(H, N), 0.0); // for spec + float pf = pow(dotHN, Shininess); // for spec + + vec3 ambient = Ka * LightIntensity * attenuation; + vec3 diffuse = Kd * LightIntensity * dotNL * attenuation; + vec3 specular = Ks * LightIntensity * pf * attenuation; + + FragColors = vec4(diffuse + specular + ambient, 1); +} diff --git a/BaseGLProject/toon.frag b/BaseGLProject/toon.frag new file mode 100644 index 0000000..8023dbc --- /dev/null +++ b/BaseGLProject/toon.frag @@ -0,0 +1,54 @@ +#version 430 + +in vec3 f_color; +out vec4 FragColors; + +uniform vec3 Kd; +uniform vec3 Ka; +uniform vec3 Ks; +uniform float Shininess; + +struct LightInfo { + vec4 Position; + vec3 Intensity; +}; + +uniform LightInfo Light[5]; + + +in vec3 fNormal; +in vec3 pos; + +void main() +{ + + vec3 finalColor; + vec3 ambient; + + ambient = Ka * Light[0].Intensity; + for (int i=0; i<5; i++) + { + vec3 L = normalize(Light[i].Position.xyz - pos); + vec3 N = fNormal; + vec3 V = normalize(-pos); + //vec3 R = normalize(reflect(-L, N)); + vec3 H = normalize(V + L); + + //Discretizing the diffuse component between (here 3) levels + + const int levels = 3; + const float scaleFactor = 1.0 / levels; + float cosine = dot(L, N); // Between 0 and 1 + float value = floor( cosine * levels) * scaleFactor; + + vec3 diffuse = Kd * Light[i].Intensity * max(dot(L, N), 0.0) * value; + + // Not needed for cartoon shader + vec3 specular = Ks * Light[i].Intensity * pow(max(dot(H, N), 0.0), Shininess); + + finalColor = finalColor + diffuse; + + } + + FragColors = vec4(finalColor + ambient, 1); +} diff --git a/BaseGLProject/vboteapot.cpp b/BaseGLProject/vboteapot.cpp index 06a55d5..411bfde 100644 --- a/BaseGLProject/vboteapot.cpp +++ b/BaseGLProject/vboteapot.cpp @@ -90,7 +90,7 @@ VBOTeapot::VBOTeapot(int grid, mat4 lidTransform) void VBOTeapot::draw(ShaderProgram * shader, glm::mat4x4 proj_matrix, glm::mat4x4 view_matrix) { - _model.glPushMatrix(); + _model.glPushMatrix(); effectTransformations(); glBindVertexArray(VAO); glm::mat4 mvpMatrix = proj_matrix * view_matrix * _model.getMatrix();