Sponza рэндэрлэх оролдлого 5, unreferenced textures

Sponza модел бол график програмистууд, оюутанууд, судлаачдийн дунд хамгийн их нэрд гарсан 3D модел юм. Дотроо гоёмсог текстуруудээс гадна гэрлийн тооцоололд хэрэглэхэд шаардлагатай текстуруудээр хангаж өгсөн байдгаараа онцлог.


Гэвч Crytek ийн сайт дээр татахаар байдаг sponza моделийн mtl файл буюу материалын тодорхойлолтонд нь Opacity, Specular текстуруудыг нь зааж өгөөгүй байдаг юм байна. Opacity-г masking, color key байдлаар хэрэглэх текстур гэж ойлгодог өөрөөр хэлбэл текстурээс шаардлагатай хэсгийг нь тайрч авах гэвэл болох байх. Харин Specular текстурыг тухайн объект дээр гэрэлтүүлгийн тооцоолол хийх үед хэр их intensity-тэй буюу хэр их хэмжээний тод specular ойлт нь харагдах вэб гэдэг мэдээллийг агуулдаг.

хэсэг гүүглэдвэл иймэрхүү асуудалтай тулгарч байсан хүмүүс байдаг юм байна. Тэгээд бас блог бичсэн байна. Sponza-ийн засагдсан mtl файлыг нь татахыг хүсвэл ЭНЭ хаягаас орж татаарай.

Ерөнхийдөө дараах 5-н төрлийн текстуруудыг sponza ашиглаж байгааг мэдлээ :

  • Diffuse
  • Normal
  • Ambient
  • Specular
  • Opacity

эд нар болно. Тиймээс материал тодорхойлсон соорс кодонд маань ч гэсэн эдгээрийг ачаалах багахан өөрчлөлт орсон.

Material.hpp
#ifndef MATERIAL_HPP
#define MATERIAL_HPP

#include <GL/glew.h>
#include <glm/glm.hpp>
#include <string>

class Material {
public:
    Material();
    ~Material();

    glm::vec4 getDiffuseColor() {
        return this->diffuseColor;
    };

    void setDiffuseColor(glm::vec4 color) {
        this->diffuseColor = color;
    }

    glm::vec3 getAmbientColor() {
        return this->ambientColor;
    }

    void setAmbientColor(glm::vec3 color) {
        this->ambientColor = color;
    }

    glm::vec3 getSpecularColor() {
        return this->specularColor;
    }

    void setSpecularColor(glm::vec3 color) {
        this->specularColor = color;
    }

    glm::vec3 getEmissiveColor() {
        return this->emissiveColor;
    }

    void setEmissiveColor(glm::vec3 color) {
        this->emissiveColor = color;
    }

    float getShininess() {
        return this->shininess;
    }

    void setShininess(float shininess) {
        this->shininess = shininess;
    }

    GLuint getDiffuseTextureID() {
        return this->diffuseTextureID;
    }

    void setDiffuseTextureID(GLuint diffuseTextureID) {
        this->diffuseTextureID = diffuseTextureID;
    }

    GLuint getNormalTextureID() {
        return this->normalTextureID;
    }

    void setNormalTextureID(GLuint normalTextureID) {
        this->normalTextureID = normalTextureID;
    }

    GLuint getSpecularTextureID() {
        return this->specularTextureID;
    }

    void setSpecularTextureID(GLuint specularTextureID) {
        this->specularTextureID = specularTextureID;
    }

    GLuint getAmbientTextureID() {
        return this->ambientTextureID;
    }

    void setAmbientTextureID(GLuint ambientTextureID) {
        this->ambientTextureID = ambientTextureID;
    }

    GLuint getOpacityTextureID() {
        return this->opacityTextureID;
    }

    void setOpacityTextureID(GLuint opacityTextureID) {
        this->opacityTextureID = opacityTextureID;
    }

    void loadDiffuseTexture(const std::string &path);
    void loadNormalTexture(const std::string &path);
    void loadSpecularTexture(const std::string &path);
    void loadAmbientTexture(const std::string &path);
    void loadOpacityTexture(const std::string &path);

    void bindMaterial(GLuint programID);
    void unbindMaterial();

private:
    glm::vec4 diffuseColor;
    glm::vec3 ambientColor;
    glm::vec3 specularColor;
    glm::vec3 emissiveColor;
    float shininess;
    GLuint diffuseTextureID;
    GLuint normalTextureID;
    GLuint specularTextureID;
    GLuint ambientTextureID;
    GLuint opacityTextureID;
};

#endif /* MATERIAL_HPP */

Material.cpp
#include "Material.hpp"
#include "SOIL.h"
#include <glm/gtc/type_ptr.hpp>
#include <iostream>

Material::Material() {
    this->diffuseColor = glm::vec4(0.5, 0.5, 0.5, 1.0); // Medium-gray
    this->ambientColor = glm::vec3(0.5); // Medium-gray 
    this->specularColor = glm::vec3(0.0); // No specular
    this->emissiveColor = glm::vec3(0.0); // No emission
    this->shininess = 0.5;
}

Material::~Material() {
    glDeleteTextures(1, &this->diffuseTextureID);
    glDeleteTextures(1, &this->normalTextureID);
    glDeleteTextures(1, &this->specularTextureID);
    glDeleteTextures(1, &this->ambientTextureID);
    glDeleteTextures(1, &this->opacityTextureID);
    std::cout << "Material destructor function" << std::endl;
}

void Material::loadDiffuseTexture(const std::string& path) {
    this->diffuseTextureID = SOIL_load_OGL_texture(
            path.c_str(),
            SOIL_LOAD_AUTO,
            SOIL_CREATE_NEW_ID,
            SOIL_FLAG_POWER_OF_TWO
            | SOIL_FLAG_MIPMAPS
            | SOIL_FLAG_MULTIPLY_ALPHA
            | SOIL_FLAG_COMPRESS_TO_DXT
            | SOIL_FLAG_DDS_LOAD_DIRECT
            | SOIL_FLAG_INVERT_Y
            );
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);

    glBindTexture(GL_TEXTURE_2D, 0);
}

void Material::loadNormalTexture(const std::string& path) {
    this->normalTextureID = SOIL_load_OGL_texture(
            path.c_str(),
            SOIL_LOAD_AUTO,
            SOIL_CREATE_NEW_ID,
            SOIL_FLAG_POWER_OF_TWO
            | SOIL_FLAG_MIPMAPS
            | SOIL_FLAG_MULTIPLY_ALPHA
            | SOIL_FLAG_COMPRESS_TO_DXT
            | SOIL_FLAG_DDS_LOAD_DIRECT
            | SOIL_FLAG_INVERT_Y
            );
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    glBindTexture(GL_TEXTURE_2D, 0);
}

void Material::loadSpecularTexture(const std::string& path) {
    this->specularTextureID = SOIL_load_OGL_texture(
            path.c_str(),
            SOIL_LOAD_AUTO,
            SOIL_CREATE_NEW_ID,
            SOIL_FLAG_POWER_OF_TWO
            | SOIL_FLAG_MIPMAPS
            | SOIL_FLAG_MULTIPLY_ALPHA
            | SOIL_FLAG_COMPRESS_TO_DXT
            | SOIL_FLAG_DDS_LOAD_DIRECT
            | SOIL_FLAG_INVERT_Y
            );
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    glBindTexture(GL_TEXTURE_2D, 0);
}

void Material::loadAmbientTexture(const std::string& path) {
    this->ambientTextureID = SOIL_load_OGL_texture(
            path.c_str(),
            SOIL_LOAD_AUTO,
            SOIL_CREATE_NEW_ID,
            SOIL_FLAG_POWER_OF_TWO
            | SOIL_FLAG_MIPMAPS
            | SOIL_FLAG_MULTIPLY_ALPHA
            | SOIL_FLAG_COMPRESS_TO_DXT
            | SOIL_FLAG_DDS_LOAD_DIRECT
            | SOIL_FLAG_INVERT_Y
            );
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    glBindTexture(GL_TEXTURE_2D, 0);
}

