# Draw instances with dynamic count

**URL:** <https://discourse.libcinder.org/t/draw-instances-with-dynamic-count/1223>\
**Category:** Uncategorized\
**Created:** [July 17, 2018, 2:04pm UTC](https://discourse.libcinder.org/t/draw-instances-with-dynamic-count/1223 "2018-07-17T14:04:16Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![hperigo](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/hperigo/32/409_2.png) [@hperigo](https://discourse.libcinder.org/u/hperigo)\
**Post date:** [July 17, 2018, 2:04pm UTC](https://discourse.libcinder.org/t/draw-instances-with-dynamic-count/1223/1 "2018-07-17T14:04:16Z")

</div>

Hi All,

is it possible to dynamically change the number of instances being drawn?

for example, in the InstancedTeapot sample, if I add this line in the keyUp fn:

```
void InstancedTeapotsApp::keyUp(cinder::app::KeyEvent event){
    
    
    if( event.getChar() == 'i' ){
        NUM_INSTANCES_Y += 1;
    }else if( event.getChar() == 'u' ){
        NUM_INSTANCES_Y -= 1;
    }
    
    mInstanceDataVbo.reset();
    
    std::vector<vec3> positions;
    for( size_t potX = 0; potX < NUM_INSTANCES_X; ++potX ) {
        for( size_t potY = 0; potY < NUM_INSTANCES_Y; ++potY ) {
            float instanceX = potX / (float)NUM_INSTANCES_X - 0.5f;
            float instanceY = potY / (float)NUM_INSTANCES_Y - 0.5f;
            positions.push_back( vec3( instanceX * vec3( DRAW_SCALE, 0, 0 ) + instanceY * vec3( 0, 0, DRAW_SCALE ) ) );
        }
    }
    
    // create the VBO which will contain per-instance (rather than per-vertex) data
    mInstanceDataVbo = gl::Vbo::create( GL_ARRAY_BUFFER, positions.size() * sizeof(vec3), positions.data(), GL_DYNAMIC_DRAW );
    console() << NUM_INSTANCES_X * NUM_INSTANCES_Y << endl;
}

```

The program does not crash, but the teapots stop moving… Recreating the actual teapot VBO every time the count changes works:

```
geom::BufferLayout instanceDataLayout;
instanceDataLayout.append( geom::Attrib::CUSTOM_0, 3, 0, 0, 1 /* per instance */ );

gl::VboMeshRef mesh = gl::VboMesh::create( geom::Teapot().subdivisions( 4 ) );
mesh->appendVbo( instanceDataLayout, mInstanceDataVbo );

// and finally, build our batch, mapping our CUSTOM_0 attribute to the "vInstancePosition" GLSL vertex attribute
mBatch = gl::Batch::create( mesh, mGlsl, { { geom::Attrib::CUSTOM_0, "vInstancePosition" } } );

```

but it feels kinda cumbersome. Is there a better way to do this?

---

<div class="post-metadata">

**Author:** ![paul.houx](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/paul.houx/32/31_2.png) [@paul.houx](https://discourse.libcinder.org/u/paul.houx)\
**Post date:** [July 17, 2018, 3:46pm UTC](https://discourse.libcinder.org/t/draw-instances-with-dynamic-count/1223/2 "2018-07-17T15:46:24Z")

</div>

Hi,

yes, this is possible, but I would not recommend the approach you took. It’s better to create a buffer large enough to draw the maximum number of instances, then use this buffer over and over again:

```auto
static const int kMaxCount = 4096;
mInstanceDataVbo = gl::Vbo::create( GL_ARRAY_BUFFER, kMaxCount * sizeof(vec3), nullptr, GL_DYNAMIC_DRAW );

```

Every update, fill it with the data of the current number of instances, no more and no less.

```auto
const float scale = 10.0f;
const unsigned count = Rand::randUint( kMaxCount );

auto ptr = (vec3*) mInstanceDataVbo->mapReplace();
for( unsigned i=0; i < count; ++i ) {
  ptr->x = ( i % 64 ) * scale; // This is...
  ptr->y = ( i / 64 ) * scale; // ...just a...
  ptr->z = 0.0f; // ...stupid example.
  ptr++;
}
mInstanceDataVbo->unmap(); // <-- Important!

```

Then in your `draw()` method, use the following call:

```auto
if( count > 0 )
  mBatch->drawInstanced( glm::min( count, kMaxCount ) );

```

-Paul

---

<div class="post-metadata">

**Author:** ![hperigo](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/hperigo/32/409_2.png) [@hperigo](https://discourse.libcinder.org/u/hperigo)\
**Post date:** [July 17, 2018, 4:10pm UTC](https://discourse.libcinder.org/t/draw-instances-with-dynamic-count/1223/3 "2018-07-17T16:10:42Z")

</div>

Ah!  
I see, thanks paul!

---

<div class="post-metadata">

**Author:** ![paul.houx](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/paul.houx/32/31_2.png) [@paul.houx](https://discourse.libcinder.org/u/paul.houx)\
**Post date:** [July 17, 2018, 6:45pm UTC](https://discourse.libcinder.org/t/draw-instances-with-dynamic-count/1223/4 "2018-07-17T18:45:30Z")

</div>

By the way: the reason your teapots stopped moving, is that by creating a new `Vbo` for your instances, you no longer use the `Vbo` attached to the `VboMesh` in use by the `Batch` (whoa, that’s a lot of info in one sentence).

One cool thing you can do with a dynamic instance count, is performing frustum culling and then sorting the instances by visibility. Then count and upload the visible instances to the buffer and draw them.

---

<div class="post-metadata">

**Author:** ![hperigo](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/hperigo/32/409_2.png) [@hperigo](https://discourse.libcinder.org/u/hperigo)\
**Post date:** [July 20, 2018, 2:18am UTC](https://discourse.libcinder.org/t/draw-instances-with-dynamic-count/1223/5 "2018-07-20T02:18:19Z")

</div>

yeah, I naively thought that because they were shared\_ptr’s the underling data would also be swapped…

nice, thanks for the example!

out of curiosity, I haven’t had time to test this out.  
But I’m guessing that if the GL\_DEPTH\_TEST is disabled, the instance shapes will be drawn according to their order in the buffer right? What would be your approach to draw a bunch of instance shapes a couple of gl::Batch’s in between in a 2D environment?

---

<div class="post-metadata">

**Author:** ![paul.houx](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/paul.houx/32/31_2.png) [@paul.houx](https://discourse.libcinder.org/u/paul.houx)\
**Post date:** [July 20, 2018, 6:29am UTC](https://discourse.libcinder.org/t/draw-instances-with-dynamic-count/1223/6 "2018-07-20T06:29:07Z")

</div>

The instances are always drawn in the order in which they appear in the buffer. If depth testing is enabled, the depth test happens per fragment (at the end of the fragment shader). If the fragment’s depth is greater than the value stored in the depth buffer, the fragment is discarded.

It does not really matter if you’re drawing in 2D or 3D, for OpenGL this is just a matter of different projections and whether or not depth testing is enabled. But if you want to draw something with depth testing disabled, make sure to draw the furthest instance first (a.k.a. _painter’s algorithm_).
