2

I am working on a game, and trying to implement the instancized CPU-Particle System programmed on http://www.opengl-tutorial.org/intermediate-tutorials/billboards-particles/particles-instancing/ i managed to get it working in my code structure, but i am trying to draw other objects in the same window, which i can't, i have tested it, and it only allows me to draw one, either draw the particle system or draw the object i want.

The problem happens specifically at this code part :

    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    // Use our shader
    glUseProgram(particleprogramID->programHandle);

    unit2 +=1;

    glActiveTexture(GL_TEXTURE0 + unit2);
    glBindTexture(GL_TEXTURE_2D, texture);
    glUniform1i(TextureID, unit2);

    glm::mat4 ViewMatrix = camera->getViewMatrix();
    // Same as the billboards tutorial
    glUniform3f(CameraRight_worldspace_ID, ViewMatrix[0][0], ViewMatrix[1][0], ViewMatrix[2][0]);
    glUniform3f(CameraUp_worldspace_ID   , ViewMatrix[0][1], ViewMatrix[1][1], ViewMatrix[2][1]);

    glUniformMatrix4fv(ViewProjMatrixID, 1, GL_FALSE, &mvp[0][0]);
    //glUniformMatrix4fv(modviewprojID, 1, GL_FALSE, &mvp[0][0]);

    //1rst attribute buffer : vertices
    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, billboard_vertex_buffer);
    glVertexAttribPointer(
        0,                  
        3,                  
        GL_FLOAT,           
        GL_FALSE,           
        0,                  
        (void*)0            
    );

    // 2nd attribute buffer : positions of particles' centers
    glEnableVertexAttribArray(1);
    glBindBuffer(GL_ARRAY_BUFFER, particles_position_buffer);
    glVertexAttribPointer(
        1,                                
        4,                               
        GL_FLOAT,                         
        GL_FALSE,                        
        0,                               
        (void*)0                         
    );

    // 3rd attribute buffer : particles' colors
    glEnableVertexAttribArray(2);
    glBindBuffer(GL_ARRAY_BUFFER, particles_color_buffer);
    glVertexAttribPointer(
        2,                                
        4,                                
        GL_UNSIGNED_BYTE,                 
        GL_TRUE,                          
        0,                                
        (void*)0                          
    );


    glVertexAttribDivisor(0, 0); 
    glVertexAttribDivisor(1, 1);
    glVertexAttribDivisor(2, 1); 

    glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, ParticlesCount);

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

then i try to draw my star:

unit2 += 1;
    starTexture->Bind(unit2);
    shaderObject ->useShader();
    glUniform1i(glGetUniformLocation(shaderObject->programHandle, "colorTexture"), unit2);
    glUniformMatrix4fv(glGetUniformLocation(shaderObject->programHandle, "modelMatrix"), 1, GL_FALSE, glm::value_ptr(star1->getModelMatrix()));
    glUniformMatrix4fv(glGetUniformLocation(shaderObject->programHandle, "projectionMatrix"), 1, GL_FALSE, glm::value_ptr(projectionViewMatrix));

    star1->draw();

the vertex and fragment shader for the particle system:

    #version 330 core

// Input vertex data, different for all executions of this shader.
layout(location = 0) in vec3 squareVertices;
layout(location = 1) in vec4 xyzs; // Position of the center of the particule and size of the square
layout(location = 2) in vec4 color; // Position of the center of the particule and size of the square

// Output data ; will be interpolated for each fragment.
out vec2 UV;
out vec4 particlecolor;

// Values that stay constant for the whole mesh.
uniform vec3 CameraRight_worldspace;
uniform vec3 CameraUp_worldspace;
uniform mat4 VP; // Model-View-Projection matrix, but without the Model (the position is in BillboardPos; the orientation depends on the camera)

