[ 前へ | 目次 | 次へ ]
ダウンロード
PC (※スマートフォンでは動きません) でダウンロードし、ZIPファイルを右クリックメニューから展開して、できたフォルダ内の「 VCSSL.bat(バッチファイル) 」をダブルクリックすると起動します。 Linux等では「 VCSSL.jar 」をコマンド実行してください。
» 詳しい使用方法や、エラーで展開できない際の対応方法などはこちら

2DCGと3DCGの合成

このプログラムは、2DCGと3DCGを一枚に合成し、画面に表示するVCSSLプログラムの例です。

使用方法

ダウンロードと展開(解凍)

まず、PC(スマホは未対応)で上の画面の「 ダウンロード 」ボタンを押してください。 するとZIP形式で圧縮されたファイルがダウンロードされます。

Windows をご使用の方は、ここでまずZIPファイルを右クリックし、「プロパティ」を選んで開かれる画面で、 下の方にあるセキュリティ項目の「許可する」にチェックを入れて「OK」で閉じてください。 これを行わないと、ZIP展開やソフト起動時に、警告メッセージが出て展開完了/起動できない場合があります。

その後、ZIPファイルを右クリックして「すべて展開」や「ここに展開」などで展開(解凍)してください。 展開が成功すると、ZIPファイルと同じ名前のフォルダができ、その中にZIPファイルの中身が入っています。

» 展開がエラーで止まってしまう場合や、ファイル名が文字化けしてしまう場合は…

プログラムの起動

Windows をご使用の場合

上記でZIPファイルを展開したフォルダ内にある、以下のバッチファイルをダブルクリック実行してください:

VCSSL__ダブルクリックでプログラム実行.bat

もしプログラムを書き変えながら使いたい場合は、代わりに「 VCSSL_Editor__プログラム編集はこちら.bat 」を実行してください。

正常に起動できると、初回のみ、Java実行環境を入手するか等を尋ねられるので、適時答えて済ませると、プログラムが起動します。 2回目以降はすぐに起動します。

» うまく起動できずにエラーになってしまう場合は…

Linux 等をご使用の場合

ZIPファイルを展開したフォルダ内へコマンドライン端末で cd して、以下の通り入力して実行してください:

java -jar VCSSL.jar
(プログラムの内容を書き変えながら使いたい場合は、代わりに VCSSL_Editor.jar を実行)

» javaコマンドが使用できない等のエラーが表示される場合は…

操作方法

画面上で、下記のマウス操作を行えます。

  • 左ドラッグ … 視点の回転
  • 右ドラッグ … 視点の平行移動
  • ホイールスクロール … 拡大/縮小

題材解説

このプログラムでは、1つの画面において、2DCGと3DCGの両機能を組み合わせています。

2Dレンダラーと3Dレンダラーを組み合わせて使用

VCSSLでは、2DCGを描画する2Dレンダラー(描画エンジン)と、3DCGを描画する3Dレンダラーが用意されています。 しかし、これらはそれぞれ 2DCG / 3DCG のどちらかしか描画できません。

従って、例えば2Dの背景画像上に3Dの立体を表示させたり、3DCGの上に2Dの情報表示などを行ったりするには、 2Dレンダラーと3Dレンダラーを組み合わせて使用し、結果を合成する必要があります。

このプログラムでは、実際にそのような合成を行う、単純な例を示します。

基本構造は普通の2D描画

このプログラムの基本構造は、普通の2D描画と同様です。より具体的に言えば、 アニメーション描画を行う2DCGプログラムとほぼ同じ構造となります。

画面に表示される内容を直接描画するのも、2Dレンダラーが担います。

画像の描画と同様に、3Dレンダラーの出力内容を2DCG上に描き込む

2D/3D合成の基本的な流れとしては、2D描画の途中で、 画像を描画する場合と全く同様にして、3Dレンダラーの出力内容を2DCG上に描き込む流れになります。

つまり、3Dレンダラーの出力を直接画面に表示させるのでは無く、 「単なる一枚の画像」として扱う流れとなります。

コード解説

このプログラムのコード全体は、以下の通りです。


coding UTF-8;

import GUI;
import Graphics;
import Graphics2D;
import Graphics3D;


//ウィンドウのX,Y,幅,高さ
const int WINDOW_X = 0;
const int WINDOW_Y = 0;
const int WINDOW_WIDTH = 820;
const int WINDOW_HEIGHT = 640;
const string WINDOW_TITLE = "Graphics Window";

//画面のX,Y,幅,高さ
const int SCREEN_X = 0;
const int SCREEN_Y = 0;
const int SCREEN_WIDTH = 800;
const int SCREEN_HEIGHT = 600;

//背景色
const int SCREEN_COLOR_RED = 0;
const int SCREEN_COLOR_GREEN = 0;
const int SCREEN_COLOR_BLUE = 0;
const int SCREEN_COLOR_ALPHA = 255;

//3Dライトのパラメータ
const float LIGHT_X = 1.2; //ライトXベクトル
const float LIGHT_Y = 1.5; //ライトYベクトル
const float LIGHT_Z = 1.0; //ライトZベクトル
const float LIGHT_BRIGHTNESS = 0.5; //ライト輝度
const float AMBIENT_BRIGHTNESS = 0.5; //環境光の輝度



//アニメーション関連
int loopWait = 30; //1フレーム当たりの待機時間(ミリ秒)
boolean mainLoopState = true; //継続判定

//GUIコンポーネント
int window;	//ウィンドウ
int screenLabel;	//画面表示ラベル

//以下、描画関連のリソース類
int graphics2D; //2D描画用グラフィックスリソース
int renderer2D; //2D描画用レンダラー

int graphics3D; //3D描画用グラフィックスリソース
int renderer3D; //3D描画用レンダラー



/**
 * main関数、最初にここから実行されます。
 */
void main(){
	//GUIの構築や初期化
	initializeComponent();

	//ユーザー定義の初期化処理
	initialize();

	//アニメーションのメインループ
	while(mainLoopState){

		//ユーザー定義の描画処理
		paint();

		//ユーザー定義の更新処理
		update();

		//GUIコンポーネントの再描画
		paintComponent(screenLabel);
		paintComponent(window);

		//指定時間待機(アニメーションウェイト)
		sleep(loopWait);
	}

	//アニメーションループを抜けたら終了
	finalize();
	exit();
}


/**
 * ウィンドウを閉じた際に呼び出されるイベントハンドラです。
 */
void onWindowClose(int id){
	if(id == window){
		//メインループを脱出させて終了させる
		mainLoopState = false;
	}
}



/**
 * ユーザー定義の初期化処理、
 * ここは起動時に一度だけ呼び出されます。
 */
void initialize(){

	// 3Dモデルなどを適当に配置

	int axis = newAxisModel(3.0, 3.0, 3.0);
	mountModel(axis, renderer3D);

	int sphere = newSphereModel(1.4, 1.4, 1.4, 30, 20);
	mountModel(sphere, renderer3D);
}


/**
 * ユーザー定義の描画処理、
 * ここはアニメーションの毎時刻呼び出されます。
 */
void paint(){

	//まず2DCGを背景色でクリア(画面には2DCGが表示される)
	clearGraphics2D(renderer2D);

	//2DCGに図形を適当に描き込み
	setDrawColor(renderer2D, 0, 0, 255, 255);
	drawRect(renderer2D, 50, 280, 300, 300, true);


	//3DCGレンダラーを動かして描画(内容はgraphics3Dに)
	paintGraphics3D(renderer3D);

	//2DCG上に、3DCG(renderer3Dの出力 = graphics3D)を描画
	drawImage(
		renderer2D, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, graphics3D
	);


	//2DCGに図形を適当に描き込み
	setDrawColor(renderer2D, 0, 255, 0, 180);
	drawOval(renderer2D, 400, 100, 200, 200, true);
}


/**
 * ユーザー定義の更新処理、
 * ここはアニメーションの毎時刻呼び出されます。
 */
void update(){
	 //立体モデルの位置などを毎時刻動かす場合に、
	 //ここに記述します。
}


/**
 * ユーザー定義の終了時処理、
 * ここは終了時に一度だけ呼び出されます。
 */
void finalize(){
	//毎時刻のファイル書き込み処理などを行っている場合に、
	//ここでファイルを閉じます。
}



/**
 * GUIの構築やレンダラーの生成など、初期化処理を行います。
 */
void initializeComponent(){

	//2D描画用レンダラーの生成
	graphics2D = newGraphics();
	renderer2D = newGraphics2DRenderer(
		SCREEN_WIDTH, SCREEN_HEIGHT, graphics2D
	);

	//3D描画用レンダラーの生成
	graphics3D = newGraphics();
	renderer3D = newGraphics3DRenderer(
		SCREEN_WIDTH, SCREEN_HEIGHT, graphics3D
	);

	//ウィンドウの生成
	window = newWindow(
		WINDOW_X, WINDOW_Y, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_TITLE
	);

	//画面表示ラベルの生成(画面には2D描画結果を表示させる)
	screenLabel = newGraphicsLabel(
		SCREEN_X, SCREEN_Y, SCREEN_WIDTH, SCREEN_HEIGHT, graphics2D
	);

	//画面表示ラベルをウィンドウ上に配置
	mountComponent(screenLabel, window);


	//2D背景色の設定
	setGraphics2DColor(
		renderer2D,
		SCREEN_COLOR_RED,
		SCREEN_COLOR_GREEN,
		SCREEN_COLOR_BLUE,
		SCREEN_COLOR_ALPHA
	);

	//3D背景色は透明に設定
	setGraphics3DColor(renderer3D, 0, 0, 0, 0);


	//3DCGの視点操作を、screenLabel上のマウス操作と結びつける
	setGraphics3DDefaultEventHandler(renderer3D, screenLabel);

	//3DCGライトの配置
	mountLight( newLight(LIGHT_X,LIGHT_Y,LIGHT_Z,LIGHT_BRIGHTNESS), renderer3D ) ;
	mountLight( newAmbientLight(0.0,0.0,0.0,AMBIENT_BRIGHTNESS), renderer3D ) ;
}
CompositeGraphics.vcssl

以下では、このコードの各部を順を追って解説します。

ヘッダ部 ~ グローバル変数の宣言

プログラムのヘッダ部では、必要なライブラリを import しています。使用しているライブラリは、 普通に2D/3D描画を扱うために必要なものばかりです。

グローバル変数でも、普通に2D/3D描画を扱うために必要となる、 レンダラー(描画エンジン)やGUIコンポーネントのID格納変数などを宣言しています。

定数パラメータ(const)を除くグローバル変数は以下の通りです。


//アニメーション関連
int loopWait = 30; //1フレーム当たりの待機時間(ミリ秒)
boolean mainLoopState = true; //継続判定

//GUIコンポーネント
int window;	//ウィンドウ
int screenLabel;	//画面表示ラベル

//以下、描画関連のリソース類
int graphics2D; //2D描画用グラフィックスリソース
int renderer2D; //2D描画用レンダラー

int graphics3D; //3D描画用グラフィックスリソース
int renderer3D; //3D描画用レンダラー
globalvar.txt

main関数とイベントハンドラ

続いてmain関数と、ウィンドウを閉じた際のイベントハンドラです。


/**
 * main関数、最初にここから実行されます。
 */
void main(){
	//GUIの構築や初期化
	initializeComponent();

	//ユーザー定義の初期化処理
	initialize();

	//アニメーションのメインループ
	while(mainLoopState){

		//ユーザー定義の描画処理
		paint();

		//ユーザー定義の更新処理
		update();

		//GUIコンポーネントの再描画
		paintComponent(screenLabel);
		paintComponent(window);

		//指定時間待機(アニメーションウェイト)
		sleep(loopWait);
	}

	//アニメーションループを抜けたら終了
	finalize();
	exit();
}


/**
 * ウィンドウを閉じた際に呼び出されるイベントハンドラです。
 */
void onWindowClose(int id){
	if(id == window){
		//メインループを脱出させて終了させる
		mainLoopState = false;
	}
}
main.txt

このフローチャートは、以下のように、典型的なアニメーション描画のフローとなっています。

まずmain関数の最初の部分でinitialize関数がコールされ、初期化処理が行われます。そしてメインループに入り、プログラム終了まで、描画(paint関数)、更新(update関数)、待機(sleep関数)を繰り返し続けます。
典型的な、メインループ型処理フローの例
まずmain関数の最初の部分でinitialize関数がコールされ、初期化処理が行われます。そしてメインループに入り、プログラム終了まで、描画(paint関数)、更新(update関数)、待機(sleep関数)を繰り返し続けます。ウィンドウが閉じられ、onWindowClose関数が呼ばれると、メインループを脱出し、終了処理(finalize関数)を行ってからプログラムを終了します。

main関数の最初に、画面構築などの処理を行った後に、 初期化のための initialize 関数を一度だけコールします。 initialize関数では、必要に応じて3Dモデルの配置などを記述します。

その後はアニメーション用のメインループ(無限ループ)に突入し、 毎秒数十回の頻度で paint 関数と update 関数を交互にコールし続けます。 paint関数では、必要に応じて2D描画などを記述します。

ウィンドウが閉じられるとメインループを脱出し、終了時処理のための finalize 関数を1度だけコールして、 プログラムを終了します。

画面構築やレンダラー生成などを行うinitializeComponent関数

main関数の最初では、画面のGUI構築や、レンダラー生成などの準備を行う initializeComponent 関数がコールされます。

この関数の内容全体は、普通にレンダラー生成や画面構築、設定などを行っているだけなので、ここでは割愛します。

重要なのは以下の、画面表示ラベルを生成している部分です。


//画面表示ラベルの生成(画面には2D描画結果を表示させる)
screenLabel = newGraphicsLabel(
	SCREEN_X, SCREEN_Y, SCREEN_WIDTH, SCREEN_HEIGHT, graphics2D
);
label.txt

上記の通り、画面の表示内容には、2Dレンダラーの出力内容( graphics2D )を指定しています。

つまり、2Dレンダラー( renderer2D )の描画内容がそのまま画面に表示されるわけです。

加えて言うなら、3Dレンダラー( renderer3D )の描画内容は、 そのままでは画面に影響しないという事にもなります。そのため、2Dレンダラーに、 3Dレンダラーの描画結果を描き込ませるわけです。詳しくは後の paint 関数の項目で解説します。

初期化処理を記述する initialize 関数

続いて呼ばれる initialize 関数は、最初に1度だけコールされます。 ここには最初に行わせたい処理を自由に記述します。

このプログラムでは、以下のように3Dレンダラーに座標軸モデルと球モデルを配置しています。


/**
 * ユーザー定義の初期化処理、
 * ここは起動時に一度だけ呼び出されます。
 */
void initialize(){

	// 3Dモデルなどを適当に配置

	int axis = newAxisModel(3.0, 3.0, 3.0);
	mountModel(axis, renderer3D);

	int sphere = newSphereModel(1.4, 1.4, 1.4, 30, 20);
	mountModel(sphere, renderer3D);
}
initialize.txt

描画処理を記述する paint 関数

最後に、このプログラムで最も重要な部分である、paint 関数です。

paint 関数は、プログラムの開始から終了まで、毎秒数十回の頻度で繰り返し呼ばれ続けます。 ここに描画処理を記述します。


/**
 * ユーザー定義の描画処理、
 * ここはアニメーションの毎時刻呼び出されます。
 */
void paint(){

	//まず2DCGを背景色でクリア(画面には2DCGが表示される)
	clearGraphics2D(renderer2D);

	//2DCGに図形を適当に描き込み
	setDrawColor(renderer2D, 0, 0, 255, 255);
	drawRect(renderer2D, 50, 280, 300, 300, true);


	//3DCGレンダラーを動かして描画(内容はgraphics3Dに)
	paintGraphics3D(renderer3D);

	//2DCG上に、3DCG(renderer3Dの出力 = graphics3D)を描画
	drawImage(
		renderer2D, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, graphics3D
	);


	//2DCGに図形を適当に描き込み
	setDrawColor(renderer2D, 0, 255, 0, 180);
	drawOval(renderer2D, 400, 100, 200, 200, true);
}
paint.txt

上記の通り、基本は2Dアニメーションの描画内容そのままです。まず clearGraphics2D 関数で画面をクリアし、 drawRect 関数や drawOval 関数で図形を描画しています。

重要なのは、途中で drawImage 関数により、3Dレンダラーの描画内容( graphics3D )を2DCG上に描き込んでいる点です。 これは、2DCG上に画像を描き込むのと全く同じです。

なお、3DCGの背景色は透明に設定してあり、 drawImage より前に記述した描画内容は3DCGの背後に、 後に記述した描画内容は手前に表示されます。

上の例では、drawRect による青い四角形は3DCGの奥に、drawOvalによる緑色の楕円は手前に表示されます。

ライセンス

このVCSSL/Vnanoコード( 拡張子が「.vcssl」や「.vnano」のファイル )は実質的な著作権フリー(パブリックドメイン) である CC0 の状態で公開しています。 記事中にC言語/C++/Java言語などでのサンプルコードが掲載されいてる場合は、それらについても同様です。 そのままでのご利用はもちろん、改造や流用などもご自由に行ってください。

※ ただし、このコードの配布フォルダ内には、ダウンロード後すぐに実行できるように、 VCSSLの実行環境も同梱されており、そのライセンス文書は「 License 」フォルダ内に同梱されています (要約すると、商用・非商用問わず自由に使用できますが、使用の結果に対して開発元は一切の責任を負いません、といった具合の内容です)。 配布フォルダ内の各構成物の一覧やライセンスについては「 ReadMe_使用方法_必ずお読みください.txt 」をご参照ください。

※ Vnano の実行環境については、別途スクリプトエンジンのソースコードも一般公開しており、 何らかのソフトウェア内に組み込んでご利用いただく事も可能です。詳細はこちらをご参照ください。

この記事中の商標などについて

  • OracleとJavaは、Oracle Corporation 及びその子会社、関連会社の米国及びその他の国における登録商標です。文中の社名、商品名等は各社の商標または登録商標である場合があります。
  • Windows は、米国 Microsoft Corporation の米国およびその他の国における登録商標です。この記事は独立著作物であり、Microsoft Corporation と関連のある、もしくはスポンサーを受けるものではありません。
  • Linux は、Linus Torvalds 氏の米国およびその他の国における商標または登録商標です。
  • その他、文中に使用されている商標は、その商標を保持する各社の各国における商標または登録商標です。

[ 前へ | 目次 | 次へ ]
画像を任意サイズに拡大・縮小する簡易ツール(複数ファイル一括処理版)

フォルダ内にある全ての画像ファイルを開き、任意のサイズに拡大・縮小して、別のフォルダに保存する簡易ツールです。
画像を任意サイズに拡大・縮小する簡易ツール

画像ファイルを開き、任意のサイズに拡大・縮小して、別名で保存する簡易ツールです。
画像の矩形(四角形)領域を切り抜く簡易ツール(複数ファイル一括処理版)

フォルダ内にある全ての画像ファイルを開き、その中の矩形(四角形)領域を切り抜いて、別のフォルダに保存する簡易ツールです。
画像の矩形(四角形)領域を切り抜く簡易ツール

画像ファイルを開き、その中の矩形(四角形)領域を切り抜いて保存する簡易ツールです。
連番画像をアニメーション再生する簡易ツール

フォルダ内の連番画像ファイルを、動画への変換不要で、そのままアニメーションとして再生できる簡易ツールです。
条件を満たす色を透明にする簡易ツール(複数ファイル一括処理版)

フォルダ内の全画像ファイルに対して、条件を満たす範囲の色を透明に置き換え、別のフォルダに保存する簡易ツールです。
特定の色を透明にする簡易ツール(複数ファイル一括処理版)

フォルダ内にある全てのPNG形式画像ファイルを開き、特定の色を透明に置き換えた上で、別のフォルダに保存する簡易ツールです。
条件を満たす色を透明にする簡易ツール

