1
\$\begingroup\$

I am implementing bullets into my game, and each bullet has a lifetime. Whenever the bullet has existed for a set amount of time or collides with an object, the bullet should be deleted. I implemented the timer properly and whenever the bullet reaches the end of its life, it gets deleted. The problem occurs whenever I shoot another bullet. This instantly causes a crash with the code: Exception thrown at 0x044765D7 (nvoglv32.dll) in gravityGame.exe: 0xC0000005: Access violation reading location 0x00000000.

After some research, I've found that this usually means that I am trying to render something that is a nullptr. My thinking is that I am not deleting the previous bullet properly and this affects the new one. A single bullet object is created on startup, and every new bullet is copied using the following line of code:

std::shared_ptr<Bullet> bullet = std::make_shared<Bullet>(*std::dynamic_pointer_cast<Bullet>(modelsLoaded.at(i)));

The reason for the dynamic pointer cast is because it is in a vector of its base class that it inherits from. Whenever the bullet needs to get deleted, it is erased from the bullets vector using bullets.erase(bullets.begin()+index); and the object it is pointing to should go out of scope, there is nothing else pointing to it. I feel like somehow having that object getting deleted has an adverse effect on the other bullets in the vector, but I do not know how. A new object is created and all the data from the original bullet gets copied over. How could deleting a copy of an object mess with the other copied objects? The functions to create, and render the models are below.

Generate Model Function

    //binds id
    glGenBuffers(1, &VBO);
    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &EBO);
    glGenTextures(1, &texture);
    glBindVertexArray(VAO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, verticesSizeTexture * 8 * sizeof(float), verticesTexture, GL_STATIC_DRAW);
    // position attribute
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);
    // color attribute
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
    glEnableVertexAttribArray(1);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, indicesSizeTexture * 4, indicesTexture, GL_STATIC_DRAW);
    //texture
    glBindTexture(GL_TEXTURE_2D, texture);
    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
    glEnableVertexAttribArray(2);

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);

Rendering Function

    unsigned int transformLoc = glGetUniformLocation(shader->ID, "location");    
    glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(trans));

    glBindTexture(GL_TEXTURE_2D, texture);   
    glBindVertexArray(VAO); 
    glDrawElements(GL_TRIANGLES, indicesSizeTexture, GL_UNSIGNED_INT, 0);
    glBindVertexArray(0);   

Destructor

glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glDeleteBuffers(1, &EBO);

Update After removing the contents of the destructor, the problem goes away. However, I would like to have some sort of destructor to allow for the proper freeing of memory.

\$\endgroup\$
1
  • \$\begingroup\$ This might be of help for you: gamedev.stackexchange.com/questions/175651/… I provided an answer to that thread aswell, which you might find interesting, that contains example code for a pattern called object pooling. \$\endgroup\$ Commented May 12, 2021 at 10:39

0

You must log in to answer this question.

Browse other questions tagged .