已屏蔽 原因:{{ notice.reason }}已屏蔽
{{notice.noticeContent}}
~~空空如也

DirectX 10/11禁止Alt Enter全屏的方法

DirectX 10/11的交换链有全屏功能,但是这个全屏并不是想象的那样,缓冲区大小不改变,画面会模糊,关掉的方法:

<code class="language-cpp">// 禁止Alt+Enter全屏
CComPtr<idxgifactory> dxgifac;
(comexcept)g_swpch->GetParent(__uuidof(IDXGIFactory), (void**)&dxgifac);
dxgifac->MakeWindowAssociation(g_hwnd, DXGI_MWA_NO_WINDOW_CHANGES | DXGI_MWA_NO_ALT_ENTER);
dxgifac = NULL;
</idxgifactory></code>

DXUT也有全屏切换,但实际上是重新建立了适合全屏的设备和交换链,不会模糊。

Win10中Debug Layer的安装

DirectXDebugWin10.png

DirectX 9/10/11比较

DirectX 9.0用起来傻瓜化,直接用API就可以绘图,但是如果想实现高级特性的话,没有集成Shader编译器,需要先行编译或者使用D3DX库编译。

DirectX 10去掉了用API直接画图的功能,但是集成了Shader编译器,加入了Geometry Shader,同时分离了DXGI,用起来稍显复杂,初始化的复杂度增加了。

DirectX 11是基于DirectX 10小幅改进的版本,加上很多功能,包括Tessellation和DirectCompute以及CommandList。但同时,DirectX 11分离了编译器,必须安装运行库(2010或之前)或者附带dll(2012或之后)才能使用,剥离了Effects11必须自己编译。但同时2012又剥离了D3DX成为DirectXTK、DirectXTex、DirectXMesh等数个开源库,需要自己编译。

DirectX 9.0需要配合GDI+出图,DirectX 10/11可以用Direct2D和DirectWrite出图。

一个更理想的DirectX 10框架程序

实现了窗口大小变化,而且使用WndProc而不是C++类管理生命周期

<code class="language-cpp">// main.cpp - 主文件

#undef UNICODE
#define UNICODE 1
#include <windows.h>
#include <d3d10.h>
#include <xnamath.h> // <directxmath.h> for VS2012+
#pragma comment(lib, "d3d10.lib")

HINSTANCE hInst;
HWND hMainWnd;

#define WM_APPIDLE (WM_APP + 10)

struct WndData
{
	ID3D10Device *dev;
	D3D10_DRIVER_TYPE dt;
	IDXGISwapChain *swpch;
	ID3D10RenderTargetView *rtv;
	ID3D10Texture2D *dsbuf;
	ID3D10DepthStencilView *dsv;
};

HRESULT CreateRTV(HWND hWnd, WndData *data)
{
	HRESULT hr = S_OK;
	ID3D10Texture2D *backbuf = NULL;
	hr = data->swpch->GetBuffer(0, __uuidof(ID3D10Texture2D), (void**)&backbuf);
	if (FAILED(hr)) return hr;

	hr = data->dev->CreateRenderTargetView(backbuf, NULL, &data->rtv);
	backbuf->Release();
	return hr;
}

HRESULT CreateDSBufAndDSV(HWND hWnd, WndData *data, int width, int height)
{
	HRESULT hr = S_OK;
	D3D10_TEXTURE2D_DESC dsbufdesc = {
		width, height, 1, 1, DXGI_FORMAT_D32_FLOAT, { 1, 0 }, D3D10_USAGE_DEFAULT, D3D10_BIND_DEPTH_STENCIL, 0, 0
	};
	hr = data->dev->CreateTexture2D(&dsbufdesc, NULL, &data->dsbuf);
	if (FAILED(hr)) return hr;

	D3D10_DEPTH_STENCIL_VIEW_DESC dsvdesc = {
		DXGI_FORMAT_D32_FLOAT, D3D10_DSV_DIMENSION_TEXTURE2D
	};
	dsvdesc.Texture2D.MipSlice = 0;
	hr = data->dev->CreateDepthStencilView(data->dsbuf, &dsvdesc, &data->dsv);
	return hr;
}

