Search code examples
c++opengl-estexturesblackberry-10vbo

glDeleteBuffers crashes during destructor call


Hi I am using VBO to load image texture and then draw it in C++. VBO id generate and bind and draw occurs here

void ViewManager::render(){

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
if(decompressTileImage->tileTexure == 0)
    {
        loadTexture(decompressTileImage);
        glGenBuffers(1,&decompressTileImage->VBOId);
        glBindBuffer(GL_ARRAY_BUFFER,decompressTileImage->VBOId);
        glBufferData(GL_ARRAY_BUFFER,sizeof(*(this->tileCoordList))+sizeof(*(this->tileTextureCoordList)),0,GL_STATIC_DRAW);
        glBufferSubData(GL_ARRAY_BUFFER,0,sizeof(*(this->tileCoordList)),this->tileCoordList);
        glBufferSubData(GL_ARRAY_BUFFER,sizeof(*(this->tileCoordList)),sizeof(*(this->tileTextureCoordList)),this->tileTextureCoordList);

    }
    else
    {
        glBindBuffer(GL_ARRAY_BUFFER,decompressTileImage->VBOId);
        glBindTexture(GL_TEXTURE_2D, decompressTileImage->tileTexure);
    }

    glColor4f(1.0f, 1.0f, 1.0f, textureAlpha);

    if(textureAlpha < 1.0)
    {
        textureAlpha = textureAlpha + .03;
        this->tiledMapView->renderNow();
    }

glTexCoordPointer(3, GL_FLOAT, 0, (void*)sizeof(*(this->tileCoordList)));
glVertexPointer(3, GL_FLOAT, 0, 0);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glBindBuffer(GL_ARRAY_BUFFER,0);
glDisable(GL_BLEND);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisable(GL_TEXTURE_2D);
}

This function is in a class named MapTile. MapTile is created 35 times for 35 images downloaded from the internet. And then a thread calls this method 35 times for 35 MapTile object and keeps doing it. That is why I first check if the method is called for the first time so that I can load data and generate VBO id only once for each MapTile object. I check this with if(decompressTileImage->tileTexure == 0) this line. and then each time I just bind the vbo id to draw. No need to load the data again.

Here decompressTileImage is a TextureImageInfo class. The implementation is

#include "TextureImageInfo.h"
TextureImageInfo::TextureImageInfo(unsigned char * image,GLuint format,int texWidth,int texHeight,int imageWidth,int imageHeight,float tex_x,float tex_y)
{
// TODO Auto-generated constructor stub
this->format = format;
this->image = image;
this->imageHeight = imageHeight;
this->imageWidth = imageWidth;
this->texHeight = texHeight;
this->texWidth = texWidth;
this->tileTexure = 0;
this->VBOId = 0;
this->time = 0;

}

TextureImageInfo::~TextureImageInfo()
{
if(VBOId!=0)
    glDeleteBuffers(1,&VBOId);
}

It draws and does everything fine but crashes when I try to clean up the memory in the destructor of TextureImageInfo class which is given here. I don't understand why. I checked to see if the VBOId is generated and loaded in the memory with the if condition in the destructor too.


Solution

  • As indicated in the comments, OpendGL ES commands should be submitted from the same thread where the context was created.

    From the Blackberry docs Parallel processing with OpenGL ES:

    It is important to note that each OpenGL ES rendering context targets a single thread of execution.

    If you want to render multiple scenes, you can separate each scene into its own thread, making sure each thread has its own context