许可优化
产品
解决方案
服务支持
关于
软件库
当前位置:服务支持 >  软件文章 >  Direct3D的初始化

Direct3D的初始化

阅读数 6
点赞 0
article_banner

(1)获取接口IDirect3D9的指针,该接口用于获取系统中物理硬件设备的信息并创建接口IDirect3DDevice9,该接口是一个C++对象,代表了我们用来显示3D图形的物理硬件设备。
使用Direct3DCreate9可获得该指针,它的参数必须是D3D_SDK_VERSION,只有如此才能保证程序使用正确头文件,如果函数调用失败,将返回一个NULL指针

(2)检查设备性能(D3DCAPS9),判断主显卡是否支持硬件顶点运算,为了创建接口IDirect3DDevice9,我们必须明确显卡是否支持该功能

  1. HRESULT IDirect3D9::GetDeviceCaps(
  2. UINT Adapter, //指定物理显卡的序号
  3. D3DDEVTYPE DeviceType, //指定设备类型 硬件设备D3DDEVTYPE_HAL 软件设备D3DDEVTYPE_REF
  4. D3DCAPS9 * pCaps //设备性能结构
  5. );
cpp
运行

(3)初始化D3DPRESENT_PARAMETERS结构示例,我们可以通过这些变量来指定即将创建接口IDirect3DDevice9的特性

(4)利用已初始化的D3DPRESENT_PARAMETERS结构创建一个IDirect3DDevice9对象

d3dUtility.h

  1. #pragma once
  2. #include <d3d9.h>
  3. namespace d3d
  4. {
  5. //初始化Direct3D
  6. bool InitD3D(
  7. HINSTANCE hInstance,
  8. int width,
  9. int height,
  10. bool windowed,
  11. D3DDEVTYPE deviceType,
  12. IDirect3DDevice9** device);
  13. //封装应用程序的消息循环,参数为实现绘制功能的函数指针,在空闲处理期间显示场景
  14. int EnterMsgLoop(
  15. bool(*ptr_display)(float timeDelta));
  16. LRESULT CALLBACK WndProc(
  17. HWND hwnd,
  18. UINT msg,
  19. WPARAM wParam,
  20. LPARAM lParam);
  21. template<class T>
  22. void Release(T t)
  23. {
  24. if (t)
  25. {
  26. t->Release();
  27. t = 0;
  28. }
  29. }
  30. template<class T>
  31. void Delete(T t)
  32. {
  33. if (t)
  34. {
  35. delete t;
  36. t = 0;
  37. }
  38. }
  39. }
cpp
运行

d3dUtility.cpp

  1. #include "d3dUtility.h"
  2. bool d3d::InitD3D(HINSTANCE hInstance, int width, int height, bool windowed, D3DDEVTYPE deviceType, IDirect3DDevice9 ** device)
  3. {
  4. //定义窗口样式
  5. WNDCLASS wc;
  6. wc.style = CS_HREDRAW | CS_VREDRAW;
  7. wc.lpfnWndProc = WndProc;
  8. wc.cbClsExtra = 0;
  9. wc.cbWndExtra = 0;
  10. wc.hInstance = hInstance;
  11. wc.hIcon = LoadIcon(0, IDI_APPLICATION);
  12. wc.hCursor = LoadCursor(0, IDC_ARROW);
  13. wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
  14. wc.lpszMenuName = 0;
  15. wc.lpszClassName = L"Direct3D9App";
  16. //窗口注册
  17. if (!RegisterClass(&wc))
  18. {
  19. MessageBox(0, L"RegisterClass() - FAILED", 0, 0);
  20. return false;
  21. }
  22. //创建窗口
  23. HWND hwnd = 0;
  24. hwnd = CreateWindow(L"Direct3D9App", L"Direct3D9App", WS_OVERLAPPEDWINDOW, 0, 0, width, height, 0, 0, hInstance, 0);
  25. if (!hwnd)
  26. {
  27. MessageBox(0, L"CreateWindow() - FAILED", 0, 0);
  28. return false;
  29. }
  30. //绘制更新窗口
  31. ShowWindow(hwnd, SW_SHOW);
  32. UpdateWindow(hwnd);
  33. //--------以下为初始化IDirect3D------------
  34. //获取IDirect3D9指针
  35. IDirect3D9* d3d9;
  36. d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
  37. if (!d3d9)
  38. {
  39. MessageBox(0, L"Direct3DCreate9() - FAILED", 0, 0);
  40. return false;
  41. }
  42. //校验硬件性能(顶点运算)
  43. D3DCAPS9 caps;
  44. d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT, deviceType, &caps);
  45. int vp = 0;
  46. if (caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)
  47. vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;
  48. else
  49. vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
  50. //填充D3DPRESENT_PARAMETERS结构
  51. D3DPRESENT_PARAMETERS d3dpp;
  52. d3dpp.BackBufferWidth = width; //后台缓存中表面的宽度,单位为像素
  53. d3dpp.BackBufferHeight = height;
  54. d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8; //后台缓存的像素格式
  55. d3dpp.BackBufferCount = 1; //所需使用的后台缓存个数,通常指定为1
  56. d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE; //后台缓存所使用的多重采样类型
  57. d3dpp.MultiSampleQuality = 0; //多重采样的质量水平
  58. d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; //交换链中缓存的页面置换方式,D3DSWAPEFFECT_DISCARD时最高
  59. d3dpp.hDeviceWindow = hwnd; //所要进行绘制的应用程序窗口
  60. d3dpp.Windowed = windowed; //true为窗口模式,false为全屏模式
  61. d3dpp.EnableAutoDepthStencil = true; //设为true则Direct3D自动创建并维护深度缓存或模板缓存
  62. d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8; //深度缓存或模板缓存的像素格式 D3DFMT_D24S8 24位表示深度,8位保留模板缓存使用
  63. d3dpp.Flags = 0; //附加特性 D3DPRESENTFLAG_LOCKABLE_BACKBUFFER指定可锁定后台缓存,使用一个可锁定的后台缓存会降低性能 D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL
  64. d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; //刷新频率
  65. d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; //提交频率 D3DPRESENT_INTERVAL_IMMEDIATE立即提交 D3DPRESENT_INTERVAL_DEFAULT由Direct3D来选择提交频率
  66. //创建IDirectDevice9接口
  67. d3d9->CreateDevice(D3DADAPTER_DEFAULT, deviceType, hwnd, vp, &d3dpp, device);
  68. d3d9->Release();
  69. return true;
  70. }
  71. #if 0
  72. GetMessage的主要功能是从消息队列中“取出”消息,消息被取出以后,就从消息队列中将其删除;而PeekMessage的主要功能是“窥视”消息,
  73. 如果有消息,就返回true,否则返回false。也可以使用PeekMessage从消息队列中取出消息,这要用到它的一个参数(UINT wRemoveMsg),
  74. 如果设置为PM_REMOVE,消息则被取出并从消息队列中删除;如果设置为PM_NOREMOVE,消息就不会从消息队列中取出
  75. #endif
  76. int d3d::EnterMsgLoop(bool(*ptr_display)(float timeDelta))
  77. {
  78. MSG msg;
  79. ::ZeroMemory(&msg, sizeof(MSG));
  80. static float lastTime = (float)timeGetTime();
  81. while (msg.message != WM_QUIT)
  82. {
  83. if (::PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
  84. {
  85. ::TranslateMessage(&msg);
  86. ::DispatchMessage(&msg);
  87. }
  88. else
  89. {
  90. float currTime = (float)timeGetTime();
  91. float timeDelta = (currTime - lastTime)*0.001f;
  92. ptr_display(timeDelta);
  93. lastTime = currTime;
  94. }
  95. }
  96. return msg.wParam;
  97. }
  98. LRESULT CALLBACK d3d::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
  99. {
  100. switch (msg)
  101. {
  102. case WM_DESTROY: //销毁
  103. PostQuitMessage(0); //终止请求
  104. break;
  105. case WM_KEYDOWN: //键按下
  106. if (wParam == VK_ESCAPE) //Esc键
  107. DestroyWindow(hwnd);
  108. break;
  109. default:
  110. break;
  111. }
  112. //调用缺省的窗口过程来为应用程序没有处理的任何窗口信息提供缺省的处理
  113. //该函数确保每一个消息得到处理
  114. return DefWindowProc(hwnd, msg, wParam, lParam);
  115. }
cpp
运行

D3DPractice.cpp

  1. #include <windows.h>
  2. #include "d3dUtility.h"
  3. #include <d3dx9math.h>
  4. IDirect3DDevice9* Device = NULL;
  5. bool DisPlay(float timeDelta)
  6. {
  7. if (Device)
  8. {
  9. Device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
  10. /*
  11. STDMETHOD(Clear)(THIS_ DWORD Count, CONST D3DRECT* pRects, DWORD Flags, D3DCOLOR Color, float Z, DWORD Stencil) PURE;
  12. Count: pRects数组中矩形的数目
  13. pRects:要执行清除操作的屏幕矩形数组,该参数允许我们只对表面的部分区域进行清除操作
  14. Flags:指定所要清除的表面
  15. D3DCLEAR_TARGET 绘制目标表面,通常指后台缓存
  16. D3DCLEAR_ZBUFFER 深度缓存
  17. D3DCLEAR_STENCIL 模板缓存
  18. Color:指定将绘制目标体设置为何种颜色
  19. Z:深度缓存所需要设定的值
  20. Stencil:模板缓存所需要设定的值
  21. */
  22. Device->Present(0, 0, 0, 0); //提交后台缓存
  23. }
  24. return true;
  25. }
  26. bool SetUp()
  27. {
  28. return true;
  29. }
  30. void CleanUp()
  31. {
  32. }
  33. int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd)
  34. {
  35. if (!d3d::InitD3D(hInstance, 800, 600, true, D3DDEVTYPE_HAL, &Device))
  36. {
  37. ::MessageBox(0, L"InitD3D() - FAILED", 0, 0);
  38. return 0;
  39. }
  40. if (!SetUp())
  41. {
  42. ::MessageBox(0, L"SetUp() - FAILED", 0, 0);
  43. return 0;
  44. }
  45. d3d::EnterMsgLoop(DisPlay);
  46. CleanUp();
  47. Device->Release();
  48. return 0;
  49. }
cpp
运行


免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删
相关文章
QR Code
微信扫一扫,欢迎咨询~

联系我们
武汉格发信息技术有限公司
湖北省武汉市经开区科技园西路6号103孵化器
电话:155-2731-8020 座机:027-59821821
邮件:tanzw@gofarlic.com
Copyright © 2023 Gofarsoft Co.,Ltd. 保留所有权利
遇到许可问题?该如何解决!?
评估许可证实际采购量? 
不清楚软件许可证使用数据? 
收到软件厂商律师函!?  
想要少购买点许可证,节省费用? 
收到软件厂商侵权通告!?  
有正版license,但许可证不够用,需要新购? 
联系方式 155-2731-8020
预留信息,一起解决您的问题
* 姓名:
* 手机:

* 公司名称:

姓名不为空

手机不正确

公司不为空