dx11学习笔记-1.创建一个空窗口
来源:互联网 发布:向量化编程为何快 编辑:程序博客网 时间:2024/06/10 08:38
资料:
Microsoft DirectX SDK (June 2010) source code&document
《DX11游戏编程入门》source code&pdf
基本流程
1、初始化dx环境:
最基本的三个变量
ID3D11Device* g_pd3dDevice = NULL;
ID3D11DeviceContext* g_pImmediateContext = NULL;
IDXGISwapChain* g_pSwapChain = NULL;
In Direct3D 10, the device object was used to perform both rendering and resource creation. In Direct3D 11, the immediate context is used by the application to perform rendering onto a buffer, and the device contains methods to create resources.
也就是说,device负责创建各种资源,context负责渲染。而swapchain管理着渲染的“画布”——缓存。
更进一步解释,device负责着dx和硬件之间的通信,context负责告诉device渲染是怎么个设置,保存着渲染的状态信息,而swapchain可以看做渲染的目标。
缓存:就是存放数据的一块空间,一块具有固定尺寸的内存。比如光栅屏幕缓存其实是个二维数组,每个像素的信息就是缓存中一个元素。所谓渲染到缓存上,其实是用计算得到的颜色值去填充每一个像素。
其他必需变量
ID3D11RenderTargetView* g_pRenderTargetView = NULL;
DX中我们通过调用swapChain的GetBuffer方法来得到其管理的缓存地址,得到缓存地址后,作为参数传入device调用的CreateRenderTargetView方法,创建并保存到g_pRenderTargetView 。我们通过变量获取的缓存指针此时便没有用处了,需要及时调用Release方法将其占用资源释放,否则会发生内存泄露。
此处《DX11游戏编程》的解释为:当我们获得一个COM对象的引用时,该对象的引用数+1,确定该对象不会被再次调用时,需要调用COM对象的Release函数将该对象的引用数-1。当COM对象的引用数为0时,就会被删除。
相关知识可查阅“缓存池”
现在我们有了渲染目标g_pRenderTargetView ,那就需要告诉context这目标是谁。调用context的OMSetRenderTargets方法,传入g_pRenderTargetView 即可关联二者。
接下来,继续为context设置渲染的各个属性。
渲染在什么区域?调用context的RSSetViewports方法。此处viewport设置了渲染视口的长宽、渲染的左上角对应在窗口内屏幕的XY坐标,和需要渲染的最大最小深度。如果XY坐标都设为0,那么渲染视口左上角就与客户区窗口左上角重合。
2、渲染:
context调用ClearRenderTargetView方法来设置用于更新缓存的基本颜色;
swapChain调用Present来重绘。
3、清理:
按照从子对象到父对象的顺序,调用COM对象的Release方法,将其释放。
注意释放前需要检查指针是否存在,如果对不存在的对象指针调用其方法,会产生不可预料的后果。
完整代码
见Microsoft DirectX SDK (June 2010) Tutorial01
//--------------------------------------------------------------------------------------// File: Tutorial01.cpp//// This application demonstrates creating a Direct3D 11 device//// Copyright (c) Microsoft Corporation. All rights reserved.//--------------------------------------------------------------------------------------#include <windows.h>#include <d3d11.h>#include <d3dx11.h>#include "resource.h"//--------------------------------------------------------------------------------------// Global Variables//--------------------------------------------------------------------------------------HINSTANCE g_hInst = NULL;HWND g_hWnd = NULL;D3D_DRIVER_TYPE g_driverType = D3D_DRIVER_TYPE_NULL;D3D_FEATURE_LEVEL g_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();LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM );void Render();//--------------------------------------------------------------------------------------// Entry point to the program. Initializes everything and goes into a 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; } // Main message 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 ( int )msg.wParam;}//--------------------------------------------------------------------------------------// Register class and create window//--------------------------------------------------------------------------------------HRESULT InitWindow( HINSTANCE hInstance, int nCmdShow ){ // Register class WNDCLASSEX wcex; 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; // Create window g_hInst = hInstance; RECT rc = { 0, 0, 640, 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 ); return S_OK;}//--------------------------------------------------------------------------------------// Called every time the application receives a message//--------------------------------------------------------------------------------------LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ){ PAINTSTRUCT ps; 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 ); } return 0;}//--------------------------------------------------------------------------------------// Create Direct3D device and swap chain//--------------------------------------------------------------------------------------HRESULT InitDevice(){ HRESULT hr = S_OK; RECT rc; GetClientRect( g_hWnd, &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 = g_hWnd; sd.SampleDesc.Count = 1; sd.SampleDesc.Quality = 0; sd.Windowed = TRUE; for( UINT driverTypeIndex = 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; // Create a render target view ID3D11Texture2D* pBackBuffer = NULL; hr = g_pSwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D ), ( LPVOID* )&pBackBuffer ); if( FAILED( hr ) ) return hr; hr = g_pd3dDevice->CreateRenderTargetView( pBackBuffer, NULL, &g_pRenderTargetView ); pBackBuffer->Release(); if( FAILED( hr ) ) return hr; g_pImmediateContext->OMSetRenderTargets( 1, &g_pRenderTargetView, NULL ); // Setup the 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 ); return S_OK;}//--------------------------------------------------------------------------------------// Render the frame//--------------------------------------------------------------------------------------void Render(){ // Just clear the backbuffer float ClearColor[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();}
- dx11学习笔记-1.创建一个空窗口
- directX学习(1)创建一个空窗口
- dx11学习笔记-2.用DX画一个三角形
- Qt学习笔记1:创建一个QT的空项目
- OpenGL_Qt学习笔记之_01(创建一个OpenGL窗口)
- OpenGL_Qt学习笔记之_01(创建一个OpenGL窗口)
- OpenGL_Qt学习笔记之_01(创建一个OpenGL窗口)
- OpenGL_Qt学习笔记之_01(创建一个OpenGL窗口)
- dx11学习笔记-4、用DX画一个旋转的立方体
- Java学习笔记-窗口创建
- win32创建空窗口
- DirectX11创建dx11项目
- win32sdk学习-创建一个对话框窗口
- 笔记----DX11.0转为DX11.2
- WINDOWS游戏编程学习笔记(二):完整创建一个窗口
- VS2013MFC单文档工程学习笔记七 - 创建新的一个窗口并让窗口2透明
- dx11 简单笔记
- LearnOpenGL学习笔记1:创建窗口
- python socket 解码IP层
- leetcode(31) Next Permutation
- 《笨办法学Python》 第38课手记
- C#里面Attribute的使用方法
- [Computer Security : Art and Science] Chapter_1 1.1 基础部分
- dx11学习笔记-1.创建一个空窗口
- HDU【3038】How Many Answers Are Wrong
- 加油小白
- 母牛问题
- leetcode:Largest Number
- 超长字符串换行处理
- 03环信好友管理 - 添加好友(好友申请处理结果回调)
- leetcode:Happy Number
- 动态规划——DNA