なお,PGraphics3Dクラスのインスタンスは実画面に繋がっていないgraphics contextのようで,最後にimage()関数で実ウィンドウにまとめて描画します.
ソースコードは以下のとおりです.重複するコードが多いので,Javaのサブラクスを作成すると,もっと簡潔になると思います.
// 2019/8/10 // 明示的にPGraphicsを用いて描画する // 2つのPGraphicsを作って,別の描画をする int loopCount; // draw()が呼ばれるたびにインクリメントされる変数 PGraphics3D pg1, pg2; int panelWidth, panelHeight; void setup() { size(950, 500, P3D); // 400x400のウィンドウ panelWidth = 400; panelHeight = 400; pg1 = (PGraphics3D)createGraphics(panelWidth, panelHeight, P3D); pg2 = (PGraphics3D)createGraphics(panelWidth, panelHeight, P3D); loopCount = 0; // 日本語フォントが効かない.サイズも反映されない. PFont font = createFont("MS Gothic", 48, true); pg1.textFont(font); pg1.textSize(24); pg1.hint(ENABLE_DEPTH_SORT); // z bufferが視点方向で正常に機能するように pg2.textFont(font); pg2.textSize(24); pg2.hint(ENABLE_DEPTH_SORT); // z bufferが視点方向で正常に機能するように frameRate(60); } void draw() { loopCount++; // pg1.beginDraw(); pg1.background(192); // light grayの背景 // ウィンドウの中心が(x, y)の原点になる pg1.translate(panelWidth/2, panelHeight/2, 0); // 原点を画面の中身にずらす // 座標軸を回転する(Processingは左手系) // x:右, y:下, z:手前 -> x:右, y:手前, z:上 pg1.rotateX(PI/2); // この座標系で視点だけ回転させる // z軸が上の斜め上方向から原点を眺める pg1.camera(300.0*cos(radians(loopCount)), 300.0*sin(radians(loopCount)), 300.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0); // 座標軸の描画 pg1.fill(255, 0, 0); // 赤 pg1.textAlign(CENTER); // x方向をセンタリング,y方向の座標はベースライン pg1.text("x軸", 150, 0, 0); // XY平面上に書く pg1.text("y軸", 0, 150, 0); // XY平面上に書く pg1.text("z軸", 0, 0, 150); // Z=150のXY平面上に書く pg1.stroke(0, 0, 0); // 黒線 pg1.line(0, 0, 0, 130, 0, 0); // X軸 pg1.line(0, 0, 0, 0, 130, 0); // Y軸 pg1.line(0, 0, 0, 0, 0, 145); // Z軸 // 3Dオブジェクトの描画 pg1.fill(0x7F0000FF); // 青の塗り潰し,透明度半分 pg1.stroke(0, 255, 0); // 緑線 pg1.box(100, 100, 100); // 原点中心,一辺のサイズ100のの立方体 pg1.translate(-100, -100, 0); // 原点をずらす pg1.stroke(0, 0, 255); // 青線 pg1.fill(0x7F00FFFF); // シアンの塗り潰し,透明度半分 pg1.sphere(100); // 原点中心,半径100の球 pg1.endDraw(); // pg2.beginDraw(); pg2.background(192); // light grayの背景 // ウィンドウの中心が(x, y)の原点になる pg2.translate(panelWidth/2, panelHeight/2, 0); // 原点を画面の中身にずらす // 座標軸を回転する(Processingは左手系) // x:右, y:下, z:手前 -> x:右, y:手前, z:上 pg2.rotateX(PI/2); // この座標系で視点だけ回転させる // z軸が上の斜め上方向から原点を眺める pg2.camera(300.0*cos(radians(-loopCount)), 300.0*sin(radians(-loopCount)), 300.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0); // 座標軸の描画 pg2.fill(255, 0, 0); // 赤 pg2.textAlign(CENTER); // x方向をセンタリング,y方向の座標はベースライン pg2.text("x軸", 150, 0, 0); // XY平面上に書く pg2.text("y軸", 0, 150, 0); // XY平面上に書く pg2.text("z軸", 0, 0, 150); // Z=150のXY平面上に書く pg2.stroke(0, 0, 0); // 黒線 pg2.line(0, 0, 0, 130, 0, 0); // X軸 pg2.line(0, 0, 0, 0, 130, 0); // Y軸 pg2.line(0, 0, 0, 0, 0, 145); // Z軸 // 3Dオブジェクトの描画 pg2.fill(0x7FFF0000); // 赤の塗り潰し,透明度半分 pg2.stroke(0, 255, 0); // 緑線 pg2.box(100, 100, 100); // 原点中心,一辺のサイズ100のの立方体 pg2.translate(-100, -100, 0); // 原点をずらす pg2.stroke(255, 0, 0); // 赤線 pg2.fill(0x7FFF00FF); // マゼンタの塗り潰し,透明度半分 pg2.sphere(100); // 原点中心,半径100の球 pg2.endDraw(); // image(pg1, 50, 50); // PGに描いた絵を表示 image(pg2, 500, 50); // PGに描いた絵を表示 }
出来上がったGIFアニメーションは以下のとおりです.1つのウィンドウに2つの描画領域を作成して,それぞれの領域で別のアニメーションを描画しています.以下の不具合があります.
- フォントの指定がうまくいかない
- 半透明描画ができていない.
上記のGIFアニメーションを作成するために書き換えたソースコードは以下のとおりです.
// 2019/8/10 // 明示的にPGraphicsを用いて描画する // 2つのPGraphicsを作って,別の描画をする import gifAnimation.*; GifMaker gifExport; int loopCount; // draw()が呼ばれるたびにインクリメントされる変数 PGraphics3D pg1, pg2; int panelWidth, panelHeight; void setup() { size(950, 500, P3D); // 400x400のウィンドウ panelWidth = 400; panelHeight = 400; pg1 = (PGraphics3D)createGraphics(panelWidth, panelHeight, P3D); pg2 = (PGraphics3D)createGraphics(panelWidth, panelHeight, P3D); loopCount = 0; // 日本語フォントが効かない.サイズも反映されない. PFont font = createFont("MS Gothic", 48, true); pg1.textFont(font); pg1.textSize(24); pg1.hint(ENABLE_DEPTH_SORT); // z bufferが視点方向で正常に機能するように pg2.textFont(font); pg2.textSize(24); pg2.hint(ENABLE_DEPTH_SORT); // z bufferが視点方向で正常に機能するように frameRate(60); gifExport = new GifMaker(this, "export.gif"); gifExport.setRepeat(0); // 無限ループ gifExport.setQuality(10); // default値 gifExport.setDelay(30); // 30ms単位で1コマ(1秒33コマ) gifExport.setTransparent(0, 0, 0); // 黒は透過色 } void draw() { loopCount++; // pg1.beginDraw(); pg1.background(192); // light grayの背景 // ウィンドウの中心が(x, y)の原点になる pg1.translate(panelWidth/2, panelHeight/2, 0); // 原点を画面の中身にずらす // 座標軸を回転する(Processingは左手系) // x:右, y:下, z:手前 -> x:右, y:手前, z:上 pg1.rotateX(PI/2); // この座標系で視点だけ回転させる // z軸が上の斜め上方向から原点を眺める pg1.camera(300.0*cos(radians(loopCount)), 300.0*sin(radians(loopCount)), 300.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0); // 座標軸の描画 pg1.fill(255, 0, 0); // 赤 pg1.textAlign(CENTER); // x方向をセンタリング,y方向の座標はベースライン pg1.text("x軸", 150, 0, 0); // XY平面上に書く pg1.text("y軸", 0, 150, 0); // XY平面上に書く pg1.text("z軸", 0, 0, 150); // Z=150のXY平面上に書く pg1.stroke(0, 0, 0); // 黒線 pg1.line(0, 0, 0, 130, 0, 0); // X軸 pg1.line(0, 0, 0, 0, 130, 0); // Y軸 pg1.line(0, 0, 0, 0, 0, 145); // Z軸 // 3Dオブジェクトの描画 pg1.fill(0x7F0000FF); // 青の塗り潰し,透明度半分 pg1.stroke(0, 255, 0); // 緑線 pg1.box(100, 100, 100); // 原点中心,一辺のサイズ100のの立方体 pg1.translate(-100, -100, 0); // 原点をずらす pg1.stroke(0, 0, 255); // 青線 pg1.fill(0x7F00FFFF); // シアンの塗り潰し,透明度半分 pg1.sphere(100); // 原点中心,半径100の球 pg1.endDraw(); // pg2.beginDraw(); pg2.background(192); // light grayの背景 // ウィンドウの中心が(x, y)の原点になる pg2.translate(panelWidth/2, panelHeight/2, 0); // 原点を画面の中身にずらす // 座標軸を回転する(Processingは左手系) // x:右, y:下, z:手前 -> x:右, y:手前, z:上 pg2.rotateX(PI/2); // この座標系で視点だけ回転させる // z軸が上の斜め上方向から原点を眺める pg2.camera(300.0*cos(radians(-loopCount)), 300.0*sin(radians(-loopCount)), 300.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0); // 座標軸の描画 pg2.fill(255, 0, 0); // 赤 pg2.textAlign(CENTER); // x方向をセンタリング,y方向の座標はベースライン pg2.text("x軸", 150, 0, 0); // XY平面上に書く pg2.text("y軸", 0, 150, 0); // XY平面上に書く pg2.text("z軸", 0, 0, 150); // Z=150のXY平面上に書く pg2.stroke(0, 0, 0); // 黒線 pg2.line(0, 0, 0, 130, 0, 0); // X軸 pg2.line(0, 0, 0, 0, 130, 0); // Y軸 pg2.line(0, 0, 0, 0, 0, 145); // Z軸 // 3Dオブジェクトの描画 pg2.fill(0x7FFF0000); // 赤の塗り潰し,透明度半分 pg2.stroke(0, 255, 0); // 緑線 pg2.box(100, 100, 100); // 原点中心,一辺のサイズ100のの立方体 pg2.translate(-100, -100, 0); // 原点をずらす pg2.stroke(255, 0, 0); // 赤線 pg2.fill(0x7FFF00FF); // マゼンタの塗り潰し,透明度半分 pg2.sphere(100); // 原点中心,半径100の球 pg2.endDraw(); // image(pg1, 50, 50); // PGに描いた絵を表示 image(pg2, 500, 50); // PGに描いた絵を表示 gifExport.addFrame(); // gifアニメーションに現在のフレームを追加 if (loopCount >= 360) { gifExport.finish(); // 1回転したらアニメーション終了 } }
1回転だけした時点で,無限繰り返し再生を行うアニメーション画像を書き出しています.
0 件のコメント:
コメントを投稿