読者です 読者をやめる 読者になる 読者になる

Cinder一巡り #2

グラフィック基礎

プロジェクトを作成するとhogeApp.cppのdrawメソッドには以下のコードが書かれています。

void BasicShapesApp::draw()
{
    // clear out the window with black
    gl::clear( Color( 0, 0, 0 ) ); 
}

gl:clear()は指定した色で画面をクリアします。draw()は毎フレームに一度だけ呼び出されるので、デフォルトの30fpsだと1秒間に30回画面が黒で上書きされます。

色はci::Color()メソッドにRGBの値をそれぞれfloatで0~1の範囲の値を渡して指定します。

gl::clear( Color( 1.0f, 0.0f, 0.0f ))

基本的なシェイプを描画する

基本的なシェイプの描画には名前空間glにメソッドが用意されているので、それを使うことができます。

void BasicShapesApp::draw()
{
    gl::clear( Color( 0, 0, 0 ) );
    
    // 線を描く
    glLineWidth(2);
    gl::color( 0, 1, 1 );
    gl::drawLine( Vec2f(0, 0),
                  Vec2f(getWindowWidth(), getWindowHeight()) );
    
    gl::color( 1, 0, 1 );
    gl::drawLine( Vec2f(getWindowWidth(), 0 ),
                  Vec2f( 0, getWindowHeight()) );
    
    // 円を描く
    // x, y, radius
    gl::drawSolidCircle( Vec2f(getWindowWidth()/2, getWindowHeight()/2 ), 50 );
    
    gl::color( 0, 1, 1 );
    gl::drawStrokedCircle( getWindowCenter(), 100 );
    
    // 3つ目の引数に数値を渡すと円を描くときに使われる3角形の数を指定できる
    //gl::drawSolidCircle( getWindowCenter(), 30, 5 );
    
    
    // 矩形を描く
    gl::drawSolidRect( Rectf(getWindowWidth()/2 - 20.0f,     // left top x
                             getWindowHeight()/2 - 20.0f,    // left top y
                             getWindowWidth()/2 + 20.0f,     // right bottom x
                             getWindowHeight()/2 + 20.0f) ); // right bottom y
    
}

画像を読み込む

画像を扱うには、cinder/ImageIo.hとcinder/gl/Texture.hをインクルードします。

#include "cinder/ImageIo.h"
#include "cinder/gl/Texture.h"

ImageIoは画像の入出力、gl/TextureはOpenGLのテクスチャを使ってスクリーンに画像を表示するためのものです。

次に、実際に画像データを格納するための変数を用意します。

gl:Texture imgTexture;

imgTextureにはURLで指定した画像と、アプリケーションのディレクトリ内でassetsというディレクトリを作り、その中に保存した画像を使用できます。

void BasicImagesApp::setup()
{
    // URLから画像を読み込む
    imgTexture = gl::Texture( loadImage( loadUrl( Url("http://libcinder.org/docs/images/logo.png") ) ) );

    // assetsから画像を読み込む
    imgTexture = gl::Texture( loadImage( loadAsset( "MyImage.png") ) );
}

void BasicImagesApp::draw()
{
    // clear out the window with black
    gl::clear( Color( 0, 0, 0 ) );
    gl::draw( imgTexture, getWindowBounds() );
}

アニメーション

アニメーションの基本はフレーム毎に呼び出されるupdate()とdraw()内で、描画のためのパラメータに変化を与えることです。

ウィンドウサイズとフレームレートを設定して、円がアニメーションするようにしてみます。

#include "cinder/app/AppBasic.h"
#include "cinder/gl/gl.h"
#include "cinder/Rand.h"

using namespace ci;
using namespace ci::app;
using namespace std;

#define DEFAULT_RADIUS 60

class BasicAnimationApp : public AppBasic {
  public:
    Vec2f currentPos;   // 円の位置座標
    Vec2f targetPos;    // 円の目標位置座標
    float circleRadius;    // 半径
    
    void prepareSettings( Settings* settings );
    void setup();
    void update();
    void draw();
};

void BasicAnimationApp::prepareSettings( Settings* settings )
{
    settings->setWindowSize( 800, 600 );
    settings->setFrameRate( 60 );
}

void BasicAnimationApp::setup()
{
    // 初期位置
    currentPos = Vec2f( Rand::randFloat( 0, getWindowWidth() ),
                       Rand::randFloat( 0, getWindowHeight() ) );
    
    // 目標位置
    targetPos = Vec2f( Rand::randFloat( 0, getWindowWidth() ),
                       Rand::randFloat( 0, getWindowHeight() ) );
    
    // 初期半径
    circleRadius = DEFAULT_RADIUS;
}

void BasicAnimationApp::update()
{
    // 描画位置の決定
    Vec2f diff = targetPos - currentPos;
    diff *= 0.8f;   // イージングさせる
    currentPos = targetPos - diff;
    circleRadius--;
    
    // 目標位置に到達する前に新しい目標位置を決める
    if( currentPos.distance( targetPos ) < 1.0f ) {
        targetPos = Vec2f( Rand::randFloat( 0, getWindowWidth() ),
                           Rand::randFloat( 0, getWindowHeight() ) );
        circleRadius = DEFAULT_RADIUS;
    }
}

void BasicAnimationApp::draw()
{
    // clear out the window with black
    gl::clear( Color( 0, 0, 0 ) );
    gl::drawSolidCircle( currentPos, circleRadius );
}


CINDER_APP_BASIC( BasicAnimationApp, RendererGl );