Skip to content

Instantly share code, notes, and snippets.

@paulhoux
Created February 28, 2020 15:09
Show Gist options
  • Save paulhoux/febdf7cc54c008dd4594eb98d07ce69b to your computer and use it in GitHub Desktop.
Save paulhoux/febdf7cc54c008dd4594eb98d07ce69b to your computer and use it in GitHub Desktop.
Instanced Circles using `geom::Ring`
#include "cinder/app/App.h"
#include "cinder/app/RendererGl.h"
#include "cinder/gl/gl.h"
using namespace ci;
using namespace ci::app;
using namespace std;
class CirclesApp : public App {
public:
void setup() override;
void update() override;
void draw() override;
private:
gl::BatchRef mBatch;
gl::VboRef mInstances;
std::vector<vec4> mData;
};
void CirclesApp::setup()
{
// Create the shader.
const char *vertShader = R"V0G0N(
#version 150
uniform mat4 ciModelViewProjection;
in vec4 ciPosition;
in vec2 ciTexCoord0;
in vec4 ciColor;
in vec4 iData; // per instance: xy = center, z = radius, w = width
out vec4 vertColor;
void main( void )
{
vertColor = ciColor;
vec4 position = ciPosition;
position.xy *= mix( iData.z, iData.w / 0.9, ciTexCoord0.x ); // Vertices on inner radius have coordinate x = 1 and radius 0.9, so compensate for that.
position.xy += iData.xy;
gl_Position = ciModelViewProjection * position;
}
)V0G0N";
const char *fragShader = R"V0G0N(
#version 150
in vec4 vertColor;
out vec4 fragColor;
void main( void )
{
fragColor = pow( vertColor, vec4( 1.0 / 2.2 ) );
}
)V0G0N";
gl::GlslProgRef glsl = gl::GlslProg::create( vertShader, fragShader );
// Create ring mesh. With a width of 0.1, we have an inner radius of 0.9. See shader.
gl::VboMeshRef mesh = gl::VboMesh::create( geom::Ring().radius( 1.0f ).width( 0.1f ).subdivisions( 128 ) );
// Create ring instances.
mData.clear();
mData.emplace_back( 0, 0, 150.0f, 144.0f ); // x,y = center, z = outer radius, w = inner radius
mData.emplace_back( 0, 0, 140.0f, 135.0f );
mData.emplace_back( 0, 0, 130.0f, 126.0f );
mData.emplace_back( 0, 0, 120.0f, 117.0f );
mData.emplace_back( 0, 0, 110.0f, 108.0f );
mInstances = gl::Vbo::create( GL_ARRAY_BUFFER, mData.size() * sizeof( vec4 ), mData.data(), GL_STATIC_DRAW );
// Describe the layout of the instance data.
geom::BufferLayout layout;
layout.append( geom::Attrib::CUSTOM_0, sizeof( vec4 ) / sizeof( float ), 0, 0, 1 /* per instance */ );
// Append instance data to mesh.
mesh->appendVbo( layout, mInstances );
// Create batch, combining the mesh, the shader and a full description of the data.
mBatch = gl::Batch::create( mesh, glsl, { { geom::Attrib::CUSTOM_0, "iData" } } );
}
void CirclesApp::update()
{
}
void CirclesApp::draw()
{
gl::clear();
gl::ScopedColor scpColor( 1, 1, 1 );
gl::ScopedModelMatrix scpModel;
gl::translate( getWindowSize() / 2 );
mBatch->drawInstanced( mData.size() );
}
CINDER_APP( CirclesApp, RendererGl( RendererGl::Options().msaa( 32 ) ) )
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment