winapi ウィンドウがすぐ閉じる

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
NN

winapi ウィンドウがすぐ閉じる

#1

投稿記事 by NN » 10年前

winapiとdirectx11でゲームを作っているんですが
アプリケーションが起動した直後に終了してしまいます。

思い当たる原因を調べても
原因は分かりませんでした。

教えてもらえたらうれしいです。
行数が多くてすみません。

コード:

#include "Application.h"

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow)
{
	UNREFERENCED_PARAMETER(hPrevInstance);
	UNREFERENCED_PARAMETER(lpCmdLine);

	//コンソールを作成
#if _DEBUG
	OpenConsole();
#endif

	Application application = Application("DirectX Test", Rect(0, 0, 640, 480), hInstance, nCmdShow);

	//メインループ
	MSG msg = { 0 };
	while (application.Message(&msg))
	{
		application.Render();
	}

	application.End();

	return (int)msg.message;
}

コード:

#include "Application.h"

struct vtx3 {
	XMFLOAT3 pos;
};

//引数なしコンストラクタ
Application::Application()
{
	MessageBox(nullptr, "Applicationクラスのコンストラクタに引数がないので\n初期化ができませんでした。", "Error", MB_ICONSTOP);
}

//引数ありコンストラク
Application::Application(string winTitle, RECT winRect, HINSTANCE hInstance, int cmdShow)
{
	Application::hInstance = hInstance;

	Application::winTitle = winTitle;
	Application::winRect = winRect;
	Application::winHandle = nullptr;

	Application::driverType = D3D_DRIVER_TYPE_NULL;
	Application::featureLevel = D3D_FEATURE_LEVEL_11_0;
	Application::device = nullptr;
	Application::immediateContext = nullptr;
	Application::swapChain = nullptr;
	Application::renderTargetView = nullptr;
	Application::vertexShader = nullptr;
	Application::pixelShader = nullptr;
	Application::vertexLayout = nullptr;
	Application::vertexBuffer = nullptr;


	if (FAILED(InitWindow(cmdShow)))
		return;

	if (FAILED(InitDevice()))
	{
		End();
		return;
	}
}

//デストラクタ
Application::~Application()
{

}

//アプリケーションの終了処理
void Application::End()
{
	CleanupDevice();
	CloseConsole();
}

//メッセージの処理
bool Application::Message(MSG *msg)
{
	while (WM_QUIT != msg->message)
	{
		if (PeekMessage(msg, winHandle, 0, 0, PM_REMOVE))
		{
			TranslateMessage(msg);
			DispatchMessage(msg);
		}
		else
		{
			return true;
		}
	}

	return false;
}

//描画
void Application::Render()
{
	//バックバッファをクリア
	float ClearColor[4] = { 0.0f, 0.125f, 0.3f, 1.0f };
	immediateContext->ClearRenderTargetView(renderTargetView, ClearColor);

	//三角ポリゴンの描画
	immediateContext->VSSetShader(vertexShader, nullptr, 0);
	immediateContext->PSSetShader(pixelShader, nullptr, 0);
	immediateContext->Draw(3, 0);

	//画面に反映
	swapChain->Present(0, 0);
}

//ウィンドウの初期化
HRESULT Application::InitWindow(int cmdShow)
{
	WNDCLASSEX winClass;
	winClass.cbSize = sizeof(WNDCLASSEX);
	winClass.style = CS_HREDRAW | CS_VREDRAW;
	winClass.lpfnWndProc = WndProc;
	winClass.cbClsExtra = 0;
	winClass.cbWndExtra = 0;
	winClass.hInstance = hInstance;
	winClass.hIcon = nullptr;
	winClass.hCursor = LoadCursor(nullptr, IDC_ARROW);
	winClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
	winClass.lpszMenuName = nullptr;
	winClass.lpszClassName = "Windows_Direct3D_11_Application_Shader_Program_Class";
	winClass.hIconSm = nullptr;
	if (!RegisterClassEx(&winClass))
		return E_FAIL;

	//ウィンドウを生成
	AdjustWindowRect(&winRect, WS_OVERLAPPEDWINDOW, false);
	winHandle = CreateWindow("Windows_Direct3D_11_Application_Shader_Program_Class", winTitle.c_str(),
		WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT, CW_USEDEFAULT, winRect.right - winRect.left, winRect.bottom - winRect.top, nullptr, nullptr, hInstance,
		nullptr);

	if (!winHandle)
		return E_FAIL;

	ShowWindow(winHandle, cmdShow);

	return S_OK;
}

//デバイスの初期化
HRESULT Application::InitDevice()
{
	HRESULT hr = S_OK;

	RECT rc;
	GetClientRect(winHandle, &rc);
	UINT width = rc.right - rc.left;
	UINT height = rc.bottom - rc.top;
	
	UINT createDeviceFlags = 0;
#ifdef _DEBUG
	createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif
	
	//デバイスのタイプを定義
	D3D_DRIVER_TYPE driverTypes[] = {
		D3D_DRIVER_TYPE_HARDWARE,
		D3D_DRIVER_TYPE_WARP,
		D3D_DRIVER_TYPE_REFERENCE,
	};
	UINT numDriverTypes = ARRAYSIZE(driverTypes);
	
	//フューチャータイプを定義
	D3D_FEATURE_LEVEL featureLevels[] = {
		D3D_FEATURE_LEVEL_11_0,
		D3D_FEATURE_LEVEL_10_1,
		D3D_FEATURE_LEVEL_10_0,
	};
	UINT numFeatureLevels = ARRAYSIZE(featureLevels);

	//スワップチェインを作成
	DXGI_SWAP_CHAIN_DESC sd;
	ZeroMemory(&sd, sizeof(sd));
	sd.BufferCount = 1;
	sd.BufferDesc.Width = width;
	sd.BufferDesc.Height = height;
	sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
	sd.BufferDesc.RefreshRate.Numerator = 60;
	sd.BufferDesc.RefreshRate.Denominator = 1;
	sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
	sd.OutputWindow = winHandle;
	sd.SampleDesc.Count = 1;
	sd.SampleDesc.Quality = 0;
	sd.Windowed = true;

	for (int i = 0; i < numDriverTypes; i++)
	{
		driverType = driverTypes[i];
		hr = D3D11CreateDeviceAndSwapChain(nullptr, driverType, nullptr, createDeviceFlags, featureLevels, numFeatureLevels,
			D3D11_SDK_VERSION, &sd, &swapChain, &device, &featureLevel, &immediateContext);
		if (SUCCEEDED(hr))
			break;
	}
	if (FAILED(hr))
		return hr;

	//描画ターゲットを作成
	ID3D11Texture2D* pBackBuffer = nullptr;
	hr = swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer);
	if (FAILED(hr))
		return hr;

	hr = device->CreateRenderTargetView(pBackBuffer, nullptr, &renderTargetView);
	pBackBuffer->Release();
	if (FAILED(hr))
		return hr;

	immediateContext->OMSetRenderTargets(1, &renderTargetView, nullptr);

	//ビューポートを設定
	D3D11_VIEWPORT vp;
	vp.Width = (FLOAT)width;
	vp.Height = (FLOAT)height;
	vp.MinDepth = 0.0f;
	vp.MaxDepth = 1.0f;
	vp.TopLeftX = 0;
	vp.TopLeftY = 0;
	immediateContext->RSSetViewports(1, &vp);

	//頂点シェーダをコンパイルする
	ID3DBlob* pVSBlob = nullptr;
	hr = CompileShaderFromFile("vs.fx", "VS", "vs_4_0", &pVSBlob);
	if (FAILED(hr))
	{
		MessageBox(winHandle, "頂点シェーダをコンパイル出来ませんでした", "Error", MB_ICONSTOP);
		return hr;
	}

	//頂点シェーダを生成
	hr = device->CreateVertexShader(pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), nullptr, &vertexShader);
	if (FAILED(hr))
	{
		pVSBlob->Release();
		return hr;
	}

	// Define the input layout
	D3D11_INPUT_ELEMENT_DESC layout[] =
	{
		{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
	};
	UINT numElements = ARRAYSIZE(layout);

	//インプットレイアウトを作成
	hr = device->CreateInputLayout(layout, numElements, pVSBlob->GetBufferPointer(),
		pVSBlob->GetBufferSize(), &vertexLayout);
	pVSBlob->Release();
	if (FAILED(hr))
		return hr;

	//インプットレイアウトを設定
	immediateContext->IASetInputLayout(vertexLayout);

	//ピクセルシェーダをコンパイルする
	ID3DBlob* pPSBlob = nullptr;
	hr = CompileShaderFromFile("ps.fx", "PS", "ps_4_0", &pPSBlob);
	if (FAILED(hr))
	{
		MessageBox(winHandle, "ピクセルシェーダをコンパイル出来ませんでした", "Error", MB_ICONSTOP);
		return hr;
	}

	//ピクセルシェーダを生成
	hr = device->CreatePixelShader(pPSBlob->GetBufferPointer(), pPSBlob->GetBufferSize(), nullptr, &pixelShader);
	pPSBlob->Release();
	if (FAILED(hr))
		return hr;

	//三角形ポリゴンを定義
	vtx3 vertices[] =
	{
		XMFLOAT3(0.0f, 0.5f, 0.5f),
		XMFLOAT3(0.5f, -0.5f, 0.5f),
		XMFLOAT3(-0.5f, -0.5f, 0.5f),
	};

	//頂点バッファを生成
	D3D11_BUFFER_DESC bd;
	ZeroMemory(&bd, sizeof(bd));
	bd.Usage = D3D11_USAGE_DEFAULT;
	bd.ByteWidth = sizeof(vtx3) * 3;
	bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
	bd.CPUAccessFlags = 0;
	D3D11_SUBRESOURCE_DATA InitData;
	ZeroMemory(&InitData, sizeof(InitData));
	InitData.pSysMem = vertices;
	hr = device->CreateBuffer(&bd, &InitData, &vertexBuffer);
	if (FAILED(hr))
		return hr;

	//頂点バッファを設定
	UINT stride = sizeof(vtx3);
	UINT offset = 0;
	immediateContext->IASetVertexBuffers(0, 1, &vertexBuffer, &stride, &offset);

	//プリミティブを設定
	immediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

	return S_OK;
}

