Direct3D初始化例程

news/2025/2/13 0:05:06/

看过Direct3D初始化之后,我们来总体的串一下,搞出个示例,方便学习。

我们现在要做的就是实现Direct3D的初始化,并将背景设置为红色。

在下面的例子中,我们使用了d3dUtility.h/cpp,这两个文件中就是实现每一个Direct3D应用程序都要干的事情,例如创建窗口、初初始化Direct3D、进入应用程序消息循环等,现在我们将这些共性的任务封装在一起。

开始例子之前,我们先来研究一下d3dUtility.h里面的内容:

#pragma once#include "d3dx9.h"namespace d3d {bool InitD3D(HINSTANCE hInstance,		//应用程序实例int width,int height,					//后台缓存的尺寸bool windowed,				//是全屏还是窗口D3DDEVTYPE devicetype,		//HAL 还是 REFIDirect3DDevice9** device   //创建的设备);int EnterMsgLoop(bool (*ptr_dispaly)(float timeDelta));// 系统的回调函数// 在创建窗口类信息结构体的时候,里面需要填写的回调函数,// 可以参见博客:https://blog.csdn.net/DY_1024/article/details/89178348第一小节LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);template<class T>void Release(T t){if (t){t->Release();t = 0;}}template<class T>void Delete(T t){if (t){delete t;t = 0;}}
}

里面头文件是我们需要的其他头文件,如果没有下载DirectX9的SDK的话,可以在这个链接下载:

链接:https://pan.baidu.com/s/1028NylXtE6T3Y7MSVEs2GQ 密码:rp5x

下载之后再头文件里面依赖DX9的include头文件(就在Iclude文件夹里面),然后将DX9的SDK里面lib库的路径依赖上(在Lib文件夹里面),然后在库依赖项里面填上:

d3d9.lib
d3dx9.lib
winmm.lib

应该就差不多了~

关于d3dUtility.h的相关内容:

InitD3D:该函数主要对应用程序的主窗口进行了初始化,并执行了之前我们在这篇博客中,所讨论的Direct3D初始化的过程。如果该函数返回成功,就会的到一个指向已经创建好的Direct3DDevice6接口的指针。

EnterMsgLoop:该函数封装了应用程序的消息循环,他接收一个指向显示函数的函数指针。该显示函数就是实现绘制功能的那个函数。该消息循环函数需要知道使用哪个显示函数,然后才进行调用。

然后给出了两个模板,用来释放资源。

d3dUtility.cpp里面就是给出了这两个函数的实现:

