while 1
while 1

Reputation: 1

Why don't I get feedback from my 3D game (OpenGL and Assimp?)

The game's music, title screen, screen clearing/switching and I don't get any errors after compiling and linking my shaders, but the model rendering doesn't.

main.cpp

#include <glad\glad.h>
#include <glfw\glfw3.h>
#include <iostream>
#include <io.h>
#define STB_IMAGE_IMPLEMENTATION
#include <stb_image.h>
#include <windows.h>
#include <glm\glm.hpp>
#include <mesh.h>
#include <model.h>
#include <shader.h>
#include <glm/gtc/matrix_transform.hpp>

void getFrame(GLFWwindow* window, int width = 900, int height = 700) {
    glViewport(0, 0, width, height);
}

int main() {
    int time = 0;

    //setup
    int x = 900;
    int y = 700;

    glfwInit();
    glfwWindowHint(GLFW_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_VERSION_MINOR, 3);
    GLFWwindow* win = glfwCreateWindow(x, y, "Herbert Engine PA.1.0.0", nullptr, nullptr);
    glfwMakeContextCurrent(win);
    glfwGetFramebufferSize(win, &x, &y);
    gladLoadGL();
    glViewport(0, 0, x, y);
    glfwSetFramebufferSizeCallback(win, getFrame);
    glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    //rectangle rendering
    float vert[] = {
         0.5f,  0.5f, 0.0f,  // top right
        0.5f, -0.5f, 0.0f,  // bottom right
        -0.5f,  0.5f, 0.0f,  // top left 
        // second triangle
        0.5f, -0.5f, 0.0f,  // bottom right
        -0.5f, -0.5f, 0.0f,  // bottom left
        -0.5f,  0.5f, 0.0f   // top left
    };

    unsigned int titleInd[] = {
        0, 1, 3,
        1, 2, 3
    };

    unsigned int tVbo, tVao, tEbo;
    
    //vao setup
    glGenVertexArrays(1, &tVao);
    glBindVertexArray(tVao);

    //vbo setup
    glGenBuffers(1, &tVbo);
    glBindBuffer(GL_ARRAY_BUFFER, tVbo);

    //vertex data buffer
    glBufferData(GL_ARRAY_BUFFER, sizeof(vert), vert, GL_STATIC_DRAW);

    //ebo setup
    glGenBuffers(1, &tEbo);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, tEbo);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(titleInd), titleInd, GL_STATIC_DRAW);

    //apply attributes
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);

    float titleVert[] = {
        // positions          // colors           // texture coords
        0.5f,  0.5f, 0.0f,   1.0f, 0.0f, 0.0f,   1.0f, 1.0f,   // top right
        0.5f, -0.5f, 0.0f,   0.0f, 1.0f, 0.0f,   1.0f, 0.0f,   // bottom right
        -0.5f, -0.5f, 0.0f,   0.0f, 0.0f, 1.0f,   0.0f, 0.0f,   // bottom left
        -0.5f,  0.5f, 0.0f,   1.0f, 1.0f, 0.0f,   0.0f, 1.0f    // top left 
    };

    const char *tVertxSrc = "#version 330 core\n"
        "layout (location = 0) in vec3 pos;\n"
        "void main() {\n"
        "   gl_Position = vec4 (pos, 1.0f);\n"
        "}\0";

    const char *tFragSrc = "#version 330 core\n"
        "out vec4 col;\n"
        "void main() {\n"
        "   col = vec4(0.0f, 1.0f, 0.0f, 1.0f);\n"
        "}\0";

    const char* titleVSrc = "#version 330 core\n"
        "layout (location = 0) in vec3 pos;\n"
        "layout (location = 1) in vec3 col;\n"
        "layout (location = 2) in vec2 cord;\n"
        "out vec3 texCol;\n"
        "out vec2 texCord;\n"
        "void main() {\n"
        "   gl_Position = vec4(pos, 1.0);\n"
        "   texCol = col;\n"
        "   texCord = cord;\n"
        "}\0";

    const char* titleFSrc = "#version 330 core\n"
        "in vec3 texCol;\n"
        "in vec2 texCord;\n"
        "out vec4 col_fra;\n"
        "uniform sampler2D tex;\n"
        "void main() {\n"
        "   col_fra = texture(tex, texCord);\n"
        "}\0";

    unsigned int triv = glCreateShader(GL_VERTEX_SHADER);
    unsigned int trif = glCreateShader(GL_FRAGMENT_SHADER);
    unsigned int triprg = glCreateProgram();

    glShaderSource(triv, 1, &tVertxSrc, nullptr);
    glShaderSource(trif, 1, &tFragSrc, nullptr);
    glCompileShader(triv);

    glCompileShader(trif);

    glAttachShader(triprg, triv);
    glAttachShader(triprg, trif);
    glLinkProgram(triprg);
    
    glUseProgram(triprg);

    //texture rendering
    
    float titlePos[] = {
        // positions          // colors           // texture coords
         0.5f,  0.5f, 0.0f,  1.0f, 0.0f, 0.0f,  1.0f, 1.0f, // top right
        0.5f, -0.5f, 0.0f,  0.0f, 1.0f, 0.0f,  1.0f, 0.0f, // bottom right
        -0.5f, -0.5f, 0.0f,  0.0f, 0.0f, 1.0f,  0.0f, 0.0f, // bottom left
        -0.5f,  0.5f, 0.0f,  1.0f, 1.0f, 0
    };

    //setup buffers
    unsigned int texVbo, texVao, texEbo;
    glGenVertexArrays(1, &texVao);
    glBindVertexArray(texVao);

    glGenBuffers(1, &texVbo);
    glBindBuffer(GL_ARRAY_BUFFER, texVbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(titleVert), titleVert, GL_STATIC_DRAW);

    glGenBuffers(1, &texEbo);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, texEbo);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(titleInd), titleInd, GL_STATIC_DRAW);

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
    glEnableVertexAttribArray(2);

    //generate vertex array
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);

    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
    glEnableVertexAttribArray(1);

    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
    glEnableVertexAttribArray(2);

    //create texture
    unsigned int title;
    glGenTextures(1, &title);
    glBindTexture(GL_TEXTURE_2D, title);

    //paramaters
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);

    //set border color
    float bordCol[] = {
        1.0f, 0.0f, 0.0f, 1.0f
    };

    glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, bordCol);

    //set filters
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

    //generate mipmap and load png
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

    int tx, ty, nrChan;

    unsigned char* img = stbi_load("png/title.png", &tx, &ty, &nrChan, 0);
    if (img) {
        GLenum frm = (nrChan == 4) ? GL_RGBA : GL_RGB;
        glTexImage2D(GL_TEXTURE_2D, 0, frm, tx, ty, 0, frm, GL_UNSIGNED_BYTE, img);
        glGenerateMipmap(GL_TEXTURE_2D);
    }

    //compile and link shaders and programs
    unsigned int titleV = glCreateShader(GL_VERTEX_SHADER);
    unsigned int titleF = glCreateShader(GL_FRAGMENT_SHADER);
    unsigned int titlePrg = glCreateProgram();

    glShaderSource(titleV, 1, &titleVSrc, nullptr);
    glShaderSource(titleF, 1, &titleFSrc, nullptr);
    
    glCompileShader(titleV);
    glCompileShader(titleF);

    glAttachShader(titlePrg, titleV);
    glAttachShader(titlePrg, titleF);

    glLinkProgram(titlePrg);

    //use new shaders
    glUseProgram(titlePrg);
    
    PlaySound(TEXT("wav/titleTheme.wav"), nullptr, SND_ASYNC | SND_LOOP);

    bool isOnTitle = true;

    if (isOnTitle == false) {
        stbi_image_free(img);

        glClearColor(0.5f, 1.0f, 0.5f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);
    }

    //main game
    const char* fragSrc = "#version 330 core\n"
        "out vec4 fragColor;\n"
        "uniform sampler2D diff1;\n"
        "uniform sampler2D diff2;\n"
        "uniform sampler2D diff3;\n"
        "uniform sampler2D spec1;\n"
        "uniform sampler2D spec2;\n"
        "void main() {\n"
        "   fragColor = vec4(1.0f, 1.0f, 1.0f, 1.0f);\n"
        "}\0";

    const char* vertSrc = "#version 330 core\n"
        "layout(location = 0) in vec3 pos;\n"
        "uniform mat4 model;\n"
        "uniform mat4 view;\n"
        "uniform mat4 proj;\n"
        "void main() {\n"
        "   gl_Position = proj * view * model * vec4(pos, 1.0);\n"
        "}\0";

    //color and light values
    glm::vec3 objColor(0.5f, 0.5f, 0.9f);
    glm::vec3 lightColor(1.0f, 1.0f, 0.2f);
    glm::vec3 diffuseColor(0.9f, 0.9f, 1.0f);
    glm::vec3 lightPosition(0.5f, 1.0f, 5.0f);
    glm::vec3 normVec;

    glm::vec3 productColor = objColor * lightColor;
    glm::vec3 productLight = normVec * lightPosition;

    //light buffer
    unsigned int lightVba;
    unsigned int lightVbo;
    unsigned int lightEbo;

    glGenBuffers(1, &lightVbo);
    glBindBuffer(GL_ARRAY_BUFFER, lightVbo);
    glGenVertexArrays(1, &lightVba);
    glBufferData(lightVbo, sizeof(productColor), &productColor, GL_DYNAMIC_DRAW);

    glGenBuffers(1, &lightEbo);
    glBindBuffer(GL_ARRAY_BUFFER, lightEbo);
    glBufferData(lightEbo, sizeof(productLight), &productLight, GL_DYNAMIC_DRAW);

    glBindVertexArray(lightVba);
    glDrawElements(GL_TRIANGLES, 1, GL_UNSIGNED_INT, 0);

    bool isOutside = true;

    Shader shader(fragSrc, vertSrc);
    Model model("3d/obj/general.obj");

    glm::mat4 proj = (0.0f, 0.0f, 0.0f);
    glm::mat4 view = (0.0f, 1.0f, 0.0f);

    while (!glfwWindowShouldClose(win)) {
        glClear(GL_COLOR_BUFFER_BIT);

        shader.setMat4("proj", proj);
        shader.setMat4("view", view);

        model.render(shader);

        if (isOnTitle == true) {
            glUseProgram(triprg);
            glBindVertexArray(tVao);
            glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

            glUseProgram(titlePrg);
            glBindTexture(GL_TEXTURE_2D, title);
            glBindVertexArray(texVao);
            glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
        }

        glfwSwapBuffers(win);
        glfwPollEvents();

        if (glfwGetKey(win, GLFW_KEY_ENTER) == GLFW_PRESS and isOnTitle == true) {
            glDeleteShader(triv);
            glDeleteShader(trif);
            glDeleteProgram(triprg);
            glDeleteBuffers(1, &tVbo);
            glDeleteShader(titleF);
            glDeleteShader(titleV);
            glDeleteProgram(titlePrg);
            glClearColor(0.0f, 3.0f, 0.1f, 1.0f);
            glClear(GL_COLOR_BUFFER_BIT);

            PlaySound(TEXT("wav/robbery.wav"), nullptr, SND_ASYNC | SND_LOOP);

            isOnTitle = false;
        }
    }
    glfwDestroyWindow(win);
    glfwTerminate();
    glfwTerminate();
    return 0;
}

model.h

#include <glm/glm.hpp>
#include <mesh.h>
#include <sstream>
#include <fstream>
#include <map>
#include <assimp/IOStream.hpp>
#include <assimp/scene.h>
#include <assimp/Importer.hpp>
#include <assimp/postprocess.h>
#include <shader.h>

using namespace std;

class Model {
public:
    vector<Mesh> meshes;
    vector<Tex> tex_load;
    string dir;
    bool gammaCorrect;

    Model(string const &path, bool gamma = false): gammaCorrect(gamma) {
        gameScene(path);
    }

    void render(Shader& shader) {
        for (unsigned int i = 0; i < meshes.size(); i++) {
            meshes[i].render(shader);
        }
    }

private:
    void gameScene(const string& path) {
        Assimp::Importer import;
        const aiScene* scene = import.ReadFile(path, aiProcess_Triangulate | aiProcess_FlipUVs);

        if (scene == nullptr) {
            cout << "Scene is nullptr!\n";
        }
    }

    void processNode(aiNode* node, const aiScene* scene, std::string &path) {
        for (unsigned int i = 0; i < node->mNumMeshes; i++) {
            aiMesh* mesh = scene->mMeshes[node->mMeshes[i]];
            meshes.push_back(processMesh(mesh, scene, path));
        }

        for (unsigned int i = 0; i < node->mNumChildren; i++) {
            processNode(node->mChildren[i], scene, path);
        }
    }

    vector<Tex> loadMaterialTextures(aiMaterial* material, string file, aiTextureType type) {
        string typeName;

        for (unsigned int i = 0; i < material->GetTextureCount(type); i++) {
            aiString texPath;
            material->GetTexture(type, i, &texPath);

            bool skip = false;

            //check if texture is already loaded
            for (unsigned int j = 0; j < tex_load.size(); j++) {
                if (std::strcmp(tex_load[j].path.data(), texPath.C_Str()) == 0) {
                    tex_load.push_back(tex_load[j]);
                    skip = true; //texture with the same filename is loaded so skip
                }
            }

            if (!skip) {
                Tex texture;
                texture.id = texFile(texPath.C_Str(), dir);
                texture.type = typeName;
                texture.path = texPath.C_Str();
                tex_load.push_back(texture);
            }
        }
        return tex_load;
    }

    unsigned int texFile(const char* path, string& dir, bool gamma = false) {
        string file = string(path);
        file = dir + '/' + file;

        unsigned int id;

        glGenTextures(1, &id);

        int x, y, nrComp;
        unsigned char* data = stbi_load(file.c_str(), &x, &y, &nrComp, 0);

        if (data) {
            GLenum format;
            
            if (nrComp == 1) {
                format = GL_RED;
            }

            else if (nrComp == 3) {
                format = GL_RGB;
            }

            else if (nrComp == 4) {
                format = GL_RGBA;
            }


            glBindTexture(GL_TEXTURE_2D, id);
            glTexImage2D(GL_TEXTURE_2D, 0, format, x, y, 0, format, GL_UNSIGNED_BYTE, data);
            glGenerateMipmap(GL_TEXTURE_2D);

            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_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_NEAREST);
        }

