Hello cinder and inputs


#1

Hello hello,

I’m working through the old Hello Cinder tutorial (I want to possibly use Cinder as the basis for a 3D app) and I’ve hit something I can’t quite figure out:

I tried adding overrides for the mouse wheel and keyboard pressed handlers, but I feel like they’re not firing properly or only firing at odd times. What I’d like is for the radius of my particles to change when I press keyboard keys 1-9, and for the mouse wheel to increase or decrease the radius by the wheel increment. Instead I get partial changes or things just jitter, but stay roughly in the same place, or will only update when I resize the window.

I’m probably doing something really silly but I’ve been trying to get this sorted for a few hours and I don’t feel like I’m any closer. I was hoping someone could take a peek and tell me where I’ve gone wrong.

Here’s a pastebin:
https://pastebin.com/xMcUC2e0

Thanks in advance!


#2

It’s because those events are pumped on the main thread and your drawing of the particles is hogging all the time. Your application (in release mode) runs at around 5fps on my new-ish iMac, and gl::drawSolidCircle is the culprit. It’s the slowest way to get a circle on to the screen and isn’t recommended for heavy usage. Once you speed up the FPS of your application, I suspect your events will start coming in as you expect.

*edit* Here’s a simple way to get some performance back. (Still not optimal).

First, in your app’s draw function:

void proj01App::draw()
{
    gl::clear(); // You were missing this!
    gl::VertBatch batch ( GL_TRIANGLES );
    
    for ( auto iterator = particles.begin(); iterator != particles.end(); iterator++ ) {
        iterator->draw( batch );
    }
    
    batch.draw();
}

Then change your particle’s draw function to:

const void draw ( gl::VertBatch& batch ) 
{
        
    int numSegments = (int)math<double>::floor( radius * M_PI * 2 );
    if( numSegments < 3 ) numSegments = 3;
    
    float a = 0.0f;
    float aStep = ( 2.0 * M_PI ) / static_cast<float>(numSegments);
    
    for ( int i = 0; i < numSegments; i++ )
    {
        vec2 p0;
        p0.x = location.x + std::cos ( a ) * radius;
        p0.y = location.y + std::sin ( a ) * radius;
        
        vec2 p1;
        p1.x = location.x + std::cos ( a + aStep ) * radius;
        p1.y = location.y + std::sin ( a + aStep ) * radius;
        
        batch.color( color );
        batch.vertex( p0 );
        
        batch.color( color );
        batch.vertex( p1 );
        
        batch.color( color );
        batch.vertex( location );
        
        a += aStep;
    }
}

This brings it back to 60fps for me, but is still doing a lot more work per frame than it needs to. Hopefully helps.

A


#3

Ha! I hadn’t gotten to checking framerate or even considered that the draw calls and uploads were killing me. Thank you for that!

Am I then correct in thinking that the input callbacks are not called asynchronously?

The batch thing is interesting-- the way you’re using it, it will work in a single draw call, yes?

In terms of doing a lot of work, I want to eventually get to a point where I’m doing a single upload of geometry, then filling dynamic buffers per frame that change the point positions using a vertex program or a compute shader. (Buffers may use matrices, but I’m not sure yet.) I figured the best way to learn a new API is to stumble through the out-of-date tutorials.

Thanks again! Onwards. :stuck_out_tongue:


#4

The batch thing is interesting-- the way you’re using it, it will work in a single draw call, yes?

Yep, it already is. I’m filling up one big buffer with all the vertex info and then the batch.draw() fires it off.

In terms of doing a lot of work, I want to eventually get to a point where I’m doing a single upload of geometry, then filling dynamic buffers per frame that change the point positions using a vertex program or a compute shader. (Buffers may use matrices, but I’m not sure yet.)

All of which are good ideas. There’s plenty of ways to skin this particular cat.

I figured the best way to learn a new API is to stumble through the out-of-date tutorials.

There’s a butt-ton of good samples, especially in the samples/_opengl folder that will give you a push in the right direction.

Cheers,

A.