#include "d3dUtility.h"
#include <windows.h>int d3d::EnterMsgLoop(bool(*ptr_display)(float timeDelta))
{// window消息结构体MSG msg;::ZeroMemory(&msg, sizeof(MSG));//timeGetTime:检索系统时间,系统时间是自Windows启动以来的时间static float lastTime = (float)timeGetTime();//WM_QUIT:关闭消息循环while (msg.message != WM_QUIT){if (::PeekMessage(&msg, 0, 0, 0, PM_REMOVE)){::TranslateMessage(&msg);::DispatchMessage(&msg);}else{//相邻两次调用timeGetTime的时间间隔,就是产生相邻帧时间间隔float currTime = (float)timeGetTime();float timeDelta = (currTime - lastTime)*0.001f;ptr_display(timeDelta);lastTime = currTime;}}return msg.wParam;
}bool d3d::InitD3D(HINSTANCE hInstance,int width, int height,bool windowed,D3DDEVTYPE devicetype,IDirect3DDevice9** device)
{// 初始化一个窗口//一个结构体:包含了一个窗口类的全部信息WNDCLASS wc;wc.style = CS_HREDRAW | CS_VREDRAW;		//表示窗口的高度或者宽度改变时,是否重画窗口wc.lpfnWndProc = (WNDPROC)d3d::WndProc;wc.cbClsExtra = 0;wc.cbWndExtra = 0;wc.hInstance = hInstance;wc.hIcon = LoadIcon(0, IDI_APPLICATION);wc.hCursor = LoadCursor(0, IDC_ARROW);wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);wc.lpszMenuName = 0;wc.lpszClassName = "Direct3D9App";if (!RegisterClass(&wc)){::MessageBox(0,"RegisterClass() - FAILED",0,0);return false;}//定义一个窗口句柄HWND hwnd = 0;hwnd = ::CreateWindow("Direct3D9App", "Direct3D9App",WS_EX_TOPMOST,0, 0, width, height,0 /*parent hwnd*/, 0 /* menu */, hInstance, 0 /*extra*/);if (!hwnd){::MessageBox(0, "CreateWindow() - FAILED", 0, 0);return false;}::ShowWindow(hwnd, SW_SHOW);::UpdateWindow(hwnd);//初始化D3D设备//这是一个即将用来存放函数执行结果的变量//不是返回结果的句柄HRESULT hr = 0;//获取一个Direct3D的指针IDirect3D9* d3d9 = 0;d3d9 = Direct3DCreate9(D3D_SDK_VERSION);if (!d3d9){::MessageBox(0, "Direct3DCreate9() - FAILED", 0, 0);return false;}//检查设备是否支持硬件顶点运算D3DCAPS9 caps;d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT, devicetype, &caps);int vp = 0;if (caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT){vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;}else{vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;}//到达这里我们的vp里面就存放着我们的设备到底是不是支持硬件顶点运算//现在将我们的设备的信息储存在一个结构体中,方便以后的使用//也就是填充结构体:D3DPRESENT_PARAMETERS D3DPRESENT_PARAMETERS d3dpp;d3dpp.BackBufferWidth = width;d3dpp.BackBufferHeight = height;d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;d3dpp.BackBufferCount = 1;d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;d3dpp.MultiSampleQuality = 0;d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;d3dpp.hDeviceWindow = hwnd;d3dpp.Windowed = windowed;d3dpp.EnableAutoDepthStencil = true;d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;d3dpp.Flags = 0;d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;//设备支持不支持硬件顶点运算,以及设备的信息我们都知道了//现在我们就开始创建一个显示的设备hr = d3d9->CreateDevice(D3DADAPTER_DEFAULT,devicetype,hwnd,vp,&d3dpp,device);if (FAILED(hr)){//如果失败的话,就将深度缓冲区的位数设置为16位然后再次创建一遍d3dpp.AutoDepthStencilFormat = D3DFMT_D16;hr = d3d9->CreateDevice(D3DADAPTER_DEFAULT,devicetype,hwnd,vp,&d3dpp,device);//如果16位还是失败,就弹窗报错if (FAILED(hr)){d3d9->Release(); // done with d3d9 object::MessageBox(0, "CreateDevice() - FAILED", 0, 0);return false;}}d3d9->Release();return true;
}

然后就是我们的main函数:

main函数里面我们需要实现Setup()、Cleanup()函数,但是现在我们在里面没有内存分配,这两个函数可以直接为空

还需要实现的就是我们在EnterMsgLoop函数里面需要传进去当做参数的显示函数;

main.cpp

#include "d3dUtility.h"IDirect3DDevice9* Device = 0;//因为这个例子中没有任何资源的分配,所以Setup函数和Cleanup函数是空函数
bool Setup() 
{return true;
}void Cleanup()
{}// 展示函数
bool Display(float timeDelta)
{if (Device){//Device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);Device->Present(0, 0, 0, 0);	//提交后台缓冲}return true;
}LRESULT CALLBACK d3d::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{switch (msg){case WM_DESTROY:::PostQuitMessage(0);break;case WM_KEYDOWN://当我们在键盘接收到ESC按下的时候,就退出if (wParam == VK_ESCAPE){::DestroyWindow(hwnd);}break;}return ::DefWindowProc(hwnd, msg, wParam, lParam);
}int WINAPI WinMain(HINSTANCE hinstance,HINSTANCE prevInstance,PSTR cmdLine,int showCmd)
{//初始化一个Init3D对象if (!d3d::InitD3D(hinstance, 640, 480, true, D3DDEVTYPE_HAL, &Device)){::MessageBox(0, "InitD3D() - FAILED", 0, 0);return 0;}//分配资源if (!Setup()){::MessageBox(0, "Setup() - FAILED", 0, 0);return 0;}//使用d3d命名空间里面EnterMsgLoop函数d3d::EnterMsgLoop(Display);Cleanup();//设备对象调用函数进行资源回收Device->Release();return 0;
}

小节:

1、Direct3D可以被认为是程序员和硬件设备之间的媒介,程序员调用一个Direct3D接口也就是在命令硬件设备和HAL设备进行交互

2、REF设备允许开发人员使用那些Direct3D支持但是硬件设备不支持的功能

3、COM是一项可以使DirectX独立于编程语言,我们不需要知道COM实现的细节,我们只需要知道怎么获取和使用然后释放就可以

4、表面是Direct3D用来储存2D图形数据的专用接口,D3DFORMAT枚举类型的成员指定了表面的像素格式;表面和其他的资源可以被存放在其他几个不同的资内存池中,内存池的类型由D2DPOOL枚举类型的成员决定,此外表面还可以进行多重采样,来创建一副比较平滑的图像

5、IDirect3D接口主要用获取系统图形设备的信息,例如:借助该接口我们可以获取某一设备的特性

6、可以将接口IDirect3DDevice0视为控制图形设备的软件接口。例如:调用IDirect3DDevice9::Clear可命令控制的图形设备对指定的表面进行清除操作


http://www.ppmy.cn/news/388587.html

相关文章

Direct3D基础——Direct3D的初始化

首先概述一下Direct初始化的大概步骤&#xff08;稍后我们会详细说明&#xff09;&#xff1a; 1、获取接口IDirect3D9 的指针。该接口用于获取系统物理硬件设备的信息并创建接口&#xff1a;IDirect3DDevice9&#xff0c;接口可以看是一个C对象&#xff0c;代表了我们用来显示…

从 Direct3D 9 到 Direct3D 11 的重要更改

本主题介绍 DirectX 9 和 DirectX 11 之间更高级别的差异。 从根本上说&#xff0c;Direct3D 11 与 Direct3D 9 是同类型的 API - 一种到图形硬件的低级别虚拟化接口。它还允许你在各种硬件实现上执行图形绘制操作。自 Direct3D 9 起&#xff0c;图形 API 的布局已更改&#xf…

初始化Direct3D

一、Direct3D概述 DirectX是微软公司开发的一套功能丰富的底层API&#xff0c;其功能涵盖了&#xff1a; 2D/3D图形加速的支持、 各种输入设备的控制、 声音和音乐输出的混音和采样、 多玩家网络游戏的控制、 各种多媒体流媒体模式的控制等。 DirectX在体系结构上很突出的优点是…

Direct3D播放RGB(通过Texture)

&#xfeff;&#xfeff; 本文接着上一篇文章继续记录Direct3D&#xff08;简称D3D&#xff09;播放视频的技术。上一篇文章中已经记录了使用Direct3D中的Surface渲染视频的技术。本文记录一种稍微复杂但是更加灵活的渲染视频的方式&#xff1a;使用Direct3D中的Texture&#…

Main.obj : error LNK2019: 无法解析的外部符号 _Direct3DCreate9@4,该符号在函数 long __cdecl InitD3D(struct HWND__ *)

错误问题&#xff1a; Main.obj : error LNK2019: 无法解析的外部符号 _Direct3DCreate94&#xff0c;该符号在函数 "long __cdecl InitD3D(struct HWND__ *)" (?InitD3DYAJPAUHWND__Z) 中被引用 1>G:\Visual_studio\Project\MyD3D_1\Debug\MyD3D_1.exe : fatal …

2007-08-03 16:04 unresolved external symbol Direct3DCreate9

选择VC的菜单项“Project/Settings...”&#xff0c;然后选中“Link”标签&#xff0c;在“Object/library modules”栏输入“d3d9.lib d3dx9.lib”&#xff08;本节中的例程只用到了d3d9.lib&#xff0c;另外一个库文件是为后面程序准备的&#xff09;。 设置目录是没有用的&a…

DirectX的error LNK2019: 无法解析的外部符号 _Direct3DCreate9@4,该符号在函数 long __cdecl InitD3D(struct HWND__ *)

在VS下弄了半天这个&#xff0c;总是出错误&#xff0c;解决方法就是 首先把安装的DirectX的 头文件和 库包含进来&#xff0c;要包含 win32 x86的&#xff0c;最后在 项目->配置属性->链接器->输入->附加依赖项 中加入 d3d9.lib&#xff0c;就可以正常编译了。

无法解析的外部符号 Direct3DCreate9@4

错误 1 error LNK2019: 无法解析的外部符号 _Direct3DCreate94&#xff0c;该符号在函数 "void __cdecl InitD3D(struct HWND__ *)" (?InitD3DYAXPAUHWND__Z) 中被引用 解决方法&#xff1a; 在VS.NET中的项目/属性/配置属性/连接器/输入/附加依赖项中添加以下文件…