3Dグラフィックスを提供するインタフェースです。
3Dグラフィックスをサポートする Graphics クラスは、
このインタフェースを実装しなければなりません。
Graphics オブジェクトは、以下の情報を保持します。
Graphics クラスのコピーメソッド
変換行列
フォグ 効果
光源 群
Graphics.copy()
により複製される情報は、上記のパラメータすべてです。
このパラメータ以外の情報、つまりレンダリング用バッファの内容は
コピーされません。
各種パラメータは、初期状態では以下のようになります。
| パラメータ | 初期状態 |
|---|---|
| クリッピング領域 | 描画領域全体
setClipRectFor3D(0, 0, width, height)
が呼ばれた状態 |
| 投影方法 | 平行投影
setParallelView(width, height)
が呼ばれた状態 |
| 視点座標への変換行列 | 恒等変換 (画面の中心にモデル座標系の原点が重なります) |
| 光源 | 設定なし |
| フォグ | 設定なし |
おおまかに説明すると、アプリケーションが3Dの描画に関して行う操作手順は、 以下のようになります。
3Dオブジェクト に、
描画したい情景を想定して、各種パラメータの設定を行います。
setTime() メソッドにより、各種の
3Dオブジェクト に、現在時刻を設定します。
renderObject3D() メソッドにより、
描画可能な3Dオブジェクト
を指定してレンダリング処理を行います(何度でも必要なだけ行います)。
なお、 グループ オブジェクトを用いることで、いくつかの
3Dオブジェクト をまとめて処理させることができます。
flushBuffer() メソッドにより、
レンダリング用バッファに貯まった内容を実描画領域に転送します。
参考資料として以下に、この Graphics3D
オブジェクトを用いている、
3Dコンテンツの実装における典型的な例を示します(抜粋)。
class someClass {
Graphics g;
Graphics3D g3;
Group obj3d;
void init() throws IOException {
// データ読み込み(即、描画可能なデータとする)
InputStream is = ... ;
try {
obj3d = (Group)Object3D.createInstance(is);
} finally {
is.close();
}
Canvas canvas = ... ;
// [省略] setCurrent() 等の処理
g = canvas.getGraphics();
g3 = (Graphics3D)g;
// 基本設定
int width = 100;
int height = 120;
g3.setClipRectFor3D(10, 20, width, height); // クリッピング領域の設定
g3.setPerspectiveView(1, 100, 120); // 透視投影の設定
// 視野変換を設定
// 未設定の場合、画面の中心にモデル座標系の原点が重なり、
// スケーリングは行われず、Z軸に重なる視線となります。
Transform tr = new Transform();
tr.lookAt(new Vector3D(0, 0, 30), // pos
new Vector3D(0, 0, -30), // look
new Vector3D(0, 1, 0)); // up
g3.setTransform(tr); // 設定
// 光源を設定
Light t = new Light();
t.setMode(Light.SPOT); // SPOT光源
t.setIntensity(0.8f); // 80%
t.setColor(0x00ff00ff); // 紫色
t.setPosition(new Vector3D(10, 10, 10)); // 位置設定
t.setVector(new Vector3D(-1, -1, -1)); // 向き設定
g3.addLight(t, null); // 設定
}
void doPaint() {
if (obj3d==null) {
return;
}
g.lock();
try {
// 平行移動 (スクリーン上)
Transform moveT = new Transform();
{
float moveX = ... ;
float moveY = ... ;
moveT.set(3, moveX);
moveT.set(7, moveY);
}
// 移動・拡大縮小・回転 (モデル座標)
Transform transM = new Transform();
{
// 行列1を設定 (移動・拡大縮小)
Transform trans1 = new Transform();
float dx = ... ; // X移動量
float dy = ... ; // Y移動量
float dz = ... ; // Z移動量
float scale = ... ; // スケール値
float[] ary = new float[] {
scale, 0.0f, 0.0f, dx,
0.0f, scale, 0.0f, dy,
0.0f, 0.0f, scale, dz,
0.0f, 0.0f, 0.0f, 1.0f
};
trans1.set(ary);
// 行列2を設定 (回転)
Transform trans2 = new Transform();
trans2.rotate(1.0f, 0.0f, 0.0f, 30.0f); // X軸回転
trans2.rotate(0.0f, 1.0f, 0.0f, 30.0f); // Y軸回転
// 行列オブジェクトへの設定
transM.set(trans2);
transM.multiply(trans1);
}
// グループに行列設定
obj3d.setTransform(transM);
// 描画
g3.renderObject3D(obj3d, moveT);
g3.flushBuffer();
} finally {
g.unlock(true);
}
}
}
| メソッドの概要 | |
void |
addLight(Light light,
Transform transform)
レンダリング時にデフォルトで配置される 光源 を追加します。
|
void |
flushBuffer()
レンダリングバッファに蓄積された情報を用いて、 レンダリング結果を実描画領域に描画します。 |
void |
renderObject3D(DrawableObject3D obj,
Transform transform)
指定された 描画可能な3Dオブジェクト
をレンダリングします。
|
void |
resetLights()
addLight() メソッドにより追加された 光源
をすべて解除します。
|
void |
setClipRectFor3D(int x,
int y,
int width,
int height)
キャンバス全体描画領域のうち3D描画のためのクリッピング領域を設定します。 |
void |
setFog(Fog fog)
デフォルトの フォグ 効果を設定します。
|
void |
setParallelView(int width,
int height)
投影面の幅と高さを指定して平行投影の設定を行います。 |
void |
setPerspectiveView(float zNear,
float zFar,
float angle)
視野角を指定して透視投影の設定を行います。 |
void |
setPerspectiveView(float zNear,
float zFar,
int width,
int height)
ニアクリップ面における投影面の幅および高さを指定して透視投影の設定を行います。 |
void |
setTransform(Transform t)
視点座標への 変換行列 オブジェクトを設定します。
|
| メソッドの詳細 |
public void setClipRectFor3D(int x,
int y,
int width,
int height)
キャンバス全体描画領域のうち3D描画のためのクリッピング領域を設定します。
このメソッドによる設定内容は、
flushBuffer() メソッドの呼び出し時にのみ利用されます。
レンダリングに関する情報には、クリッピング領域の設定内容は含まれません。
つまり、クリッピング領域の設定内容は、
renderObject3D(DrawableObject3D, Transform) メソッド
での処理内容に、まったく影響を与えません。
x - クリッピング領域の矩形の左上の X 座標を指定します。y - クリッピング領域の矩形の左上の Y 座標を指定します。width - クリッピング領域の矩形の幅を指定します。height - クリッピング領域の矩形の高さを指定します。
IllegalArgumentException - 引数 width, height のいずれかが 0 以下の場合に発生します。
public void setParallelView(int width,
int height)
投影面の幅と高さを指定して平行投影の設定を行います。
投影面の、視点座標系での幅と高さをセットします。
投影面の幅と高さを大きくすると、レンダリングの対象となる領域が広がるため、
結果として フィギュア オブジェクトが持つモデルデータ、および、
プリミティブ オブジェクトが持つプリミティブ図形データは、
より小さくレンダリングされることになります。
平行投影時には、ニアクリップ面の距離は0に、ファークリップ面の距離は 32767の固定となります。 実行環境によっては、ニア/ファークリップ面の扱い時に、多くの 演算誤差が発生するケースが想定できますので、クリップ面に重なる ポリゴンの描画結果は、環境依存となります。
このメソッドは、透視投影の設定機能である、
setPerspectiveView(float, float, float)
メソッドおよび
setPerspectiveView(float, float, int, int)
メソッドとは排他的な関係です。
このメソッドを呼び出した後は、レンダリングは平行投影で処理されます。
width - 投影面の幅を指定します。height - 投影面の高さを指定します。
IllegalArgumentException - 引数 width, height のいずれかが
0 以下
の場合に発生します。
public void setPerspectiveView(float zNear,
float zFar,
int width,
int height)
ニアクリップ面における投影面の幅および高さを指定して透視投影の設定を行います。
ニアクリップ面からファークリップ面までの図形がレンダリングされます。 パラメータは、視点座標系での距離や幅・高さを指定します。
このメソッドは、平行投影の設定機能である、
setParallelView(int, int)
メソッドとは排他的な関係です。
このメソッドを呼び出した後は、レンダリングは全て透視投影で処理されます。
zNear - カメラからニアクリップ面までの距離を指定します。zFar - カメラからファークリップ面までの距離を指定します。width - ニアクリップ面における投影面の幅を指定します。height - ニアクリップ面における投影面の高さを指定します。
IllegalArgumentException - 引数 width, height のいずれかが 0 以下の場合に発生します。
IllegalArgumentException - 引数 zNear, zFar が、0 < zNear < zFar < 32768 を満たしていない場合に発生します。
public void setPerspectiveView(float zNear,
float zFar,
float angle)
視野角を指定して透視投影の設定を行います。
ニアクリップ面からファークリップ面までの図形がレンダリングされます。 パラメータは、視点座標系での距離を指定します。
このメソッドは、平行投影の設定機能である、
setParallelView(int, int)
メソッドとは排他的な関係です。
このメソッドを呼び出した後は、レンダリングは全て透視投影で処理されます。
zNear - カメラからニアクリップ面までの距離を指定します。zFar - カメラからファークリップ面までの距離を指定します。angle - 視野角 (degree) を指定します。
有効範囲は 0度 < 視野角 < 180度です。
IllegalArgumentException - 引数 angle が 0 以下または 180 以上の場合に発生します。
IllegalArgumentException - 引数 zNear, zFar が、0 < zNear < zFar < 32768 を満たしていない場合に発生します。
public void flushBuffer()
レンダリングバッファに蓄積された情報を用いて、 レンダリング結果を実描画領域に描画します。
このメソッドが終了後、レンダリング用バッファの内容は空になります。
まだレンダリングが行われていないとき、つまり、 レンダリングバッファの内容が空のときは、何もしません。 また、このときには例外は発生しません。
このメソッドの処理に限り、
setClipRectFor3D(int, int, int, int) メソッドによって設定されている
クリッピング領域が利用されます。
この3D描画のためのクリッピング領域、および、
Graphics3D オブジェクト (Graphics オブジェクト) に設定されている
2D描画のためのクリッピング領域、この両方の情報を用いて、
レンダリング結果を実描画領域に描画します。
具体的には、両方の領域に属している場所は矩形で表現されますが、
この矩形を実描画領域に対するクリッピング領域とみなして、
描画処理を行います。
UnsupportedOperationException - 旧3Dグラフィックスの描画機能を利用した後に呼ばれた場合に発生します。
RuntimeException - ネイティブ処理においてメモリ不足やスタック不足、あるいは
各種の値に関するオーバフローによる副作用など、
特別な理由によって描画に失敗した場合に発生します。
public void setTransform(Transform t)
視点座標への 変換行列 オブジェクトを設定します。
このメソッドでは、指定された 変換行列
オブジェクトの内容を内部処理により完全に複製します。
そのため、メソッドから戻った後に、
指定された 変換行列 を変更しても設定内容は
変わりません。
初期状態では、恒等変換を意味する行列が設定されています。
t - 視点座標への 変換行列 オブジェクトを指定します。
NullPointerException - 引数 t
に null が指定された場合に発生します。
public void addLight(Light light,
Transform transform)
レンダリング時にデフォルトで配置される 光源 を追加します。
レンダリング機能である
renderObject3D(DrawableObject3D, Transform)
呼び出し時には、
setTransform(Transform)
メソッドにより設定されている
変換行列 A に、指定された行列
変換行列 L を乗算した結果 (A x L) を
用いて、 光源 が持つベクトル情報を変換します。
その結果が、レンダリング用バッファに蓄積されます。
なおベクトルを変換する処理には、
Transform.transVector(Vector3D, Vector3D) に相当する
機能が用いられます。
このメソッドでは、指定された
変換行列
オブジェクトの内容を内部処理により完全に複製します。
そのため、メソッドから戻った後に該当オブジェクトの内容を
変更しても設定内容は変わりません。
このメソッドは、指定された 光源
オブジェクトへの参照を、このオブジェクト内に保存する処理を
行います。
そのため、メソッドから戻った後に該当オブジェクトの内容を
変更した場合、このオブジェクトに設定された光源の設定内容は
変化します。
レンダリング機能である
renderObject3D(DrawableObject3D, Transform)
メソッド呼び出し時に、参照が保持されている
光源オブジェクトに設定されている情報が内部処理により
完全に複製され、レンダリングに関する情報の一部に含まれて、
レンダリング用バッファに蓄積されます。
この renderObject3D(DrawableObject3D, Transform)
メソッドから戻った後に、該当する光源オブジェクトの内容を変更しても、
レンダリング用バッファに登録されている光源に関する状態は変わりません。
レンダリング機能である
renderObject3D(DrawableObject3D, Transform)
メソッド呼び出し時に、描画対象のグループに
光源 オブジェクトが含まれるとき、
本メソッドによる設定内容に加えて、
グループ 内の
光源 オブジェクトのすべてが有効になります。
ただし、その総数が、同時に設定可能な最大数を超えるときには、
本メソッドにより追加された 光源 が優先されます。
また、描画対象が グループ オブジェクトであり、
その中に 光源 オブジェクトが複数含まれる
ときには、
ネストしているグループ オブジェクトのうちで、
最も上位の グループ オブジェクトに存在する
順に優先になります。
同一の グループ に属する
光源 オブジェクトが複数あるときには、
そのうちで若い番号が振られている順に優先になります。
若い番号が優先とは、 Group.getElement(int) メソッドによって
該当する 光源 オブジェクトを取得しようとするとき、
このメソッドの引数に指定するインデックス番号が小さいもの
ほど、優先度が高いということです。
レンダリング時に有効とされる 光源 の最大数は機種依存です。
最大値は Light.getMaxLights() メソッドにより取得できます。
レンダリング機能である
renderObject3D(DrawableObject3D, Transform)
メソッドが終了後には、
本メソッドによって指定された
光源 だけが設定されている状態に戻ります。
従って、
renderObject3D(DrawableObject3D, Transform)
メソッドに与える内容が、本オブジェクトに
設定されている 光源 の情報に影響を与えることはありません。
light - 光源 オブジェクトを指定します。transform - 変換行列 オブジェクトを指定します。
null のときは恒等変換を設定した場合と等価になります。
NullPointerException - 引数 light が null の場合に発生します。
UIException - 引数 light が既に
dispose() されたオブジェクトの場合に発生します
(ILLEGAL_STATE)。
public void resetLights()
addLight() メソッドにより追加された 光源
をすべて解除します。
public void setFog(Fog fog)
デフォルトの フォグ 効果を設定します。
初期状態ではフォグ効果はオフになっています。
このメソッドは、指定された フォグ
オブジェクトへの参照を、このオブジェクト内に保存する処理を
行います。
そのため、メソッドから戻った後に該当オブジェクトの内容を
変更した場合、このオブジェクトに設定されたフォグの設定内容は
変化します。
レンダリング機能である
renderObject3D(DrawableObject3D, Transform)
メソッド呼び出し時に、参照が保持されている
フォグオブジェクトに設定されている情報が内部処理により
完全に複製され、レンダリングに関する情報の一部に含まれて、
レンダリング用バッファに蓄積されます。
この renderObject3D(DrawableObject3D, Transform)
メソッドから戻った後に、該当するフォグオブジェクトの内容を変更しても、
レンダリング用バッファに登録されているフォグに関する状態は変わりません。
レンダリング機能である
renderObject3D(DrawableObject3D, Transform)
メソッド呼び出し時に、描画対象に フォグ オブジェクトが
含まれる場合、本メソッドによる設定内容は該当オブジェクトの内容によって
上書きされます。ただし
レンダリング機能である
renderObject3D(DrawableObject3D, Transform)
メソッドが終了後には、本メソッドによって指定された
フォグ の状態に戻ります。
描画対象が グループ
オブジェクトであり、その中に フォグ
オブジェクトが複数含まれる
ときには、
ネストしているグループ オブジェクトのうちで、
最も上位の グループ オブジェクトに存在する
ものが上書きの対象になります。
同一の グループ に属する
フォグ オブジェクトが複数あるときには、
そのうちで最も若い番号が振られているものが上書きの対象になります。
若い番号とは、 Group.getElement(int) メソッドによって
該当する フォグ オブジェクトを取得しようとするとき、
このメソッドの引数に指定するインデックス番号が最も小さいもの
のことです。
fog - フォグ オブジェクトを指定します。
null のときは、設定されているフォグ効果が解除されます。
UIException - 引数 fog が既に
dispose() されたオブジェクトの場合に発生します
(ILLEGAL_STATE)。
public void renderObject3D(DrawableObject3D obj,
Transform transform)
指定された 描画可能な3Dオブジェクト
をレンダリングします。
このメソッドを呼び出すことで、
レンダリングに関する情報がレンダリング用バッファに蓄積されます。
レンダリング用バッファに蓄積された情報は、
flushBuffer() メソッドが呼ばれたときに、実描画領域に反映され、
実際に描画されます。
setTransform(Transform)
メソッドにより設定されている
変換行列 A に、指定された
変換行列 T を乗算した結果 (A x T) を
用いて、指定された
描画可能な3Dオブジェクト を描画します。
ただし、
描画可能な3Dオブジェクト が グループ
である場合には、その グループ に設定されている
変換行列 B を用いた結果
(A x T x B)
が用いられます。
グループ に含まれている
光源 の位置および向きにも、この結果は反映されます。
なお、光源
が保持している位置および方向ベクトルを変換する処理には、
Transform.transVector(Vector3D, Vector3D) に相当する
機能が用いられます。
該当する グループ オブジェクトがネストしているときは、
B はネスト毎に次々と乗算された結果が用いられます。
ただし例外として、メッシュグループ同士がネストしている場合は、
最も上位のメッシュグループに設定されている
変換行列 は参照されますが、
それより下位のメッシュグループに設定されている
変換行列 は参照されません。
異なる複数のグループ に、同一の
描画可能な3Dオブジェクト が含まれている場合、
そのオブジェクトは参照されている回数と同じ回数、描画対象になります。
つまり、そのオブジェクトは一度だけ描画対象になるわけではありません。
例えば、グループ A がグループ B とグループ C への参照を保持している
ときに、 B と C がそれぞれ、フィギュア F への参照を保持しているとします。
このときにグループ A を描画しようとすると、 F は 2 回描画されます。
このメソッド呼び出し時には、与えられた
描画可能な3Dオブジェクト の内容が
すべて解析されてレンダリング処理が行われます。
従って、その後にオブジェクトの内容に変更があっても、
描画結果が変わることはありません。
与えられた 描画可能な3Dオブジェクト
が グループ であり、その中に
テクスチャ オブジェクトまたは
アクションテーブル オブジェクトが含まれるとき、
そのオブジェクト
の存在は無視されます。
与えられた 描画可能な3Dオブジェクト
が グループ であり、その中に フィギュア
オブジェクトおよび プリミティブ
オブジェクトがまったく含まれないときには、
このメソッド呼び出しは、レンダリング処理を行わずに終了します。
この場合に例外は発生しません。
obj - 描画可能な3Dオブジェクト を指定します。transform - 変換行列 を指定します。
null のときは恒等変換を意味します。
UnsupportedOperationException - 旧3Dグラフィックスの描画機能を利用した後に呼ばれた場合に発生します。
NullPointerException - 引数 obj が null の場合に発生します。
UIException - 引数 obj が既に
dispose() されたオブジェクトの場合に発生します
(ILLEGAL_STATE)。
UIException - 引数 obj が グループ であり、その中に含まれる
いずれかの 3Dオブジェクト が
dispose() されたオブジェクトの場合に発生します
(ILLEGAL_STATE)。
UIException -
引数 obj に指定された フィギュア オブジェクト、あるいは、
グループ に含まれる フィギュア オブジェクト
のいずれかに、設定されているオブジェクトのうちで既に
dispose() されたオブジェクトがある場合に発生します
(ILLEGAL_STATE)。
具体的には、
アクションテーブル オブジェクト、
テクスチャ オブジェクト群、および、
個々の テクスチャ オブジェクトに設定されている環境用
テクスチャ オブジェクトが検査されます。
UIException -
引数 obj に指定された プリミティブ オブジェクト、あるいは、
グループ に含まれる プリミティブ オブジェクト
のいずれかに、設定されているオブジェクトのうちで既に
dispose() されたオブジェクトがある場合に発生します
(ILLEGAL_STATE)。
具体的には、
テクスチャ オブジェクト、および、
テクスチャ オブジェクトに設定されている環境用
テクスチャ オブジェクトが検査されます。
IllegalArgumentException - 引数 obj から参照可能な
プリミティブ オブジェクトの
いずれかに、 テクスチャ
オブジェクトが適切に設定されていない場合に発生します。
具体的には、テクスチャ オブジェクトが必要なのにも
関わらず設定されていない場合などの、本機能が実行されるときに判明する
エラーが起きた場合です。
RuntimeException - ネイティブ処理においてメモリ不足やスタック不足、あるいは
各種の値に関するオーバフローによる副作用など、
特別な理由によってレンダリングに失敗した場合に発生します。