void Material::loadOpacityTexture(const std::string& path) {
    this->opacityTextureID = SOIL_load_OGL_texture(
            path.c_str(),
            SOIL_LOAD_AUTO,
            SOIL_CREATE_NEW_ID,
            SOIL_FLAG_POWER_OF_TWO
            | SOIL_FLAG_MIPMAPS
            | SOIL_FLAG_MULTIPLY_ALPHA
            | SOIL_FLAG_COMPRESS_TO_DXT
            | SOIL_FLAG_DDS_LOAD_DIRECT
            | SOIL_FLAG_INVERT_Y
            );
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    glBindTexture(GL_TEXTURE_2D, 0);
}

void Material::bindMaterial(GLuint programID) {
    GLuint diffuseTextureUniformID = glGetUniformLocation(programID, "material_diffuse_texture");
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, this->diffuseTextureID);
    glUniform1i(diffuseTextureUniformID, 0);

    GLuint normalTextureUniformID = glGetUniformLocation(programID, "material_normal_texture");
    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, this->normalTextureID);
    glUniform1i(normalTextureUniformID, 1);

    GLuint specularTextureUniformID = glGetUniformLocation(programID, "material_specular_texture");
    glActiveTexture(GL_TEXTURE2);
    glBindTexture(GL_TEXTURE_2D, this->specularTextureID);
    glUniform1i(specularTextureUniformID, 2);

    GLuint ambientTextureUniformID = glGetUniformLocation(programID, "material_ambient_texture");
    glActiveTexture(GL_TEXTURE3);
    glBindTexture(GL_TEXTURE_2D, this->ambientTextureID);
    glUniform1i(ambientTextureUniformID, 3);
    
    GLuint opacityTextureUniformID = glGetUniformLocation(programID, "material_opacity_texture");
    glActiveTexture(GL_TEXTURE4);
    glBindTexture(GL_TEXTURE_2D, this->opacityTextureID);
    glUniform1i(opacityTextureUniformID, 4);

    GLuint shininessUniformID = glGetUniformLocation(programID, "material_shininess");
    glUniform1f(shininessUniformID, this->shininess);

    GLuint diffuseColorUniformID = glGetUniformLocation(programID, "material_diffuse_color");
    glUniform4fv(diffuseColorUniformID, 1, glm::value_ptr(this->diffuseColor));
}

void Material::unbindMaterial() {
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, 0);
    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, 0);
    glActiveTexture(GL_TEXTURE2);
    glBindTexture(GL_TEXTURE_2D, 0);
    glActiveTexture(GL_TEXTURE3);
    glBindTexture(GL_TEXTURE_2D, 0);
    glActiveTexture(GL_TEXTURE4);
    glBindTexture(GL_TEXTURE_2D, 0);
}

Main.cpp
#include <cstdlib>
#include <string>
#include <iostream>
#include <assimp/Importer.hpp>
#include <assimp/scene.h>
#include <assimp/postprocess.h>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <glm/gtx/constants.hpp>
#include "MaterialManager.hpp"
#include "Material.hpp"
#include "ShaderManager.hpp"
#include "Shader.hpp"
#include "SceneObject.hpp"

using namespace std;


GLFWwindow *window;
int windowWidth = 1000;
int windowHeight = 800;

bool wKeyPressed;
bool sKeyPressed;
bool aKeyPressed;
bool dKeyPressed;
double mouseX, mouseY;
float speed = 150.09f;
float mouseSpeed = 0.04f;
glm::vec3 position = glm::vec3(0, 0, 5);
glm::vec3 direction;
//glm::vec3 right;
glm::vec3 up;
float horizontalAngle = 3.14159f;
float verticalAngle = 0.0f;
float fov = 60.0f;

glm::mat4 modelMatrix;
glm::mat4 viewMatrix;
glm::mat4 projectionMatrix;

void initWindow();
void disposeWindow();
void handleKeyboardInput(GLFWwindow *window, int key, int scancode, int action, int mods);
void processInput(float dt);

void processMaterial(aiMaterial* material, int index);
void processMesh(aiMesh* mesh, SceneObject *object);