        else {
            cout << "Texture not loaded!\n";
        }

        return id;
    }

    Mesh processMesh(aiMesh* mesh, const aiScene* scene, std::string &path) {
        vector<Vert> verti;
        vector<unsigned int> ind;
        vector<Tex> tex;

        for (unsigned int i = 0; i < mesh->mNumVertices; i++) {
            Vert vert;

            glm::vec3 vec;
            vec.x = mesh->mVertices[i].x;
            vec.y = mesh->mVertices[i].y;
            vec.z = mesh->mVertices[i].z;
            vec.x = mesh->mNormals[i].x;
            vec.y = mesh->mNormals[i].y;
            vec.z = mesh->mNormals[i].z;
            vert.pos = vec;
            verti.push_back(vert);

            if (mesh->mTextureCoords[0]) {
                glm::vec2 vec;
                vec.x = mesh->mTextureCoords[0][i].x;
                vec.y = mesh->mTextureCoords[0][i].y;
                vert.texCoords = vec;
            }

            else {
                vert.texCoords = glm::vec2(0, 0);
            }

        }

        for (unsigned int i = 0; i < mesh->mNumFaces; i++) {
            aiFace face = mesh->mFaces[i];

            for (unsigned int j = 0; j < face.mNumIndices; j++) {
                ind.push_back(face.mIndices[j]);
            }
        }

        if (mesh->mMaterialIndex >= 0) {
            aiMaterial* material = scene->mMaterials[mesh->mMaterialIndex];
            vector<Tex> diffMaps = loadMaterialTextures(material, path, aiTextureType_DIFFUSE);
            tex.insert(tex.end(), diffMaps.begin(), diffMaps.end());
            vector<Tex> specMaps = loadMaterialTextures(material, path, aiTextureType_SPECULAR);
            tex.insert(tex.end(), specMaps.begin(), specMaps.end());
        }

        return Mesh(verti, ind, tex);
    }
};