画像ファイルを開き、指定された条件を満たす色を透明に置き換えて保存する簡易ツールです。
特定の色を透明にする簡易ツール

画像ファイルを開き、特定の色を透明に置き換えて保存する簡易ツールです。
2DCGと3DCGの合成

2DCGと3DCGを一枚に合成し、画面に表示するプログラムの例です。
RGBやカラーコードの色表示と相互変換ができる簡易ツール

RGB値とカラーコードから、GUI画面上で色の表示や相互変換を行う事ができる簡易ツールです。
頂点配列によるモデルの変形アニメーション

頂点配列によってモデルを変形アニメーションさせるサンプルです。
頂点配列によるモデルの作成(四角形格子メッシュ形式)

四角形格子メッシュの形式で、頂点配列からモデルを作成するサンプルです。
この階層の目次
[ 前へ | 目次 | 次へ ]
RINEARN からのお知らせ
※ VCSSL は RINEARN が開発しています。

VCSSLの最新版をリリース: 外部プログラムとの連携機能を少し強化、他
2025-05-25 - VCSSL 3.4.52をリリースしました。外部プログラム(C言語製の実行ファイル等)との連携機能を少し強化し、文字化け対策やOS判別などを可能にしました。他にも細かい機能追加があります。詳細をお知らせします。

VCSSLの最新版をリリース、Java 24上での非互換な挙動を対処
2025-04-22 - VCSSL 3.4.50をリリースしました。Java 24環境上でのネットワークドライブ関連のファイルパス解決で、従来環境とは異なる挙動が生じていたのを解消しました。詳細をお知らせします。

リニアングラフやVCSSLの最新版をリリース、目盛りの位置や内容を自由に指定可能に!
2024-11-24 - リニアングラフ3D/2Dを更新し、自由な位置に、自由な表記内容の目盛りを描けるようになりました! 併せて、Java言語やVCSSLでの、プログラム制御用APIも拡張しています。詳細をお知らせします。

Exevalator 2.2 をリリース、TypeScript 対応によりWebブラウザ上で動作可能に
2024-10-22 - オープンソースの式計算ライブラリ「Exevalator(エグゼバレータ)」の2.1をリリースしました。新たに TypeScript に対応し、Webブラウザ上での式計算にも使えるようになりました。詳細を解説します。

アシスタントAI作成の舞台裏(その2、作成編)
2024-10-12 - アシスタントAIの作成方法解説の後編です。実際にChatGPTの「GPTs」機能を用いて、アシスタントAIを作成する手順や、独自の知識をもたせたり、精度を出すためのノウハウなどを解説しています。

アシスタントAI作成の舞台裏(その1、基礎知識編)
2024-10-07 - アシスタントAI作成方法解説の前編です。今回はまず、アシスタントAIを作る前に抑えておきたい、基礎知識を延々と解説しています。そもそもLLM型AIとはどんな存在か? RAGとは何か? 等々です。

ソフトの利用をサポートしてくれるアシスタントAIを提供開始!
2024-09-20 - RINEARN製ソフトの使い方の質問応答や、一部作業のお手伝いをしてくれる、アシスタントAIを提供開始しました。ChatGPTアカウントさえあれば、誰でも無料で使用できます。使い方を解説します。

Exevalator 2.1 をリリース、新たに Visual Basic に対応
2024-07-28 - オープンソースの式計算ライブラリ「Exevalator(エグゼバレータ)」の2.1をリリースしました。今回から、新たに Visual Basic(VB.NET)でも使用できるようになりました。詳細を解説します。

関数電卓 RINPn(りんぷん)、Esc キーで計算式の一発クリアが可能に
2024-07-20 - 関数電 RINPn の Ver.1.0.2 をリリースしました。今回から、キーボードの「 Esc 」キーを押すと、入力中の計算式を一発でクリアできるようになりました。詳細を解説します。

Exevalator 2.0 をリリース、互換性に注意が必要なバグ修正が 1 件
2024-07-14 - オープンソースの式計算ライブラリ「Exevalator (エグゼバレータ)」の2.0をリリースしました。今回の更新では、互換性に注意を要する 1 件のバグ修正があります。詳細を解説します。