/*
 * experiment with ASSIMP
 */
int main(int argc, char** argv) {
    initWindow();
    glfwSetKeyCallback(window, handleKeyboardInput);
    MaterialManager::getSingleton();
    ShaderManager* sm = ShaderManager::getSingleton();
    sm->CreateShaderProgram("phong");
    sm->AttachShader("phongVertex", VERTEX);
    sm->AttachShader("phongFragment", FRAGMENT);
    sm->LoadShaderSource("phongVertex", "shaders/phong.vert.glsl");
    sm->LoadShaderSource("phongFragment", "shaders/phong.frag.glsl");
    sm->CompileShader("phongVertex");
    sm->CompileShader("phongFragment");
    sm->AttachShaderToProgram("phong", "phongVertex");
    sm->AttachShaderToProgram("phong", "phongFragment");
    sm->LinkProgramObject("phong");
    std::cout << "ShaderProgram ID is " << (*sm)["phong"]->GetID() << std::endl;

    glEnable(GL_TEXTURE_2D);
    glEnable(GL_ALPHA_TEST);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    SceneObject *sceneObject = new SceneObject();
    std::string filePath = "sponza.obj";
    Assimp::Importer importer;
    const aiScene *scene = importer.ReadFile(
            filePath.c_str(),
            aiProcess_OptimizeGraph |
            aiProcess_OptimizeMeshes |
            aiProcess_ImproveCacheLocality |
            aiProcess_SplitLargeMeshes |
            aiProcess_Triangulate |
            aiProcess_JoinIdenticalVertices |
            aiProcess_SortByPType
            );
    if (!scene) {
        std::cout << "error in loading file : " << importer.GetErrorString() << std::endl;
        return 1;
    }
    for (unsigned int i = 0; i < scene->mNumMaterials; i++) {
        processMaterial(scene->mMaterials[i], i);
    }
    for (unsigned int i = 0; i < scene->mNumMeshes; i++) {
        processMesh(scene->mMeshes[i], sceneObject);
    }

    SceneObject *carObject = new SceneObject();
    filePath = "phoenix_ugv.md2";
    scene = importer.ReadFile(
            filePath.c_str(),
            aiProcess_OptimizeGraph |
            aiProcess_OptimizeMeshes |
            aiProcess_ImproveCacheLocality |
            aiProcess_SplitLargeMeshes |
            aiProcess_Triangulate |
            aiProcess_JoinIdenticalVertices |
            aiProcess_SortByPType
            );
    if (!scene) {
        std::cout << "error in loading file : " << importer.GetErrorString() << std::endl;
        return 1;
    }
    for (unsigned int i = 0; i < scene->mNumMaterials; i++) {
        processMaterial(scene->mMaterials[i], i);
    }
    for (unsigned int i = 0; i < scene->mNumMeshes; i++) {
        processMesh(scene->mMeshes[i], carObject);
    }

    projectionMatrix = glm::mat4(1.0f);
    viewMatrix = glm::mat4(1.0f);
    viewMatrix = glm::translate(viewMatrix, glm::vec3(0, 0, -2));
    glViewport(0, 0, (int) windowWidth, (int) windowHeight);
    projectionMatrix = glm::perspective(60.0f, (float) windowWidth / windowHeight, 1.0f, 10000.0f);

    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LESS);
    glEnable(GL_CULL_FACE);
    glCullFace(GL_BACK);
    glFrontFace(GL_CCW);


    GLuint programID = (*sm)["phong"]->GetID();
    float deltaTime = 0.0f;
    float startTime = glfwGetTime();
    float buffTime = 0.0;
    int counter = 0;
    while (!glfwWindowShouldClose(window)) {
        processInput(deltaTime);
        glClearColor(0.0f, 0.5f, 1.0f, 0.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glUseProgram(programID);
        glUniformMatrix4fv(glGetUniformLocation(programID, "viewMatrix"), 1, GL_FALSE, glm::value_ptr(viewMatrix));
        glUniformMatrix4fv(glGetUniformLocation(programID, "projectionMatrix"), 1, GL_FALSE, glm::value_ptr(projectionMatrix));
        sceneObject->render();
        glUseProgram(0);

        glUseProgram(programID);
        glUniformMatrix4fv(glGetUniformLocation(programID, "viewMatrix"), 1, GL_FALSE, glm::value_ptr(viewMatrix));
        glUniformMatrix4fv(glGetUniformLocation(programID, "projectionMatrix"), 1, GL_FALSE, glm::value_ptr(projectionMatrix));
        carObject->render();
        glUseProgram(0);

        glfwSwapBuffers(window);
        glfwPollEvents();
        double lastTime = glfwGetTime();
        deltaTime = lastTime - startTime;
        startTime = lastTime;
        counter++;
        buffTime += deltaTime;
        if (buffTime > 1.0f) {
            buffTime = 0.0f;
            cout << "fps " << counter << endl;
            counter = 0;
        }
    }

    delete sceneObject;
    delete carObject;
    delete MaterialManager::getSingleton();
    delete ShaderManager::getSingleton();
    disposeWindow();
    return 0;
}

