DirectX学习笔记(十):3D字体的实现及用ID3DXFont接口绘制文本
2016-09-19 23:54
886 查看
ID3DXFont接口介绍:
D3DX库提供了ID3DXFont 接口,该接口用于在Direct3D应用程序中绘制文本。这个接口的使用,有优点,也有缺点。缺点就是在接口的内部使用了GDI图形设备接口,导致了该接口在性能上会有稍微的损失。优点就是由于在接口的内部使用了GDI图形设备接口,导致了它能够处理一些复杂的字体和格式。1.如何使用ID3DXFont接口绘制文本信息
第一步:创建一个ID3DXFont对象:
//字体接口 ID3DXFont* Font = 0;
第二步:填充D3DXFONT_DESC结构
在创建完毕后,我们需要对索要使用的字体进行描述,那么这个时候就需要用到D3DXFONT_DESC结构。该结构的参数如下typedef struct D3DXFONT_DESC { INT Height;//Height, in logical units,指的是字体的高度, UINT Width;//Width, in logical units UINT Weight;//Weight of the font in the range from 0 through 1000. UINT MipLevels;//文本的Miplevels BOOL Italic;//是否斜体 BYTE CharSet;//字符集 BYTE OutputPrecision;// 指定Windows与期望字体大小的匹配方法 BYTE Quality;//输出质量 BYTE PitchAndFamily;//斜度和family索引 TCHAR FaceName;//字体类型名称 } D3DXFONT_DESC, *LPD3DXFONT_DESC;
那么我们这样填充:
D3DXFONT_DESC df; ZeroMemory(&df, sizeof(D3DXFONT_DESC)); df.Height = 25; df.Width = 12; df.MipLevels = D3DX_DEFAULT; df.Italic = false; df.CharSet = DEFAULT_CHARSET; df.OutputPrecision = 0; df.Quality = 0; df.PitchAndFamily = 0; strcpy_s(df.FaceName, "TIME NEW ROMAN");
第三部:填充完绘制:
如果我们获取到了ID3DXFont接口的指针,就只需要调用ID3DXFont::DrawText即可完成文本的绘制:函数参数如下:
INT DrawText( [in] LPD3DXSPRITE pSprite,//用来绘制文字的sprite对象 [in] LPCTSTR pString,//指向字符串的指针 [in] INT Count,//字数.假如字符是以null结束的字符串则可将其指定为-1 [in] LPRECT pRect,//指向一个RECT结构,它定义一个文字被绘制在屏幕上的范围。 [in] DWORD Format,//可选参数,指定文字怎样被格式化,具体可以查sdk文档 [in] D3DCOLOR Color//文字的颜色 );
我们就这样指定:
Font->DrawTextA(NULL, "Hello World", -1,&rect, DT_TOP | DT_LEFT, 0xff000000);
以上就完成了。
完整代码:
#include <windows.h>
#include<d3d9.h>
#include<string>
#include<d3dx9.h>
using namespace std;
#define SCREEN_WIDTH 800 //窗口宽度
#define SCREEN_HEIGHT 600 //窗口高度
#define FVF_VERTEX (D3DFVF_XYZ | D3DFVF_TEX1)
#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } } //自定义一个SAFE_RELEASE()宏,便于资源的释放
IDirect3DDevice9* _device; //Direct3D设备
//字体接口 ID3DXFont* Font = 0;
//函数声明
//初始化Direct3D
//消息过程,处理消息
bool InitD3D(HINSTANCE hInstance, int width, int height, bool windowed, D3DDEVTYPE deviceType, IDirect3DDevice9 ** device);
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
//以下为窗口过程
LRESULT CALLBACK 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);
}
//初始化D3D
bool InitD3D(HINSTANCE hInstance, int width, int height, bool windowed, D3DDEVTYPE deviceType, IDirect3DDevice9 ** device)
{
//定义一个完整的窗口类
WNDCLASS wc;
wc.style = CS_VREDRAW | CS_HREDRAW;
wc.lpfnWndProc = 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.lpszClassName = "LSZDX";
wc.lpszMenuName = 0;
//注册窗口类
if (!(RegisterClass(&wc)))
{
MessageBox(0, "RegisterClass is FAILED", 0, 0);
return false;
}
//创建窗口
HWND hwnd = 0;
hwnd = CreateWindow("LSZDX", "LSZDXDEMO", WS_OVERLAPPEDWINDOW, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0, hInstance, 0);
if (hwnd == 0)
{
MessageBox(0, "CreateWIndow is FAILED", 0, 0);
return false;
}
//绘制和更新窗口
ShowWindow(hwnd, SW_SHOW);
UpdateWindow(hwnd);
//以下为初始化D3D
//*---------------
//获取IDirect3D9的指针
IDirect3D9 *d3d9 = 0;
d3d9 = Direct3DCreate9((D3D_SDK_VERSION));
if (!d3d9)
{
MessageBox(0, "Direct3D9Create9 is 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;
//填充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;
//创建IDirect3DDevice9接口
if (FAILED(d3d9->CreateDevice(
D3DADAPTER_DEFAULT,
deviceType,
hwnd,
vp,
&d3dpp,
device)))
{
MessageBox(0, "CreateDevice is FAILED", 0, 0);
return false;
}
d3d9->Release();
return true;
}
//初始化工作
bool Setup()
{ //填充D3DXFONT_DESC结构
D3DXFONT_DESC df;
ZeroMemory(&df, sizeof(D3DXFONT_DESC));
df.Height = 25;
df.Width = 12;
df.MipLevels = D3DX_DEFAULT;
df.Italic = false;
df.CharSet = DEFAULT_CHARSET;
df.OutputPrecision = 0;
df.Quality = 0;
df.PitchAndFamily = 0;
strcpy_s(df.FaceName, "TIME NEW ROMAN");
//创建ID3DXFont对象
D3DXCreateFontIndirect(_device, &df, &Font);
return true;
}
//显示操作
bool DisPlay()
{
MSG msg;
::ZeroMemory(&msg, sizeof(MSG));//用0来填充消息可类比为:memset()函数
while (msg.message != WM_QUIT)
{
//PeekMessage函数是以查看的方式从系统中获取消息
//并将该消息(如果存在)放于指定的结构
if (::PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
{
//PM_REMOVE:PeekMessage处理后,消息从队列里除掉。
//TranslateMessage函数将虚拟键消息转换为字符消息。
//字符消息被寄送到调用线程的消息队列里,
//当下一次线程调用函数GetMessage或PeekMessage时被读出。
//TranslateMessage只能用于转换调用GetMessage或PeekMessage接收的消息。
::TranslateMessage(&msg);
//DispatchMessage函数
//该函数分发一个消息给窗口程序。
//通常消息从GetMessage函数获得。
//消息被分发到回调函数(过程函数),作用是消息传递给操作系统,
//然后操作系统去调用我们的回调函数,也就是说我们在窗体的过程函数中处理消息
::DispatchMessage(&msg);
}
else
{
if (_device)
{
//
// 绘制场景
//
_device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
_device->BeginScene();
//绘制文本
RECT rect = { 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT };
Font->DrawTextA(NULL, "Hello World", -1,&rect, DT_TOP | DT_LEFT, 0xff000000);
_device->EndScene();
_device->Present(0, 0, 0, 0);
}
}
}
return true;
}
//
int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd)
{
if (!InitD3D(hInstance, SCREEN_WIDTH, SCREEN_HEIGHT, true, D3DDEVTYPE_HAL, &_device))
{
MessageBox(0, "InitD3D is FAILED", 0, 0);
return 0;
}
if (!Setup())
{
MessageBox(0, "Setup() - FAILED", 0, 0);
return 0;
}
DisPlay();
_device->Release();
return 0;
}
运行效果:
那么如何创建3D字体呢?
创建3D字体:
第一步:创建一个Mesh结构用来保存我们的3D文本数据:
ID3DXMesh * Text = 0;
第二步:填充LOGFONT结构
如上一样填充字体存储的结构,但是这里我们填充的是LOGFONT结构:老版本的DirectX使用LOGFONT作为参数创建字体,在DirectX9.0c以及以后的版本里面改为使用D3DXFONT_DESC作为参数创建字体。这两个结构体大体是相同的。
下面分别列举一个使用D3DXFONT_DESC和LOGFONT作为参数的例子:
使用这个函数时,需要一个D3DXFONT_DESC结构:
D3DXFONT_DESC d3dFont;
memset(&d3dFont,0,sizeof(d3dFont));
d3dFont.Height=25; // in logical units
d3dFont.Width=12; // in logical units
d3dFont.Weight=500;// boldness, range 0(light) - 1000(bold)
d3dFont.Italic=FALSE;
d3dFont.CharSet=DEFAULT_CHARSET;
strcpy(d3dFont.FaceName,"Times New Roman");
ID3DXFont* font=0;
D3DXCreateFontIndirect(Device,&d3dFont,&font);
如果你使用的是LOGFONT结构,则:
LOGFONT lf;
ZeroMemory(&lf, sizeof(LOGFONT));
lf.lfHeight = 25; // in logical units
lf.lfWidth = 12; // in logical units
lf.lfWeight = 500; // boldness, range 0(light) - 1000(bold)
lf.lfItalic = false;
lf.lfUnderline = false;
lf.lfStrikeOut = false;
lf.lfCharSet = DEFAULT_CHARSET;
strcpy(lf.lfFaceName, "Times New Roman"); // font style
ID3DXFont* font = 0;
D3DXCreateFontIndirect(Device, &lf, &font);
我们可以这样填充:
HDC hdc = CreateCompatibleDC(0);
HFONT hFont;
HFONT hFontOld;
LOGFONT lf;
ZeroMemory(&lf, sizeof(LOGFONT));
lf.lfHeight = 25; // in logical units
lf.lfWidth = 12; // in logical units
lf.lfEscapement = 0;
lf.lfOrientation = 0;
lf.lfWeight = 500; // boldness, range 0(light) - 1000(bold)
lf.lfItalic = false;
lf.lfUnderline = false;
lf.lfStrikeOut = false;
lf.lfCharSet = DEFAULT_CHARSET;
lf.lfOutPrecision = 0;
lf.lfClipPrecision = 0;
lf.lfQuality = 0;
lf.lfPitchAndFamily = 0;
strcpy_s(lf.lfFaceName, "Times New Roman"); // font style
hFont = CreateFontIndirect(&lf);
hFontOld = (HFONT)SelectObject(hdc, hFont);
第三步:D3DXCreateText函数调用
在D3D中,自带了一个函数:D3DXCreateText函数,就是用此函数来创建3D文本:D3DXCreateText函数参数如下:
HRESULT D3DXCreateText(
LPDIRECT3DDEVICE8 pDevice,//与网格相关的设备
HDC hDC, //一个环境句柄
LPCTSTR pText, //只想所要生成的文本字符串指针
FLOAT Deviation, //TureType字体轮廓的最大弦偏差。
FLOAT Extrusion, //Z、轴负方向度量的字体深度
LPD3DXMESH* ppMesh, //返回所创建的网格
LPD3DXMESH* ppAdjacency, //返回所创建的网格的邻接信息
LPGLYPHMETRICSFLOAT pGlyphMetrics
);
完整代码:
#include <windows.h> #include<d3d9.h> #include<string> #include<d3dx9.h> using namespace std; #define SCREEN_WIDTH 800 //窗口宽度 #define SCREEN_HEIGHT 600 //窗口高度 #define FVF_VERTEX (D3DFVF_XYZ | D3DFVF_TEX1) #define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } } //自定义一个SAFE_RELEASE()宏,便于资源的释放 IDirect3DDevice9* _device; //Direct3D设备 ID3DXMesh * Text = 0; //字体网格结构 //函数声明 //初始化Direct3D //消息过程,处理消息 bool InitD3D(HINSTANCE hInstance, int width, int height, bool windowed, D3DDEVTYPE deviceType, IDirect3DDevice9 ** device); LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); D3DMATERIAL9 InitMtrl(D3DXCOLOR a, D3DXCOLOR d, D3DXCOLOR s, D3DXCOLOR e, float p); D3DLIGHT9 InitDirectionalLight(D3DXVECTOR3* direction, D3DXCOLOR* color); const D3DXCOLOR BLACK(D3DCOLOR_XRGB(0, 0, 0)); const D3DXCOLOR WHITE(D3DCOLOR_XRGB(255, 255, 255)); D3DMATERIAL9 WHITE_MTRL = InitMtrl(WHITE, WHITE, WHITE, BLACK, 2.0f); //初始化材质: D3DMATERIAL9 InitMtrl(D3DXCOLOR a, D3DXCOLOR d, D3DXCOLOR s, D3DXCOLOR e, float p) { D3DMATERIAL9 mtrl; mtrl.Ambient = a; mtrl.Diffuse = d; mtrl.Specular = s; mtrl.Emissive = e; mtrl.Power = p; return mtrl; } //初始化直射光: D3DLIGHT9 InitDirectionalLight(D3DXVECTOR3* direction, D3DXCOLOR* color) { D3DLIGHT9 light; ::ZeroMemory(&light, sizeof(light)); light.Type = D3DLIGHT_DIRECTIONAL; light.Ambient = *color * 0.4f; light.Diffuse = *color; light.Specular = *color * 0.6f; light.Direction = *direction; return light; } //函数声明 //初始化Direct3D //消息过程,处理消息 bool InitD3D(HINSTANCE hInstance, int width, int height, bool windowed, D3DDEVTYPE deviceType, IDirect3DDevice9 ** device); LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); //以下为窗口过程 LRESULT CALLBACK 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); } //初始化D3D bool InitD3D(HINSTANCE hInstance, int width, int height, bool windowed, D3DDEVTYPE deviceType, IDirect3DDevice9 ** device) { //定义一个完整的窗口类 WNDCLASS wc; wc.style = CS_VREDRAW | CS_HREDRAW; wc.lpfnWndProc = 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.lpszClassName = "LSZDX"; wc.lpszMenuName = 0; //注册窗口类 if (!(RegisterClass(&wc))) { MessageBox(0, "RegisterClass is FAILED", 0, 0); return false; } //创建窗口 HWND hwnd = 0; hwnd = CreateWindow("LSZDX", "LSZDXDEMO", WS_OVERLAPPEDWINDOW, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0, hInstance, 0); if (hwnd == 0) { MessageBox(0, "CreateWIndow is FAILED", 0, 0); return false; } //绘制和更新窗口 ShowWindow(hwnd, SW_SHOW); UpdateWindow(hwnd); //以下为初始化D3D //*--------------- //获取IDirect3D9的指针 IDirect3D9 *d3d9 = 0; d3d9 = Direct3DCreate9((D3D_SDK_VERSION)); if (!d3d9) { MessageBox(0, "Direct3D9Create9 is 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; //填充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; //创建IDirect3DDevice9接口 if (FAILED(d3d9->CreateDevice( D3DADAPTER_DEFAULT, deviceType, hwnd, vp, &d3dpp, device))) { MessageBox(0, "CreateDevice is FAILED", 0, 0); return false; } d3d9->Release(); return true; } //初始化工作 bool Setup() { HDC hdc = CreateCompatibleDC(0); HFONT hFont; HFONT hFontOld; LOGFONT lf; ZeroMemory(&lf, sizeof(LOGFONT)); lf.lfHeight = 25; // in logical units lf.lfWidth = 12; // in logical units lf.lfEscapement = 0; lf.lfOrientation = 0; lf.lfWeight = 500; // boldness, range 0(light) - 1000(bold) lf.lfItalic = false; lf.lfUnderline = false; lf.lfStrikeOut = false; lf.lfCharSet = DEFAULT_CHARSET; lf.lfOutPrecision = 0; lf.lfClipPrecision = 0; lf.lfQuality = 0; lf.lfPitchAndFamily = 0; strcpy_s(lf.lfFaceName, "Times New Roman"); // font style hFont = CreateFontIndirect(&lf); hFontOld = (HFONT)SelectObject(hdc, hFont); D3DXCreateText(_device, hdc, "LSZDX", 0.001f, 0.4f, &Text, 0, 0); SelectObject(hdc, hFontOld); DeleteObject(hFont); DeleteDC(hdc); // // Lights. // D3DXVECTOR3 dir(0.0f, -0.5f, 1.0f); D3DXCOLOR col = WHITE; D3DLIGHT9 light = InitDirectionalLight(&dir, &col); _device->SetLight(0, &light); _device->LightEnable(0, true); _device->SetRenderState(D3DRS_NORMALIZENORMALS, true); _device->SetRenderState(D3DRS_SPECULARENABLE, true); // // Set camera. // D3DXVECTOR3 pos(0.0f, 1.5f, -3.3f); D3DXVECTOR3 target(0.0f, 0.0f, 0.0f); D3DXVECTOR3 up(0.0f, 1.0f, 0.0f); D3DXMATRIX V; D3DXMatrixLookAtLH( &V, &pos, &target, &up); _device->SetTransform(D3DTS_VIEW, &V); // // Set projection matrix. // D3DXMATRIX proj; D3DXMatrixPerspectiveFovLH( &proj, D3DX_PI * 0.25f, // 45 - degree (float)SCREEN_WIDTH / (float)SCREEN_HEIGHT, 0.01f, 1000.0f); _device->SetTransform(D3DTS_PROJECTION, &proj); return true; } //显示操作 bool DisPlay() { MSG msg; ::ZeroMemory(&msg, sizeof(MSG));//用0来填充消息可类比为:memset()函数 while (msg.message != WM_QUIT) { //PeekMessage函数是以查看的方式从系统中获取消息 //并将该消息(如果存在)放于指定的结构 if (::PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) { //PM_REMOVE:PeekMessage处理后,消息从队列里除掉。 //TranslateMessage函数将虚拟键消息转换为字符消息。 //字符消息被寄送到调用线程的消息队列里, //当下一次线程调用函数GetMessage或PeekMessage时被读出。 //TranslateMessage只能用于转换调用GetMessage或PeekMessage接收的消息。 ::TranslateMessage(&msg); //DispatchMessage函数 //该函数分发一个消息给窗口程序。 //通常消息从GetMessage函数获得。 //消息被分发到回调函数(过程函数),作用是消息传递给操作系统, //然后操作系统去调用我们的回调函数,也就是说我们在窗体的过程函数中处理消息 ::DispatchMessage(&msg); } else { if (_device) { D3DXMATRIX yRot, T; static float y = 0.0f; D3DXMatrixRotationY(&yRot, y); y += 0.001f; if (y >= 6.28f) y = 0.0f; D3DXMatrixTranslation(&T, -1.6f, 0.0f, 0.0f); T = T * yRot; _device->SetTransform(D3DTS_WORLD, &T); // // 绘制场景 // _device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0); _device->BeginScene(); _device->SetMaterial(&WHITE_MTRL); Text->DrawSubset(0); _device->EndScene(); _device->Present(0, 0, 0, 0); } } } return true; } // int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd) { if (!InitD3D(hInstance, SCREEN_WIDTH, SCREEN_HEIGHT, true, D3DDEVTYPE_HAL, &_device)) { MessageBox(0, "InitD3D is FAILED", 0, 0); return 0; } if (!Setup()) { MessageBox(0, "Setup() - FAILED", 0, 0); return 0; } DisPlay(); _device->Release(); return 0; }
运行结果:
相关文章推荐
- js+html5实现canvas绘制镂空字体文本的方法
- 图形的绘制,如何使用自定义画笔(颜色,线宽,线形)。如何为程序中添加选项菜单和选项设置对话框,如何使用标准颜色对话框,如何使用字体对话框,在选项对话框中实现预览功能。实现选项对话框和窗口类中的数据交换。如何改变对话框和控件的背景色,如何改变控件的文本颜色,
- js+html5实现canvas绘制镂空字体文本的方法
- 自己动手实现简易代码生成器、采用文本模板文件生成服务层、服务层接口代码的做法参考
- VC++ GDI+编程的字体和文本绘制
- 关于23D 采用EMI接口实现16位的LCD接口的一种方法
- VC++ GDI+编程的字体和文本绘制
- 精通DirectX 3D 字体与文本显示
- 3D API中,字体绘制的Batch优化
- 自己动手实现简易代码生成器、采用文本模板文件生成服务层、服务层接口代码的做法参考
- 用C#接口实现通用的文本数据序列化(ZT)
- 3D API中,字体绘制的Batch优化
- 用C#接口实现通用的文本数据序列化
- C++(MFC)中WebBrowser去除3D边框的方法(实现IDocHostUIHandler接口)
- IOS 根据 指定的 字体类型 ,size ,计算 绘制 文本 所需要的 宽度与高度
- Silverlight实现对图片的涂鸦、绘制矩形、圆形、直线、文本,并且能够移动
- WindowsSDK实现3D字体特效
- 3DGS脚本教程翻译(7)-字符串,文本和字体
- 如何实现3D效果(绘制长方体/立方体)
- 面试例题4:绘制5行文本,每一行的字体大小逐渐增加