mesh.h

#pragma once
#include <glm\glm.hpp>
#include <string>
#include <vector>
#include <shader.h>

#define MAX_BONE 4

using namespace std;

struct Vert {
    glm::vec3 pos;
    glm::vec3 normVec;
    glm::vec2 texCoords;
    glm::vec3 tan;
    glm::vec3 bitTan;

    int m_BoneIDs[MAX_BONE];
    float w_weights[MAX_BONE];
};

struct Tex {
    unsigned int id;
    string type;
    string path;
};

class Mesh {
public:
    unsigned int vao;
    vector<Vert> verti;
    vector<unsigned int> ind;
    vector<Tex> texs;

    Mesh(vector<Vert> verti, vector<unsigned int> ind, vector<Tex> texs) {
        this->verti = verti;
        this->ind = ind;
        this->texs = texs;

        setup();
    }
    
    void render(Shader& shader) {
        unsigned int diffNR = 1;
        unsigned int specNR = 1;
        unsigned int normNR = 1;
        unsigned int heightNR = 1;

        for (unsigned int i = 0; i < texs.size(); i++) {
            glActiveTexture(GL_TEXTURE0 + i);

            string no;
            string name = texs[i].type;

            if (name == ("texture_diffuse")) {
                no = std::to_string(diffNR++);
            }

            else if (name == "texture_specular") {
                no = std::to_string(specNR++);
            }

            else if (name == "texture_normal") {
                no = std::to_string(normNR++);
            }

            else if (name == "texture_height") {
                no = std::to_string(heightNR++);
            }

            shader.setInt(("material." + name + no).c_str(), i);
            glBindTexture(GL_TEXTURE_2D, texs[i].id);
            glUniform1i(glGetUniformLocation(shader.id, (name + no).c_str()), i);
        }
        glActiveTexture(GL_TEXTURE0);
        glBindVertexArray(vao);
        glDrawElements(GL_TRIANGLES, ind.size(), GL_UNSIGNED_INT, 0);
        glBindVertexArray(0);
    }

private:
    unsigned int vbo, vba, ebo;
    void setup() {
        glGenVertexArrays(1, &vao);
        glGenBuffers(1, &vbo);
        glGenBuffers(1, &ebo);

        glBindBuffer(GL_ARRAY_BUFFER, vbo);
        glBufferData(GL_TRIANGLES, verti.size() * sizeof(Vert), &verti[0], GL_STATIC_DRAW);

        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, ind.size() * sizeof(unsigned int), &ind[0], GL_UNSIGNED_BYTE);

        //pos
        glEnableVertexAttribArray(0);
        glVertexAttribPointer(0, 3, GL_FLOAT , GL_FALSE, sizeof(Vert), (void*)0);

        //norms
        glEnableVertexAttribArray(1);
        glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vert), (void*)offsetof(Vert, normVec));

        //coords
        glEnableVertexAttribArray(2);
        glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vert), (void*)offsetof(Vert, texCoords));

        //tanget
        glEnableVertexAttribArray(3);
        glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(Vert), (void*)offsetof(Vert, tan));

        //bittanget
        glEnableVertexAttribArray(4);
        glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, sizeof(Vert), (void*)offsetof(Vert, bitTan));

        //ids
        glEnableVertexAttribArray(5);
        glVertexAttribIPointer(5, 4, GL_INT, sizeof(Vert), (void*)offsetof(Vert, m_BoneIDs));

        //weights
        glEnableVertexAttribArray(6);
        glVertexAttribIPointer(6, 4, GL_FLOAT, sizeof(Vert), (void*)offsetof(Vert, w_weights));

        glBindVertexArray(0);
    }
};

I fixed issues in the Mesh, Shader and Model classes but it still won't even display an error message or even a partially rendered scene.

Upvotes: -7

Views: 52

Answers (0)

Related Questions