void processMesh(aiMesh* mesh, SceneObject *object) {
    if (mesh->mMaterialIndex == 5)
        return;
    float *normals, *textureCoordinates;
    float *vertices = (float *) malloc(4 * mesh->mNumVertices * sizeof (float));
    if (mesh->HasNormals())
        normals = (float *) malloc(3 * mesh->mNumVertices * sizeof (float));
    if (mesh->HasTextureCoords(0))
        textureCoordinates = (float *) malloc(2 * mesh->mNumVertices * sizeof (float));
    for (unsigned int i = 0; i < mesh->mNumVertices; i++) {
        vertices[4 * i + 0] = mesh->mVertices[i].x;
        vertices[4 * i + 1] = mesh->mVertices[i].y;
        vertices[4 * i + 2] = mesh->mVertices[i].z;
        vertices[4 * i + 3] = 1.0f;
        if (mesh->HasNormals()) {
            normals[3 * i + 0] = mesh->mNormals[i].x;
            normals[3 * i + 1] = mesh->mNormals[i].y;
            normals[3 * i + 2] = mesh->mNormals[i].z;
        }
        if (mesh->HasTextureCoords(0)) {
            textureCoordinates[2 * i + 0] = mesh->mTextureCoords[0][i].x;
            textureCoordinates[2 * i + 1] = mesh->mTextureCoords[0][i].y;
        }
    }
    int *faces = (int *) malloc(3 * mesh->mNumFaces * sizeof (int));
    for (unsigned int i = 0; i < mesh->mNumFaces; i++) {
        faces[3 * i + 0] = mesh->mFaces[i].mIndices[0];
        faces[3 * i + 1] = mesh->mFaces[i].mIndices[1];
        faces[3 * i + 2] = mesh->mFaces[i].mIndices[2];
    }
    object->addMesh(vertices, mesh->mNumVertices, normals, mesh->mNumVertices, textureCoordinates, mesh->mNumVertices, faces, mesh->mNumFaces, mesh->mMaterialIndex);
}

