Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 5 of 5

Thread: Particles are not drawn

  1. #1
    Junior Member Newbie
    Join Date
    Jan 2017
    Posts
    17

    Particles are not drawn

    Hi,

    I wrote a code for a particle generator. It runs, but it doesn't show anything. Here is the code:

    Emitter.cpp:

    Code :
    #include "Emitter.h"
     
     
    Emitter::Emitter(GLuint nrParticles, glm::vec3 position, GLfloat radius, char *imgName)
    {
    this->m_Position = position;
    this->m_radius = radius;
     
    for (int i = 0; i < nrParticles; i++)
    {
    this->particles.push_back(Particle(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 0.0f), 0.0f, "blur.png"));
    }
     
    }
     
    void Emitter::Draw(Shader &shader)
    {
    for (int i = 0; i < particles.size() - 1; i++)
    {
    particles[i].Draw(shader);
    }
    }
     
    void Emitter::Update(GLfloat dt)
    {
    for (int i = 0; i <= particles.size() - 1; i++)
    {
    particles[i].Update(dt);
    }
    }
     
    void Emitter::SetParticlesAttributes()
    {
     
    for (int i = 0; i <= particles.size() - 1; i++)
    {
    particles[i].setLife(10.0f); //(((rand() % 10) + 1) * 15);
    particles[i].setVelocity(glm::vec3(0.0f, 2.0f, 0.0f)); //(((rand() % 10) + 1) * 2));
    }
    }

    Particle.cpp
    Code :
    #include "Particle.h"
    #include "Camera.h"
    GLfloat vertices[] = {
    0.5f,  0.5f, 0.0f, 1.0f, 1.0f,
    0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
    -0.5f, -0.5f, 0.0f, 0.0f, 0.0f,
    -0.5f,  0.5f, 0.0f, 0.0f, 1.0f
    };
     
    //Camera camera(glm::vec3(0.0f, 0.0f, 10.0f));
    Vbo vbo;
    Ebo ebo;
     
    Texture texture;
     
    GLuint indices[] = {  // Note that we start from 0!
    0, 1, 3,   // First Triangle
    1, 2, 3    // Second Triangle
    };
     
    Particle::Particle(glm::vec3 position, glm::vec3 velocity, GLfloat life, GLchar *imgName)
    {
    this->m_Position = position;
    this->m_Velocity = velocity;
    this->m_Life = life;
     
    this->vao.Init(1);
    vbo.Init(1);
    ebo.Init(1);
     
    this->vao.Bind();
    vbo.Bind(vertices, 20);
    ebo.Bind(indices, 6);
    this->vao.AttribPointer(0, 3, 5, 0);
    this->vao.AttribPointer(1, 2, 5, 3);
    this->vao.UnBind();
     
    texture.Init(1, imgName);
     
    }
     
    void Particle::Draw(Shader &shader)
    {
     
    shader.Use();
     
    glm::mat4 model;
    glm::mat4 view;
    glm::mat4 projection;
     
    model = glm::translate(model, glm::vec3(this->m_Position));
    model = glm::scale(model, glm::vec3(30.0f, 30.0f, 0.0f));
    view = glm::lookAt(glm::vec3(0.0f, 0.0f, 3.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
    projection = glm::perspective(45.0f, (float)1600 / (float)1200, 0.1f, 100.0f);
     
    GLuint modelLoc(glGetUniformLocation(shader.Program, "model"));
    GLuint viewLoc(glGetUniformLocation(shader.Program, "view"));
    GLuint projLoc(glGetUniformLocation(shader.Program, "projection"));
     
    glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
    glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
    glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection));
     
    texture.Bind();
    glUniform1i(glGetUniformLocation(shader.Program, "ourTexture"), 0);
     
    this->vao.Bind();
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
    this->vao.UnBind();
     
    }
     
    void Particle::Update(GLfloat dt)
    {
    if (this->m_Life > 0)
    {
    this->m_Position += m_Velocity;
    }
    else
    {
    //m_Life -= dt;
    }
    }
     
    void Particle::setLife(GLfloat life)
    {
    this->m_Life = life;
    }
    GLfloat Particle::getLife()
    {
    return this->m_Life;
    }
     
    void Particle::setPosition(glm::vec3 position)
    {
    this->m_Position = position;
    }
    glm::vec3 Particle::getPosition()
    {
    return this->m_Position;
    }
     
    void Particle::setVelocity(glm::vec3 velocity)
    {
    this->m_Velocity = velocity;
    }
    glm::vec3 Particle::getVelocity()
    {
    return this->m_Velocity;
    }

    And Main.cpp:
    Code :
    #include <iostream> 
    #include <glad/glad.h>
    #include<KHR\khrplatform.h>
    //GLFW
    #include <glfw3.h>
     
    #include "Shader.h"
    #include "Camera.h"
     
    // GLM
    #include <glm/glm.hpp>
    #include <glm/gtc/matrix_transform.hpp>
    #include <glm/gtc/type_ptr.hpp>
    #include "stb_image.h"
     
    #include "Emitter.h"
     
    void framebuffer_size_callback(GLFWwindow* window, int width, int height);
    void processInput(GLFWwindow *window);
     
    // settings
    const unsigned int SCR_WIDTH = 1600;
    const unsigned int SCR_HEIGHT = 1200;
     
    Emitter *e1;
     
    int main()
    {
    // glfw: initialize and configure
    // ------------------------------
    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    //glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // uncomment this statement to fix compilation on OS X
     
    // glfw window creation
    // --------------------
    GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL);
    if (window == NULL)
    {
    std::cout << "Failed to create GLFW window" << std::endl;
    glfwTerminate();
    return -1;
    }
    glfwMakeContextCurrent(window);
    glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
     
    // glad: load all OpenGL function pointers
    // ---------------------------------------
     
    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
    {
    std::cout << "Failed to initialize GLAD" << std::endl;
    return -1;
    }
     
    // build and compile our shader zprogram
    // ------------------------------------
    Shader shader("particle.vs", "particle.frag");
    e1 = new Emitter(100, glm::vec3(0.0f), 30.0f, "blur.png");
     
    // render loop
    // -----------
    while (!glfwWindowShouldClose(window))
    {
    GLfloat dt = glfwGetTime();
    // input
    // -----
    processInput(window);
    e1->Update(dt);
     
    // render
    // ------
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
     
    e1->Draw(shader);
    // glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
    // -------------------------------------------------------------------------------
    glfwSwapBuffers(window);
    glfwPollEvents();
    }
     
    // optional: de-allocate all resources once they've outlived their purpose:
    // ------------------------------------------------------------------------
     
    // glfw: terminate, clearing all previously allocated GLFW resources.
    // ------------------------------------------------------------------
    glfwTerminate();
    return 0;
    }
     
    // process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly
    // ---------------------------------------------------------------------------------------------------------
    void processInput(GLFWwindow *window)
    {
    if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
    glfwSetWindowShouldClose(window, true);
     
    if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS)
    {
    std::cout << "Space Pressed" << std::endl;
    e1->SetParticlesAttributes();
    }
    }
     
    // glfw: whenever the window size changed (by OS or user resize) this callback function executes
    // ---------------------------------------------------------------------------------------------
    void framebuffer_size_callback(GLFWwindow* window, int width, int height)
    {
    // make sure the viewport matches the new window dimensions; note that width and 
    // height will be significantly larger than specified on retina displays.
    glViewport(0, 0, width, height);
    }

    I tried to debug it but I can't figure it out what could be wrong. If I delete the emitter object and create a particle object it draws it.But with the emitter and many particles(even with one) it doesn't draw anything.
    Can you help me with some clues please ?
    Thank you very much. :P

  2. #2
    Member Regular Contributor
    Join Date
    Jul 2012
    Posts
    418
    Maybe because of this ?

    this->particles.push_back(Particle(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 0.0f), 0.0f, "blur.png"));
    All values are set to 0. If they refer to position and size, you'll see nothing.
    But since the code related to particles was not provided, this is just a far guess.

  3. #3
    Junior Member Newbie
    Join Date
    Jan 2017
    Posts
    17
    Hi,

    Thank you for your reply.The code for the particles I posted it as well. Is Particle.cpp, the second one. Also the values from the constructor are for position, velocity, life, and image. In main I give some velocity to the particles with e1->SetParticlesAttributes(); inside the processInput() function.

    I've made 2 projects.One for instantiated particle and one for instantiated emitter. I've debugged and I've played a little and then I saw that on the emitter project, after I insert the particle objects into the vector, the constructors are destroyed (which is normal, because are going out of scope). But the objects shouldn't be kept with them variables and all stuff inside the vector ?

    What I saw more was that with the Emitter Project, the bindings with the Vao's, Vbo's and Ebo's are destroyed as well, to say like that... they don't have the same values like in Particle Project.
    For 1st particle I should have VaoID = 1, VboID = 1, EboID = 2 and for the other: VaoID = 2, VboID = 3, and Ebo = 4.

    All the buffers contain the same values: 3452816845.

    I tried to create a copy constructor (for the first time). I'm not sure is good how I did it. The new code is:

    For Constructor:

    Particle::Particle(const Particle &particle)
    {
    this->m_Position = particle.m_Position;
    this->m_Velocity = particle.m_Velocity;
    this->m_Life = particle.m_Life;
    }

    For creating particle objects and inserting them into the vector:

    Emitter::Emitter(GLuint nrParticles, glm::vec3 position, GLfloat radius, GLchar *imgName)
    {
    this->m_Position = position;
    this->m_radius = radius;

    for (int i = 0; i < nrParticles; i++)
    {
    this->particles.push_back(Particle(Particle(glm::vec3(0 .0f), glm::vec3(0.0f), 0.0f, imgName)));
    }
    }

    Although I've made this change, still doesn't work.

  4. #4
    Member Regular Contributor
    Join Date
    May 2016
    Posts
    415
    maybe you're interested in "gpu-particles", that allows you to simulate alot more particles that "cpu-particles": (>1 million particles)
    https://sites.google.com/site/john87...pute-shader/tu


    therefore you need 2 programs (shaders) instaed of 1:
    -- the first program (shader) simulates the particles
    -- the second program (shader) draws the particles

    to simultate particles, you use a computeshader or a vertexshader + transformfeedback
    to draw them, just call glDrawArrays(GL_POINTS, 0, particlecount) with a simple color program

    if you want to be able to collide the particles on some of our scene's geometry, you can "capture" the geometry too with a transformfeedback and do a simple "triangle-line" intersection test in the shader, the complete program is described in "OpenGL Programming Guide 8th edition"
    Last edited by john_connor; 06-06-2017 at 12:02 PM.

  5. #5
    Junior Member Newbie
    Join Date
    Jan 2017
    Posts
    17
    I found what was the problem. In the code is used a copy constructor(Particle). Somebody told me that the object was created, copied and destroyed during the "push_back" and the copy lives on in the vector, and is destroyed after returning. So that's why my variables have other values.
    Unfortunately John, for the moment I don't want to go to deep. I try to do the things first in my way :P
    Anyway thank you again for your replies. :P

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •