GPU渲染时代——2D图形图像中的应用(二)
2014-07-06 09:49
706 查看
代码和例子的下载路径:http://pan.baidu.com/s/1ntFPXhv
联系方式:crazycooler@qq.com
这篇博文来介绍DX的初始化,并封装成MDxKernel模块。
MDxKernel模块非常简单,类似于一个工厂模式,其中MDxKernel和DX是对外导出的接口和类。
![](http://img.blog.csdn.net/20140706095228687?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY3Jhenljb29sZXI=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
该模块中最重要的是MDxKernelImp类的实现
1)创建和设备无关的的资源:
创建DirectWrite,WIC,Direct2D相对应的工厂对象。
2)创建设备相关的资源
创建Direct3D和DXGI的设备
3)设置输出设备
创建交换链,
通过DXGI,将交换链和窗口句柄进行绑定。
4)根据垂直同步,控制交换链输出到窗口
5)设备丢失的处理
这个就不贴代码了。
以上列出了MDxKernel模块的五个重点,完整的封装请查看代码。
其中多处地方参考微软官网和MSDN,在此表示感谢。
代码和例子的下载路径:http://pan.baidu.com/s/1ntFPXhv
联系方式:crazycooler@qq.com
联系方式:crazycooler@qq.com
这篇博文来介绍DX的初始化,并封装成MDxKernel模块。
MDxKernel模块非常简单,类似于一个工厂模式,其中MDxKernel和DX是对外导出的接口和类。
该模块中最重要的是MDxKernelImp类的实现
1)创建和设备无关的的资源:
创建DirectWrite,WIC,Direct2D相对应的工厂对象。
// These are the resources required independent of the device. void MDxKernelImp::CreateDeviceIndependentResources() { D2D1_FACTORY_OPTIONS options; ZeroMemory(&options, sizeof(D2D1_FACTORY_OPTIONS)); #if defined(_DEBUG) // If the project is in a debug build, enable Direct2D debugging via SDK Layers. options.debugLevel = D2D1_DEBUG_LEVEL_INFORMATION; #endif DX::ThrowIfFailed( D2D1CreateFactory( D2D1_FACTORY_TYPE_SINGLE_THREADED, //D2D1_FACTORY_TYPE_MULTI_THREADED, __uuidof(ID2D1Factory1), &options, &m_d2dFactory ) ); DX::ThrowIfFailed( DWriteCreateFactory( DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory1), &m_dwriteFactory ) ); /* DX::ThrowIfFailed( CoCreateInstance( CLSID_WICImagingFactory, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&m_wicFactory) ) ); */ DX::ThrowIfFailed( CoCreateInstance( CLSID_WICImagingFactory, NULL,CLSCTX_INPROC_SERVER, IID_IWICImagingFactory, (void **)&m_wicFactory ) ); }
2)创建设备相关的资源
创建Direct3D和DXGI的设备
// These are the resources that depend on the device. void MDxKernelImp::CreateDeviceResources() { // This flag adds support for surfaces with a different color channel ordering // than the API default. It is required for compatibility with Direct2D. UINT creationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT; ComPtr<IDXGIDevice> dxgiDevice; #if defined(_DEBUG) if (DX::SdkLayersAvailable()) { // If the project is in a debug build, enable debugging via SDK Layers with this flag. creationFlags |= D3D11_CREATE_DEVICE_DEBUG; } #endif // This array defines the set of DirectX hardware feature levels this app will support. // Note the ordering should be preserved. // Don't forget to declare your application's minimum required feature level in its // description. All applications are assumed to support 9.1 unless otherwise stated. D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0, D3D_FEATURE_LEVEL_9_3, D3D_FEATURE_LEVEL_9_2, D3D_FEATURE_LEVEL_9_1 }; // Create the Direct3D 11 API device object and a corresponding context. ComPtr<ID3D11Device> device; ComPtr<ID3D11DeviceContext> context; DX::ThrowIfFailed( D3D11CreateDevice( nullptr, // Specify nullptr to use the default adapter. D3D_DRIVER_TYPE_HARDWARE, 0, creationFlags, // Set debug and Direct2D compatibility flags. featureLevels, // List of feature levels this app can support. ARRAYSIZE(featureLevels), D3D11_SDK_VERSION, // Always set this to D3D11_SDK_VERSION for Windows Store apps. &device, // Returns the Direct3D device created. &m_featureLevel, // Returns feature level of device created. &context // Returns the device immediate context. ) ); // Get the Direct3D 11.1 API device and context interfaces. DX::ThrowIfFailed( device.As(&m_d3dDevice) ); DX::ThrowIfFailed( context.As(&m_d3dContext) ); // Get the underlying DXGI device of the Direct3D device. DX::ThrowIfFailed( m_d3dDevice.As(&dxgiDevice) ); // Create the Direct2D device object and a corresponding context. DX::ThrowIfFailed( m_d2dFactory->CreateDevice(dxgiDevice.Get(), &m_d2dDevice) ); DX::ThrowIfFailed( m_d2dDevice->CreateDeviceContext( D2D1_DEVICE_CONTEXT_OPTIONS_NONE, &m_d2dContext ) ); }
3)设置输出设备
创建交换链,
通过DXGI,将交换链和窗口句柄进行绑定。
// Allocate all memory resources that change on a window SizeChanged event. void MDxKernelImp::CreateWindowSizeDependentResources() { // Store the window bounds so the next time we get a SizeChanged event we can // avoid rebuilding everything if the size is identical. //m_windowBounds = m_window->Bounds; HRESULT hr=S_OK; if (m_swapChain != nullptr) { // If the swap chain already exists, resize it. HRESULT hr = m_swapChain->ResizeBuffers(2, 0, 0, DXGI_FORMAT_B8G8R8A8_UNORM, 0); if (hr == DXGI_ERROR_DEVICE_REMOVED) { // If the device was removed for any reason, a new device and swapchain will need to be created. HandleDeviceLost(); // Everything is set up now. Do not continue execution of this method. return; } else { DX::ThrowIfFailed(hr); } } else { // Otherwise, create a new one using the same adapter as the existing Direct3D device. DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {0}; swapChainDesc.Width = 0; // Use automatic sizing. swapChainDesc.Height = 0; swapChainDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; // This is the most common swap chain format. swapChainDesc.Stereo = false; swapChainDesc.SampleDesc.Count = 1; // Don't use multi-sampling. swapChainDesc.SampleDesc.Quality = 0; swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.BufferCount = 2; // Use double-buffering to minimize latency. //swapChainDesc.Scaling = DXGI_SCALING_NONE; swapChainDesc.Scaling = DXGI_SCALING_STRETCH; //swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; // All Windows Store apps must use this SwapEffect. //swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_SEQUENTIAL; swapChainDesc.Flags = 0; ComPtr<IDXGIDevice1> dxgiDevice; DX::ThrowIfFailed( m_d3dDevice.As(&dxgiDevice) ); ComPtr<IDXGIAdapter> dxgiAdapter; DX::ThrowIfFailed( dxgiDevice->GetAdapter(&dxgiAdapter) ); ComPtr<IDXGIFactory2> dxgiFactory; DX::ThrowIfFailed( dxgiAdapter->GetParent(IID_PPV_ARGS(&dxgiFactory)) ); // CoreWindow^ window = m_window.Get(); // DX::ThrowIfFailed( // dxgiFactory->CreateSwapChainForCoreWindow( // m_d3dDevice.Get(), // reinterpret_cast<IUnknown*>(window), // &swapChainDesc, // nullptr, // &m_swapChain // ) // ); /*DX::ThrowIfFailed(*/ hr = dxgiFactory->CreateSwapChainForHwnd( m_d3dDevice.Get(), m_hWnd, &swapChainDesc, nullptr, nullptr, &m_swapChain ); //); // Ensure that DXGI does not queue more than one frame at a time. This both reduces latency and // ensures that the application will only render after each VSync, minimizing power consumption. DX::ThrowIfFailed( dxgiDevice->SetMaximumFrameLatency(1) ); } // Create a Direct3D render target view of the swap chain back buffer. ComPtr<ID3D11Texture2D> backBuffer; DX::ThrowIfFailed( m_swapChain->GetBuffer(0, IID_PPV_ARGS(&backBuffer)) ); DX::ThrowIfFailed( m_d3dDevice->CreateRenderTargetView( backBuffer.Get(), nullptr, &m_d3dRenderTargetView ) ); // Cache the rendertarget dimensions in our helper class for convenient use. D3D11_TEXTURE2D_DESC backBufferDesc = {0}; backBuffer->GetDesc(&backBufferDesc); m_renderTargetSize.cx = backBufferDesc.Width; m_renderTargetSize.cy = backBufferDesc.Height; // Create a depth stencil view for use with 3D rendering if needed. CD3D11_TEXTURE2D_DESC depthStencilDesc( DXGI_FORMAT_D24_UNORM_S8_UINT, backBufferDesc.Width, backBufferDesc.Height, 1, 1, D3D11_BIND_DEPTH_STENCIL ); ComPtr<ID3D11Texture2D> depthStencil; DX::ThrowIfFailed( m_d3dDevice->CreateTexture2D( &depthStencilDesc, nullptr, &depthStencil ) ); auto viewDesc = CD3D11_DEPTH_STENCIL_VIEW_DESC(D3D11_DSV_DIMENSION_TEXTURE2D); DX::ThrowIfFailed( m_d3dDevice->CreateDepthStencilView( depthStencil.Get(), &viewDesc, &m_d3dDepthStencilView ) ); // Set the 3D rendering viewport to target the entire window. CD3D11_VIEWPORT viewport( 0.0f, 0.0f, static_cast<float>(backBufferDesc.Width), static_cast<float>(backBufferDesc.Height) ); m_d3dContext->RSSetViewports(1, &viewport); // Create a Direct2D target bitmap associated with the // swap chain back buffer and set it as the current target. D2D1_BITMAP_PROPERTIES1 bitmapProperties = BitmapProperties1( D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW, PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED), m_dpi, m_dpi ); ComPtr<IDXGISurface> dxgiBackBuffer; DX::ThrowIfFailed( m_swapChain->GetBuffer(0, IID_PPV_ARGS(&dxgiBackBuffer)) ); DX::ThrowIfFailed( m_d2dContext->CreateBitmapFromDxgiSurface( dxgiBackBuffer.Get(), &bitmapProperties, &m_d2dTargetBitmap ) ); m_d2dContext->SetTarget(m_d2dTargetBitmap.Get()); // Grayscale text anti-aliasing is recommended for all Windows Store apps. m_d2dContext->SetTextAntialiasMode(D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE); }
4)根据垂直同步,控制交换链输出到窗口
// Method to deliver the final image to the display. void MDxKernelImp::Present(CRect *dtRect) { // The application may optionally specify "dirty" or "scroll" rects to improve efficiency // in certain scenarios. In this sample, however, we do not utilize those features. DXGI_PRESENT_PARAMETERS parameters = {0}; if(dtRect) { parameters.DirtyRectsCount = 1; parameters.pDirtyRects = dtRect; } else { parameters.DirtyRectsCount = 0; parameters.pDirtyRects = nullptr; } parameters.pScrollRect = nullptr; parameters.pScrollOffset = nullptr; // The first argument instructs DXGI to block until VSync, putting the application // to sleep until the next VSync. This ensures we don't waste any cycles rendering // frames that will never be displayed to the screen. //HRESULT hr = m_swapChain->Present1(1, 0, ¶meters); HRESULT hr = m_swapChain->Present1(1, 0, ¶meters); // Discard the contents of the render target. // This is a valid operation only when the existing contents will be entirely // overwritten. If dirty or scroll rects are used, this call should be removed. // m_d3dContext->DiscardView(m_d3dRenderTargetView.Get()); // Discard the contents of the depth stencil. // m_d3dContext->DiscardView(m_d3dDepthStencilView.Get()); // If the device was removed either by a disconnect or a driver upgrade, we // must recreate all device resources. if (hr == DXGI_ERROR_DEVICE_REMOVED) { HandleDeviceLost(); } // else // { // DX::ThrowIfFailed(hr); // } if (m_windowSizeChangeInProgress) { // A window size change has been initiated and the app has just completed presenting // the first frame with the new size. Notify the resize manager so we can short // circuit any resize animation and prevent unnecessary delays. //CoreWindowResizeManager::GetForCurrentView()->NotifyLayoutCompleted(); m_windowSizeChangeInProgress = false; } }
5)设备丢失的处理
这个就不贴代码了。
以上列出了MDxKernel模块的五个重点,完整的封装请查看代码。
其中多处地方参考微软官网和MSDN,在此表示感谢。
代码和例子的下载路径:http://pan.baidu.com/s/1ntFPXhv
联系方式:crazycooler@qq.com
相关文章推荐
- GPU渲染时代——2D图形图像中的应用(一)
- 图形与多媒体技术——图像渲染技术
- 用OpenGL ES 如何将2D图形更方便的渲染?
- OpenGL对场景中的图像进行渲染时所执行的主要图形操作
- 【Android开发】图形图像处理技术-使用BitmapShader渲染图像
- 深度卷积神经网络CNNs的多GPU并行框架 及其在图像识别的应用
- [分享]各种图片格式详解及应用[图像图形(图象)论坛]
- Android性能优化之GPU过度绘制与图形渲染优化
- PHP图形图像的典型应用 --常用图像的应用(验证码)
- PHP图形图像的典型应用 --常用图像的应用(统计图)
- 从GPU到3D渲染:游戏图形渲染技巧与性能优化
- SVG与J2ME移动2D图形的应用初探
- /LGC图形渲染/Pure GPU Computing Platform : NVIDIA CUDA Tutorial
- /LGC图形渲染/图像处理之基本概念和思想
- GPU图形处理管线、图形硬件接口(OpenGL)与可编程图形渲染语言(CG)的关系
- iOS应用开发之免费2D图形绘制开源插件推荐
- 基于XNA的3D图形GPU渲染技术
- /LGC图形渲染/彩色图像转换为灰度图像
- 用OpenGL ES 如何将2D图形更方便的渲染?
- ios图像处理第2部分:核心图形,核心图像,GPUImage