OpenGL - 渲染粒子和地形,但不能同时工作

时间:2014-02-04 11:45:23

标签: opengl visual-studio-2012 rendering terrain particle-system

我正在进行学校实验,而我的任务是使用高度图渲染基本地形,以及某种粒子系统(现在我只是将绘制成平面正方形的点爆破)。

问题在于,虽然我可以渲染地形和粒子系统,但出于某种原因我不能同时渲染它们。

地形的启动和绘制功能:

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);
}

粒子系统初始化和绘制函数:

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);
}

我当前的通话顺序是Terrain.Buffers(),Particles.Init(),Terrain.Render(),Particles.Render()。

现在看来,程序将渲染地形和仅地形。是什么让这个令人不安的情况是Terrain.Render()中有两行代码,即:

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

如果我在这两个上切换位置,以便glUniformMatrix4fv出现在glUseProgram之前,则渲染粒子而不是地形。

编辑:

添加了glGenVertexArrays(1, VAOid); glBindVertexArray(VAOid[0]); 在代码中,在Particles.Init中。我老实说不知道VAO是如何工作的,我的一位朋友说这就是我需要做的。虽然没有解决问题。

0 个答案:

没有答案