コード:
#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;
}