2008/09/02

Flight404のソースコードを読み解く part2

何も表示されないアプリケーションを作る

Flight404のサンプルではOpenGLを使用して平面に別途用意したパーティクルの画像を貼り付けて、表示するという手法をとっている。そのためP3Dと比べて、非常に高速で高精度な3D画像を描画できるのだが、その分生のOpenGLを叩かないといけないため、コードはいささか面倒になってくる。そこでとりあえずソースコードの中から何も表示されないアプリケーションを作って、コードの流れについて調べてみることにした。コードは以下。

particle1.pde

import toxi.geom.*;
import processing.opengl.*;
import javax.media.opengl.*;

// Settings about OPENGL
PGraphicsOpenGL pgl;
GL gl;

// Settings about some functions

void setup(){
size( 600, 600, OPENGL );
colorMode( RGB, 1.0);

hint( ENABLE_OPENGL_4X_SMOOTH );

pgl = (PGraphicsOpenGL) g;
gl = pgl.gl;
gl.setSwapInterval(1);

initGL();
}

void draw(){
background( 0.0 );
perspective( PI/3.0, (float)width/(float)height, 1, 5000 );

gl.glDepthMask(false);
gl.glEnable( GL.GL_BLEND );
gl.glBlendFunc( GL.GL_SRC_ALPHA, GL.GL_ONE );

pgl.beginGL();
// write something...
pgl.endGL();
}

_gl.pde

int squareList;

void initGL(){
pgl.beginGL();
squareList = gl.glGenLists(1);
gl.glNewList(squareList, GL.GL_COMPILE);
gl.glBegin(GL.GL_POLYGON);
gl.glTexCoord2f(0, 0); gl.glVertex2f(-0.5, -0.5);
gl.glTexCoord2f(1, 0); gl.glVertex2f( 0.5, -0.5);
gl.glTexCoord2f(1, 1); gl.glVertex2f( 0.5, 0.5);
gl.glTexCoord2f(0, 1); gl.glVertex2f(-0.5, 0.5);
gl.glEnd();
gl.glEndList();
pgl.endGL();
}

void renderImage( Vec3D _loc, float _diam, color _col, float _alpha){
gl.glPushMatrix();
gl.glTranslatef( _loc.x, _loc.y, _loc.z );
gl.glScalef( _diam, _diam, _diam );
gl.glColor4f( red(_col), green(_col), blue(_col), _alpha );
gl.glCallList( squareList );
gl.glPopMatrix();
}

まずhint( ENABLE_OPENGL_4X_SMOOTH )を指定して、4xのオーバーサンプリングを許可。setSwapInterval()については、主に画面がちらつく現象を防ぐ目的のようだ。その後initGL()を呼び出して、_gl.pdeで書いたOpenGL周辺のセットアップを開始する。

initGL()では、正方形のポリゴンを作って画像を貼り付けるという作業が何回も繰り返されるので、ディスプレイリストの機能を利用する。テクスチャのUV座標と頂点をそれぞれglTexCoord2fとgl.glVertex2fで指定して、正方形を描画している。

renderImage()で実際に画像の描画を行う。glPushMatrix()とglPopMatrix()で行列スタックを取得、開放し、その間に平行移動やスケールをもってくることで、ローカル座標が狂わないようにしているようだ。

次にdraw()の項を見てみる。glDepthMask(false)で陰線消去を行わないようにして、glBlendFunc( GL.GL_SRC_ALPHA, GL.GL_ONE )で画像の加算処理を指定している。そしてbeginGL()とendGL()の間にOpenGLの描画命令を組み込むことで、実際にOpenGLで描画処理が行われるようになるという次第。

0 件のコメント: