一.DirectX11窗口,设备,交换链,上下文创建及最简单的渲染例程 渲染上下文

由于要做directx方面的东西,所以今天开始学习directx。

硬件环境:Win7 X64

软件环境:directx sdk(DXSDK_Jun10)+VS2010

参考资料:direct documentations for C++

例程:Tutorial01(sdk自带)

代码:见附录

代码效果:



学习过程:

首先说明要创建的三个必须objects:a device, an immediate context, and a swapchain.

然后分别说明三个objects的作用:

the device object was used to perform both rendering andresource creation.

the immediate context is used by the application to performrendering onto a buffer, and the device contains methods to createresources.

The swap chain is responsible for taking the buffer to which thedevice renders, and displaying the content on the actual monitorscreen.

其中在swap chain作用介绍中提到了backbuffer和frontbuffer,swapchain主要就是用来操纵这两个buffer。

提到了要用到的:

structure:

DXGI_SWAPCHAIN_DESC

flag:

BackBufferUsage -> a flag thattells the application how the back buffer will be used.

并说明,由于我们这个例子中要渲染的是backbuffer,可以将BackBufferUsage设置为DXGI_USAGE_RENDER_TARGET_OUTPUT。

看代码我们知道

一共有四个过程函数和一个wWinMain函数(这里定义和声明都在cpp文件中),当然从wWinMain开始看


看wWinMain就知道函数结构了,相当清晰

先创建句柄hPrevInstance和lpCmdLine。

然后调用InitWindow,InitDevice,初始化失败调用CleanupDevice直接返回。初始化成功则开启消息循环,当

程序退出时再调用CleanupDevice正常结束。

结合文档分析:

1:

Once the description has been filled out, we can call theD3D11CreateDeviceAndSwapChain function to create both thedevice and the swap chain for us.

可以知道先填充一个DXGI_SWAP_CHAIN_DESC 类型的sd,然后调用D3D11CreateDeviceAndSwapChain

就可以创建device and the swap chain。这个部分例子是在InitDevice函数中实现的。

2:

然后需要创建一个a render targetview,渲染视图,这个东西是用来解释资源的。做过C++的知道,当内存中存有一定的数据,按不同方式解释出的结果是不同的。比如同样是11111111这样一个字节,按unsingedint类型解释和int类型解释出来的值就不同。这个东西的功能和这个类似(视图嘛是吧,应该很好理解,就是说从不同的角度去看,去解释同样的资源啊)。

3:

然后初始化一个D3D11_VIEWPORT 类型的vp。网上翻译为视口

查找msdn可以知道这个东西

http://msdn.microsoft.com/en-us/library/windows/desktop/ff476260(v=vs.85).aspx

是与视角坐标系有关的一个东西,猜测可能与视角深度的应用,比如透视等的实现有关系,这个东西在11和10中的支持不同。

4:

然后就构建一个消息循环,如果获取到什么消息就去处理消息,否则一直不停地渲染界面。这里用非足赛方式的函数PeekMessage()来等待消息,用GetMessage()的话会阻塞的。

5.渲染函数,这里例子程序只是最简单地向屏幕填充一种颜色,在Directx11中,用ClearRenderTargetView()可以很轻松地实现对目标的渲染。不过文档中说当我们填充完backbuffer,就调用Present()去完成渲染,由

http://msdn.microsoft.com/en-us/library/windows/desktop/bb173539(v=vs.85).aspx

可知它的作用是

Set all the elements in a render target to one value.

即把目标的所有元素设置成一个值。这里用来把窗口的工作区颜色都设置成蓝色,就是说定义了一个颜色点,可以用这个这个函数把这个颜色点的性质应用到对象的所有元素上。链接还讲了一个不宜使用的情况,自己看。

整个程序就是这样。

展示了一个最基本的directx11程序。

这不过是本人的学习笔记。

有人描述的比较专业,理解也比本人深刻,更值得大家参考,可以看看:

http://www.cnblogs.com/xdotnet/archive/2011/07/15/directx11_cpp_device.html

同时把代码也附在后面,其实代码在directx11的sdk文档及例程中都有的,在官网上下载一个directx11的sdk一安装,资料就全都有了,暂时学这个要看英语能力了。

附录:

//--------------------------------------------------------------------------------------
// File: Tutorial01.cpp
//
// This application demonstrates creating a Direct3D 11device
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//--------------------------------------------------------------------------------------
#include <windows.h>
#include <d3d11.h>
#include <d3dx11.h>
#include "resource.h"

