DXライブラリにて、ピクセルシェーダーのロードができない

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
Choucreampuff
記事: 12
登録日時: 8年前

DXライブラリにて、ピクセルシェーダーのロードができない

#1

投稿記事 by Choucreampuff » 8年前

現在、DXライブラリを利用して、3Dアクションゲームのステージを作成するための、ステージエディタ「ActionStageEditor」を作成しているのですが、モデル等をそのまま描画すると何か寂しいので、技術評価プログラムを作成し、シェーダーを勉強し始めました。
hart_edsf様http://qiita.com/hart_edsf/items/799b0af6d63f9e200853を参考にし、fxファイルの記述・コンパイルを行い、「test.pso」を生成しました。
本体を記述、いざ実行すると、画面が真っ暗です。

・本体プログラム
それぞれの機能等でクラス分けをしているため、描画クラスの定義部分を示します。

コード:

#include "GV.h"

GameDrawer::GameDrawer(StageData* stgData) {
	Stage = stgData;
}

GameDrawer::GameDrawer(StageTemplateData* stgTemplateData) {
	Stage_TemplateData = stgTemplateData;
	StageTemplateOnly = true;
}

void GameDrawer::Initialize() {
	if (StageTemplateOnly) {
		EntityMgr = new EntityManager(Stage_TemplateData);
		StgMgr->StageTemplateData_Initialize(Stage_TemplateData);
		
	}else{
		EntityMgr = new EntityManager(Stage);
		StgMgr->StageData_Initialize(Stage);
	}

	shaderhandle = LoadPixelShader("test.pso");
	if (shaderhandle == -1) {
		printfDebugMessage("利用可能なプログラマブルシェーダー:%d\n", GetValidShaderVersion());
		MessageBox(GetMainWindowHandle(), "ピクセルシェーダーの作成に失敗しました。", "ERROR", MB_OK);
	}

	thirdscreen = MakeScreen(Window_SizeX, Window_SizeY);
	//頂点の設定
	for (int i = 0; i < 4; i++)
	{
		vertex[i].pos = VGet((i % 2)*Window_SizeX, (i / 2)*Window_SizeY, 0);
		vertex[i].rhw = 1.0f;
		vertex[i].dif = GetColorU8(255, 255, 255, 255);
		vertex[i].spc = GetColorU8(0, 0, 0, 0);
		vertex[i].u = vertex[i].su = (float)(i % 2);
		vertex[i].v = vertex[i].sv = (float)(i / 2);
	}
}

void GameDrawer::Finalize() {
	if (StageTemplateOnly) {
		StgMgr->StageTemplateData_Finalize(Stage_TemplateData);
	}
	else {
		StgMgr->StageData_Finalize(Stage);
	}
	delete(EntityMgr);
}

void GameDrawer::Process() {
	//エンティティ情報を更新
	EntityMgr->Update();
	// カメラの位置と角度を更新
	SetCameraPositionAndAngle(Camera_Position, Camera_Rotation.x, Camera_Rotation.y, Camera_Rotation.z);
}

void GameDrawer::Draw() {
	SetDrawScreen(thirdscreen);
	ClearDrawScreen();

	VECTOR LightPos = GetLightPosition();
	SetLightPosition(VAdd(LightPos, VGet(0, 10, 0)));
	SetUseLighting(FALSE);
	DrawSphere3D(GetLightPosition(), 1000.0f, 100, GetColor(255, 255, 255), GetColor(255, 255, 255), TRUE);
	SetUseLighting(TRUE);

	//ステージモデルを描画
	if (StageTemplateOnly) {
		DrawStageTemplate();
	}
	else {
		DrawStageTemplate();
		DrawStage();
	}

	//エンティティを描画
	EntityMgr->Draw();

	//描画対象をバックスクリーンに戻してシェーダを使って描画
	SetDrawScreen(DX_SCREEN_BACK);
	//シェーダで使うテクスチャは先ほど作った描画可能画像
	SetUseTextureToShader(0, thirdscreen);
	//ピクセルシェーダのセット
	SetUsePixelShader(shaderhandle);
	DrawPrimitive2DToShader(vertex, 4, DX_PRIMTYPE_TRIANGLESTRIP);
	//ScreenFlip();
	//ステージモデルを描画
	if (StageTemplateOnly) {
		DrawStageTemplate();
	}
	else {
		DrawStageTemplate();
		DrawStage();
	}

	//エンティティを描画
	EntityMgr->Draw();
}

void GameDrawer::DrawStageTemplate() {
	for (int i = 0; i < Stage_TemplateData->objectNum; i++) {
		MV1DrawModel(Stage_TemplateData->objects[i].modelHandle);
	}
}

void GameDrawer::DrawStage() {
	for (int i = 0; i < Stage->objectNum; i++) {
		MV1DrawModel(Stage->userObjects[i].modelHandle);
	}
}
また、構造体「StageData」「StageTemplateData」は、構造体「ObjectData」の配列を保持し、「ObjectData」は、モデルデータの場所、位置、回転、縮尺などのデータを持ちます。「StageData」は「StageTemplateData」を保持します。

・ログ
問題のある場所(25行目、MessageBoxが表示されている時点)で出力されるデバッグ情報を示します。
[ActionStageEditor_DEBUG] ファイル"\stage\test\test.cfstgt"を正常に読み込みました。(1944324byte)
[ActionStageEditor_DEBUG] ステージテンプレートデータ"test"の読み込みを開始します...
[ActionStageEditor_DEBUG] ステージテンプレートデータ"test"の読み込み最適化を開始します...
[ActionStageEditor_DEBUG] オブジェクト"stage/test/models/盆地~海.x"の読み込み最適化を開始します...
[ActionStageEditor_DEBUG] オブジェクト"stage/test/models/盆地~海.x"の読み込み最適化完了
[ActionStageEditor_DEBUG] ステージテンプレートデータ"test"の読み込み最適化完了
[ActionStageEditor_DEBUG] オブジェクトモデル"stage/test/models/盆地~海.x"の読み込みを開始...
[ActionStageEditor_DEBUG] オブジェクトモデル"stage/test/models/盆地~海.x" 正常に読み込み
[ActionStageEditor_DEBUG] ステージテンプレートデータ"test" 正常に読み込みました。
0x00007FF9D58E7788 で例外がスローされました (ActionStageEditor.exe 内): Microsoft C++ の例外: _com_error (メモリの場所 0x000000B1BBDACDF0)。
3939:ピクセルシェーダーの作成に失敗しました
[ActionStageEditor_DEBUG] 利用可能なプログラマブルシェーダー:500
(ここでエラーダイアログ表示)

・環境  
 [OS]:Windows 10 Pro (x64)
 [コンパイラ]:Visual C++ 2015(x64/x86)
 [IDE]:Visual Studio 2015 Community

ピクセルシェーダーファイルをフルパスで指定してみたり、ピクセルシェーダーのコンパイル時にバージョンを変えてコンパイルしてみたりと努力しましたが、解決までたどり着くことはできませんでした。

C++の知識についてですが、始めてから大体1、2年立つでしょうか。クラス、構造体やポインタ等、基本的なことは理解しているつもりです。
しかしながらまだまだ初心者ですので、分からない部分もあるかもしれませんが、それに関しては上乗せで質問させていただきます。
汚いコードで申し訳ないです。

この現象について、何か分かる方はどうかご教授お願い致します。


初質問ですので、(理解したつもりですが)ルールに従っていない/ふさわしくない事柄があればお申し付けください。速やかに修正・改善に努めます。

Math

Re: DXライブラリにて、ピクセルシェーダーのロードができない

#2

投稿記事 by Math » 8年前

ピクセルシェーダについては詳しい方がいらしゃいますのでアドバイスがあるやも知れません。私も勉強中です。試してみます。
C++のプログラムですがシューティングゲームを1つのファイルにしたものです。このように主要な部分をまとめて検証可能なコードにはできないでしょうか。「さっき動作確認済みです」

コード:

#include <algorithm> 
#include <memory>
#include <map>
#include <list>
#include <string>
#include "DxLib.h"

enum ChrType { TYPE_NONE, TYPE_SHOT, TYPE_PLAYER, TYPE_ENEMY, TYPE_CLOUD, TYPE_NUM };

class Chr;/////////////////////////////////////////////////////////////////////
typedef std::shared_ptr<Chr> ChrRef;

// キャラクタ基本クラス
class Chr { ///////////////////////////////////////////////////////////////////
	static int loaded_images[TYPE_NUM];
	bool remove_flag;
protected:
	int image;
	int x, y;
	int width, height;
	int hit_x, hit_y;
	int hit_width, hit_height;
	void remove() { remove_flag = true; }
public:
	Chr();
	void setImage(char*);
	void setPosition(int, int);
	void setHitArea(int, int, int, int);
	bool isRemove() { return remove_flag; }
	virtual ChrType getType() = 0;
	virtual ChrType hitType() { return TYPE_NONE; }
	virtual void move() = 0;
	virtual void draw();
	bool hitTest(ChrRef&);
	virtual void hit() {};
};
int Chr::loaded_images[] = {};

// 弾クラス
class Shot : public Chr { /////////////////////////////////////////////////////
public:
	Shot();
	ChrType getType() { return TYPE_SHOT; }
	ChrType hitType() { return TYPE_ENEMY; }
	void move();
	void hit();
};

// プレイヤークラス
class Player : public Chr { ///////////////////////////////////////////////////
	bool shot_flag;
	int dead_time;
public:
	Player();
	ChrType getType() { return TYPE_PLAYER; }
	void move();
	void draw();
	void hit();
};

// 敵クラス
class Enemy : public Chr { ////////////////////////////////////////////////////
public:
	Enemy();
	ChrType getType() { return TYPE_ENEMY; }
	ChrType hitType() { return TYPE_PLAYER; }
	void move();
	void hit();
};

// 雲クラス
class Cloud : public Chr {
	int speed;
	void resetPosition(bool);
public:
	static const int NUM = 25;
	Cloud();
	ChrType getType() { return TYPE_CLOUD; }
	void move();
};

// ゲームクラス
class Game {
	std::list<ChrRef> chr_list;
	int score;
public:
	static const int WIDTH = 640;
	static const int HEIGHT = 480;
	static Game* me;
	void addList(ChrRef&);
	void addScore(int s) { score += s; }
	void init();
	void main();
	void end();
};
Game* Game::me;

// キャラクタクラス メンバ関数

Chr::Chr() {
	remove_flag = false;
}

void Chr::setImage(char* file_name) {
	if (loaded_images[getType()] == 0) {
		loaded_images[getType()] = LoadGraph(file_name);
	}
	image = loaded_images[getType()];
	GetGraphSize(image, &width, &height);
	hit_width = width;
	hit_height = height;
	hit_x = hit_y = 0;
}

void Chr::setPosition(int px, int py) {
	x = px; y = py;
}

void Chr::setHitArea(int hx, int hy, int hw, int hh) {
	hit_x = hx; hit_y = hy;
	hit_width = hw; hit_height = hh;
}

void Chr::draw() {
	DrawGraph(x, y, image, TRUE);
}

bool Chr::hitTest(ChrRef& dst) {
	int x1 = x + hit_x;
	int y1 = y + hit_y;
	int w1 = hit_width;
	int h1 = hit_height;
	int x2 = dst->x + dst->hit_x;
	int y2 = dst->y + dst->hit_y;
	int w2 = dst->hit_width;
	int h2 = dst->hit_height;
	if (x1 + w1 > x2 && x1 < x2 + w2 && y1 + h1 > y2 && y1 < y2 + h2) return true;
	return false;
}

// 弾クラス メンバ関数

Shot::Shot() {
	setImage("shot.png");
}

void Shot::move() {
	x += 12;
	if (x > Game::WIDTH) remove();
}

void Shot::hit() {
	remove();
}

// プレイヤークラス メンバ関数

Player::Player() {
	setImage("player.png");
	setPosition(30, 200);
	setHitArea(14, 12, 36, 16);
	shot_flag = false;
	dead_time = 0;
}

void Player::move() {
	if (dead_time > 0) {
		dead_time--;
		return;
	}
	if (CheckHitKey(KEY_INPUT_LEFT)) x -= 6;
	if (CheckHitKey(KEY_INPUT_RIGHT)) x += 6;
	if (CheckHitKey(KEY_INPUT_UP)) y -= 6;
	if (CheckHitKey(KEY_INPUT_DOWN)) y += 6;
	if (x < -hit_x) x = -hit_x;
	if (x > Game::WIDTH - hit_x - hit_width) x = Game::WIDTH - hit_x - hit_width;
	if (y < -hit_y) y = -hit_y;
	if (y > Game::HEIGHT - hit_y - hit_height) y = Game::HEIGHT - hit_y - hit_height;
	if (CheckHitKey(KEY_INPUT_SPACE)) {
		if (!shot_flag) {
			ChrRef shot(new Shot());
			shot->setPosition(x + width - 16, y + 16);
			Game::me->addList(shot);
			shot_flag = true;
		}
	}
	else {
		shot_flag = false;
	}
}

void Player::draw() {
	if (dead_time % 5 == 0) Chr::draw();
}

void Player::hit() {
	dead_time = 50;
}

// 敵クラス メンバ関数

Enemy::Enemy() {
	setImage("enemy.png");
	setPosition(Game::WIDTH, GetRand(Game::HEIGHT - height));
}

void Enemy::move() {
	x -= 4;
	if (x < -width) remove();
}

void Enemy::hit() {
	Game::me->addScore(100);
	remove();
}

// 雲クラス メンバ関数

Cloud::Cloud() {
	setImage("cloud.png");
	resetPosition(true);
}

void Cloud::resetPosition(bool init) {
	int cx = GetRand(Game::WIDTH + width) - width;
	int cy = GetRand(Game::HEIGHT + height) - height;
	if (init) setPosition(cx, cy);
	else setPosition(Game::WIDTH, cy);
	speed = GetRand(4) + 2;
}

void Cloud::move() {
	x -= speed;
	if (x < -width) resetPosition(false);
}

// ゲームクラス メンバ関数

void Game::addList(ChrRef& c) {
	chr_list.push_back(c);
}

void Game::init() { //---------------------------------------------------------init
	me = this;
	score = 0;
	ChangeWindowMode(TRUE);SetGraphMode(Game::WIDTH, Game::HEIGHT, 32);////////DxLib
	DxLib_Init();SetDrawScreen(DX_SCREEN_BACK);////////////////////////////////DxLib
	SetBackgroundColor(124, 210, 255);
	// 雲生成
	for (int i = 0; i < Cloud::NUM; i++) {
		ChrRef cloud(new Cloud());
		addList(cloud);
	}
	// プレイヤー生成
	ChrRef player(new Player());
	addList(player);
}

void Game::main() { //---------------------------------------------------------main
	while (!ProcessMessage()) {
		ClearDrawScreen();
		// 敵生成
		if (GetRand(49) == 0) {
			ChrRef enemy(new Enemy());
			addList(enemy);
		}
		// 移動
		std::for_each(chr_list.begin(), chr_list.end(), [](ChrRef& c) {c->move(); });
		// 描画
		std::for_each(chr_list.begin(), chr_list.end(), [](ChrRef& c) {c->draw(); });
		// 当たり判定
		std::for_each(chr_list.begin(), chr_list.end(), [&](ChrRef& src) {
			if (src->hitType() == TYPE_NONE) return;
			std::for_each(chr_list.begin(), chr_list.end(), [&](ChrRef& dst) {
				if (src->hitType() == dst->getType()) {
					if (src->hitTest(dst)) {
						src->hit();
						dst->hit();
					}
				}
			});
		});
		// スコア表示
		DrawFormatString(Game::WIDTH - 120, 5, GetColor(0, 0, 0), "SCORE %d", score);
		ScreenFlip();
		// 消すべきキャラクタの消去
		auto end = std::remove_if(chr_list.begin(), chr_list.end(), [](ChrRef& c) {return c->isRemove(); });
		chr_list.erase(end, chr_list.end());
	}
}
//-----------------------------------------------------------------------------end
void Game::end() {
	DxLib_End();///////////////////////////////////////////////////////////////DxLib
}
// WinMain---------------------------------------------------------------------WniMain
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) {
	Game game;
	game.init();
	game.main();
	game.end();
	return 0;
}
//-----------------------------------------------------------------------------
[/size]

Choucreampuff
記事: 12
登録日時: 8年前

Re: DXライブラリにて、ピクセルシェーダーのロードができない

#3

投稿記事 by Choucreampuff » 8年前

返信ありがとうございます。
了解です、明日、動作に必要なクラス等を分解して一つのソースコードにまとめ、それ一つで検証が可能な状態にします。

Choucreampuff
記事: 12
登録日時: 8年前

Re: DXライブラリにて、ピクセルシェーダーのロードができない

#4

投稿記事 by Choucreampuff » 8年前

Math さんが書きました:ピクセルシェーダについては詳しい方がいらしゃいますのでアドバイスがあるやも知れません。私も勉強中です。試してみます。
C++のプログラムですがシューティングゲームを1つのファイルにしたものです。このように主要な部分をまとめて検証可能なコードにはできないでしょうか。「さっき動作確認済みです」

コード:

#include <algorithm> 
#include <memory>
#include <map>
#include <list>
#include <string>
#include "DxLib.h"

enum ChrType { TYPE_NONE, TYPE_SHOT, TYPE_PLAYER, TYPE_ENEMY, TYPE_CLOUD, TYPE_NUM };

class Chr;/////////////////////////////////////////////////////////////////////
typedef std::shared_ptr<Chr> ChrRef;

// キャラクタ基本クラス
class Chr { ///////////////////////////////////////////////////////////////////
	static int loaded_images[TYPE_NUM];
	bool remove_flag;
protected:
	int image;
	int x, y;
	int width, height;
	int hit_x, hit_y;
	int hit_width, hit_height;
	void remove() { remove_flag = true; }
public:
	Chr();
	void setImage(char*);
	void setPosition(int, int);
	void setHitArea(int, int, int, int);
	bool isRemove() { return remove_flag; }
	virtual ChrType getType() = 0;
	virtual ChrType hitType() { return TYPE_NONE; }
	virtual void move() = 0;
	virtual void draw();
	bool hitTest(ChrRef&);
	virtual void hit() {};
};
int Chr::loaded_images[] = {};

// 弾クラス
class Shot : public Chr { /////////////////////////////////////////////////////
public:
	Shot();
	ChrType getType() { return TYPE_SHOT; }
	ChrType hitType() { return TYPE_ENEMY; }
	void move();
	void hit();
};

// プレイヤークラス
class Player : public Chr { ///////////////////////////////////////////////////
	bool shot_flag;
	int dead_time;
public:
	Player();
	ChrType getType() { return TYPE_PLAYER; }
	void move();
	void draw();
	void hit();
};

// 敵クラス
class Enemy : public Chr { ////////////////////////////////////////////////////
public:
	Enemy();
	ChrType getType() { return TYPE_ENEMY; }
	ChrType hitType() { return TYPE_PLAYER; }
	void move();
	void hit();
};

// 雲クラス
class Cloud : public Chr {
	int speed;
	void resetPosition(bool);
public:
	static const int NUM = 25;
	Cloud();
	ChrType getType() { return TYPE_CLOUD; }
	void move();
};

// ゲームクラス
class Game {
	std::list<ChrRef> chr_list;
	int score;
public:
	static const int WIDTH = 640;
	static const int HEIGHT = 480;
	static Game* me;
	void addList(ChrRef&);
	void addScore(int s) { score += s; }
	void init();
	void main();
	void end();
};
Game* Game::me;

// キャラクタクラス メンバ関数

Chr::Chr() {
	remove_flag = false;
}

void Chr::setImage(char* file_name) {
	if (loaded_images[getType()] == 0) {
		loaded_images[getType()] = LoadGraph(file_name);
	}
	image = loaded_images[getType()];
	GetGraphSize(image, &width, &height);
	hit_width = width;
	hit_height = height;
	hit_x = hit_y = 0;
}

void Chr::setPosition(int px, int py) {
	x = px; y = py;
}

void Chr::setHitArea(int hx, int hy, int hw, int hh) {
	hit_x = hx; hit_y = hy;
	hit_width = hw; hit_height = hh;
}

void Chr::draw() {
	DrawGraph(x, y, image, TRUE);
}

bool Chr::hitTest(ChrRef& dst) {
	int x1 = x + hit_x;
	int y1 = y + hit_y;
	int w1 = hit_width;
	int h1 = hit_height;
	int x2 = dst->x + dst->hit_x;
	int y2 = dst->y + dst->hit_y;
	int w2 = dst->hit_width;
	int h2 = dst->hit_height;
	if (x1 + w1 > x2 && x1 < x2 + w2 && y1 + h1 > y2 && y1 < y2 + h2) return true;
	return false;
}

// 弾クラス メンバ関数

Shot::Shot() {
	setImage("shot.png");
}

void Shot::move() {
	x += 12;
	if (x > Game::WIDTH) remove();
}

void Shot::hit() {
	remove();
}

// プレイヤークラス メンバ関数

Player::Player() {
	setImage("player.png");
	setPosition(30, 200);
	setHitArea(14, 12, 36, 16);
	shot_flag = false;
	dead_time = 0;
}

void Player::move() {
	if (dead_time > 0) {
		dead_time--;
		return;
	}
	if (CheckHitKey(KEY_INPUT_LEFT)) x -= 6;
	if (CheckHitKey(KEY_INPUT_RIGHT)) x += 6;
	if (CheckHitKey(KEY_INPUT_UP)) y -= 6;
	if (CheckHitKey(KEY_INPUT_DOWN)) y += 6;
	if (x < -hit_x) x = -hit_x;
	if (x > Game::WIDTH - hit_x - hit_width) x = Game::WIDTH - hit_x - hit_width;
	if (y < -hit_y) y = -hit_y;
	if (y > Game::HEIGHT - hit_y - hit_height) y = Game::HEIGHT - hit_y - hit_height;
	if (CheckHitKey(KEY_INPUT_SPACE)) {
		if (!shot_flag) {
			ChrRef shot(new Shot());
			shot->setPosition(x + width - 16, y + 16);
			Game::me->addList(shot);
			shot_flag = true;
		}
	}
	else {
		shot_flag = false;
	}
}

void Player::draw() {
	if (dead_time % 5 == 0) Chr::draw();
}

void Player::hit() {
	dead_time = 50;
}

// 敵クラス メンバ関数

Enemy::Enemy() {
	setImage("enemy.png");
	setPosition(Game::WIDTH, GetRand(Game::HEIGHT - height));
}

void Enemy::move() {
	x -= 4;
	if (x < -width) remove();
}

void Enemy::hit() {
	Game::me->addScore(100);
	remove();
}

// 雲クラス メンバ関数

Cloud::Cloud() {
	setImage("cloud.png");
	resetPosition(true);
}

void Cloud::resetPosition(bool init) {
	int cx = GetRand(Game::WIDTH + width) - width;
	int cy = GetRand(Game::HEIGHT + height) - height;
	if (init) setPosition(cx, cy);
	else setPosition(Game::WIDTH, cy);
	speed = GetRand(4) + 2;
}

void Cloud::move() {
	x -= speed;
	if (x < -width) resetPosition(false);
}

// ゲームクラス メンバ関数

void Game::addList(ChrRef& c) {
	chr_list.push_back(c);
}

void Game::init() { //---------------------------------------------------------init
	me = this;
	score = 0;
	ChangeWindowMode(TRUE);SetGraphMode(Game::WIDTH, Game::HEIGHT, 32);////////DxLib
	DxLib_Init();SetDrawScreen(DX_SCREEN_BACK);////////////////////////////////DxLib
	SetBackgroundColor(124, 210, 255);
	// 雲生成
	for (int i = 0; i < Cloud::NUM; i++) {
		ChrRef cloud(new Cloud());
		addList(cloud);
	}
	// プレイヤー生成
	ChrRef player(new Player());
	addList(player);
}

void Game::main() { //---------------------------------------------------------main
	while (!ProcessMessage()) {
		ClearDrawScreen();
		// 敵生成
		if (GetRand(49) == 0) {
			ChrRef enemy(new Enemy());
			addList(enemy);
		}
		// 移動
		std::for_each(chr_list.begin(), chr_list.end(), [](ChrRef& c) {c->move(); });
		// 描画
		std::for_each(chr_list.begin(), chr_list.end(), [](ChrRef& c) {c->draw(); });
		// 当たり判定
		std::for_each(chr_list.begin(), chr_list.end(), [&](ChrRef& src) {
			if (src->hitType() == TYPE_NONE) return;
			std::for_each(chr_list.begin(), chr_list.end(), [&](ChrRef& dst) {
				if (src->hitType() == dst->getType()) {
					if (src->hitTest(dst)) {
						src->hit();
						dst->hit();
					}
				}
			});
		});
		// スコア表示
		DrawFormatString(Game::WIDTH - 120, 5, GetColor(0, 0, 0), "SCORE %d", score);
		ScreenFlip();
		// 消すべきキャラクタの消去
		auto end = std::remove_if(chr_list.begin(), chr_list.end(), [](ChrRef& c) {return c->isRemove(); });
		chr_list.erase(end, chr_list.end());
	}
}
//-----------------------------------------------------------------------------end
void Game::end() {
	DxLib_End();///////////////////////////////////////////////////////////////DxLib
}
// WinMain---------------------------------------------------------------------WniMain
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) {
	Game game;
	game.init();
	game.main();
	game.end();
	return 0;
}
//-----------------------------------------------------------------------------
[/size]
申し訳ないです、いざ一つにまとめるとなると、(ファイル数が多すぎて)途方もない時間がかかりそうなので、同じ現象を再現できるソースコードを書かせていただきますね。

Math

Re: DXライブラリにて、ピクセルシェーダーのロードができない

#5

投稿記事 by Math » 8年前

分かりました。簡単なほうがいいですよ。良く分かってないので。

Choucreampuff
記事: 12
登録日時: 8年前

Re: DXライブラリにて、ピクセルシェーダーのロードができない

#6

投稿記事 by Choucreampuff » 8年前

私の環境では以下のコードで同じ現象が確認できました。
尚、使用している「test.pso」は、参考元のサイトに記述されている「test.fx」をコンパイルしたものです。

コード:

#define _CRT_SECURE_NO_WARNINGS
#include "DxLib.h"

#ifdef _DEBUG
#   define printfDebugMessage( str, ... ) \
      { \
        TCHAR c[256]; \
        _stprintf( c, str, __VA_ARGS__ ); \
		OutputDebugString( "[DEBUG] " ); \
        OutputDebugString( c ); \
      }

#   define printfDxDebugMessage( str, ... ) \
      { \
        printfDx( str, __VA_ARGS__ ); \
      }
#else
#	define printfDebugMessage( str, ... ) // 空実装
#	define printfDxDebugMessage(str, ...)
#endif

#define CAMERA_MOVE_SPEED 30

int Window_SizeX = 1280, Window_SizeY = 720;

class GameDrawer
{
private:
	bool StageTemplateOnly = false;
	bool useShader = false;
	VECTOR Camera_Position;
	VECTOR Camera_Rotation;

	int shaderhandle;
	//新たに描画可能画像を作成してシェーダにこれを渡す
	int thirdscreen;
	//頂点の設定
	VERTEX2DSHADER vertex[4];

public:
	bool isEditMode = false;
	void Initialize(bool useShader);//初期化
	void Finalize();//終了処理
	void Process();//更新
	void Draw();
	void DrawStageTemplate();
	void DrawStage();

	bool SetCameraPosition(VECTOR pos);
	bool SetCameraRotation(VECTOR rot);

	bool MoveCameraPosition(VECTOR pos);
	bool MoveCameraRotation(VECTOR rot);

	VECTOR GetCameraPosition();
	VECTOR GetCameraRotation();
};

void GameDrawer::Initialize(bool n) {
	useShader = n;
	if (useShader) {
		shaderhandle = LoadPixelShader("test.pso");
		if (shaderhandle == -1) {
			printfDebugMessage("利用可能なプログラマブルシェーダー:%d\n", GetValidShaderVersion());
			MessageBox(GetMainWindowHandle(), "ピクセルシェーダーの作成に失敗しました。", "ERROR", MB_OK | MB_ICONERROR);
		}
		//新たに描画可能画像を作成してシェーダにこれを渡す
		thirdscreen = MakeScreen(1280, 720);
		//頂点の設定
		for (int i = 0; i < 4; i++)
		{
			vertex[i].pos = VGet((i % 2) * 1280, (i / 2) * 720, 0);
			vertex[i].rhw = 1.0f;
			vertex[i].dif = GetColorU8(255, 255, 255, 255);
			vertex[i].spc = GetColorU8(0, 0, 0, 0);
			vertex[i].u = vertex[i].su = (float)(i % 2);
			vertex[i].v = vertex[i].sv = (float)(i / 2);
		}
	}
}

void GameDrawer::Finalize() {
}

void GameDrawer::Process() {
	// カメラの位置と角度を更新
	SetCameraPositionAndAngle(Camera_Position, Camera_Rotation.x, Camera_Rotation.y, Camera_Rotation.z);
	Draw();
}

void GameDrawer::Draw() {
	printfDx("Esc:終了  W/S/A/D:視点移動  LSHIFT:視点下降  SPACE:視点上昇  マウス:視点回転");
	if(useShader) SetDrawScreen(thirdscreen),ClearDrawScreen();
	DrawFillBox(0, 0, Window_SizeX, Window_SizeY, GetColor(128, 128, 255));
	//ステージモデルを描画
	DrawStage();

	//エンティティを描画
	//EntityMgr->Draw();

	if (useShader) {
		//描画対象をバックスクリーンに戻してシェーダを使って描画
		SetDrawScreen(DX_SCREEN_BACK);
		//シェーダで使うテクスチャは先ほど作った描画可能画像
		SetUseTextureToShader(0, thirdscreen);
		//ピクセルシェーダのセット
		SetUsePixelShader(shaderhandle);
		DrawPrimitive2DToShader(vertex, 4, DX_PRIMTYPE_TRIANGLESTRIP);
	}
}

void GameDrawer::DrawStageTemplate() {
}

void GameDrawer::DrawStage() {
	DrawSphere3D(VGet(0, 0, 0), 200.0f, 32, GetColor(255, 255, 255), GetColor(255, 255, 255), TRUE);
}

bool GameDrawer::SetCameraPosition(VECTOR pos) {
	Camera_Position = pos;
	return true;
}

bool GameDrawer::SetCameraRotation(VECTOR rot) {
	Camera_Rotation = rot;
	return true;
}

bool GameDrawer::MoveCameraPosition(VECTOR pos) {
	Camera_Position = VAdd(Camera_Position, pos);
	return true;
}

bool GameDrawer::MoveCameraRotation(VECTOR rot) {
	Camera_Rotation = VAdd(Camera_Rotation, rot);
	return true;
}

VECTOR GameDrawer::GetCameraPosition() {
	return Camera_Position;
}

VECTOR GameDrawer::GetCameraRotation() {
	return Camera_Rotation;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

struct PADINPUT
{
	int		NowInput;				// 現在の入力
	int		NowInputMouse;
	int		EdgeInput;				// 現在のフレームで押されたボタンのみビットが立っている入力値
};
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class InputManager
{
private:
	PADINPUT inp;// 入力情報の実体宣言
	int WindowX;
	int WindowY;
	int Input_Key[256]; // 0:入力されていない 1:入力された瞬間 2:入力されている 3:離された瞬間
	int Input_Mouse;
	int MouseX;
	int MouseY;
	int Old;
	int OldMouse;
	int OldMouseX;
	int OldMouseY;
	int MouseWheel;

public:
	//TaskManager();
	void Initialize();//初期化
	void Finalize();//終了処理
	void Process();//更新
	void DrawMouse();
	bool CheckKey_Push(int key);
	bool CheckKey_Hold(int key);
	bool CheckKey_Release(int key);
	bool CheckLeftClick();
	bool CheckWheelClick();
	bool CheckRightClick();
	int GetWindowX();
	int GetWindowY();

	int GetMouseX();
	int GetMouseY();
	void SetMouseX(int x);
	void SetMouseY(int y);

	bool CheckOldLeftClick();
	bool CheckOldWheelClick();
	bool CheckOldRightClick();
	int GetOldMouseX();
	int GetOldMouseY();
	int GetWheelVol();
};


void InputManager::Initialize(void)
{

}

void InputManager::Finalize(void)
{

}

// 入力処理
void InputManager::Process(void)
{
	OldMouse = Input_Mouse;
	OldMouseX = MouseX;
	OldMouseY = MouseY;
	// ひとつ前のフレームの入力を変数にとっておく
	Old = inp.NowInput;

	GetWindowPosition(&WindowX, &WindowY);

	MouseWheel = GetMouseWheelRotVol();

	//printfDx("Old", Old[KEY_INPUT_UP]);

	// 現在の入力状態を取得
	inp.NowInput = GetJoypadInputState(DX_INPUT_KEY_PAD1);

	// 今のフレームで新たに押されたボタンのビットだけ立っている値を EdgeInput に代入する
	inp.EdgeInput = inp.NowInput & ~Old;

	static char buf[256];
	GetHitKeyStateAll(buf);
	for (int i = 0; i < 256; i++) {
		if (buf[i]) {
			if (Input_Key[i] == 0) Input_Key[i] = 1;
			else if (Input_Key[i] == 1) Input_Key[i] = 2;
		}
		else if ((Input_Key[i] != 0) && (Input_Key[i] != 3)) Input_Key[i] = 3;
		else Input_Key[i] = 0;
	}

	Input_Mouse = GetMouseInput();
	GetMousePoint(&MouseX, &MouseY);
}

void InputManager::DrawMouse(void) {
	int mx, my;
	GetMousePoint(&mx, &my);
	DrawCircle(mx, my, 20, GetColor(255, 0, 0));
	DrawPixel(mx, my, GetColor(0, 0, 0));
}

bool InputManager::CheckKey_Push(int key)
{
	if (Input_Key[key] == 1) {
		return true;
	}
	return false;
}

bool InputManager::CheckKey_Hold(int key)
{
	if (Input_Key[key] == 2) {
		return true;
	}
	return false;
}

bool InputManager::CheckKey_Release(int key)
{
	if (Input_Key[key] == 3) {
		return true;
	}
	return false;
}

int InputManager::GetWindowX() {
	return WindowX;
}
int InputManager::GetWindowY() {
	return WindowY;
}

int InputManager::GetMouseX() {
	return MouseX;
}
int InputManager::GetMouseY() {
	return MouseY;
}

void InputManager::SetMouseX(int x) {
	SetMousePoint(x, MouseY);
	MouseX = x;
	OldMouseX = x;
}
void InputManager::SetMouseY(int y) {
	SetMousePoint(MouseX, y);
	MouseY = y;
	OldMouseY = y;
}

int InputManager::GetOldMouseX() {
	return OldMouseX;
}
int InputManager::GetOldMouseY() {
	return OldMouseY;
}

int InputManager::GetWheelVol() {
	return MouseWheel;
}

bool InputManager::CheckLeftClick() {
	return Input_Mouse & MOUSE_INPUT_LEFT;
}

bool InputManager::CheckWheelClick() {
	return Input_Mouse & MOUSE_INPUT_MIDDLE;
}

bool InputManager::CheckRightClick() {
	return Input_Mouse & MOUSE_INPUT_RIGHT;
}

bool InputManager::CheckOldLeftClick() {
	return OldMouse & MOUSE_INPUT_LEFT;
}

bool InputManager::CheckOldWheelClick() {
	return OldMouse & MOUSE_INPUT_MIDDLE;
}

bool InputManager::CheckOldRightClick() {
	return OldMouse & MOUSE_INPUT_RIGHT;
}

//////////////////////////////////////////////////////////////////////////////////


// WinMain
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{

	SetDoubleStartValidFlag(TRUE);

	SetGraphMode(Window_SizeX, Window_SizeY, 32);
	SetWindowSize(Window_SizeX, Window_SizeY);
	ChangeWindowMode(TRUE);
	SetMainWindowText("PixelShader does not work");

	// ライブラリの初期化
	if (DxLib_Init() < 0)
		exit(EXIT_FAILURE);

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

	ChangeFont("MS ゴシック");

	//霧を描画する
	SetFogEnable(TRUE);
	float DrawDistance = 100000.0f;
	SetFogStartEnd(DrawDistance - (DrawDistance / 4), DrawDistance);
	SetFogColor(0, 0, 0);
	//SetFogStartEnd(SystemConfig.Fog_Start, SystemConfig.Draw_Distance);
	SetCameraNearFar(5.0f, DrawDistance);

	GameDrawer *gd = new GameDrawer();
	InputManager *InpMgr = new InputManager();

	int result = MessageBox(GetMainWindowHandle(), "シェーダーを使用しますか?", "SELECT", MB_YESNO);
	bool isUseShader = false;
	if (result == IDYES) isUseShader = true;
	gd->Initialize(isUseShader);
	InpMgr->Initialize();
	SetMouseDispFlag(FALSE);

	////////////////////////////////////////////////////////////////////////////////

	while (ProcessMessage() == 0 && CheckHitKey(KEY_INPUT_ESCAPE) == 0)
	{
		clsDx();

		InpMgr->Process();

		//カメラの制御
		{
			VECTOR MoveVec = VGet(0, 0, 0);
			bool Moved = false;
			if (InpMgr->CheckKey_Hold(KEY_INPUT_A)) {
				Moved = true;
				MoveVec.x += -CAMERA_MOVE_SPEED;
			}
			if (InpMgr->CheckKey_Hold(KEY_INPUT_D)) {
				Moved = true;
				MoveVec.x += CAMERA_MOVE_SPEED;
			}
			if (InpMgr->CheckKey_Hold(KEY_INPUT_W)) {
				Moved = true;
				MoveVec.z += CAMERA_MOVE_SPEED;
			}
			if (InpMgr->CheckKey_Hold(KEY_INPUT_S)) {
				Moved = true;
				MoveVec.z += -CAMERA_MOVE_SPEED;
			}
			if (InpMgr->CheckKey_Hold(KEY_INPUT_SPACE)) {
				Moved = true;
				MoveVec.y += CAMERA_MOVE_SPEED;
			}
			if (InpMgr->CheckKey_Hold(KEY_INPUT_LSHIFT)) {
				Moved = true;
				MoveVec.y += -CAMERA_MOVE_SPEED;
			}

			if (Moved) {
				VECTOR NowCameraRotVec = gd->GetCameraRotation();
				//VECTOR NormalRot = VNorm(NowCameraRotVec);

				VECTOR PosVec = VGet(0, 0, 0);
				PosVec = VTransform(MoveVec, MGetRotY(NowCameraRotVec.y));

				gd->MoveCameraPosition(PosVec);
			}

			if (InpMgr->GetMouseX() < 0) {
				InpMgr->SetMouseX(Window_SizeX);
			}
			if (InpMgr->GetMouseY() < 0) {
				InpMgr->SetMouseY(Window_SizeY);
			}

			if (InpMgr->GetMouseX() > Window_SizeX) {
				InpMgr->SetMouseX(0);
			}
			if (InpMgr->GetMouseY() > Window_SizeY) {
				InpMgr->SetMouseY(0);
			}
			float MouseX_move = InpMgr->GetMouseX() - InpMgr->GetOldMouseX();
			float MouseY_move = InpMgr->GetMouseY() - InpMgr->GetOldMouseY();
			VECTOR NowRot = gd->GetCameraRotation();
			if ((NowRot.x + MouseY_move / 200) > DX_PI_F / 2.0f) {
				MouseY_move = 0;
			}
			if ((NowRot.x + MouseY_move / 200) < -DX_PI_F / 2.0f)
			{
				MouseY_move = 0;
			}
			gd->MoveCameraRotation(VGet(MouseY_move / 200, MouseX_move / 200, 0));
		}

		gd->Process();
		
		ClearDrawScreen();

		gd->Draw();

		ScreenFlip();
	}

	gd->Finalize();
	InpMgr->Finalize();
	delete gd;
	delete InpMgr;

	DxLib_End();

	// ソフト終了
	return 0;
}

Math

Re: DXライブラリにて、ピクセルシェーダーのロードができない

#7

投稿記事 by Math » 8年前

PixelShaderTestPS.psoだと表示されるのでtest.psoの作成に失敗してますね!

Choucreampuff
記事: 12
登録日時: 8年前

Re: DXライブラリにて、ピクセルシェーダーのロードができない

#8

投稿記事 by Choucreampuff » 8年前

うーん...私の環境がいけないのでしょうか...DxLib「サンプルプログラム実行用フォルダ」内のPixelShaderTestPS.psoを使用しても例外が出ますね...
ダイアログが表示された時点で
0x76C2A832 で例外がスローされました (TEST.exe 内): Microsoft C++ の例外: _com_error (メモリの場所 0x001AE9A8)。
2160:ピクセルシェーダーの作成に失敗しました
[DEBUG] 利用可能なプログラマブルシェーダー:500
がログに記されますね...
シェーダーは上位互換がありますよね?

Math

Re: DXライブラリにて、ピクセルシェーダーのロードができない

#9

投稿記事 by Math » 8年前

あれーtest.psoの生成もサイトの方法で成功しました。!

Choucreampuff
記事: 12
登録日時: 8年前

Re: DXライブラリにて、ピクセルシェーダーのロードができない

#10

投稿記事 by Choucreampuff » 8年前

むむむ、何がいけないのでしょう...
ちなみに、シェーダーコンパイラのサンプルプログラムのバイナリは動作しました。(赤が青になっていた)
しかし、付属したソースコードを私がコンパイルしたものであると動作しません。


Choucreampuff
記事: 12
登録日時: 8年前

Re: DXライブラリにて、ピクセルシェーダーのロードができない

#12

投稿記事 by Choucreampuff » 8年前

おや、Ver3.17なんてあったのですね。
私が現在使用しているのは3.16bでした。
早速アップデートしてみます。

Choucreampuff
記事: 12
登録日時: 8年前

Re: DXライブラリにて、ピクセルシェーダーのロードができない

#13

投稿記事 by Choucreampuff » 8年前

ありゃ、Ver3.17aに差し替えましたが、何も変わりませんね...

Choucreampuff
記事: 12
登録日時: 8年前

Re: DXライブラリにて、ピクセルシェーダーのロードができない

#14

投稿記事 by Choucreampuff » 8年前

利用するDirect3Dのバージョンが悪かったみたいです。
SetUseDirect3DVersion(DX_DIRECT3D_9EX);
をDxLib_Init関数前に入れたら正常に動作しました!
ありがとうございました。

Math

Re: DXライブラリにて、ピクセルシェーダーのロードができない

#15

投稿記事 by Math » 8年前

サンプルがそうですね!

コード:

#include "DxLib.h"

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
	int grhandle, pshandle ;
	VERTEX2DSHADER Vert[ 6 ] ;

	// ウインドウモードで起動
	ChangeWindowMode( TRUE );

	// 使用する Direct3D のバージョンを 9EX に設定
	SetUseDirect3DVersion( DX_DIRECT3D_9EX );

	// DXライブラリの初期化
	if( DxLib_Init() < 0 ) return -1;

	// 画像の読み込み
	grhandle = LoadGraph( "Test1.bmp" );

	// ピクセルシェーダーバイナリコードの読み込み
	pshandle = LoadPixelShader( "SamplePS.pso" ) ;//SamplePS

	// 頂点データの準備
	Vert[ 0 ].pos = VGet(   0.0f,   0.0f, 0.0f ) ;
	Vert[ 1 ].pos = VGet( 128.0f,   0.0f, 0.0f ) ;
	Vert[ 2 ].pos = VGet(   0.0f, 512.0f, 0.0f ) ;
	Vert[ 3 ].pos = VGet( 128.0f, 512.0f, 0.0f ) ;
	Vert[ 0 ].dif = GetColorU8( 255,255,255,255 ) ;
	Vert[ 0 ].spc = GetColorU8( 0,0,0,0 ) ;
	Vert[ 0 ].u = 0.0f ; Vert[ 0 ].v = 0.0f ;
	Vert[ 1 ].u = 1.0f ; Vert[ 1 ].v = 0.0f ;
	Vert[ 2 ].u = 0.0f ; Vert[ 2 ].v = 1.0f ;
	Vert[ 3 ].u = 1.0f ; Vert[ 3 ].v = 1.0f ;
	Vert[ 0 ].su = 0.0f ; Vert[ 0 ].sv = 0.0f ;
	Vert[ 1 ].su = 1.0f ; Vert[ 1 ].sv = 0.0f ;
	Vert[ 2 ].su = 0.0f ; Vert[ 2 ].sv = 1.0f ;
	Vert[ 3 ].su = 1.0f ; Vert[ 3 ].sv = 1.0f ;
	Vert[ 0 ].rhw = 1.0f ;
	Vert[ 1 ].rhw = 1.0f ;
	Vert[ 2 ].rhw = 1.0f ;
	Vert[ 3 ].rhw = 1.0f ;
	Vert[ 4 ] = Vert[ 2 ] ;
	Vert[ 5 ] = Vert[ 1 ] ;

	// 使用するテクスチャをセット
	SetUseTextureToShader( 0, grhandle ) ;

	// 使用するピクセルシェーダーをセット
	SetUsePixelShader( pshandle ) ;

	// 描画
	DrawPrimitive2DToShader( Vert, 6, DX_PRIMTYPE_TRIANGLELIST ) ;

	// キー入力待ち
	WaitKey() ;

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

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

Choucreampuff
記事: 12
登録日時: 8年前

Re: DXライブラリにて、ピクセルシェーダーのロードができない

#16

投稿記事 by Choucreampuff » 8年前

はい、Ver3.16にはそのような記述が無かったので^^;

閉鎖

“C言語何でも質問掲示板” へ戻る