diff --git a/tests/OpenGL/main.cpp b/tests/OpenGL/main.cpp index 85fa4e9f..556b4c0b 100644 --- a/tests/OpenGL/main.cpp +++ b/tests/OpenGL/main.cpp @@ -14,6 +14,7 @@ #include #include #include +#include const unsigned int SCR_WIDTH = 800; const unsigned int SCR_HEIGHT = 600; @@ -35,6 +36,8 @@ class Shader public: unsigned int ID; + Shader() : ID(0) {} + Shader(const char* vertexPath, const char* fragmentPath, const char* geometryPath = nullptr) { std::string vertexCode; @@ -222,28 +225,51 @@ public: setupMesh(); } + unsigned int defaultTexture = 0; + void Draw(Shader* shader) { + static unsigned int defaultTex = 0; + static bool defaultTexCreated = false; + if (!defaultTexCreated) { + glGenTextures(1, &defaultTex); + unsigned char white[] = {200, 200, 200, 255}; + glBindTexture(GL_TEXTURE_2D, defaultTex); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, white); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + defaultTexCreated = true; + } + unsigned int diffuseNr = 1; unsigned int specularNr = 1; unsigned int normalNr = 1; unsigned int heightNr = 1; - for (unsigned int i = 0; i < textures.size(); i++) + + if (textures.size() == 0) { + glActiveTexture(GL_TEXTURE0); + glUniform1i(glGetUniformLocation(shader->ID, "material.texture_diffuse1"), 0); + glBindTexture(GL_TEXTURE_2D, defaultTex); + } + else { - glActiveTexture(GL_TEXTURE0 + i); - std::string number; - std::string name = textures[i].type; - if (name == "texture_diffuse") - number = std::to_string(diffuseNr++); - else if (name == "texture_specular") - number = std::to_string(specularNr++); - else if (name == "texture_normal") - number = std::to_string(normalNr++); - else if (name == "texture_height") - number = std::to_string(heightNr++); + for (unsigned int i = 0; i < textures.size(); i++) + { + glActiveTexture(GL_TEXTURE0 + i); + std::string number; + std::string name = textures[i].type; + if (name == "texture_diffuse") + number = std::to_string(diffuseNr++); + else if (name == "texture_specular") + number = std::to_string(specularNr++); + else if (name == "texture_normal") + number = std::to_string(normalNr++); + else if (name == "texture_height") + number = std::to_string(heightNr++); - glUniform1i(glGetUniformLocation(shader->ID, ("material." + name + number).c_str()), i); - glBindTexture(GL_TEXTURE_2D, textures[i].id); + glUniform1i(glGetUniformLocation(shader->ID, ("material." + name + number).c_str()), i); + glBindTexture(GL_TEXTURE_2D, textures[i].id); + } } glBindVertexArray(VAO); @@ -300,6 +326,7 @@ unsigned int TextureFromFile(const char* path, const std::string& directory, boo unsigned char* data = stbi_load(filename.c_str(), &width, &height, &nrComponents, 0); if (data) { + std::cout << "Loaded texture: " << filename << " (" << width << "x" << height << ")" << std::endl; GLenum format; if (nrComponents == 1) format = GL_RED; @@ -321,8 +348,26 @@ unsigned int TextureFromFile(const char* path, const std::string& directory, boo } else { - std::cout << "Texture failed to load at path: " << path << std::endl; - stbi_image_free(data); + std::cout << "Texture not found: " << filename << ", trying earth_d.jpg" << std::endl; + std::string fallback = directory + "/earth_d.jpg"; + data = stbi_load(fallback.c_str(), &width, &height, &nrComponents, 0); + if (data) { + std::cout << "Loaded fallback: " << fallback << " (" << width << "x" << height << ")" << std::endl; + GLenum format = nrComponents == 4 ? GL_RGBA : GL_RGB; + glBindTexture(GL_TEXTURE_2D, textureID); + glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, data); + glGenerateMipmap(GL_TEXTURE_2D); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + stbi_image_free(data); + } else { + std::cout << "Fallback also failed, using white" << std::endl; + unsigned char white[] = {200, 200, 200, 255}; + glBindTexture(GL_TEXTURE_2D, textureID); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, white); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + } } return textureID; @@ -673,36 +718,48 @@ void framebuffer_size_callback(GLFWwindow* window, int width, int height) void Initialize() { - camera = new Camera(glm::vec3(-1, 0, 3), 0, 0); + char exePath[MAX_PATH]; + GetModuleFileNameA(NULL, exePath, MAX_PATH); + std::string exeDir = std::string(exePath); + exeDir = exeDir.substr(0, exeDir.find_last_of("\\/")); + + SetCurrentDirectoryA(exeDir.c_str()); + + std::cout << "Working directory: " << exeDir << std::endl; + + camera = new Camera(glm::vec3(0, 0, 3), 0, 0); + std::cout << "Loading model..." << std::endl; model = new Model("res/models/backpack/backpack.obj"); + std::cout << "Model loaded, meshes: " << model->meshes.size() << std::endl; + std::cout << "Textures loaded: " << model->textures_loaded.size() << std::endl; shader = new Shader("Shaders/vertexshader.glsl", "Shaders/fragmentshader.glsl"); + std::cout << "Shader loaded" << std::endl; glEnable(GL_DEPTH_TEST); + glDisable(GL_CULL_FACE); } void Render() { - glClearColor(0, 0, 0, 1.0f); + glClearColor(0.1f, 0.1f, 0.1f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); shader->use(); - Transform(); + + glm::mat4 projection = glm::perspective(glm::radians(45.0f), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f); + glm::mat4 modelMat = glm::mat4(1.0f); + glm::mat4 view = glm::lookAt(glm::vec3(0, 0, 3), glm::vec3(0, 0, 0), glm::vec3(0, 1, 0)); + + shader->setMat4("view", view); + shader->setMat4("model", modelMat); + shader->setMat4("projection", projection); + shader->setVec3("viewPos", glm::vec3(0, 0, 3)); shader->setFloat("material.shininess", 32.0f); - shader->setVec3("dirLight.direction", 0.0f, -1.0f, 0.0f); - shader->setVec3("dirLight.ambient", 0.1f, 0.1f, 0.1f); - shader->setVec3("dirLight.diffuse", 0.4f, 0.4f, 0.4f); + shader->setVec3("dirLight.ambient", 0.3f, 0.3f, 0.3f); + shader->setVec3("dirLight.diffuse", 0.8f, 0.8f, 0.8f); shader->setVec3("dirLight.specular", 0.5f, 0.5f, 0.5f); - - shader->setInt("PointLightNum", 3); - - shader->setVec3("pointLights[0].position", glm::vec3(0.0f, -1.0f, 0.0f)); - shader->setVec3("pointLights[0].ambient", 0.05f, 0.05f, 0.05f); - shader->setVec3("pointLights[0].diffuse", 0.8f, 0.8f, 0.8f); - shader->setVec3("pointLights[0].specular", 1.0f, 1.0f, 1.0f); - shader->setFloat("pointLights[0].constant", 1.0f); - shader->setFloat("pointLights[0].linear", 0.09f); - shader->setFloat("pointLights[0].quadratic", 0.032f); + shader->setInt("PointLightNum", 0); model->Draw(shader); } @@ -710,13 +767,11 @@ void Render() void Transform() { glm::mat4 projection = glm::perspective(glm::radians(45.0f), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f); - origine = glm::rotate(origine, glm::radians(-0.01f), glm::vec3(1.0f, 1.0f, 1.0f)); - glm::mat4 modelMat = origine; - glm::mat4 cameraTrans = camera->GetTrans(); - glm::mat4 view = glm::inverse(cameraTrans); + glm::mat4 modelMat = glm::mat4(1.0f); + glm::mat4 view = glm::lookAt(glm::vec3(0, 0, 3), glm::vec3(0, 0, 0), glm::vec3(0, 1, 0)); shader->setMat4("view", view); shader->setMat4("model", modelMat); shader->setMat4("projection", projection); - shader->setVec3("viewPos", camera->GetPos()); + shader->setVec3("viewPos", glm::vec3(0, 0, 3)); } diff --git a/tests/OpenGL/res/models/backpack/ao.jpg b/tests/OpenGL/res/models/backpack/ao.jpg new file mode 100644 index 00000000..11a2aeec Binary files /dev/null and b/tests/OpenGL/res/models/backpack/ao.jpg differ diff --git a/tests/OpenGL/res/models/backpack/backpack.mtl b/tests/OpenGL/res/models/backpack/backpack.mtl new file mode 100644 index 00000000..f8b974ca --- /dev/null +++ b/tests/OpenGL/res/models/backpack/backpack.mtl @@ -0,0 +1,16 @@ +# Blender MTL File: 'None' +# Material Count: 1 + +newmtl Scene_-_Root +Ns 225.000000 +Ka 1.000000 1.000000 1.000000 +Kd 0.800000 0.800000 0.800000 +Ks 0.500000 0.500000 0.500000 +Ke 0.0 0.0 0.0 +Ni 1.450000 +d 1.000000 +illum 2 +map_Kd diffuse.jpg +map_Bump normal.png +map_Ks specular.jpg + diff --git a/tests/OpenGL/res/models/backpack/diffuse.jpg b/tests/OpenGL/res/models/backpack/diffuse.jpg new file mode 100644 index 00000000..e971a331 Binary files /dev/null and b/tests/OpenGL/res/models/backpack/diffuse.jpg differ diff --git a/tests/OpenGL/res/models/backpack/normal.png b/tests/OpenGL/res/models/backpack/normal.png new file mode 100644 index 00000000..3a8a1030 Binary files /dev/null and b/tests/OpenGL/res/models/backpack/normal.png differ diff --git a/tests/OpenGL/res/models/backpack/roughness.jpg b/tests/OpenGL/res/models/backpack/roughness.jpg new file mode 100644 index 00000000..9f50e674 Binary files /dev/null and b/tests/OpenGL/res/models/backpack/roughness.jpg differ diff --git a/tests/OpenGL/res/models/backpack/source_attribution.txt b/tests/OpenGL/res/models/backpack/source_attribution.txt new file mode 100644 index 00000000..a704b4ae --- /dev/null +++ b/tests/OpenGL/res/models/backpack/source_attribution.txt @@ -0,0 +1,3 @@ +Model by Berk Gedik, from: https://sketchfab.com/3d-models/survival-guitar-backpack-low-poly-799f8c4511f84fab8c3f12887f7e6b36 + +Modified material assignment (Joey de Vries) for easier load in OpenGL model loading chapter, and renamed albedo to diffuse and metallic to specular to match non-PBR lighting setup. \ No newline at end of file diff --git a/tests/OpenGL/res/models/backpack/specular.jpg b/tests/OpenGL/res/models/backpack/specular.jpg new file mode 100644 index 00000000..1fd675a6 Binary files /dev/null and b/tests/OpenGL/res/models/backpack/specular.jpg differ