//--------------------------------------------------------------------------------------
// Global Variables
//--------------------------------------------------------------------------------------
HINSTANCEg_hInst = NULL;
HWNDg_hWnd = NULL;
D3D_DRIVER_TYPEg_driverType = D3D_DRIVER_TYPE_NULL;
D3D_FEATURE_LEVELg_featureLevel = D3D_FEATURE_LEVEL_11_0;
ID3D11Device*g_pd3dDevice = NULL;
ID3D11DeviceContext*g_pImmediateContext = NULL;
IDXGISwapChain*g_pSwapChain = NULL;
ID3D11RenderTargetView* g_pRenderTargetView = NULL;


//--------------------------------------------------------------------------------------
// Forward declarations
//--------------------------------------------------------------------------------------
HRESULT InitWindow( HINSTANCE hInstance, int nCmdShow );
HRESULT InitDevice();
void CleanupDevice();
LRESULTCALLBACKWndProc( HWND, UINT, WPARAM, LPARAM );
void Render();


//--------------------------------------------------------------------------------------
// Entry point to the program. Initializes everything and goes intoa message processing
// loop. Idle time is used to render the scene.
//--------------------------------------------------------------------------------------
int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPWSTR lpCmdLine, int nCmdShow )
{
UNREFERENCED_PARAMETER( hPrevInstance );
UNREFERENCED_PARAMETER( lpCmdLine );

if(FAILED( InitWindow( hInstance, nCmdShow ) ) )
return 0;
if( FAILED(InitDevice() ) )
{
CleanupDevice();
return 0;
}
// Mainmessage loop
MSG msg ={0};
while(WM_QUIT != msg.message )
{
if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ))
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
else
{
Render();
}
}

CleanupDevice();
return 0;
// return ( int)msg.wParam;
}


//--------------------------------------------------------------------------------------
// Register class and create window
//--------------------------------------------------------------------------------------
HRESULT InitWindow( HINSTANCE hInstance, int nCmdShow )
{
// Registerclass
WNDCLASSEXwcex;
wcex.cbSize= sizeof( WNDCLASSEX );
wcex.style =CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon =LoadIcon( hInstance, ( LPCTSTR )IDI_TUTORIAL1 );
wcex.hCursor= LoadCursor( NULL, IDC_ARROW );
wcex.hbrBackground = ( HBRUSH )( COLOR_WINDOW + 1 );
wcex.lpszMenuName = NULL;
wcex.lpszClassName = L"TutorialWindowClass";
wcex.hIconSm= LoadIcon( wcex.hInstance, ( LPCTSTR )IDI_TUTORIAL1 );
if(!RegisterClassEx( &wcex ) )
return E_FAIL;

// Createwindow
g_hInst =hInstance;
RECT rc = {0, 0, 900, 480 };
//计算需要创建的客户区窗口大小
//第二个参数决定窗口的样式
//第三个参数决定窗口是否有菜单
AdjustWindowRect( &rc,WS_OVERLAPPEDWINDOW, FALSE );
g_hWnd =CreateWindow( L"TutorialWindowClass", L"Direct3D 11 Tutorial 1:Direct3D 11 Basics", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom -rc.top, NULL, NULL, hInstance,
NULL );
if( !g_hWnd)
return E_FAIL;

ShowWindow( g_hWnd, nCmdShow );

returnS_OK;
}


//--------------------------------------------------------------------------------------
// Called every time the application receives a message
//--------------------------------------------------------------------------------------
LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam,LPARAM lParam )
{
PAINTSTRUCTps;
HDC hdc;

switch(message )
{
case WM_PAINT:
hdc = BeginPaint( hWnd, &ps );
EndPaint( hWnd, &ps );
break;

case WM_DESTROY:
PostQuitMessage( 0 );
break;

default:
return DefWindowProc( hWnd, message, wParam, lParam );
}

return0;
}


