1

I am failing to render my own created model with loaded obj at the same time. I have mesh.h that is designed for loading objects:

struct Vertex {
    glm::vec3 Position;
    glm::vec3 Normal;
};   
struct Light {
    glm::vec3 position;
    glm::vec3 ambient;
    float diffuse;
    float specular;
};
struct Material {
    float shininess;
    glm::vec3 ambient;
    glm::vec3 diffuse;
    glm::vec3 specular;
};

class Mesh {
public:
    vector<Vertex>       vertices;
    vector<unsigned int> indices;
    Material material;
    unsigned int VAO;

    Mesh(vector<Vertex> vertices, vector<unsigned int> indices, Material material)
    {
        this->vertices = vertices;
        this->indices = indices;
        this->material = material;
        setupMesh();
    }


    void Draw(Shader &shader, Camera &camera)
    {
        glm::mat4 projection = glm::perspective(glm::radians(camera.Zoom), (float) 1024 / (float) 768, 0.1f,
                                                2000.0f);
        glm::mat4 view = camera.GetViewMatrix();
        shader.setMat4("projection", projection);
        shader.setMat4("view", view);

        shader.setFloat("material.shininess", material.shininess);
        shader.setVec3("material.ambient", material.ambient);
        shader.setVec3("material.diffuse", material.diffuse);
        shader.setVec3("material.specular", material.specular);
        shader.setVec3("light.direction", -camera.Position);
        shader.setVec3("viewPos", camera.Position);
        shader.setVec3("light.ambient", 1.0f, 1.0f, 1.0f);
        shader.setVec3("light.diffuse", 0.8f, 0.8f, 0.8f);
        shader.setVec3("light.specular", 0.8f, 0.8f, 0.8f);

        glBindVertexArray(VAO);
        glDrawElements(GL_TRIANGLES, static_cast<unsigned int>(indices.size()), GL_UNSIGNED_INT, 0);
        glBindVertexArray(0);
    }

private:
    unsigned int VBO, EBO;

    void setupMesh()
    {
        glGenVertexArrays(1, &VAO);
        glGenBuffers(1, &VBO);
        glGenBuffers(1, &EBO);

        glBindVertexArray(VAO);
        glBindBuffer(GL_ARRAY_BUFFER, VBO);
        glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex), &vertices[0], GL_STATIC_DRAW);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), &indices[0], GL_STATIC_DRAW);

        glEnableVertexAttribArray(0);
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)0);
        glEnableVertexAttribArray(1);
        glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, Normal));
    }
};

Model.h and main for drawing the objects:

    void Draw(Shader &shader, Camera &camera)
    {
        shader.use();
        for(unsigned int i = 0; i < meshes.size(); i++)
            meshes[i].Draw(shader, camera);
    }
  while (!glfwWindowShouldClose(window))
    {
        processInput(window, unitBox.size_x(), unitBox.size_y(), unitBox.size_z());
        glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        for (auto & modelMatrice : modelMatrices)
        {
            ourShader.setMat4("model", modelMatrice);
            moleculeModel.Draw(ourShader, camera);
        }
        glfwSwapBuffers(window);
        glfwPollEvents();
    }
    glfwTerminate();

Now I want to draw and load at the same time my custom model, cube. I made a separate class cubeMesh.h:

class BoxMesh
{
public:
unsigned int VAO;
std::vector<float> boxVertices = {
        -0.5f, -0.5f, 0.0f,  0.0f,  0.0f, -1.0f,
        0.5f, -0.5f, 0.0f,  0.0f,  0.0f, -1.0f,
        0.5f,  0.5f, 0.0f,  0.0f,  0.0f, -1.0f,
        0.5f,  0.5f, 0.0f,  0.0f,  0.0f, -1.0f,
        -0.5f,  0.5f, 0.0f,  0.0f,  0.0f, -1.0f,
        -0.5f, -0.5f, 0.0f,  0.0f,  0.0f, -1.0f,

        -0.5f, -0.5f,  1.0f,  0.0f,  0.0f,  1.0f,
        0.5f, -0.5f,  1.0f,  0.0f,  0.0f,  1.0f,
        0.5f,  0.5f,  1.0f,  0.0f,  0.0f,  1.0f,
        0.5f,  0.5f,  1.0f,  0.0f,  0.0f,  1.0f,
        -0.5f,  0.5f,  1.0f,  0.0f,  0.0f,  1.0f,
        -0.5f, -0.5f,  1.0f,  0.0f,  0.0f,  1.0f,

        -0.5f,  0.5f,  1.0f, -1.0f,  0.0f,  0.0f,
        -0.5f,  0.5f, 0.0f, -1.0f,  0.0f,  0.0f,
        -0.5f, -0.5f, 0.0f, -1.0f,  0.0f,  0.0f,
        -0.5f, -0.5f, 0.0f, -1.0f,  0.0f,  0.0f,
        -0.5f, -0.5f,  1.0f, -1.0f,  0.0f,  0.0f,
        -0.5f,  0.5f,  1.0f, -1.0f,  0.0f,  0.0f,

        0.5f,  0.5f,  1.0f,  1.0f,  0.0f,  0.0f,
        0.5f,  0.5f, 0.0f,  1.0f,  0.0f,  0.0f,
        0.5f, -0.5f, 0.0f,  1.0f,  0.0f,  0.0f,
        0.5f, -0.5f, 0.0f,  1.0f,  0.0f,  0.0f,
        0.5f, -0.5f, 1.0f,  1.0f,  0.0f,  0.0f,
        0.5f,  0.5f, 1.0f,  1.0f,  0.0f,  0.0f,

        -0.5f, -0.5f, 0.0f,  0.0f, -1.0f,  0.0f,
        0.5f, -0.5f, 0.0f,  0.0f, -1.0f,  0.0f,
        0.5f, -0.5f,  1.0f,  0.0f, -1.0f,  0.0f,
        0.5f, -0.5f,  1.0f,  0.0f, -1.0f,  0.0f,
        -0.5f, -0.5f,  1.0f,  0.0f, -1.0f,  0.0f,
        -0.5f, -0.5f, 0.0f,  0.0f, -1.0f,  0.0f,

        -0.5f,  0.5f, 0.0f,  0.0f,  1.0f,  0.0f,
        0.5f,  0.5f, 0.0f,  0.0f,  1.0f,  0.0f,
        0.5f,  0.5f,  1.0f,  0.0f,  1.0f,  0.0f,
        0.5f,  0.5f,  1.0f,  0.0f,  1.0f,  0.0f,
        -0.5f,  0.5f,  1.0f,  0.0f,  1.0f,  0.0f,
        -0.5f,  0.5f, 0.0f,  0.0f,  1.0f,  0.0f
};
BoxMesh()
{
    setupBox();
}

void Draw(Shader &shader, Camera &camera)
{
    glm::mat4 projection = glm::perspective(glm::radians(camera.Zoom), (float) 1024 / (float) 768, 0.1f,
                                            2000.0f);
    glm::mat4 view = camera.GetViewMatrix();
    shader.setMat4("projection", projection);
    shader.setMat4("view", view);

    shader.setFloat("material.shininess", 1.0f);
    shader.setVec3("material.ambient",1.0f, 1.0f, 1.0f);
    shader.setVec3("material.diffuse", 1.0f, 1.0f, 1.0f);
    shader.setVec3("material.specular", 1.0f, 1.0f, 1.0f);
    shader.setVec3("light.direction", -camera.Position);
    shader.setVec3("viewPos", camera.Position);
    shader.setVec3("light.ambient", 1.0f, 1.0f, 1.0f);
    shader.setVec3("light.diffuse", 0.8f, 0.8f, 0.8f);
    shader.setVec3("light.specular", 0.8f, 0.8f, 0.8f);

    glBindVertexArray(VAO);
    glDrawArrays(GL_TRIANGLES, 0, 36);
    glBindVertexArray(0);

}

private:
    unsigned int VBO;
    void setupBox()
{
    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);

    glBindVertexArray(VAO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, boxVertices.size() * sizeof(boxVertices), &boxVertices[0], GL_STATIC_DRAW);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float)));
    glEnableVertexAttribArray(1);
}
};

and I would expect that it would draw me a single cube + many loaded models:

 while (!glfwWindowShouldClose(window))
    {
        processInput(window, unitBox.size_x(), unitBox.size_y(), unitBox.size_z());
        glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        for (auto & modelMatrice : modelMatrices)
        {
            ourShader.setMat4("model", modelMatrice);
            moleculeModel.Draw(ourShader, camera);
        }

        BoxMesh box;
        box.Draw(ourShader, camera);

        glfwSwapBuffers(window);
        glfwPollEvents();
    }
    glfwTerminate();

Yet I am failing, where?

Rabbid76
  • 202,892
  • 27
  • 131
  • 174
  • Why do you instantiate `BoxMesh` in the application loop? `BoxMesh box;` should be done before the application loop. But bind the VAO in `box.Draw(ourShader, camera)`. – Rabbid76 Oct 09 '22 at 12:23
  • Anyway, what is the problem? What does not work? – Rabbid76 Oct 09 '22 at 12:28
  • i have updated boxMesh code. Only empty window is presented with no errors. – Alexander S Oct 09 '22 at 12:54
  • 1
    Do not apply the suggestions of an answer to the question. That will make the answer useless. – Rabbid76 Oct 09 '22 at 13:07
  • @Rabbid76 how can then I update the answer if I simplified the problem ? – Alexander S Oct 09 '22 at 13:42
  • 1
    You cannot. It is only possible to edit the question so that the original problem is not changed. Why do you want to do this at all? You have asked your question. Wait until you get answers. You may get more than 1 answer. If there are multiple issues in your code, you may need more than 1 answer to solve all you problems. – Rabbid76 Oct 09 '22 at 13:46

1 Answers1

2

You create the object BoxMesh and the corresponding VAO and VBO in each frame. Apart from the performance penalty, VAO and VBO are never deleted, which results in new objects being created in every frame, and the exhaust of memory until the end. The BoxMesh should be instanciated before the application loop. You only need to bind the VAO before drawing the mesh.
Since the box does not appear to have a model matrix, you must set the identity matrix, otherwise the matrix of the most recently drawn mesh would be stated in the shader's default uniform block:

class BoxMesh {
public:
    // [...]

    void Draw(Shader &shader, Camera &camera)
    {
        // [...]
 
        glBindVertexArray(VAO);
        glDrawArrays(GL_TRIANGLES, 0, 36);
    }
BoxMesh box;

while (!glfwWindowShouldClose(window))
{
    // [...]

    ourShader.setMat4("model", glm:mat4(1.0f));
    box.Draw(ourShader, camera);

    // [...]
}
Rabbid76
  • 202,892
  • 27
  • 131
  • 174