diff --git a/Images/black.png b/Images/black.png new file mode 100644 index 0000000000000000000000000000000000000000..3cf27f47d2f6feba4ef91b8eba997329bf447d58 Binary files /dev/null and b/Images/black.png differ diff --git a/Images/container2.png b/Images/container2.png new file mode 100644 index 0000000000000000000000000000000000000000..596e8da31ad9bba6f5b2f9db07bff69d9363e507 Binary files /dev/null and b/Images/container2.png differ diff --git a/Images/container2_specular.png b/Images/container2_specular.png new file mode 100644 index 0000000000000000000000000000000000000000..681bf6ef32f8ad13a151bc80d63fd2ce6810bb8a Binary files /dev/null and b/Images/container2_specular.png differ diff --git a/Images/magenta.png b/Images/magenta.png new file mode 100644 index 0000000000000000000000000000000000000000..d325aa25cada98b13e07d5e7c2db48debcd82641 Binary files /dev/null and b/Images/magenta.png differ diff --git a/Images/orange.png b/Images/orange.png new file mode 100644 index 0000000000000000000000000000000000000000..664c14b677a106f9a40bfca542c864d923db8b96 Binary files /dev/null and b/Images/orange.png differ diff --git a/Images/white.png b/Images/white.png new file mode 100644 index 0000000000000000000000000000000000000000..818c71d03f435db011069584cda25c1f66af1a85 Binary files /dev/null and b/Images/white.png differ diff --git a/LearnOpenGL/OpenGLWrapper.cpp b/LearnOpenGL/OpenGLWrapper.cpp index ee357c0f574664e6793714d3439236d65859c68a..4d39a5cf0887e79728043cd747abc2466e9d0576 100644 --- a/LearnOpenGL/OpenGLWrapper.cpp +++ b/LearnOpenGL/OpenGLWrapper.cpp @@ -38,6 +38,27 @@ void draw_mesh(Mesh &mesh) glBindVertexArray(0); } +Material::Material(GLuint _prog, GLuint _diffuseMap, GLuint _specularMap) +{ + prog = _prog; + + diffuseMap = _diffuseMap; + specularMap = _specularMap; +} + +GLuint Material::get_program() +{ + return prog; +} +GLuint Material::get_diffuseMap() +{ + return diffuseMap; +} +GLuint Material::get_specularMap() +{ + return specularMap; +} + RenderObject::RenderObject(Mesh * _mesh) { translate = glm::vec3(0.0f, 0.0f, 0.0f); @@ -49,9 +70,9 @@ RenderObject::RenderObject(Mesh * _mesh) update_model_matrix(); } -GLuint RenderObject::get_programs() +Material *RenderObject::get_material() { - return prog; + return material; } GLuint RenderObject::get_vertex_count() @@ -111,31 +132,44 @@ void RenderObject::move(glm::vec3 _direction, glm::vec1 _velocity) update_model_matrix(); } -void RenderObject::set_program(GLuint _prog) +void RenderObject::set_material(Material *_material) { - prog = _prog; + material = _material; } void RenderObject::render(Camera &camera) { + auto prog = material->get_program(); glUseProgram(prog); - auto objectColor = glm::vec3(1.0f, 0.5f, 0.31f); - set_uniform_value(prog, "objectColor", objectColor); - - auto lightColor = glm::vec3(1.0f, 1.0f, 1.0f); - set_uniform_value(prog, "lightColor", lightColor); - set_uniform_value(prog, "lightPos", _lightPos); + set_uniform_value(prog, "light.position", _lightPos); set_uniform_value(prog, "viewPos", camera.Position); - glm::mat4 projection = glm::perspective(glm::radians(camera.Zoom), (float)_SCR_WIDTH / (float)_SCR_HEIGHT, 0.1f, 100.0f); - set_uniform_value(prog, "projection", projection); + glm::vec3 a = { 0.2f, 0.2f, 0.2f }; + glm::vec3 d = { 0.5f, 0.5f, 0.5f }; + glm::vec3 f = { 1.0f, 1.0f, 1.0f }; + set_uniform_value(prog, "light.ambient", a); + set_uniform_value(prog, "light.diffuse", d); + set_uniform_value(prog, "light.specular", f); + + set_uniform_value(prog, "material.shininess", glm::fvec1{ 64.0f }); + glm::mat4 projection = glm::perspective(glm::radians(camera.Zoom), (float)_SCR_WIDTH / (float)_SCR_HEIGHT, 0.1f, 100.0f); glm::mat4 view = camera.GetViewMatrix(); + set_uniform_value(prog, "projection", projection); set_uniform_value(prog, "view", view); - set_uniform_value(prog, "model", model); + { + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, material->get_diffuseMap()); + } + + { + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, material->get_specularMap()); + } + draw_mesh(*mesh); glUseProgram(0); @@ -143,7 +177,7 @@ void RenderObject::render(Camera &camera) RenderObject *make_render_object(Mesh *mesh) { - RenderObject *ro = new RenderObject{ mesh }; + RenderObject *ro = new RenderObject(mesh); return ro; }; @@ -320,12 +354,13 @@ GLuint allocate_VAO() Mesh *make_mesh(const std::string fileName) { std::vector<glm::vec3> vertices; + std::vector<glm::vec3> vertexTexCoord; std::vector<glm::vec3> vertexNormals; const std::string ext = get_extension(fileName); if (ext.compare("obj") == 0) { - openObj(fileName, vertices, vertexNormals); + openObj(fileName, vertices, vertexTexCoord, vertexNormals); } else { @@ -334,6 +369,10 @@ Mesh *make_mesh(const std::string fileName) std::vector<std::vector<glm::vec3> *> vertexInfo; vertexInfo.push_back(&vertices); + if (vertexTexCoord.size() > 0) + { + vertexInfo.push_back(&vertexTexCoord); + } if (vertexNormals.size() > 0) { vertexInfo.push_back(&vertexNormals); diff --git a/LearnOpenGL/OpenGLWrapper.h b/LearnOpenGL/OpenGLWrapper.h index d15dd3cf45cc679d409bac736ea6d65855d09e2a..bed0e34268606a5f5cf135981a76de5ccbe92f46 100644 --- a/LearnOpenGL/OpenGLWrapper.h +++ b/LearnOpenGL/OpenGLWrapper.h @@ -27,12 +27,32 @@ public: }; void draw_mesh(Mesh &mesh); +class Material +{ +private: + GLuint prog; + + GLuint diffuseMap; + GLuint specularMap; + GLuint ambientMap; + +public: + Material(GLuint _prog, GLuint _diffuseMap, GLuint _specularMap); + + GLuint get_program(); + + GLuint get_diffuseMap(); + GLuint get_specularMap(); +}; + class RenderObject { private: GLuint id; - GLuint prog; + Mesh *mesh; + Material *material; + glm::mat4 model; glm::vec3 translate; @@ -44,7 +64,7 @@ private: public: RenderObject(Mesh * _mesh); - GLuint get_programs(); + Material *get_material(); GLuint get_vertex_count(); glm::mat4 get_model_matrix(); @@ -55,7 +75,7 @@ public: void move(glm::vec3 _delta); void move(glm::vec3 _direction, glm::vec1 _velocity); - void set_program(GLuint _prog); + void set_material(Material *_material); void render(Camera &camera); }; diff --git a/LearnOpenGL/ResourceLoader.cpp b/LearnOpenGL/ResourceLoader.cpp index a279d5c97c53a0559730acc028bfeedf19691127..07853fc7c476c743270ba2264628985b17ef0313 100644 --- a/LearnOpenGL/ResourceLoader.cpp +++ b/LearnOpenGL/ResourceLoader.cpp @@ -31,17 +31,18 @@ std::string get_extension(const std::string &filePath) return filePath.substr(filePath.find_last_of(".") + 1); } -bool openObj(const std::string fileName, std::vector<glm::vec3> &vertices, std::vector<glm::vec3> &vertexNormals) +bool openObj(const std::string fileName, std::vector<glm::vec3> &vertices, std::vector<glm::vec3> &vertexTexCoord, std::vector<glm::vec3> &vertexNormals) { vertices.clear(); + vertexTexCoord.clear(); vertexNormals.clear(); std::ifstream ifs; std::string line; char op[3]; - glm::vec3 pos; std::vector<glm::vec3> vertexIndices; + std::vector<glm::vec3> vertexTexCoordIndices; std::vector<glm::vec3> vertexNormalIndices; ifs.open("../Models/" + fileName); @@ -53,8 +54,6 @@ bool openObj(const std::string fileName, std::vector<glm::vec3> &vertices, std:: sscanf_s(line.c_str(), "%s", op, sizeof(op)); - pos.x = 0; pos.y = 0; pos.z = 0; - charPos = 0; if ((charPos = line.find(' ')) != std::string::npos) { @@ -63,23 +62,28 @@ bool openObj(const std::string fileName, std::vector<glm::vec3> &vertices, std:: if (strcmp(op, "v") == false) { + glm::vec3 pos = { 0,0,0 }; sscanf_s(line.c_str(), "%f %f %f", &pos.x, &pos.y, &pos.z); vertexIndices.push_back(pos); } else if (strcmp(op, "vn") == false) { + glm::vec3 pos = { 0,0,0 }; sscanf_s(line.c_str(), "%f %f %f", &pos.x, &pos.y, &pos.z); vertexNormalIndices.push_back(pos); } else if (strcmp(op, "vt") == false) { - // TODO : texCoord + glm::vec3 pos = { 0,0,0 }; + sscanf_s(line.c_str(), "%f %f", &pos.x, &pos.y); + vertexTexCoordIndices.push_back(pos); } if (strncmp(op, "f", 1) == false) { int vIndex = 0, uvIndex = 0, vnIndex = 0; std::vector<int> faceVertexIndicies; + std::vector<int> faceVertexTexCoordIndicies; std::vector<int> faceVertexNormalIndicies; charPos = 0; @@ -88,7 +92,14 @@ bool openObj(const std::string fileName, std::vector<glm::vec3> &vertices, std:: sscanf_s(line.substr(0, charPos).c_str(), "%d%*[-/]%d%*[-/]%d", &vIndex, &uvIndex, &vnIndex); line.erase(0, charPos + 1); - faceVertexIndicies.push_back(vIndex - 1); + if (vIndex >= 1) + { + faceVertexIndicies.push_back(vIndex - 1); + } + if (uvIndex >= 1) + { + faceVertexTexCoordIndicies.push_back(uvIndex - 1); + } if (vnIndex >= 1) { faceVertexNormalIndicies.push_back(vnIndex - 1); @@ -114,7 +125,29 @@ bool openObj(const std::string fileName, std::vector<glm::vec3> &vertices, std:: else { GLchar infoLog[512] = { 0, }; - log_warn(infoLog, "faceVertexIndices.size() : " + std::to_string(faceVertexIndicies.size())); + log_warn(infoLog, fileName + " : " + "faceVertexIndices.size() : " + std::to_string(faceVertexIndicies.size())); + } + + if (faceVertexTexCoordIndicies.size() == 3) + { + vertexTexCoord.push_back(vertexTexCoordIndices[faceVertexTexCoordIndicies[0]]); + vertexTexCoord.push_back(vertexTexCoordIndices[faceVertexTexCoordIndicies[1]]); + vertexTexCoord.push_back(vertexTexCoordIndices[faceVertexTexCoordIndicies[2]]); + } + else if (faceVertexTexCoordIndicies.size() == 4) + { + vertexTexCoord.push_back(vertexTexCoordIndices[faceVertexTexCoordIndicies[0]]); + vertexTexCoord.push_back(vertexTexCoordIndices[faceVertexTexCoordIndicies[1]]); + vertexTexCoord.push_back(vertexTexCoordIndices[faceVertexTexCoordIndicies[2]]); + + vertexTexCoord.push_back(vertexTexCoordIndices[faceVertexTexCoordIndicies[0]]); + vertexTexCoord.push_back(vertexTexCoordIndices[faceVertexTexCoordIndicies[2]]); + vertexTexCoord.push_back(vertexTexCoordIndices[faceVertexTexCoordIndicies[3]]); + } + else + { + GLchar infoLog[512] = { 0, }; + log_warn(infoLog, fileName + " : " + "vertexTexCoordIndices.size() : " + std::to_string(faceVertexTexCoordIndicies.size())); } if (faceVertexNormalIndicies.size() == 3) @@ -136,7 +169,7 @@ bool openObj(const std::string fileName, std::vector<glm::vec3> &vertices, std:: else { GLchar infoLog[512] = { 0, }; - log_warn(infoLog, "faceVertexNormalIndices.size() : " + std::to_string(faceVertexNormalIndicies.size())); + log_warn(infoLog, fileName + " : " + "faceVertexNormalIndices.size() : " + std::to_string(faceVertexNormalIndicies.size())); } } } diff --git a/LearnOpenGL/ResourceLoader.h b/LearnOpenGL/ResourceLoader.h index 1086e7e0636c30a9381198ee9e5c659b0e0ccead..5123afe10061e087c74a4c13added1a5331512a0 100644 --- a/LearnOpenGL/ResourceLoader.h +++ b/LearnOpenGL/ResourceLoader.h @@ -6,7 +6,10 @@ #include <vector> #include <GL/glew.h> -#include <glm/vec3.hpp> + +#include <glm/glm.hpp> +#include <glm/gtc/matrix_transform.hpp> +#include <glm/gtc/type_ptr.hpp> #include "Logger.h" @@ -28,6 +31,6 @@ public: }; std::string get_extension(const std::string &filePath); -bool openObj(const std::string fileName, std::vector<glm::vec3> &vertices, std::vector<glm::vec3> &vertexNormals); +bool openObj(const std::string fileName, std::vector<glm::vec3> &vertices, std::vector<glm::vec3> &vertexTexCoord, std::vector<glm::vec3> &vertexNormals); Image *load_Image(std::string fileName, int *width, int *height, int *nrChannels); void free_image(Image *img); \ No newline at end of file diff --git a/LearnOpenGL/Source.cpp b/LearnOpenGL/Source.cpp index c55e0089e8b23b6963c88dee9161c7988208bc62..b711dd2257d7d66f1292e00943ad8b41e1c83f86 100644 --- a/LearnOpenGL/Source.cpp +++ b/LearnOpenGL/Source.cpp @@ -55,17 +55,25 @@ int main() auto cam_programID = build_program("Camera"); auto lighting = build_program("Lighting_Specular"); auto lamp = build_program("Lighting_Lamp"); + auto lightmap = build_program("Lighting_Maps"); auto texture_shader = build_program("Texture"); auto cube = make_mesh("cube.obj"); + auto black = load_image("black.png"); + auto magenta = load_image("magenta.png"); + auto orange = load_image("orange.png"); + auto white = load_image("white.png"); + + auto defaultMaterial = new Material(lightmap, orange, white); + auto teapot = make_render_object(make_mesh("teapot.obj")); { teapot->set_translate(glm::vec3(0.0f, -10.0f, -40.0f)); teapot->set_rotate(glm::vec3(-90.0f, 0.0f, 0.0f)); } { - teapot->set_program(lighting); + teapot->set_material(defaultMaterial); } auto cube1 = make_render_object(cube); @@ -75,7 +83,7 @@ int main() cube1->set_scale(glm::vec3(10, 10, 4)); } { - cube1->set_program(lighting); + cube1->set_material(defaultMaterial); } auto cube2 = make_render_object(cube); @@ -85,7 +93,7 @@ int main() cube2->set_scale(glm::vec3(12, 12, 1)); } { - cube2->set_program(lighting); + cube2->set_material(defaultMaterial); } auto plane = make_render_object(make_mesh("plane.obj")); @@ -93,7 +101,7 @@ int main() plane->set_scale(glm::vec3(10, 10, 1)); } { - plane->set_program(lighting); + plane->set_material(defaultMaterial); } auto cube3 = make_render_object(cube); @@ -103,16 +111,7 @@ int main() cube3->set_scale(glm::vec3(50, 50, 0.5)); } { - cube3->set_program(lighting); - } - - GLuint textureID; - { - textureID = load_image("container.jpg"); - - glUseProgram(texture_shader); - - set_uniform_value(texture_shader, "texture1", glm::ivec1(0)); + cube3->set_material(defaultMaterial); } while (!glfwWindowShouldClose(window)) @@ -127,20 +126,13 @@ int main() glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); { - glUseProgram(texture_shader); - - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, textureID); - - glUseProgram(0); + teapot->render(camera); + cube1->render(camera); + cube2->render(camera); + cube3->render(camera); + plane->render(camera); } - teapot->render(camera); - cube1->render(camera); - cube2->render(camera); - cube3->render(camera); - plane->render(camera); - glfwSwapBuffers(window); glfwPollEvents(); } diff --git a/Shaders/Lighting_Maps/Lighting_Maps.frag b/Shaders/Lighting_Maps/Lighting_Maps.frag new file mode 100644 index 0000000000000000000000000000000000000000..fdab7e521fb0400fdb86ad700f932bce33750532 --- /dev/null +++ b/Shaders/Lighting_Maps/Lighting_Maps.frag @@ -0,0 +1,47 @@ +#version 330 core +out vec4 FragColor; + +struct Material +{ + sampler2D diffuse; + sampler2D specular; + float shininess; +}; + +struct Light +{ + vec3 position; + + vec3 ambient; + vec3 diffuse; + vec3 specular; +}; + +in vec3 FragPos; +in vec3 Normal; +in vec2 TexCoords; + +uniform vec3 viewPos; +uniform Material material; +uniform Light light; + +void main() +{ + // ambient + vec3 ambient = light.ambient * texture(material.diffuse, TexCoords).rgb; + + // diffuse + vec3 norm = normalize(Normal); + vec3 lightDir = normalize(light.position - FragPos); + float diff = max(dot(norm, lightDir), 0.0); + vec3 diffuse = light.diffuse * diff * texture(material.diffuse, TexCoords).rgb; + + // specular + vec3 viewDir = normalize(viewPos - FragPos); + vec3 reflectDir = reflect(-lightDir, norm); + float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); + vec3 specular = light.specular * spec * texture(material.specular, TexCoords).rgb; + + vec3 result = ambient + diffuse + specular; + FragColor = vec4(result, 1.0); +} \ No newline at end of file diff --git a/Shaders/Lighting_Maps/Lighting_Maps.vert b/Shaders/Lighting_Maps/Lighting_Maps.vert new file mode 100644 index 0000000000000000000000000000000000000000..c3142455e70b791c54c23393b79075d3e58eda57 --- /dev/null +++ b/Shaders/Lighting_Maps/Lighting_Maps.vert @@ -0,0 +1,21 @@ +#version 330 core +layout (location = 0) in vec3 aPos; +layout (location = 1) in vec3 aNormal; +layout (location = 2) in vec2 aTexCoords; + +out vec3 FragPos; +out vec3 Normal; +out vec2 TexCoords; + +uniform mat4 model; +uniform mat4 view; +uniform mat4 projection; + +void main() +{ + FragPos = vec3(model * vec4(aPos, 1.0)); + Normal = mat3(transpose(inverse(model))) * aNormal; + TexCoords = aTexCoords; + + gl_Position = projection * view * vec4(FragPos, 1.0); +} \ No newline at end of file