void processMaterial(aiMaterial* material, int index) {
    MaterialManager *mm = MaterialManager::getSingleton();
    std::cout << "================ ID " << index << "====================" << std::endl;

    aiString materialName;

    // Get the name for managing purpose
    if (material->Get(AI_MATKEY_NAME, materialName) != AI_SUCCESS) {
        std::cout << "ERROR: while getting name of material" << std::endl;
    }

    aiString diffuseTexturePath;
    aiString normalMapTexturePath;
    aiString specularTexturePath;
    aiString ambientTexturePath;
    aiString opacityTexturePath;
    aiColor3D diffuseColor, ambientColor, specularColor, emissiveColor;
    float opacity, shininess;

    // Get diffuse color
    if (material->Get(AI_MATKEY_COLOR_DIFFUSE, diffuseColor) != AI_SUCCESS) {
        std::cout << "ERROR: Could not get diffuse color for Material " << materialName.data << std::endl;
    }

    // Get ambient color
    if (material->Get(AI_MATKEY_COLOR_AMBIENT, ambientColor) != AI_SUCCESS) {
        std::cout << "ERROR: Could not get ambient color for Material " << materialName.data << std::endl;
    }

    // Get diffuse color
    if (material->Get(AI_MATKEY_COLOR_SPECULAR, specularColor) != AI_SUCCESS) {
        std::cout << "ERROR: Could not get specular color for Material " << materialName.data << std::endl;
    }

    // Get opacity
    if (material->Get(AI_MATKEY_OPACITY, opacity) != AI_SUCCESS) {
        std::cout << "ERROR: Could not get opacity for Material " << materialName.data << std::endl;
    }

    // Get emissive color
    if (material->Get(AI_MATKEY_COLOR_EMISSIVE, emissiveColor) != AI_SUCCESS)
        emissiveColor = aiColor3D(0);

    // Get shininess
    if (material->Get(AI_MATKEY_SHININESS, shininess) != AI_SUCCESS) {
        std::cout << "ERROR: Could not get Shininess for Material " << materialName.data << std::endl;
    }


    // material color parameters
    std::cout << "diffuse color [" << diffuseColor.r << "," << diffuseColor.g << "," << diffuseColor.b << "] opacity=" << opacity << std::endl;
    std::cout << "ambient color [" << ambientColor.r << "," << ambientColor.g << "," << ambientColor.b << "]" << std::endl;
    std::cout << "specular color [" << specularColor.r << "," << specularColor.g << "," << specularColor.b << "]" << std::endl;
    std::cout << "emissive color [" << emissiveColor.r << "," << emissiveColor.g << "," << emissiveColor.b << "]" << std::endl;


    Material *m = mm->createMaterial(std::string(materialName.data), index);
    m->setDiffuseColor(glm::vec4(diffuseColor.r, diffuseColor.g, diffuseColor.b, opacity));
    m->setAmbientColor(glm::vec3(ambientColor.r, ambientColor.g, ambientColor.b));
    m->setSpecularColor(glm::vec3(specularColor.r, specularColor.g, specularColor.b));
    m->setEmissiveColor(glm::vec3(emissiveColor.r, emissiveColor.g, emissiveColor.b));

    // diffuse map
    if (material->GetTextureCount(aiTextureType_DIFFUSE) > 0) {
        if (material->Get(AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE, 0), diffuseTexturePath) != AI_SUCCESS) {
            std::cout << "ERROR: Could not get Diffuse Texture for Material " << materialName.data << std::endl;
            return;
        }
        m->loadDiffuseTexture(diffuseTexturePath.data);
        std::cout << "diffuse texture path " << diffuseTexturePath.data << std::endl;
    }

    // normal map
    if (material->GetTextureCount(aiTextureType_HEIGHT) > 0) {
        if (material->Get(AI_MATKEY_TEXTURE(aiTextureType_HEIGHT, 0), normalMapTexturePath) != AI_SUCCESS) {
            std::cout << "ERROR: Could not get Height Map Texture for Material " << materialName.data << std::endl;
            return;
        }
        m->loadNormalTexture(normalMapTexturePath.data);
        std::cout << "height map texture path " << normalMapTexturePath.data << std::endl;
    }

    // specular map
    if (material->GetTextureCount(aiTextureType_SPECULAR) > 0) {
        if (material->Get(AI_MATKEY_TEXTURE(aiTextureType_SPECULAR, 0), specularTexturePath) != AI_SUCCESS) {
            std::cout << "ERROR: Could not get Mask Texture for Material " << materialName.data << std::endl;
            return;
        }
        m->loadSpecularTexture(specularTexturePath.data);
        std::cout << "specular texture path " << specularTexturePath.data << std::endl;
    } else {
        std::cout << "there is no specular texture at ID=" << index << std::endl;
    }

    // ambient map
    if (material->GetTextureCount(aiTextureType_AMBIENT) > 0) {
        if (material->Get(AI_MATKEY_TEXTURE(aiTextureType_AMBIENT, 0), ambientTexturePath) != AI_SUCCESS) {
            std::cout << "ERROR: Could not get Ambient Texture for Material " << materialName.data << std::endl;
            return;
        }
        m->loadAmbientTexture(ambientTexturePath.data);
        std::cout << "ambient texture path " << ambientTexturePath.data << std::endl;
    } else {
        std::cout << ":( THERE IS NO AMBIENT MAP" << std::endl;
    }
    // opacity map
    if (material->GetTextureCount(aiTextureType_OPACITY) > 0) {
        if (material->Get(AI_MATKEY_TEXTURE(aiTextureType_OPACITY, 0), opacityTexturePath) != AI_SUCCESS) {
            std::cout << "ERROR: Couldn't get opacity texture for material" << materialName.data << std::endl;
            return;
        }
        m->loadOpacityTexture(opacityTexturePath.data);
        std::cout << "opacity texture path" << opacityTexturePath.data << std::endl;
    } else {
        std::cout << ":( THERE IS NO OPACITY MAP" << std::endl;
    }
    std::cout << "==========================================" << std::endl;
}

