1
\$\begingroup\$

I am trying to render my terrain using an EBO, but the function glDrawElements returns an error (1282). I tried to find out what is causing the error, but everything seems to be as it should according to my understanding.

In my ResourceManager class I load the heightmap and create the EBO and VBO.

std::shared_ptr<Terrain> ResourceManager::LoadTerrain(const std::string& filePath)
{
    int nrChannels;
    unsigned int vertexCount;
    int width;
    int length;
    float w = 10.0f, l = 10.0f;
    unsigned char* data = stbi_load(filePath.c_str(),&width, &length,&nrChannels,0);
    std::vector<glm::vec3> vertices(width * length);
    std::vector<unsigned int> triangles;

    if (data == NULL)
    {
        std::cout << "Cannot load the heightmap!" << std::endl;
    }

    for (int z = 0; z < length; z++)
    {
        for (int x = 0; x < width; x++)
        {
            // normalizing the x and z of the vector
            glm::vec3 vertex = glm::vec3(x/(float)width,0,z/(float)length);

            // multiplying by the width and length
            vertex.x *= w;
            vertex.z *= l;
            // shifting the center to be in the center of the object.
            vertex.x -= width/2;
            vertex.z -= length/2;

            vertices[vertexCount] = vertex;

            // unsigned char* pixelOffset = data + (z + this->length * x) * nrChannels;
            // std::cout << "red " << static_cast<unsigned int>(pixelOffset[0]) << std::endl;

            if ((vertexCount+1 % width) != 0 && z+1 < length)
            {
                triangles.push_back(vertexCount);
                triangles.push_back(vertexCount + width);
                triangles.push_back(vertexCount + width + 1);

                triangles.push_back(vertexCount);
                triangles.push_back(vertexCount + width + 1);
                triangles.push_back(vertexCount + 1);
            }
            vertexCount++;
        }
    }    
    stbi_image_free(data);

    // OPENGL Part
    GLuint IBO, VBO;
    glGenBuffers(1, &VBO);
    glBindBuffer(GL_ARRAY_BUFFER,VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * vertices.size(), vertices.data(), GL_STATIC_DRAW);

    glGenBuffers(1, &IBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,IBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * triangles.size(), triangles.data(), GL_STATIC_DRAW);

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

    std::shared_ptr<Terrain> terrain = std::make_shared<Terrain>(Terrain(VBO, IBO, triangles.size(), Transform()));
    terrain->transform.SetScale(glm::vec3(1.0f,1.0f,1.0f));
    terrain->transform.SetPosition(glm::vec3(0.0f,0.0f,0.0f));
    for (int i = 0; i < triangles.size(); i++)
    {
        std::cout << triangles[i] << std::endl;
    }
    return terrain;
}

The part of the code that generates the error is the following

void Terrain::Render()
{
    this->Bind();
    glDrawElements(GL_TRIANGLES,this->indexCount, GL_UNSIGNED_INT, (void*)0);
    std::cout << "after render but before unbind " << glGetError()<< " " << this->indexCount << std::endl;
    this->Unbind();
}

Bind and Unbind are just 2 GL calls.

void Terrain::Bind()
{
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->indexBuffer);
}

void Terrain::Unbind()
{
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}

EDIT : The code for the rendering is below :

Renderer.cpp

void Renderer::Draw(std::unique_ptr<Scene>& scene, std::shared_ptr<Terrain> terrain)
{
    glm::mat4 projection = scene->camera.GetProjectionMatrix();
    glm::mat4 view = scene->camera.GetViewMatrix();
    this->shader.Use();
    this->shader.SetMat4("projection", projection);
    this->shader.SetMat4("view", view);

    this->shader.SetMat4("model", terrain->transform.getWorldMatrix());
    std::cout << glGetError() << std::endl;
    terrain->Render();
    std::cout << glGetError() << "after render" << std::endl;
    for (int i = 0 ; i < scene->gameObjects.size(); i++)
    {   
        glm::mat4 model = scene->gameObjects[i]->transform.getWorldMatrix();   
        this->shader.SetMat4("model", model);
        scene->gameObjects[i]->Render();
    }
}
\$\endgroup\$
3
  • \$\begingroup\$ What happens if you don't unbind? \$\endgroup\$ Commented Aug 21, 2018 at 12:56
  • \$\begingroup\$ Where is your call to glUseProgram and glVertexAttribPointer? It looks like you're calling draw on indices without a shader program or vertices. \$\endgroup\$
    – Kyy13
    Commented Aug 21, 2018 at 13:35
  • \$\begingroup\$ @MaximusMinimus nothing, the issue continues to appear \$\endgroup\$ Commented Aug 22, 2018 at 7:45

1 Answer 1

3
\$\begingroup\$

1282 is GL_INVALID_OPERATION. This means that the operation you asked OpenGL to perform isn't valid for the set of active state or the given set of parameters to the function. Which, yes, is really broad and unhelpful.

What you can do to diagnose these errors is try to enable the debug output and see if that provides additional information and guidance that leads you to the cause of the error. You can turn on debug output using glEnable(GL_DEBUG_OUTPUT) or by creating a debug context.

Then use glDebugMessageCallback to hook up a callback that receives the debug output messages, and dump them to a log file or the screen or whatever.

\$\endgroup\$
2
  • \$\begingroup\$ i will try that right away. First time I hear about it \$\endgroup\$ Commented Aug 22, 2018 at 7:46
  • \$\begingroup\$ Turns out that this helped figure out the issue with one of the buffers. Thank you! \$\endgroup\$ Commented Aug 22, 2018 at 8:03

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .