Instanced rendering glBufferSubData EXC_BAD_ACCESS

Hi. If I want to render more than 40000 instances I always run into this error EXC_BAD_ACCESS on glBufferSubData when I update the per instance attribute. (xcode). sometimes i can add more than 20000 but after a while i start to get this error, and after a few run i can add only 6000-8000 without EXC_BAD_ACCESS

The updateInstance() runs in the ofApp::update() function.

Mostly the mVboBox.getVbo().updateAttributeData(possize, &_size[0], _size.size()); line triggers this error sometimes the mVboBox.getVbo().updateAttributeData(posCoord, &_coord[0], _coord.size());. I check the values, and everything seems fine with the _coord and _size but i still got these errors after a few seconds.

void ofApp::updateInstance() {

      vector<float> _coord;
      vector<float> _texcoord;
      vector<float> _brightness;
      vector<float> _type;
      vector<float> _height;
      vector<float> _size;

      for (int i = 0; i < 10000; i++)
      {
             if (i < mainWordArray.size()) {
                  _texcoord.push_back(mainWordArray[i].word.x);
                  _texcoord.push_back(mainWordArray[i].word.y);
                  
                  _coord.push_back(mainWordArray[i].x / float(PORT_WIDTH ));
                  _coord.push_back(mainWordArray[i].y / float(PORT_HEIGHT));
                   _size.push_back(mainWordArray[i].word.width);
                  _size.push_back(mainWordArray[i].word.height);
                  _height.push_back(mainWordArray[i].height / float(PORT_HEIGHT));
                 _type.push_back( 6.0 );
            }
            else {
                  _texcoord.push_back(atlas.fboAtlases[0].szo[0].x);
                  _texcoord.push_back(atlas.fboAtlases[0].szo[0].y);
                  _coord.push_back(-10.0);
                  _coord.push_back(-10.0);
                  _size.push_back(atlas.fboAtlases[0].szo[0].width);
                  _size.push_back(atlas.fboAtlases[0].szo[0].height);
                  _height.push_back(1.0);
                  _type.push_back( 6.0 );
            }
      }

      mVboBox.getVbo().updateAttributeData(posCoord, &_coord[0], _coord.size());
      mVboBox.getVbo().updateAttributeData(posheight, &_height[0], _height.size());
      mVboBox.getVbo().updateAttributeData(postexcoord, &_texcoord[0], _texcoord.size());
      mVboBox.getVbo().updateAttributeData(possize, &_size[0], _size.size());
      mVboBox.getVbo().updateAttributeData(postype, &_type[0], _type.size());
}

when you call updateAttributeData (or any other upadte method in ofVbo you can’t pass more elements than there are already allocated, might that be the problem? if so you need to use set*Data instead or, better even. preallocate with enough space

ok but i setup the attributes in the ofApp::setup(). (forget to post the related code before, sorry) is this not allocate properly the space i need?

  vector<float> _type;
  vector<float> _texcoord;
  vector<float> _size;
  vector<float> _height;
  vector<float> _coord;
  
  for (int i = 0; i < 10000; i++)
  {
        float _t = 0;
        int _s = 0;
        
        _type.push_back( float(_t) );
        _texcoord.push_back(atlas.fboAtlases[int(_t)].szo[_s].x);
        _texcoord.push_back(atlas.fboAtlases[int(_t)].szo[_s].y);
        _size.push_back(atlas.fboAtlases[int(_t)].szo[_s].width * 1.0);
        _size.push_back(atlas.fboAtlases[int(_t)].szo[_s].height * 1.0);
        _height.push_back(1.0);
        _coord.push_back(0.0);
        _coord.push_back(0.0);
        
  }
  
  postype = glGetAttribLocation(mShdInstanced->getProgram(), "_type");
  mVboBox.getVbo().setAttributeData(postype, &_type[0], 1, 10000, GL_DYNAMIC_DRAW);
  
  postexcoord = glGetAttribLocation(mShdInstanced->getProgram(), "_texcoord");
  mVboBox.getVbo().setAttributeData(postexcoord, &_texcoord[0], 2, 10000 * 2, GL_DYNAMIC_DRAW);
  
  possize = glGetAttribLocation(mShdInstanced->getProgram(), "_size");
  mVboBox.getVbo().setAttributeData(possize, &_size[0], 2, 10000 * 2, GL_DYNAMIC_DRAW);
  
  posheight = glGetAttribLocation(mShdInstanced->getProgram(), "_height");
  mVboBox.getVbo().setAttributeData(posheight, &_height[0], 1, 10000, GL_DYNAMIC_DRAW);
  
  posCoord = glGetAttribLocation(mShdInstanced->getProgram(), "_coord");
  mVboBox.getVbo().setAttributeData(posCoord, &_coord[0], 2, 10000 * 2, GL_DYNAMIC_DRAW);


  mVboBox.getVbo().setAttributeDivisor(postype, 1);
  mVboBox.getVbo().setAttributeDivisor(postexcoord, 1);
  mVboBox.getVbo().setAttributeDivisor(posColor, 1);
  mVboBox.getVbo().setAttributeDivisor(posCoord, 1);
  mVboBox.getVbo().setAttributeDivisor(posheight, 1);
  mVboBox.getVbo().setAttributeDivisor(possize, 1);

ok, total shouldn’t be the total number of elements in the vector but the total number of vertices or colors or whatever you are passing, so in setAttributeData you need to call it with 10000 and it’ll be multiplied by 2 because that’s the number of coordinates and the same in update.

also instead of using vector for everything you can use vector or ofVec2f or ofFloatColor which makes it easier to reason about the sizes…

and as a performance advice, don’t create the vectors every time in update, keep the first ones from setup in the .h and just update their contents in update

Thanks! I changed the setAttributeData total number as you described and now it works fine. I don’t know why i thought that i have to multiply the total number with numCoords.