void SetViewport(HWND hWnd, WndData *data, int width, int height)
{
	D3D10_VIEWPORT vp = {
		0, 0, width, height, 0.0f, 1.0f
	};
	data->dev->RSSetViewports(1, &vp);
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	WndData *data = (WndData *)GetWindowLongPtr(hWnd, 0);

	if (msg == WM_CREATE)
	{
		data = (WndData *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof (WndData));
		if (data == NULL) DestroyWindow(hWnd);
		SetWindowLongPtr(hWnd, 0, (LONG_PTR)data);

		RECT rc = { 0 };
		GetClientRect(hWnd, &rc);
		int width = rc.right - rc.left;
		int height = rc.bottom - rc.top;

		DXGI_MODE_DESC mode = {
			width, height, { 60, 1 }, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED, DXGI_MODE_SCALING_UNSPECIFIED,
		};
		DXGI_SWAP_CHAIN_DESC swpchdesc = {
			mode, { 1, 0 }, DXGI_USAGE_RENDER_TARGET_OUTPUT, 1, hWnd, TRUE, DXGI_SWAP_EFFECT_DISCARD, 0
		};
		D3D10_DRIVER_TYPE drvtype[] = { D3D10_DRIVER_TYPE_HARDWARE, D3D10_DRIVER_TYPE_WARP, D3D10_DRIVER_TYPE_REFERENCE };
		HRESULT hr = S_OK;
		for (int i = 0; i < sizeof drvtype / sizeof drvtype[0]; i++)
		{
			data->dt = drvtype[i];
			hr = D3D10CreateDeviceAndSwapChain(NULL, data->dt, NULL, 0, D3D10_SDK_VERSION, &swpchdesc, &data->swpch, &data->dev);
			if (SUCCEEDED(hr)) break;
		}
		if (FAILED(hr)) DestroyWindow(hWnd);

		hr = CreateRTV(hWnd, data);
		if (FAILED(hr)) DestroyWindow(hWnd);

		hr = CreateDSBufAndDSV(hWnd, data, width, height);
		if (FAILED(hr)) DestroyWindow(hWnd);

		data->dev->OMSetRenderTargets(1, &data->rtv, data->dsv);

		SetViewport(hWnd, data, width, height);
		
		// TODO - create objects

		return 0;
	}

	if (msg == WM_DESTROY)
	{
		if (data != NULL)
		{
			if (data->dev) data->dev->ClearState();
			if (data->dsv) data->dsv->Release();
			if (data->dsbuf) data->dsbuf->Release();
			if (data->rtv) data->rtv->Release();
			if (data->swpch) data->swpch->Release();
			if (data->dev) data->dev->Release();
			HeapFree(GetProcessHeap(), 0, data);
		}
		PostQuitMessage(0);
		return 0;
	}

	if (data == NULL)
		return DefWindowProc(hWnd, msg, wParam, lParam); // 下边的消息都是需要data的

	if (msg == WM_SIZE)
	{
		int width = LOWORD(lParam);
		int height = HIWORD(lParam);

		char buf[1024] = "";
		wsprintfA(buf, "%d %d\r\n", width, height);
		OutputDebugStringA(buf);

		data->dev->ClearState();
		data->rtv->Release(); data->rtv = NULL;
		data->dsv->Release(); data->dsv = NULL;
		data->dsbuf->Release(); data->dsbuf = NULL;

		HRESULT hr = data->swpch->ResizeBuffers(1, width, height, DXGI_FORMAT_R8G8B8A8_UNORM, 0);
		if (FAILED(hr)) DestroyWindow(hWnd);

		hr = CreateRTV(hWnd, data);
		if (FAILED(hr)) DestroyWindow(hWnd);

		hr = CreateDSBufAndDSV(hWnd, data, width, height);
		if (FAILED(hr)) DestroyWindow(hWnd);

		data->dev->OMSetRenderTargets(1, &data->rtv, data->dsv);

		SetViewport(hWnd, data, width, height);
		
		return 0;
	}

	if (msg == WM_APPIDLE)
	{
		float backcolor[4] = { 0.0f, 0.5f, 0.5f, 1.0f };
		data->dev->ClearRenderTargetView(data->rtv, backcolor);
		data->dev->ClearDepthStencilView(data->dsv, D3D10_CLEAR_DEPTH, 1.0f, 0);

		// TODO - draw frames

		data->swpch->Present(0, 0);
		return 0;
	}

	return DefWindowProc(hWnd, msg, wParam, lParam);
}

int WINAPI WinMain( __in HINSTANCE hInstance, __in_opt HINSTANCE hPrevInstance, __in_opt LPSTR lpCmdLine, __in int nShowCmd )
{
	hInst = hInstance;

	WNDCLASSEX wcex = {
		sizeof wcex, CS_VREDRAW|CS_HREDRAW, WndProc, 0, sizeof (WndData *), hInstance, LoadIcon(NULL, IDI_APPLICATION), LoadCursor(NULL, IDC_ARROW),
		(HBRUSH)GetStockObject(NULL_BRUSH), NULL, L"MainWndClass", LoadIcon(NULL, IDI_APPLICATION),
	};
	RegisterClassEx(&wcex);

	RECT rc = { 0, 0, 640, 480 };
	AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, FALSE);
	hMainWnd = CreateWindow(L"MainWndClass", L"Main Window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
		rc.right - rc.left, rc.bottom - rc.top, NULL, NULL, hInstance, NULL);
	ShowWindow(hMainWnd, nShowCmd);
	UpdateWindow(hMainWnd);

	MSG msg = { 0 };
	while (msg.message != WM_QUIT)
	{
		if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		else
		{
			SendMessage(hMainWnd, WM_APPIDLE, 0, 0);
		}
	}

	return 0;
}
</directxmath.h></xnamath.h></d3d10.h></windows.h></code>
文号 / 826998

千古风流
名片发私信
学术分 4
总主题 466 帖总回复 2942 楼拥有证书:进士 学者 笔友
注册于 2009-05-30 21:22最后登录 2019-01-31 17:16
主体类型:个人
所属领域:无
认证方式:邮箱
IP归属地:未同步

个人简介

暂未填写
文件下载
加载中...
{{errorInfo}}
{{downloadWarning}}
你在 {{downloadTime}} 下载过当前文件。
文件名称:{{resource.defaultFile.name}}
下载次数:{{resource.hits}}
上传用户:{{uploader.username}}
所需积分:{{costScores}},{{holdScores}}下载当前附件免费{{description}}
积分不足,去充值
文件已丢失

当前账号的附件下载数量限制如下:
时段 个数
{{f.startingTime}}点 - {{f.endTime}}点 {{f.fileCount}}
视频暂不能访问,请登录试试
仅供内部学术交流或培训使用,请先保存到本地。本内容不代表科创观点,未经原作者同意,请勿转载。
音频暂不能访问,请登录试试
投诉或举报
加载中...
{{tip}}
请选择违规类型:
{{reason.type}}

空空如也

插入资源
全部
图片
视频
音频
附件
全部
未使用
已使用
正在上传
空空如也~
上传中..{{f.progress}}%
处理中..
上传失败,点击重试
等待中...
{{f.name}}
空空如也~
(视频){{r.oname}}
{{selectedResourcesId.indexOf(r.rid) + 1}}
处理中..
处理失败
插入表情
我的表情
共享表情
Emoji
上传
注意事项
最大尺寸100px,超过会被压缩。为保证效果,建议上传前自行处理。
建议上传自己DIY的表情,严禁上传侵权内容。
点击重试等待上传{{s.progress}}%处理中...已上传,正在处理中
空空如也~
处理中...
处理失败
加载中...
草稿箱
加载中...
此处只插入正文,如果要使用草稿中的其余内容,请点击继续创作。
{{fromNow(d.toc)}}
{{getDraftInfo(d)}}
标题:{{d.t}}
内容:{{d.c}}
继续创作
删除插入插入
插入公式
评论控制
加载中...
文号:{{pid}}
加载中...
详情
详情
推送到专栏从专栏移除
设为匿名取消匿名
查看作者
回复
只看作者
加入收藏取消收藏
收藏
取消收藏
折叠回复
置顶取消置顶
评学术分
鼓励
设为精选取消精选
管理提醒
编辑
通过审核
评论控制
退修或删除
历史版本
违规记录
投诉或举报
加入黑名单移除黑名单
查看IP
{{format('YYYY/MM/DD HH:mm:ss', toc)}}
ID: {{user.uid}}