0
\$\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\$
  • \$\begingroup\$ What happens if you don't unbind? \$\endgroup\$ – Maximus Minimus Aug 21 '18 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 Aug 21 '18 at 13:35
  • \$\begingroup\$ @MaximusMinimus nothing, the issue continues to appear \$\endgroup\$ – Martin Spasov Aug 22 '18 at 7:45
2
\$\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.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ i will try that right away. First time I hear about it \$\endgroup\$ – Martin Spasov Aug 22 '18 at 7:46
  • \$\begingroup\$ Turns out that this helped figure out the issue with one of the buffers. Thank you! \$\endgroup\$ – Martin Spasov Aug 22 '18 at 8:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.