画面更新タイミング
< 前へ [ トップへ ] 次へ >

 これまで、Realtime3DFrameクラスを利用する事で非常に簡単に仮想3D空間のモデリングを行ってきました。ところでRealtime3DFrameクラスはどのような用途にも即席で使用可能なように設計されているので、用途によっては無駄に負荷の大きい処理を行っている場合もあります。実はこれまで説明してきた全ての例題プログラムにおいてもRealtime3DFrameは不必要な処理を行っています。そこでRealtime3DFrameクラスの設定を変更する事で、負荷を大幅に削減する事が可能です。
 ここでは、Realtime3DFrameクラスの基本的な設定項目である 「 プロセスモード 」 について解説し、用途に応じてプロセスモードを設定してみましょう。


 プロセスモード

・3Dでの画面更新処理は重い
 3D仮想空間の様子を画面に表示するには、一体どのような処理が必要なのでしょうか。処理の流れを大まかに述べると、まず最初に3D仮想空間内の全ポリゴン及び光源を座標変換して画面上の位置関係を求め、続いて光学計算を行ってポリゴンの色に陰や光の効果を加え、最後に画面上に大量の三角形や四角形を描き込んでいくという作業になります。このような長い処理を終えてようやく一枚の3D画像が表示されるわけです。言うまでも無くこれはかなり重い処理です。私たちがマウスで視点を操作した際に、立体の角度も滑らかに変わっていくのは、上に実は述べたような処理を1秒間に30回も繰り返しているからなのです。

・画面更新が必要なタイミングはプログラム内容によって異なる
 それでは、画面更新が必要になるタイミングは一体いつなのでしょうか。それは開発するプログラムの内容によって異なります。例えばアクションゲームのように舞台の様子が時間毎に ( 動的に ) 変化するような場合は、当然ながら常に画面を更新しなければなりません。つまりこのような場合、1秒間に何十回も上に述べたような重い処理を繰り返し続ける必要があるわけです。反対に、舞台やモデルの形状が全く変化しないような ( 静的な ) 場合、例えば静的な結晶格子構造を表示するような用途には、視点を操作する時のみ画面更新処理を行えば十分です。

・Realtime3DFrameクラスの画面更新頻度
 さて、これまでずっとRealtime3DFrameクラスを利用した3Dプログラミングを行ってきましたが、Realtime3DFrameクラスは初期設定状態では常に秒間30回の画面更新を行うように設定されています。これはRealtime3DFrameクラスがどのような用途にも即席で使用できるようにするための配慮からです。従ってこれまでの例題プログラムのように静的な形状を表現する用途には、あまりに無駄な処理を繰り返している事になります。

・画面更新頻度は「プロセスモード」で指定できる
 そこでRealtime3DFrameクラスには、用途に応じた画面更新タイミングを設定するために、画面更新タイミングのパターンがいくつか存在します。それらは「プロセスモード」と言い、Realtime3DFrameクラスの setProcessMode メソッドで指定できます。

setProcessMode( int プロセスモード番号 )

 引数のプロセスモード番号には、Realtime3DFrameのフィールドを渡します。設定可能なフィールドには以下のようなものがあります。

プロセスモード 設定概要
IDLE_MODE 完全休止モードです。画面更新をする事は一切ありません。マウス操作を含め全ての処理をスルーし、プロセスは完全に休止状態に移行します。
SEMI_IDLE_MODE 準休止モードです。画面更新をする事は一切ありません。マウス操作があった時にカメラアングルを変える設定は行いますが、画面は更新されないままです。
SEMI_REALTIME_MODE 準リアルタイムモードです。外部からの操作が無い時には休止していますが、マウスにより視点が操作されている時にはカメラアングルを変えつつ、秒間30回の画面更新を行います。静的な空間を表現する場合に用います。
REALTIME_MODE リアルタイム描画モードです。外部から操作のある無しに関わらず、常に秒間30回の画面更新を行い続けます。動的な空間を表現する場合に用います。

 なお、プロセスモードに関わらず、Realtime3DFrameクラスの再描画要求メソッド repaint3D( ) を呼び出す事により、強制的に画面を再描画させる事も可能です。このメソッドを用いると、画面更新タイミングを自分で自由に制御する事ができます。

・REALTIME_MODE時のフレームレートは setFrameRate メソッドでで指定可能
 プロセスモードがREALTIME_MODEに設定さている場合、デフォルトでは一秒間に30回のフレームレートで画面を描画します。このフレームレートを変更したい場合は setFrameRate メソッドを使用します。

setFrameRate( int 毎秒フレームレート )

 但し必ずしも指定したフレームレートが実現されるわけではない事は留意しておいて下さい。RINEARN-X 3Dでは、フレームレートの制御を、処理中に空白時間を挟む事により実現しています。この空白時間の長さをリアルタイムで自動調整する事で、なるべく設定されているフレームレートに近くなるようにしているのです。
 しかし当然ながら、高負荷時などには、空白時間の長さを限界値まで下げても処理が追いつかない場合もあります。この場合、設定されたフレームレートよりも実際のフレームレートは低くなります。これがいわゆる処理落ちです。どうあがいてもCPUが1秒間にこなせる処理量には限界があるので、処理落ちが発生している場合にフレームレートを上げても、高速化の効果は全く無い事に注意して下さい。


 プロセスモードを設定する

 Realtime3DFrameクラスの標準設定は REALTIME_MODE になっています。つまり視点操作の全くされていない時にも秒間30回の画面更新を処理し続けています。これを SEMI_REALTIME_MODE に設定変更し、無操作時のシステム負荷を大幅に軽減させてみましょう。

・デフォルト状態
 まずはデフォルト状態の負荷を確かめてみましょう。以下に例として、 80×80=6400 ポリゴンの球を配置した空間を用意してみましょう。

import rxvesapi.system3d.geometry.*;
import rxvesapi.system3d.renderer.*;
import rxvesapi.system3d.model.*;

import java.awt.Color;


public class Test{

  public static void main(String[] args){

    /*3D仮想空間*/
    Realtime3DFrame frame = new Realtime3DFrame();

    /*80×80ポリゴンの球モデル*/
    SphereModel3DEG sph = new SphereModel3DEG( 80, 80 );
    sph.setRadius( 1.0 );
    sph.setColor( Color.blue );
    frame.add( sph );

  }
}


 この空間は6400ポリゴンで構成されているわけですが、これを毎秒30回の画面更新頻度で処理しようとすると毎秒20万ポリゴン程度の処理能力が必要になります。これは一昔前のマシンにとっては結構な処理です。
 例として、2006年製のシングルコアCPU搭載ノートPC上でこの空間を表示した際のCPU負荷を計測したところ、何も操作していない時にもCPUの稼働率は73%に達していました。ところで上のようなプログラムでは、このような高負荷処理をユーザーが何も視点操作していない時にまで実行する必要は全く無く、CPUにとって非常に無駄な負荷をかけている事になります。

・プロセスモードを SEMI_REALTIME_MODE に設定する
 それでは上のような無駄を省くため、プロセスモードを SEMI_REALTIME_MODE に設定してみましょう。このモードは、マウスによる視点操作があった時のみ画面更新処理を行い、操作されていない時は何もしないで待機するモードです。


import rxvesapi.system3d.geometry.*;
import rxvesapi.system3d.renderer.*;
import rxvesapi.system3d.model.*;

import java.awt.Color;


public class Test{

  public static void main(String[] args){

    /*3D仮想空間*/
    Realtime3DFrame frame = new Realtime3DFrame();

    /*プロセスモードを設定*/
    frame.setProcessMode( frame.SEMI_REALTIME_MODE );


    /*80×80ポリゴンの球モデル*/
    SphereModel3DEG sph = new SphereModel3DEG( 80, 80 );
    sph.setRadius( 1.0 );
    sph.setColor( Color.blue );
    frame.add( sph );


    /*起動時の初回画面更新は自動ではされないため、
    プログラマが明示的に行う*/
    frame.repaint3D();

  }
}

 このプログラムを先ほどと同様、2006年製のシングルコアCPU搭載ノートPC上で表示したところ、何も操作していない時のCPU稼働率は4%にまで押さえることができました。73%から4%ですから、これはかなりの効果があったといえるでしょう。

< 前へ [ トップへ ] 次へ >