//--------------------------------------------------------------------------------------
// Create Direct3D device and swap chain
//--------------------------------------------------------------------------------------
HRESULT InitDevice()
{
HRESULT hr =S_OK;

RECTrc;
GetClientRect( g_hWnd, &rc );
UINT width =rc.right - rc.left;
UINT height= rc.bottom - rc.top;

UINTcreateDeviceFlags = 0;
#ifdef _DEBUG
createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif

//创建下面这个数组的目的是为了定义一些可能用到的驱动类型和SDK支持版本等级

//后面还有个循环,用来一个一个试,看到底是哪种驱动,采用这种方式,

//从而可以使代码在各种可能驱动环境下都可以用

D3D_DRIVER_TYPE driverTypes[] =
{
D3D_DRIVER_TYPE_HARDWARE,
D3D_DRIVER_TYPE_WARP,
D3D_DRIVER_TYPE_REFERENCE,
};
UINTnumDriverTypes = 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 = g_hWnd;
sd.SampleDesc.Count = 1;
sd.SampleDesc.Quality = 0;
sd.Windowed= TRUE;

for( UINTdriverTypeIndex = 0; driverTypeIndex <numDriverTypes; driverTypeIndex++ )
{
g_driverType = driverTypes[driverTypeIndex];
hr = D3D11CreateDeviceAndSwapChain( NULL, g_driverType, NULL,createDeviceFlags, featureLevels, numFeatureLevels,
D3D11_SDK_VERSION, &sd,&g_pSwapChain, &g_pd3dDevice,&g_featureLevel,&g_pImmediateContext );
if(SUCCEEDED( hr ) )
break;
}
if(FAILED(hr ))
return hr;

// Createa render target view
ID3D11Texture2D* pBackBuffer = NULL;
//绑定buffer和交换链
hr =g_pSwapChain->GetBuffer( 0, __uuidof(ID3D11Texture2D ), ( LPVOID* )&pBackBuffer );
if(FAILED(hr ))
return hr;
//为资源数据创建一个渲染视图
//第一个参数指向一个ID3D11Resource 类型的着色目标
//第二个参数指向一个D3D11_RENDER_TARGET_VIEW_DESC类型的结构,这个用来描述访问资源的方式
//第三个参数指向一个视图,
hr =g_pd3dDevice->CreateRenderTargetView( pBackBuffer,NULL, &g_pRenderTargetView );
pBackBuffer->Release();
if( FAILED(hr ) )
return hr;
//将渲染目标和buffer绑定到OMstage,这个决定最后哪些像素点是可见的
g_pImmediateContext->OMSetRenderTargets( 1,&g_pRenderTargetView, NULL );

// Setupthe viewport
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;
g_pImmediateContext->RSSetViewports( 1,&vp );

returnS_OK;
}


//--------------------------------------------------------------------------------------
// Render the frame
//--------------------------------------------------------------------------------------
void Render()
{
// Justclear the backbuffer
floatClearColor[4] = { 0.0f, 0.125f, 0.3f, 1.0f };//red,green,blue,alpha
//将渲染目标的每一个元素都设置为同一个值,类似于纹理映射
g_pImmediateContext->ClearRenderTargetView(g_pRenderTargetView, ClearColor );
g_pSwapChain->Present(0, 0 );
}


//--------------------------------------------------------------------------------------
// Clean up the objects we've created
//--------------------------------------------------------------------------------------
void CleanupDevice()
{
//将视图,交换链,上下文以及设备都释放
if(g_pImmediateContext )g_pImmediateContext->ClearState();

if(g_pRenderTargetView )g_pRenderTargetView->Release();
if(g_pSwapChain ) g_pSwapChain->Release();
if(g_pImmediateContext )g_pImmediateContext->Release();
if(g_pd3dDevice ) g_pd3dDevice->Release();
}

  

爱华网本文地址 » http://www.413yy.cn/a/25101011/66189.html

更多阅读

怎么粘假睫毛,教你最简单的假睫毛戴法 粘假睫毛

再怎么刷,睫毛总是不够纤长卷翘吗?假睫毛是你的救星!像换衣服一样穿戴各种睫毛并不是梦哦! 大家知道有很多不同种类的假睫毛,有的很夸张,有的很自然,如果你想要更自然点的话可以选择透明梗。怎么粘假睫毛,教你最简单的假睫毛戴法——工具

最简单的做法,最原始的味道——盐水虾古运河游 原始的味道

周一乘公交车去上班时,车子驶到一半时,看到有人在问讯。我心中还在嘀咕,问我也行,俺乘公交车上班快一年了,这条路闭着眼睛都知道怎么走的。就在我闭眼睛的那时,我往外一看,公交车驶上了一条陌生的路线,不知开到什么地方了。赶紧,只能也去问

相聚有时,后会无期 最美的英文情话

我总是期待和当初的那个你再次相遇,却发现已渐渐找不回当年的自己。一转眼毕业已近一年,离开了那个恣意的大学校园,品尝了各种喜怒哀乐,体会了社会的纷纷扰扰,回过头才发现已和那个美好的时光分别甚远。于是,我们尝试着用各种各样的方式

声明:《一.DirectX11窗口,设备,交换链,上下文创建及最简单的渲染例程 渲染上下文》为网友小男人大智慧分享!如侵犯到您的合法权益请联系我们删除