プログラマーの卵の日記

備忘録になってます!小難しそうなことから超簡単なことまでやってます!!

【DxLib】遠近法カメラと正射影カメラ切り替えたい

構成


No.1 実際にやったこと
No.2 必要な関数たち
No.3 遠近法カメラをやってみる
No.4 正射影カメラをやってみる
No.5 動的にカメラを切り替えたい







    No.1 実際にやったこと


 細かく言うと、正射影カメラは少し斜め上になるようにしていいます。
遠近法カメラだけは上下移動できるようになっています。
それと遠近法カメラでも正射影カメラでも横回転するようにしています。

 

0:19~


【Re.Gleam】オプション【説明】







    No.2 こんな感じ


 まず、よくある3Dゲームで使われている遠近法カメラに必要な関数は以下のような者です。
int SetCameraNearFar( float Near, float Far ) ;

 次に正射影カメラに必要な関数は以下のような者です。
int SetupCamera_Ortho( float Size ) ;

 で、両方のカメラで使うものは以下のような者です。
int SetCameraPositionAndTarget_UpVecY( VECTOR Position, VECTOR Target ) ;





    No.3 遠近法カメラをやってみる


 じゃあまぁとりあえず遠近法カメラがどんな感じなのか実際に動かしてみてみる。
SimpleModel.mqoというのはDxLib_VC\サンプルプログラム実行用フォルダの中にあります。
htmlで書いている関係でincludeのところであれがないけどわざとだから許して…


#include "DxLib.h"
#include cmath

void RLrotate(const float speed, float& axisOne, float& axisTwo)
{
	const float tempX = axisOne;
	const float tempY = axisTwo;
	axisOne = tempX * cosf(speed) + tempY * sinf(speed);
	axisTwo = -tempX * sinf(speed) + tempY * cosf(speed);
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	int ModelHandle;
	ChangeWindowMode(TRUE);

	// DXライブラリの初期化
	if (DxLib_Init() < 0)
	{
		// エラーが発生したら直ちに終了
		return -1;
	}

	// モデルの読み込み
	ModelHandle = MV1LoadModel("SimpleModel.mqo");

	// 描画先を裏画面にする
	SetDrawScreen(DX_SCREEN_BACK);

	// カメラの座標を初期化
	VECTOR perspesctiveViewArea = VGet(0, 150, 0);
	VECTOR cameraPerspectiveArea = VGet(0, 530, 700);
	VECTOR charaArea = VGet(0.0f, 0.0f, 0.0f);

	SetCameraNearFar(100.0f, 9500.0f);	// カメラの描画範囲を指定
	SetCameraPositionAndTarget_UpVecY(VAdd(cameraPerspectiveArea, charaArea), VAdd(perspesctiveViewArea, charaArea));

	// ESCキーが押されるかウインドウが閉じられるまでループ
	while (ProcessMessage() == 0 && CheckHitKey(KEY_INPUT_ESCAPE) == 0)
	{
		// 画面をクリア
		ClearDrawScreen();

		// 方向キーでカメラの座標を移動
		if (CheckHitKey(KEY_INPUT_LEFT) == 1)
		{
			RLrotate(0.1f, cameraPerspectiveArea.x, cameraPerspectiveArea.z);
		}
		if (CheckHitKey(KEY_INPUT_RIGHT) == 1)
		{
			RLrotate(-0.1f, cameraPerspectiveArea.x, cameraPerspectiveArea.z);
		}

		// カメラの位置と注視点をセット、注視点は原点
		SetCameraPositionAndTarget_UpVecY(VAdd(cameraPerspectiveArea, charaArea), VAdd(perspesctiveViewArea, charaArea));

		// モデルの描画
		MV1DrawModel(ModelHandle);

		// 裏画面の内容を表画面に反映
		ScreenFlip();
	}

	// モデルハンドルの削除
	MV1DeleteModel(ModelHandle);

	// DXライブラリの後始末
	DxLib_End();

	// ソフトの終了
	return 0;
}






    No.4 正射影カメラをやってみる


 やってみる!


#include "DxLib.h"
#include cmath

void RLrotate(const float speed, float& axisOne, float& axisTwo)
{
	const float tempX = axisOne;
	const float tempY = axisTwo;
	axisOne = tempX * cosf(speed) + tempY * sinf(speed);
	axisTwo = -tempX * sinf(speed) + tempY * cosf(speed);
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	int ModelHandle;
	ChangeWindowMode(TRUE);

	// DXライブラリの初期化
	if (DxLib_Init() < 0)
	{
		// エラーが発生したら直ちに終了
		return -1;
	}

	// モデルの読み込み
	ModelHandle = MV1LoadModel("SimpleModel.mqo");

	// 描画先を裏画面にする
	SetDrawScreen(DX_SCREEN_BACK);

	// カメラの座標を初期化
	VECTOR orthoViewArea = VGet(0, 150, 0);
	VECTOR cameraOrthoArea = VGet(0, 1700, 2430);
	float orthoArea = 2200.0f;
	VECTOR charaArea = VGet(0.0f, 0.0f, 0.0f);

	SetupCamera_Ortho(orthoArea);
	SetCameraPositionAndTarget_UpVecY(VAdd(cameraOrthoArea, charaArea), VAdd(orthoViewArea, charaArea));

	// ESCキーが押されるかウインドウが閉じられるまでループ
	while (ProcessMessage() == 0 && CheckHitKey(KEY_INPUT_ESCAPE) == 0)
	{
		// 画面をクリア
		ClearDrawScreen();

		// 方向キーでカメラの座標を移動
		if (CheckHitKey(KEY_INPUT_LEFT) == 1)
		{
			RLrotate(0.1f, cameraOrthoArea.x, cameraOrthoArea.z);
		}
		if (CheckHitKey(KEY_INPUT_RIGHT) == 1)
		{
			RLrotate(-0.1f, cameraOrthoArea.x, cameraOrthoArea.z);
		}

		// カメラの位置と注視点をセット、注視点は原点
		SetCameraPositionAndTarget_UpVecY(VAdd(cameraOrthoArea, charaArea), VAdd(orthoViewArea, charaArea));

		// モデルの描画
		MV1DrawModel(ModelHandle);

		// 裏画面の内容を表画面に反映
		ScreenFlip();
	}

	// モデルハンドルの削除
	MV1DeleteModel(ModelHandle);

	// DXライブラリの後始末
	DxLib_End();

	// ソフトの終了
	return 0;
}






              No.5 動的にカメラを切り替えたい


 本編。だけどここまでのやりとりで大体把握できたと思うので全文コードはやめる。(決してめんどくさくなったとかではないです。)

切り替えるといっても簡単な話。
遠近法カメラなら切り替えた時に以下のこれを呼ぶ。


    SetCameraNearFar(100.0f, 9500.0f);	// カメラの描画範囲を指定
	SetCameraPositionAndTarget_UpVecY(VAdd(cameraPerspectiveArea, charaArea), VAdd(perspesctiveViewArea, charaArea));


そしたらマイループ時にこれを呼ぶ。


	SetCameraPositionAndTarget_UpVecY(VAdd(cameraPerspectiveArea, charaArea), VAdd(perspesctiveViewArea, charaArea));

という話。

正射影カメラは


	SetupCamera_Ortho(orthoArea);
	SetCameraPositionAndTarget_UpVecY(VAdd(cameraOrthoArea, charaArea), VAdd(orthoViewArea, charaArea));


マイループで。


	SetCameraPositionAndTarget_UpVecY(VAdd(cameraOrthoArea, charaArea), VAdd(orthoViewArea, charaArea));

という話。


で、一応気を付けてほしいこととして、遠近法カメラの時でも正射影カメラの回転をさせないといけない。
これをしないと連続で切り替えた時にプレイヤーを見ている方向がおかしくなっちゃうからね。