0

I am working on a school laboration whereas my task is to render a basic terrain using a heightmap, and also some sort of particle system (right now I'm just blasting away points that are drawn into flat squares).

The problem is that while I can render both the terrain and the particle system, for some reason I cannot render both of them at the same time.

The terrain's initiation and draw functions:

int Buffers()
{

    ShaderInfo shaders[] = {
        { GL_VERTEX_SHADER, "Vertex.txt"},
        { GL_FRAGMENT_SHADER, "Fragment.txt"},
        { GL_NONE, NULL},
    };

    program = LoadShaders(shaders);

    createTerrain.loadBMP_custom("heightmap.bmp");
    textureID = createTerrain.loadBMP_texture("texture.bmp");
    textureLocID = glGetUniformLocation(program, "tex");
    glUniform1i(textureLocID, textureID);

    glGenBuffers(1, &VBOid); // Generate our Vertex Buffer Object
    glBindBuffer(GL_ARRAY_BUFFER, VBOid); // Bind our Vertex Buffer Object
    glBufferData(GL_ARRAY_BUFFER, sizeof(VertexData)*createTerrain.vertices.size(), &createTerrain.vertices[0], GL_STATIC_DRAW); // Set the size and data of our VBO and set it to STATIC_DRAW

    glGenBuffers(1, &indexes);// bind kopplingarna med buffern
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexes);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned short)*createTerrain.indices.size(), &createTerrain.indices[0], GL_STATIC_DRAW);

    glGenTextures(1, &textureID);
    glBindTexture(GL_TEXTURE_2D, textureID);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, createTerrain.globalWidth, createTerrain.globalHeight, 0, GL_BGR, GL_UNSIGNED_BYTE, createTerrain.globalData);

    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_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);     
    glGenerateMipmap(GL_TEXTURE_2D);


    MVPMatrixID = glGetUniformLocation(program, "gMVPMatrix");
    return 0;
}

void Render()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    //glClearColor(1, 0, 0, 1);
    glEnable(GL_DEPTH_TEST);

    camera.SetPosition(glm::vec3(camera.ReturnPosition().x, height - createTerrain.checkHeight(camera.ReturnPosition().x, camera.ReturnPosition().z), camera.ReturnPosition().z));  
    camera.ComputeMatricesFromInputs(window);
    projectionMatrix = camera.ReturnProjectionMatrix();
    viewMatrix = camera.ReturnViewMatrix();
    MVPMatrix = projectionMatrix * viewMatrix;
    particles.CalculateMVPMatrix(camera);

    //binda ihop location i shadern med buffern
    glBindBuffer(GL_ARRAY_BUFFER, VBOid);
    glEnableVertexAttribArray(0);  
    glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(VertexData), BUFFER_OFFSET(0));
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), BUFFER_OFFSET(16));     //The starting point of normals, 12 bytes away
    glEnableVertexAttribArray(2);
    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(VertexData), BUFFER_OFFSET(28)); 

    glUseProgram(program);
    glUniformMatrix4fv(MVPMatrixID, 1, GL_FALSE, &MVPMatrix[0][0]);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexes);
    glDrawElements(GL_TRIANGLES, createTerrain.indices.size(), GL_UNSIGNED_SHORT, BUFFER_OFFSET(0));

    glDisableVertexAttribArray(0);
    glDisableVertexAttribArray(1);
    glDisableVertexAttribArray(2);
}

The particle systems init and draw functions:

void Particles::Init()
{
    ShaderInfo shaders[] = {
        { GL_VERTEX_SHADER, "ParticleVert.txt"},
        { GL_GEOMETRY_SHADER, "ParticleGeo.txt"},
        { GL_FRAGMENT_SHADER, "ParticleFrag.txt"},
        { GL_NONE, NULL},
    };

    program = LoadShaders(shaders);

    glGenVertexArrays(1, VAOid);
    glBindVertexArray(VAOid[0]);

    glGenBuffers(1, &VBOid);
    glBindBuffer(GL_ARRAY_BUFFER, VBOid);
    glBufferData(GL_ARRAY_BUFFER, sizeof(PARTICLE) * particlePos.size(), &particlePos[0], GL_STATIC_DRAW);
    MVPMatrixID = glGetUniformLocation(program, "gMVPMatrix");
}

void Particles::Render(glm::mat4 MVPMatrix)
{
    UpdateParticles();

    glBindBuffer(GL_ARRAY_BUFFER, VBOid);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));

    glUseProgram(program);
    glUniformMatrix4fv(MVPMatrixID, 1, GL_FALSE, &MVPMatrix[0][0]);
    glDrawArrays(GL_POINTS, 0, maxParticles);
    glDisableVertexAttribArray(0);
}

My current call order is Terrain.Buffers(), Particles.Init(), Terrain.Render(), Particles.Render().

As it looks now, the program will render the terrain and Only the terrain. What makes this such a troubling case is that there are two lines of code in Terrain.Render(), namely:

glUseProgram(program);
glUniformMatrix4fv(MVPMatrixID, 1, GL_FALSE, &MVPMatrix[0][0]);

If I switch place on these two, so that glUniformMatrix4fv comes before glUseProgram, the particles are rendered instead of the terrain.

EDIT:

added glGenVertexArrays(1, VAOid); glBindVertexArray(VAOid[0]); in the code, in Particles.Init. I honestly do not know how VAO's works, a friend of mine said this was all I needed to do. Hasn't solved the problem though.

Uyghur Lives Matter
  • 18,820
  • 42
  • 108
  • 144
Jens Lomander
  • 111
  • 2
  • 10
  • learn how to use a VAO, and use one for each, it'll reduce the glVertexAttribPointer rebinding (you still need to enable and disable them though) – ratchet freak Feb 04 '14 at 12:10
  • Do your particles pass Z-Test? If they are behind the terrain, they wouldn't be rendered at all of course. – Pavel Beliy Feb 04 '14 at 13:11
  • Ratchet: This code snippets are from the code I had from school. I have a similar code at home, with the addition of VAO's. I'll update my post to the code with the VAO, although I'm not sure I've done it correctly. Pavel: It does pass Z-Test, since I can go all around the terrain with my camera and it is never rendered (It is also rendered above the terrain, so there should be nothing hidden by the terrain) – Jens Lomander Feb 04 '14 at 15:27

0 Answers0