Home > Enterprise >  Opengl only draw the first object create
Opengl only draw the first object create

Time:11-20

i can't render multiples triangles using openGl, only 1 object is display.

I only view the first object, i have create.

For me the problem is with indices or glBufferData() or glVertexAttribPointer(). For the demo is only use vertices and indices.

Vertices are type Float and indices are type unsigned int.

void Objets::createShader() {
    
        GLuint vertexShaderID = glCreateShader(GL_VERTEX_SHADER);
        GLuint fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
    
        const GLchar* adapter[1];
        string temp = readShaderCode("VertexShaderCode.glsl");
        adapter[0] = temp.c_str();
        glShaderSource(vertexShaderID, 1, adapter, 0);
        temp = readShaderCode("FragmentShaderCode.glsl");
        adapter[0] = temp.c_str();
        glShaderSource(fragmentShaderID, 1, adapter, 0);
    
        glCompileShader(vertexShaderID);
        glCompileShader(fragmentShaderID);
    
        //checkShaders(vertexShaderID, fragmentShaderID); no error
    
        programID = glCreateProgram();
        glAttachShader(programID, vertexShaderID);
        glAttachShader(programID, fragmentShaderID);
        glLinkProgram(programID);
    
        //checkProgram(programID); no error
    
        glDeleteShader(vertexShaderID);
        glDeleteShader(fragmentShaderID);
    
        glGenVertexArrays(1, &VAO);
    
        glGenBuffers(1, &vertexBufferID);
        glGenBuffers(1, &colorBufferID);
        glGenBuffers(1, &indexBufferID);
    }

I use createShader() after i have create my window with sfml.

I create 2 shapes and load my 2 shapes :

graphiques3d.createShapeAndBufferit(Shapes::loadFromFileObj("objs/Cube.004.obj"));
graphiques3d.createShapeAndBufferit(Shapes::loadFromFileObj("objs/Cube.007.obj"));
Shapes Shapes::loadFromFileObj(string nameFile) {

    Shapes shape;

    string newString;
    string buf;
    string line;

    ifstream myfile(nameFile);
    if (myfile.is_open())
    {
        while (getline(myfile, line))
        {
            std::stringstream ss;

            if (line.rfind(shape.verticesS, 0) == 0) {

                newString = line.substr(2, line.length());
                ss.str(newString);
                while (ss >> buf) {
                    shape.vertices.push_back((GLfloat)stof(buf));
                }

            }
            else if (line.rfind(shape.indicesS, 0) == 0) {

                newString = line.substr(2, line.length());
                ss.str(newString);
                while (ss >> buf) {
                    GLuint valBuffer = (GLuint)atoi(buf.c_str());
                    shape.indices.push_back((GLuint)(valBuffer - 1));
                }

            }

        }
        myfile.close();
    }
    else cout << "Unable to open file";

    return shape;

}

Then it use createShapeAndBufferit(Shapes shape);

void Objets::createShapeAndBufferit(Shapes shape) {

    for (int a = 0; a < shape.getVertices().size(); a  )
        vertices.push_back(shape.getVertices().at(a));
    for (int b = 0; b < shape.getIndices().size(); b  )
        indices.push_back(shape.getIndices().at(b));

    glBindVertexArray(VAO);

    glBindBuffer(GL_ARRAY_BUFFER, vertexBufferID);
    glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(GLfloat), &vertices[0], GL_STATIC_DRAW);

    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferID);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(GLuint), &indices[0], GL_STATIC_DRAW);

}

When i print my shapes, i have this :

/1/1/-3/1/-1/-3/1/1/-1/1/-1/-1/-1/1/-3/-1/-1/-3/-1/1/-1/-1/-1/-1 sizeVertices: 24 :4:2:0:2:7:3:6:5:7:1:7:5:0:3:1:4:1:5:4:6:2:2:6:7:6:4:5:1:3:7:0:2:3:4:0:1 sizeIndices: 36

/3/1/1/3/-1/1/3/1/3/3/-1/3/1/1/1/1/-1/1/1/1/3/1/-1/3 sizeVertices: 24 :4:2:0:2:7:3:6:5:7:1:7:5:0:3:1:4:1:5:4:6:2:2:6:7:6:4:5:1:3:7:0:2:3:4:0:1 sizeIndices: 36

And then i draw :

void Objets::dessiner(float x, float y, float z) {

    glClearColor(0.f, 0.f, 0.f, 1.f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glViewport(0, 0, width, height);

    glUseProgram(programID);

    mat4 projectionMatrix = glm::perspective(90.f, width / height, 0.1f, 100.f);
    mat4 modelTransformMatrix = glm::translate(vec3(x, y, z));

    mat4 modelFullTransformMatrix = projectionMatrix * modelTransformMatrix;

    GLint modelTransformMatrixUniformLocation =
        glGetUniformLocation(programID, "modelFullTransformMatrix");

    glUniformMatrix4fv(modelTransformMatrixUniformLocation,
        1, GL_FALSE, &modelFullTransformMatrix[0][0]);

    glBindVertexArray(VAO);
    glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, (GLvoid*)0);
    glBindVertexArray(0);
}

I don't know if you need the fragmentShader and the vertexShader, so i put it :

fragmentShader :

#version 330 core

out vec4 FragColor;
in vec3 color;

void main()
{
    FragColor = vec4(1.0f, 0.0f, 0.0f, 1.0f);
}

vertexShader :

#version 330 core

layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;

uniform mat4 modelFullTransformMatrix;
out vec3 color;

void main()
{
    vec4 v = vec4(aPos, 1.0);
    gl_Position = modelFullTransformMatrix*v;
    color = aColor;
}

CodePudding user response:

So if I understand your explanation correctly, your problem is that you load two separate meshes ('shapes'), and for each one the indices start from zero, but you want to draw both of them in a single draw call?

Maybe glMultiDrawElementsBaseVertex is what you're after?

See also https://www.khronos.org/opengl/wiki/Vertex_Rendering for other alternatives in addition to the basic DrawArrays / DrawElements.

  • Related