void initWindow() {
    if (!glfwInit()) {
        std::cout << "Error: GLFW failed to initialize.\n";
        return;
    }

    window = glfwCreateWindow(windowWidth, windowHeight, "OpenGL ASSIMP", NULL, NULL);
    if (!window) {
        std::cout << "Error: Failed to create window.\n";
        glfwTerminate();
        return;
    }
    glfwMakeContextCurrent(window);

    if (GLEW_OK != glewInit()) {
        std::cout << "Error: Failed to load OpenGL functions.\n";
        glfwTerminate();
        return;
    }
    glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
}

void disposeWindow() {
    glfwDestroyWindow(window);
    glfwTerminate();
}

void handleKeyboardInput(GLFWwindow *window, int key, int scancode, int action, int mods) {
    if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
        glfwSetWindowShouldClose(window, 1);
    else if (key == GLFW_KEY_W && action == GLFW_PRESS)
        wKeyPressed = true;
    else if (key == GLFW_KEY_S && action == GLFW_PRESS)
        sKeyPressed = true;
    else if (key == GLFW_KEY_A && action == GLFW_PRESS)
        aKeyPressed = true;
    else if (key == GLFW_KEY_D && action == GLFW_PRESS)
        dKeyPressed = true;
    else if (key == GLFW_KEY_W && action == GLFW_RELEASE)
        wKeyPressed = false;
    else if (key == GLFW_KEY_S && action == GLFW_RELEASE)
        sKeyPressed = false;
    else if (key == GLFW_KEY_A && action == GLFW_RELEASE)
        aKeyPressed = false;
    else if (key == GLFW_KEY_D && action == GLFW_RELEASE)
        dKeyPressed = false;
}

void processInput(float dt) {
    static glm::vec3 right;
    if (wKeyPressed)
        position += direction * speed * dt;
    if (sKeyPressed)
        position -= direction * speed * dt;
    if (aKeyPressed)
        position -= right * speed * dt;
    if (dKeyPressed)
        position += right * speed * dt;

    direction = glm::vec3
            (
            std::cos(verticalAngle) * std::sin(horizontalAngle),
            std::sin(verticalAngle),
            std::cos(verticalAngle) * std::cos(horizontalAngle)
            );
    right = glm::vec3
            (
            std::sin(horizontalAngle - 3.14159f / 2.0f),
            0.0f,
            std::cos(horizontalAngle - 3.14159f / 2.0f)
            );
    up = glm::cross(right, direction);

    glfwGetCursorPos(window, &mouseX, &mouseY);
    glfwSetCursorPos(window, windowWidth / 2, windowHeight / 2);
    horizontalAngle += mouseSpeed * dt * float(windowWidth / 2 - mouseX);
    if (!up.y >= -0.5f)
        verticalAngle += mouseSpeed * dt * float(windowHeight / 2 - mouseY);
    else if (up.y == -1.0f)
        up = glm::vec3(up.x, 1, up.z);

    viewMatrix = glm::lookAt(position, position + direction, up);
}

Popular posts from this blog

Apache Spark + Cassandra. Hello World