//デバイスのクリーンアップ
void Application::CleanupDevice()
{
#ifdef _DEBUG
	//デバック時は終了処理を通過しているか確認するため
	//ビープ音を鳴らす
	MessageBeep(MB_OK);
#endif
	//すべてリリースする
	if (immediateContext) immediateContext->ClearState();

	if (vertexBuffer) vertexBuffer->Release();
	if (vertexLayout) vertexLayout->Release();
	if (vertexShader) vertexShader->Release();
	if (pixelShader) pixelShader->Release();
	if (renderTargetView) renderTargetView->Release();
	if (swapChain) swapChain->Release();
	if (immediateContext) immediateContext->Release();
	if (device) device->Release();
}

//ウィンドウメッセージの処理
LRESULT CALLBACK Application::WndProc(HWND winHandle, UINT msg, WPARAM wParam, LPARAM lParam)
{
	PAINTSTRUCT ps;
	HDC hdc;
	switch (msg)
	{
	case WM_PAINT:
		hdc = BeginPaint(winHandle, &ps);
		EndPaint(winHandle, &ps);
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	default:
		return DefWindowProc(winHandle, msg, wParam, lParam);
	}
	return 0;
}

//シェーダファイルをコンパイルする
HRESULT Application::CompileShaderFromFile(string fileName, LPCSTR entryPoint, LPCSTR shaderModel, ID3DBlob** blobOut)
{
	HRESULT hr = S_OK;

	DWORD shaderFlags = D3DCOMPILE_ENABLE_STRICTNESS;
#ifdef _DEBUG
	shaderFlags |= D3DCOMPILE_DEBUG;
#endif

	//シェーダファイルをコンパイルする
	ID3DBlob *errorBlob;
	hr = D3DX11CompileFromFile(fileName.c_str(), nullptr, nullptr, entryPoint, shaderModel, shaderFlags, 0, nullptr, blobOut, &errorBlob, nullptr);
	if (FAILED(hr))
	{
		if (errorBlob != nullptr)
			OutputDebugString((char *)errorBlob->GetBufferPointer());
		if (errorBlob)errorBlob->Release();
		MessageBox(winHandle, "頂点レイアウトが\n作成できませんでした。", "Error", MB_ICONSTOP);
		return hr;
	}
	
	if (errorBlob)errorBlob->Release();

	return hr;
}

アバター
みけCAT
記事: 6734
登録日時: 15年前
住所: 千葉県
連絡を取る:

Re: winapi ウィンドウがすぐ閉じる

#2

投稿記事 by みけCAT » 10年前

316行目のWM_PAINTの処理のあとbreak;が無いので、PostQuitMessage(0);が呼ばれ、終了する可能性があります。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

閉鎖

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