D3D初始化窗口显示
//代码来源于教材(重庆大学---基于Dx11的案例教程)
#pragma once #include <iostream> #include<d3dcompiler.h> #include <DirectXMath.h> #include<d3d11.h> #include<dxgi.h> using namespace DirectX; namespace d3d { bool initD3D(HINSTANCE hinstance, int W, int H, ID3D11RenderTargetView** renderTarview,//目标渲染视图接口 ID3D11DeviceContext** immCtx, IDXGISwapChain** swapChain, ID3D11Device** device //设备,至少一个设备 ); int EnterMsgLoop(bool (*ptr)(float timeDelta)); LRESULT CALLBACK WndProc(HWND,UINT msg,WPARAM,LPARAM Iparam); }
#include "d3dinit.h" bool d3d::initD3D(HINSTANCE hinstance, int W, int H, ID3D11RenderTargetView** renderTarview, ID3D11DeviceContext** immCtx, IDXGISwapChain** swapChain, ID3D11Device** device) { //窗口类实例 WNDCLASS wnd; wnd.style = CS_HREDRAW | CS_VREDRAW;//窗口风格 wnd.lpfnWndProc = d3d::WndProc;//窗口回调 wnd.cbClsExtra = 0;//窗口类附加内存 wnd.cbWndExtra = 0;//窗口附加内存 wnd.hInstance = hinstance;//实例句柄 wnd.hIcon = LoadIcon(0, IDI_APPLICATION);//图标句柄 wnd.hCursor = LoadCursor(0, IDC_ARROW);//光标句柄--此时为默认箭头光标 wnd.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);//背景画刷句柄--(HBRUSH)为强制类型转换 wnd.lpszMenuName = 0;//菜单名字 wnd.lpszClassName = L"D3D TEST";//窗口类名 //注册窗口 if (!RegisterClass(&wnd)) { MessageBox(0, L"Register d3d Windows Failed !", L"Warning !", 0); return false; } //创建窗口 HWND hwnd = 0; hwnd = ::CreateWindow(L"D3D TEST", L"D3D11", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, W, H, 0, 0, hinstance, 0); if (!hwnd) { MessageBox(0, L"create d3d!", L"Warning !", 0); return false; } ::ShowWindow(hwnd,SW_SHOW); ::UpdateWindow(hwnd); //交换链的描述 DXGI_SWAP_CHAIN_DESC sd; ZeroMemory(&sd,sizeof(sd)); sd.BufferCount = 1;//后缓冲数量 sd.BufferDesc.Width = W; sd.BufferDesc.Height = H; sd.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;//24bit RGB sd.BufferDesc.RefreshRate.Numerator = 60; sd.BufferDesc.RefreshRate.Denominator = 1; sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; sd.OutputWindow = hwnd; sd.SampleDesc.Count = 1; sd.SampleDesc.Quality = 0; sd.Windowed = true; //创建设备,交换链,上下文 D3D_FEATURE_LEVEL featurelevs[] = { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0, }; UINT NUM_featurelevel = ARRAYSIZE(featurelevs); //创建设备和交换链 if (FAILED(D3D11CreateDeviceAndSwapChain( NULL, //确定显示适配器,NULL表示默认显示适配器 D3D_DRIVER_TYPE_HARDWARE, //选择驱动类型,这里表示使用三维硬件加速 NULL, //只有上一个参数设置D3D_DRIVER_TYPE_SOFTWARE时,才使用这个参数 0, //也可以设置为D3D11_CREATE_DEVICE_DEBUG开启调试模式 featurelevs, //前面定义的D3D_FEATURE_LEVEL数组 NUM_featurelevel, //D3D_FEATURE_LEVEL的元素个数 D3D11_SDK_VERSION, //SDK的版本,这里为D3D11 &sd, //前面定义的DXGI_SWAP_CHAIN_DESC对象 swapChain, //返回创建好的交换链指针,InitD3D函数传递的实参 device, //返回创建好的设备用指针,InitD3D函数传递的实参 NULL, //返回当前设备支持的featureLevels数组中的第一个对象,一般设置为NULL immCtx))) //返回创建好的设备上下文指针,InitD3D函数传递的实参 { ::MessageBox(0, L"CreateDevice and swapchain - FAILED", 0, 0); //如果创建失败,弹出消息框 return false; } //设置渲染目标视图 HRESULT hr = 0; ID3D11Texture2D* pbackBuf = NULL;//surface //调用GetBuffer()函数得到后台缓存对象,并存入&pBackBuffer中 hr = (*swapChain)->GetBuffer(0,__uuidof(ID3D11Texture2D),(LPVOID*)&pbackBuf); if (FAILED(hr)) { ::MessageBox(0, L"GetBuffer - FAILED", 0, 0); //如果调用失败,弹出消息框 return false; } //创建渲染目标视图 hr = (*device)->CreateRenderTargetView(pbackBuf,NULL,renderTarview); pbackBuf->Release(); //判断CreateRenderTargetView是否调用成功 if (FAILED(hr)) { ::MessageBox(0, L"CreateRender - FAILED", 0, 0); //如果调用失败,弹出消息框 return false; } //渲染目标视图绑定到渲染管线上 (*immCtx)->OMSetRenderTargets(1, // 绑定的目标视图的个数 renderTarview,NULL);// //设置为NULL表示不绑定深度模板 //第四步,设置视口大小,D3D11默认不会设置视口,此步骤必须手动设置 D3D11_VIEWPORT vp; //创建一个视口的对象 vp.Width = W; //视口的宽 vp.Height = H; //视口的高 vp.MinDepth = 0.0f; //深度值的下限,**由于深度值是[0, 1]所以下限值是0 vp.MaxDepth = 1.0f; //深度值的上限,上限值是1 vp.TopLeftX = 0; //视口左上角的横坐标 vp.TopLeftY = 0; //视口左上角的总坐标 //设置视口 (*immCtx)->RSSetViewports(1, //视口的个数 &vp); //上面创建的视口对象 return true; } int d3d::EnterMsgLoop(bool(*ptr)(float timeDelta)) { MSG msg; ::ZeroMemory(&msg, sizeof(MSG)); //初始化内存 static float lastTime = (float)timeGetTime(); //第一次获取当前时间 while (msg.message != WM_QUIT) { if (::PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) { ::TranslateMessage(&msg); ::DispatchMessage(&msg); } else { float currTime = (float)timeGetTime(); //第二次获取当前时间 float timeDelta = (currTime - lastTime) * 0.001f; //获取两次时间之间的时间差 ptr(timeDelta); //调用显示函数,这在后面实现图形的变化(如旋转)时会用到 lastTime = currTime; } } return msg.wParam; }
// D3Dtest.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 // #include "d3dinit.h" ID3D11Device* device = NULL; //D3D11设备指针 IDXGISwapChain* swapChain = NULL; //交换链指针 ID3D11DeviceContext* immediateContext = NULL; //设备上下文指针 ID3D11RenderTargetView* renderTargetView = NULL;//渲染目标视图指针 void Cleanup() { //释放指针 if (renderTargetView) renderTargetView->Release(); if (immediateContext) immediateContext->Release(); if (swapChain) swapChain->Release(); if (device) device->Release(); } LRESULT CALLBACK d3d::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { //处理窗口消息 switch (msg) { case WM_DESTROY: ::PostQuitMessage(0); break; case WM_KEYDOWN: if (wParam == VK_ESCAPE) ::DestroyWindow(hwnd); break; } return ::DefWindowProc(hwnd, msg, wParam, lParam); } bool Display(float timeDelta) { if (device) { //声明一个数组存放颜色信息,4个元素分别表示红,绿,蓝以及alpha float ClearColor[4] = { 0.3f, 0.5f, 0.6f, 1.0f }; //清除渲染目标视图 immediateContext->ClearRenderTargetView(renderTargetView, ClearColor); //显示渲染好的图像 swapChain->Present(0, //指定如何同步显示,设置0表示不同步显示 0);//可选项,设置0表示为从每个缓存中显示一帧 } return true; } int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE prevInstance, PSTR cmdLine, int showCmd) { //初始化 //**注意**:最上面声明的4个指针,在这里作为参数传给InitD3D函数 if (!d3d::initD3D(hinstance, 800, 600, &renderTargetView, &immediateContext, &swapChain, &device)) { ::MessageBox(0, L"InitD3D() - FAILED", 0, 0); return 0; } //执行消息循环,将函数Display的指针作为参数传递 d3d::EnterMsgLoop(Display); Cleanup(); return 0; }
注意创建窗口程序:vs2022



浙公网安备 33010602011771号