void main()
{
    float particleSize = xyzs.w; // because we encoded it this way.
    vec3 particleCenter_wordspace = xyzs.xyz;

    vec3 vertexPosition_worldspace = 
        particleCenter_wordspace
        + CameraRight_worldspace * squareVertices.x * particleSize
        + CameraUp_worldspace * squareVertices.y * particleSize;

    // Output position of the vertex
    gl_Position = VP * vec4(vertexPosition_worldspace, 1.0f);

    // UV of the vertex. No special space for this one.
    UV = squareVertices.xy + vec2(0.5, 0.5);
    particlecolor = color;
}

frragment shader:

    #version 330 core

// Interpolated values from the vertex shaders
in vec2 UV;
in vec4 particlecolor;

// Ouput data
out vec4 color;

uniform sampler2D myTexture;

void main(){
    // Output color = color of the texture at the specified UV
    color = texture2D( myTexture, UV ) * particlecolor;

}

and it only displays the particle system:

worth mentioning is: the object i want to draw is a star modelled in blender and is displayed correctly when drawn alone or with other objects other than the particle system. and has its own class having buffers for psitions, UVs, indices and normals...

it seems like the star data are being swallowed by the buffer...

i appreciate every help...

  • 1
    Are you setting the `glVertexAttribDivisor()` values back to `0` after you're done with the instanced rendering? – Reto Koradi Jun 14 '14 at 17:37
  • yes, just like in the tutorial glVertexAttribDivisor(0, 0); glVertexAttribDivisor(1, 1); glVertexAttribDivisor(2, 1); – user3561689 Jun 14 '14 at 17:42
  • Well, yes, I saw that, but that's not what I'm talking about. That sets them **for** instanced rendering. But it looks like your trying to do non-instanced rendering afterwards. If that's the case, you have to set those values back to their original value of 0. – Reto Koradi Jun 14 '14 at 18:17
  • Using VAOs here would help a lot. If your implementation supports instanced arrays it definitely supports VAOs. And then you would not need a lot of this `DisableVertexAttribArray` junk and you would not need to continually set the vertex pointers every time you draw. – Andon M. Coleman Jun 14 '14 at 18:45
  • @RetoKoradi you mean setting them to glVertexAttribDivisor(0, 0); glVertexAttribDivisor(0, 0); glVertexAttribDivisor(0, 0); after: glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, ParticlesCount); glDisableVertexAttribArray(0); glDisableVertexAttribArray(1); glDisableVertexAttribArray(2); and then try to draw the star? – user3561689 Jun 14 '14 at 20:42
  • 1
    @user3561689: `glVertexAttribDivisor(1, 0)` and `glVertexAttribDivisor(2, 0)` after you're done drawing the instanced geometry. – Reto Koradi Jun 14 '14 at 20:45
  • @user3561689: Calling `glVertexAttribDivisor (0, ...)` 3 times like that is pointless. Each call applies to a particular vertex attribute array, so you would actually want `0,0`, `1,0`, `2,0`. – Andon M. Coleman Jun 14 '14 at 20:46
  • @RetoKoradi writing glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, ParticlesCount); glVertexAttribDivisor(0, 0); // particles vertices : always reuse the same 4 vertices -> 0 glVertexAttribDivisor(1, 0); // positions : one per quad (its center) -> 1 glVertexAttribDivisor(2, 0); glDisableVertexAttribArray(0); glDisableVertexAttribArray(1); glDisableVertexAttribArray(2); gives me an error in vertexshader:Failed to compile shaderShader/Particle.vertexshader ERROR: 0:4: 'location' : syntax error parse error i will post the code of the vertex and fragment shader – user3561689 Jun 15 '14 at 07:23
  • You completely lost me there. How would adding a couple of API calls in your C++ code cause the shader to fail compiling? – Reto Koradi Jun 15 '14 at 19:08
  • @RetoKoradi oh sorry, i think i forgot to switch to the HD graphic card, that's why it didn't compile, but i tried it and it still only draws the particle system without the star... – user3561689 Jun 15 '14 at 20:31

0 Answers0