Direct3D 9的介绍以及Demo演示

文章目录

  • 1、d3d9的介绍
      • 1. 概述
      • 2. 核心概念
      • 3. 初始化和渲染流程
      • 4. 常见用法
      • 5. 先进特性
      • 6. 总结
  • 2、d3d9demo详解
      • 1.头文件和全局变量
      • 2.IGW 相关全局变量
      • 3.函数:CloseIGW
      • 4.函数:OpenIGW
      • 5.UI 控件和日志处理
      • 6.登录和登出相关函数
      • 7.登录回调函数
      • 8.DXUT 相关回调函数
      • 9.日志和 UI 控件初始化
      • 10.程序入口点
      • 11.总结
  • 3、Direct3D 9 相关的部分,包括设备创建、重置、丢失和销毁的完整流程。
      • 1.Direct3D 9 设备创建和管理
        • 1. 初始化 Direct3D 和创建设备
      • 2. 渲染流程
      • 3.消息处理
      • 4. 主程序入口点

1、d3d9的介绍

Direct3D 9(简称 D3D9)是 Microsoft 提供的一种 API,用于在 Windows 操作系统上进行 3D 图形渲染。它是 DirectX 套件的一部分,被广泛应用于游戏开发和其他需要图形渲染的应用程序。以下是对 D3D9 的详细解释:

1. 概述

D3D9 提供了一组 API,允许开发者使用 C++ 编写高性能的 3D 应用程序。通过 D3D9,可以直接访问图形硬件(GPU),以实现复杂的图形效果和高效的渲染。

2. 核心概念

Direct3D 对象:

  • IDirect3D9D3D9 的核心对象,所有的 D3D9 操作都从这个对象开始。你可以使用 Direct3DCreate9 函数来创建这个对象。

设备对象:

  • IDirect3DDevice9 是渲染的核心,它代表了与图形硬件的一个连接。你可以通过 IDirect3D9::CreateDevice 函数来创建设备对象。

交换链:

  • 交换链(Swap Chain)负责管理渲染缓冲区(Back Buffer),并将其呈现到显示器上。IDirect3DSwapChain9 接口表示一个交换链。

顶点缓冲区和索引缓冲区:

  • 顶点缓冲区(Vertex Buffer)和索引缓冲区(Index Buffer)分别存储顶点数据和顶点索引数据,用于描述几何图形。

纹理:

  • 纹理(Texture)是应用于几何图形表面的图像。IDirect3DTexture9 接口表示一个 2D 纹理。

着色器:

  • 着色器(Shader)是用于在 GPU 上运行的小程序,可以控制顶点处理和像素处理。D3D9 支持 HLSL(高阶着色语言)。

3. 初始化和渲染流程

初始化 Direct3D

#include <d3d9.h>// 初始化 Direct3D 对象
LPDIRECT3D9 d3d = Direct3DCreate9(D3D_SDK_VERSION);if (d3d == NULL) {// 错误处理return;
}// 设置设备参数
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(d3dpp));
d3dpp.Windowed = TRUE; // 窗口模式
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; // 交换效果
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN; // 后备缓冲区格式// 创建 Direct3D 设备
LPDIRECT3DDEVICE9 d3ddev;
if (FAILED(d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3ddev))) {// 错误处理d3d->Release();return;
}
// 清空缓冲区
d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 40, 100), 1.0f, 0);// 开始渲染
d3ddev->BeginScene();// 渲染代码
// ...// 结束渲染
d3ddev->EndScene();// 显示渲染结果
d3ddev->Present(NULL, NULL, NULL, NULL);

释放资源:

d3ddev->Release();
d3d->Release();

4. 常见用法

渲染三角形:

struct CUSTOMVERTEX {FLOAT x, y, z;DWORD color;
};#define CUSTOMFVF (D3DFVF_XYZ | D3DFVF_DIFFUSE)// 创建顶点缓冲区
LPDIRECT3DVERTEXBUFFER9 v_buffer;
d3ddev->CreateVertexBuffer(3 * sizeof(CUSTOMVERTEX),0,CUSTOMFVF,D3DPOOL_MANAGED,&v_buffer,NULL);// 定义顶点数据
CUSTOMVERTEX vertices[] = {{ 0.0f, 1.0f, 0.0f, D3DCOLOR_XRGB(255, 0, 0) },{ 1.0f, -1.0f, 0.0f, D3DCOLOR_XRGB(0, 255, 0) },{ -1.0f, -1.0f, 0.0f, D3DCOLOR_XRGB(0, 0, 255) },
};// 填充顶点缓冲区
void* pVoid;
v_buffer->Lock(0, 0, (void**)&pVoid, 0);
memcpy(pVoid, vertices, sizeof(vertices));
v_buffer->Unlock();// 渲染顶点缓冲区
d3ddev->SetFVF(CUSTOMFVF);
d3ddev->SetStreamSource(0, v_buffer, 0, sizeof(CUSTOMVERTEX));
d3ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);

5. 先进特性

光照和材质:

  • D3D9 支持多种光照模型(如点光源、平行光源)和材质属性,可以实现逼真的光影效果。

着色器和效果:

  • 通过使用 HLSL 编写自定义的顶点着色器和像素着色器,可以实现复杂的图形效果。

多线程渲染:

  • D3D9 提供了一些多线程支持,允许在多个线程中执行图形命令,提高渲染效率。

6. 总结

  • DirectX SDK
  • Microsoft Docs - Direct3D 9

D3D9 是一个功能强大的图形 API,通过它,你可以创建各种复杂的 3D 图形效果和高性能的图形应用程序。希望这些详细的解释和代码示例能帮助你更好地理解和使用 D3D9。

2、d3d9demo详解

  • 以下是对这段代码的详细解释。这段代码主要实现了一个 Direct3D 9 的应用程序框架,使用 DXUT 框架来管理 Direct3D 设备和窗口。代码还集成了一个名为 IGW 的组件,用于登录和支付功能。

代码如下:

//--------------------------------------------------------------------------------------
// File: EmptyProject.cpp
//
// Empty starting point for new Direct3D applications
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//--------------------------------------------------------------------------------------
#include "dxstdafx.h"
#include "resource.h"
#include <xstring>#include "interface.h"#include "DXUTgui.h"
#include "Oleauto.h"
#include "comutil.h"
#include <time.h>
//#pragma comment(lib, "comsupp.lib")#include "SDOA4Client.h"
#include "SDOADx9.h"/* 接入相关全局变量  */
HINSTANCE          g_hInstIGWDll = 0;
LPigwInitialize    igwInitialize = NULL;
LPigwGetModule     igwGetModule = NULL;
LPigwTerminal      igwTerminal = NULL;ISDOADx9*			g_SDOADx9 = NULL;
ISDOAApp3*			g_SDOAApp = NULL;
ISDOLLogin4*		g_SDOLogin = NULL;
ISDOAAppUtils*		g_SDOAAppUtils = NULL;
ISDOAClientService* g_SDOAClientService = NULL;extern HMODULE LoadModuleEx(LPCWSTR lpszPath);/* 释放IGW */
void CloseIGW()
{if (g_SDOADx9){g_SDOADx9->Release();g_SDOADx9 = NULL;}if (g_SDOAApp){g_SDOAApp->Release();g_SDOAApp = NULL;}if (g_SDOAAppUtils){g_SDOAAppUtils->Release();g_SDOAAppUtils = NULL;}if (g_SDOAClientService){g_SDOAClientService->Release();g_SDOAClientService = NULL;}if(g_SDOLogin){g_SDOLogin->Release();g_SDOLogin = NULL;}if (igwTerminal){  // 释放DLL前总是先调用igwTerminaligwTerminal();igwTerminal = NULL;}if (g_hInstIGWDll){FreeLibrary(g_hInstIGWDll);g_hInstIGWDll = 0;}igwInitialize = NULL;
}/* 加载IGW */
void OpenIGW()
{WCHAR strExePath[MAX_PATH] = {0};WCHAR strExeName[MAX_PATH] = {0};WCHAR* strLastSlash = NULL;GetModuleFileNameW( NULL, strExePath, MAX_PATH );strExePath[MAX_PATH-1]=0;strLastSlash = wcsrchr( strExePath, TEXT('\\') );if( strLastSlash ){	// 得到EXE所在路径StringCchCopyW( strExeName, MAX_PATH, &strLastSlash[1] );*strLastSlash = 0;strLastSlash = wcsrchr( strExeName, TEXT('.') );if( strLastSlash )*strLastSlash = 0;}WCHAR strGameWidgetDll[MAX_PATH] = {0};
#ifdef _WIN64StringCchPrintfW( strGameWidgetDll, MAX_PATH, L"%s\\sdo\\sdologinentry64.dll", strExePath );
#elseStringCchPrintfW( strGameWidgetDll, MAX_PATH, L"%s\\sdo\\sdologinentry.dll", strExePath );
#endif
// 	if ( !(GetFileAttributesW(strGameWidgetDll) != 0xFFFFFFFF) ) {
// 		StringCchPrintfW( strGameWidgetDll, MAX_PATH, L"%s\\GameWidget.dll", strExePath );
// 	};
/*if ( !(GetFileAttributesW(strGameWidgetDll) != 0xFFFFFFFF) ){ // 如果程序运行路径中不存在则换个路径再试StringCchPrintfW( strGameWidgetDll, MAX_PATH, L"%s\\..\\..\\..\\..\\bin\\GameWidget.dll", strExePath );}if ( !(GetFileAttributesW(strGameWidgetDll) != 0xFFFFFFFF) ){ // 如果程序运行路径中不存在则换个路径再试StringCchPrintfW( strGameWidgetDll, MAX_PATH, L"E:\\Worke\\Ez\\IGP\\demo&prototype\\allsnap\\bin\\GameWidget.dll" );}
*/CloseIGW();if ( GetFileAttributesW(strGameWidgetDll) != 0xFFFFFFFF ){	// 找到组件则加载	g_hInstIGWDll = LoadModuleEx(strGameWidgetDll);if (g_hInstIGWDll){igwInitialize = (LPigwInitialize)GetProcAddress( g_hInstIGWDll, "igwInitialize" );igwGetModule = (LPigwGetModule)GetProcAddress( g_hInstIGWDll, "igwGetModule" );igwTerminal = (LPigwTerminal)GetProcAddress( g_hInstIGWDll, "igwTerminal" );if ( igwInitialize && igwGetModule && igwTerminal){// 加载成功// 调试方便,可从配置中读取int appId = 88;FILE* f = fopen("./appid.txt", "r");if (f != NULL) {char value[1024] = {0};if (fgets(value, 1024, f)) {appId = atoi(value);};fclose(f);};// 注意AppInfo类型所有字段必须填AppInfo tmpAppInfo = {sizeof(AppInfo),       // 结构体大小,方便扩展appId,                 // 接入应用ID,从开发者网站中申请L"龙潭虎穴OnLine",     // 应用名称L"0.1.2.0",            // 应用客户端当前版本号SDOA_RENDERTYPE_D3D9,  // 客户端支持的图形引擎类型,这里同时支持d3d9和d3d81,                     // 可同时在一台机器上游戏的最大人数(通常为1,例如:KOF应该是2)1,                    // 游戏区ID,不可用时传入-11                     // 游戏组ID,不可用时传入-1};if (igwInitialize(SDOA_SDK_VERSION, &tmpAppInfo) == SDOA_OK){	// 初始化组件成功// 获取组件接口					igwGetModule(__uuidof(ISDOADx9), (void**)&g_SDOADx9);igwGetModule(__uuidof(ISDOAApp3), (void**)&g_SDOAApp);igwGetModule(__uuidof(ISDOAAppUtils), (void**)&g_SDOAAppUtils);igwGetModule(__uuidof(ISDOAClientService), (void**)&g_SDOAClientService);					igwGetModule(__uuidof(ISDOLLogin4), (void**)&g_SDOLogin);if ( (!g_SDOADx9) || (!g_SDOAApp) || (!g_SDOAAppUtils) || (!g_SDOAClientService))CloseIGW();}else // 初始化失败清除环境CloseIGW();}else  // 加载DLL失败清除环境CloseIGW();}}}#define IDC_BUTTON_SHOWLOGINDIALOG 1
#define IDC_BUTTON_DOLOGIN 2
#define IDC_BUTTON_LOGOUT 3
#define IDC_BUTTON_CODEPAY 4
#define IDC_BUTTON_CODEPAY2 5#define IDC_STATIC_LOG 100#define LOG_LINE_COUNT 5
#define LOG_LINE_HEIGHT 20void Trace(LPCWSTR format, ...);BOOL onSDOLogin = false;
BOOL isSDOLogin = false; // 注意一定要是BOOL类型,不能为bool否则可能会导致问题
LoginResult loginResult;/* 显示SDOLogin登录窗口 */
void Logout()
{if (g_SDOLogin){int code = g_SDOLogin->Logout();Trace(L"ISDOLLoginEx::Logout result[%d]\n", code);}
}void DoLogin()
{if(g_SDOLogin){int code = g_SDOLogin->DoLogin();Trace(L"ISDOLLoginEx::DoLogin result[%d]\n", code);}
}void OpenWindow(LPCWSTR pwcsWinType, LPCWSTR pwcsWinName, LPCWSTR pwcsSrc, int nLeft, int nTop, int nWidth, int nHeight, LPCWSTR pwcsMode)
{if (g_SDOLogin){int code = g_SDOLogin->OpenWindow(pwcsWinType,pwcsWinName,pwcsSrc,nLeft,nTop,nWidth,nHeight,pwcsMode);Trace(L"ISDOLLoginEx::OpenWindow result[%d]\n", code);}
}/* 登录回调函数 */
int CALLBACK OnLogin(int nErrorCode, const SDOLLoginResult* pLoginResult, int nUserData, int nReserved) 
{ SDOLLoginResult loginResult;if (SDOL_ERRORCODE_OK == nErrorCode) { Trace(L"Login success. SessionId[%s] Sndaid[%s] IdentityState[%s] Appendix[%s]\n", pLoginResult->SessionId, pLoginResult->Sndaid, pLoginResult->IdentityState, pLoginResult->Appendix);loginResult = *pLoginResult; ShowWindow( DXUTGetHWND(), SW_SHOW );SetForegroundWindow(DXUTGetHWND());} else if (SDOL_ERRORCODE_LOGINCANCEL == nErrorCode){Logout();CloseIGW();ExitProcess(0);}return SDOL_LOGINRESULT_CLOSE; //关闭登录窗口
} BOOL CALLBACK OnLogin2(int nErrorCode, const LoginResult* pLoginResult, int nUserData, int nReserved) 
{ // 注意该回调返回true则关闭登录对话框,否则登录对话框仍然显示isSDOLogin = (SDOA_ERRORCODE_OK == nErrorCode); if (isSDOLogin) { loginResult = *pLoginResult;// 登录成功后,把用户使用的游戏角色信息传入IGWif (g_SDOAApp){RoleInfo tmpRoleInfo = { sizeof(RoleInfo), L"美貌仙子", 0 } ;g_SDOAApp->SetRoleInfo(&tmpRoleInfo);  // 设置角色信息,可多次调用,只要用户切换了角色就调用通知IGW}onSDOLogin = false;} if (SDOA_ERRORCODE_CANCEL == nErrorCode){onSDOLogin = false;//	ExitProcess(0);}if (SDOA_ERRORCODE_SHOWMESSAGE == nErrorCode){ // 登录错误消息处理if (nReserved != 0){LoginMessage* pCurLoginMsg = (LoginMessage*)nReserved;if (pCurLoginMsg->dwSize >= sizeof(LoginMessage)){ // 兼容性处理 // 修改错误提示对话框标题//SysReAllocString(pCurLoginMsg->pbstrTitle, L"[测试游戏错误提示]");// 此时返回FALSE则使用默认提示// 此时返回TRUE则使用自定义的提示//isSDOLogin = TRUE;//::MessageBox(0, *pCurLoginMsg->pbstrContent, *pCurLoginMsg->pbstrTitle, MB_OK);}}onSDOLogin = false;}return isSDOLogin; // 常规逻辑,登录成功则关闭登录对话框
} /* 显示SDOLogin登录窗口 */
void ShowLoginDialog()
{//if (g_SDOLogin)//{//	HWND hMainWin = DXUTGetHWND();//	::SendMessage(hMainWin, WM_ACTIVATEAPP, 0, 0);//	g_SDOLogin->SetOwnerWindow(hMainWin);//	g_SDOLogin->ShowLoginDialog(OnLogin, 0, 0);//}onSDOLogin = true;g_SDOAApp->ShowLoginDialog(OnLogin2, 0, 0);
}CDXUTDialogResourceManager	g_DialogResourceManager; // manager for shared resources of dialogs
CDXUTDialog					g_LoginDialog;      
CDXUTDialog					g_LogDialog;      //--------------------------------------------------------------------------------------
// Rejects any devices that aren't acceptable by returning false
//--------------------------------------------------------------------------------------
bool CALLBACK IsDeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat, bool bWindowed, void* pUserContext )
{// Typically want to skip backbuffer formats that don't support alpha blendingIDirect3D9* pD3D = DXUTGetD3DObject(); if( FAILED( pD3D->CheckDeviceFormat( pCaps->AdapterOrdinal, pCaps->DeviceType,AdapterFormat, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, BackBufferFormat ) ) )return false;return true;
}//--------------------------------------------------------------------------------------
// Before a device is created, modify the device settings as needed
//--------------------------------------------------------------------------------------
bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, const D3DCAPS9* pCaps, void* pUserContext )
{//	pDeviceSettings->pp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;return true;
}//--------------------------------------------------------------------------------------
// Create any D3DPOOL_MANAGED resources here 
//--------------------------------------------------------------------------------------
HRESULT CALLBACK OnCreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext )
{HRESULT hr;V_RETURN( g_DialogResourceManager.OnCreateDevice( pd3dDevice ) );if (g_SDOADx9){	// 初始化IGW内部图形引擎D3DPRESENT_PARAMETERS d3dpp = DXUTGetPresentParameters ();g_SDOADx9->Initialize( pd3dDevice, &d3dpp, FALSE );}return S_OK;
}//--------------------------------------------------------------------------------------
// Create any D3DPOOL_DEFAULT resources here 
//--------------------------------------------------------------------------------------
HRESULT CALLBACK OnResetDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext )
{HRESULT hr;V_RETURN( g_DialogResourceManager.OnResetDevice() );g_LoginDialog.SetLocation( 10, 10 );g_LoginDialog.SetSize( 180, 180 );RECT rect;GetClientRect(DXUTGetHWND(), &rect);g_LogDialog.SetLocation(0, rect.bottom - LOG_LINE_COUNT * LOG_LINE_HEIGHT);g_LogDialog.SetSize(rect.right, LOG_LINE_COUNT * LOG_LINE_HEIGHT);//g_LogDialog.SetBackgroundColors(D3DCOLOR_ARGB(255, 0, 0, 0));for(int i=0; i<LOG_LINE_COUNT; i++){CDXUTStatic* pStatic = g_LogDialog.GetStatic(IDC_STATIC_LOG + i);pStatic->SetLocation(0, LOG_LINE_HEIGHT * i);pStatic->SetSize(g_LogDialog.GetWidth(), LOG_LINE_HEIGHT);}if(g_SDOADx9){	// 通知IGW d3d设备重置成功D3DPRESENT_PARAMETERS d3dpp = DXUTGetPresentParameters () ;	g_SDOADx9->OnDeviceReset ( &d3dpp ) ;}return S_OK;
}//--------------------------------------------------------------------------------------
// Handle updates to the scene
//--------------------------------------------------------------------------------------
void CALLBACK OnFrameMove( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
{
}//--------------------------------------------------------------------------------------
// Render the scene 
//--------------------------------------------------------------------------------------
void CALLBACK OnFrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
{HRESULT hr;// Clear the render target and the zbuffer V( pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(0, 45, 50, 170), 1.0f, 0) );// Render the sceneif( SUCCEEDED( pd3dDevice->BeginScene() ) ){g_LoginDialog.OnRender( fElapsedTime );g_LogDialog.OnRender(fElapsedTime);/* 绘制IGW界面 */if (g_SDOADx9)g_SDOADx9->RenderEx();V( pd3dDevice->EndScene() );}
}//--------------------------------------------------------------------------------------
// Handle messages to the application 
//--------------------------------------------------------------------------------------
LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool* pbNoFurtherProcessing, void* pUserContext )
{if(g_SDOADx9) {	// 把消息交给IGW模块处理 LRESULT lResult; if (g_SDOADx9->OnWindowProc( hWnd, uMsg, wParam, lParam, &lResult ) == SDOA_OK ) { *pbNoFurtherProcessing = true;// 不让自身再处理消息 return lResult; } } if ( (UINT)SDOA_WM_CLIENT_RUN == uMsg ){// 此刻可以开始登录if (g_SDOAApp){onSDOLogin = true;g_SDOAApp->ShowLoginDialog(OnLogin2, 0, 0);SDOAWinProperty tmpWinPro;tmpWinPro.nLeft = 10;tmpWinPro.nTop = 10;if ( g_SDOAApp->GetWinProperty(L"igwUserLoginDialog", &tmpWinPro) == SDOA_OK){if ( g_SDOAApp->SetWinProperty(L"igwUserLoginDialog", &tmpWinPro) == SDOA_OK){tmpWinPro.nTop = 10;}else{tmpWinPro.nTop = 20;}}}}if (uMsg == WM_KEYDOWN && wParam == 'F') {DXUTToggleFullScreen();};if (uMsg == WM_TIMER) {};// Always allow dialog resource manager calls to handle global messages// so GUI state is updated correctly*pbNoFurtherProcessing = g_DialogResourceManager.MsgProc( hWnd, uMsg, wParam, lParam );if( *pbNoFurtherProcessing )return 0;*pbNoFurtherProcessing = g_LoginDialog.MsgProc( hWnd, uMsg, wParam, lParam );if( *pbNoFurtherProcessing )return 0;*pbNoFurtherProcessing = g_LogDialog.MsgProc( hWnd, uMsg, wParam, lParam );if( *pbNoFurtherProcessing )return 0;return 0;
}//--------------------------------------------------------------------------------------
// Release resources created in the OnResetDevice callback here 
//--------------------------------------------------------------------------------------
void CALLBACK OnLostDevice( void* pUserContext )
{g_DialogResourceManager.OnLostDevice();/* 通知IGW d3d设备丢失 */if(g_SDOADx9)g_SDOADx9->OnDeviceLost();
}//--------------------------------------------------------------------------------------
// Release resources created in the OnCreateDevice callback here
//--------------------------------------------------------------------------------------
void CALLBACK OnDestroyDevice( void* pUserContext )
{g_DialogResourceManager.OnDestroyDevice();/* 释放IGW图形引擎 */if (g_SDOADx9)g_SDOADx9->Finalize();
}int g_LogIndex = 0;void Trace(LPCWSTR format, ...)
{if(g_LogIndex >= LOG_LINE_COUNT){for(int i=0;i<LOG_LINE_COUNT - 1;i++){CDXUTStatic* pStatic = g_LogDialog.GetStatic(IDC_STATIC_LOG + i);CDXUTStatic* pStatic1 = g_LogDialog.GetStatic(IDC_STATIC_LOG + i + 1);pStatic->SetText(pStatic1->GetText());}g_LogIndex = LOG_LINE_COUNT - 1;}CDXUTStatic* pStatic = g_LogDialog.GetStatic(IDC_STATIC_LOG + g_LogIndex++);if(pStatic){WCHAR buffer[1024] = {0};va_list args;va_start(args, format);::_vsnwprintf(buffer, _countof(buffer) - 1, format, args);va_end(args);pStatic->SetText(buffer);}
}void CALLBACK OnGUIEvent( UINT nEvent, int nControlID, CDXUTControl* pControl, void* pUserContext )
{switch( nControlID ){case IDC_BUTTON_SHOWLOGINDIALOG:Logout();ShowLoginDialog();break;case IDC_BUTTON_DOLOGIN:DoLogin();break;case IDC_BUTTON_LOGOUT:Logout();break;case IDC_BUTTON_CODEPAY:OpenWindow(L"",L"Pay",L"http://cas.sdo.com/cas/login?service=http://qrcode.sdo.com/qrcode/index?appId=$gid$",0,0,444,490,L"center|showmodal");			// width+10,height+45break;case IDC_BUTTON_CODEPAY2:OpenWindow(L"", L"扫码支付", L"http://cas.sdo.com/cas/login?gateway=true&service=http%3a%2f%2fqrcode.sdo.com%2fqrcode%2findex%3fappId%3d$gid$%26areaId%3d$gaid$", 0, 0, 449, 460, L"center");			// width+10,height+45break;}
}//--------------------------------------------------------------------------------------
// Initialize the app 
//--------------------------------------------------------------------------------------
void InitApp()
{g_LoginDialog.Init( &g_DialogResourceManager );g_LoginDialog.SetCallback( OnGUIEvent );g_LogDialog.Init( &g_DialogResourceManager );g_LogDialog.SetCallback( OnGUIEvent );int iY = 10;g_LoginDialog.AddButton(IDC_BUTTON_SHOWLOGINDIALOG, L"显示登陆框", 10, iY, 80, 26);g_LoginDialog.AddButton(IDC_BUTTON_DOLOGIN, L"登录", 10, iY += 30, 80, 26);g_LoginDialog.AddButton(IDC_BUTTON_LOGOUT, L"注销", 10, iY += 30, 80, 26);g_LoginDialog.AddButton(IDC_BUTTON_CODEPAY, L"扫码支付", 10, iY += 30, 80, 26);g_LoginDialog.AddButton(IDC_BUTTON_CODEPAY2, L"扫码支付(包含区ID)", 10, iY += 30, 80, 26);for(int i=0; i<LOG_LINE_COUNT; i++){g_LogDialog.AddStatic(IDC_STATIC_LOG + i, L"", 0, 0, 0, 0);}
}INT WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int )
{// Enable run-time memory check for debug builds.
#if defined(DEBUG) | defined(_DEBUG)_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
#endif/* 加载IGW */OpenIGW();// Set the callback functionsDXUTSetCallbackDeviceCreated( OnCreateDevice );DXUTSetCallbackDeviceReset( OnResetDevice );DXUTSetCallbackDeviceLost( OnLostDevice );DXUTSetCallbackDeviceDestroyed( OnDestroyDevice );DXUTSetCallbackMsgProc( MsgProc );DXUTSetCallbackFrameRender( OnFrameRender );DXUTSetCallbackFrameMove( OnFrameMove );// TODO: Perform any application-level initialization hereInitApp();// Initialize DXUT and create the desired Win32 window and Direct3D device for the applicationDXUTInit( true, true, true ); // Parse the command line, handle the default hotkeys, and show msgboxesDXUTSetCursorSettings( true, true ); // Show the cursor and clip it when in full screenDXUTCreateWindow( L"EmptyProject" );DXUTCreateDevice( D3DADAPTER_DEFAULT, true, 1024, 768, IsDeviceAcceptable, ModifyDeviceSettings );HWND hMainWin = DXUTGetHWND();SetTimer(hMainWin, 1, 500, 0);if (igwInitialize){	// 说明加载成功,表示下......SetWindowTextW(hMainWin, L"EmptyProject [加载IGW组件成功]");}		// Start the render loopDXUTMainLoop();// TODO: Perform any application-level cleanup hereif (isSDOLogin && g_SDOAApp){ // 登录成功,退出时要登出g_SDOAApp->Logout();}/* 释放IGW */CloseIGW();return DXUTGetExitCode();
}
  • 这段代码是一个使用 Direct3D 9DXUT 框架的简单演示程序,包含了与 IGW(一个游戏组件接口)的集成。代码展示了一个完整的 Direct3D 应用程序从初始化到渲染的过程。下面将详细解释代码中的各个部分。

1.头文件和全局变量

#include "dxstdafx.h"
#include "resource.h"
#include <xstring>#include "interface.h"#include "DXUTgui.h"
#include "Oleauto.h"
#include "comutil.h"
#include <time.h>
//#pragma comment(lib, "comsupp.lib")#include "SDOA4Client.h"
#include "SDOADx9.h"

这些头文件引入了必要的库和声明,例如 DXUT 框架、OLE 自动化、COM 实用程序等。

2.IGW 相关全局变量

HINSTANCE          g_hInstIGWDll = 0;
LPigwInitialize    igwInitialize = NULL;
LPigwGetModule     igwGetModule = NULL;
LPigwTerminal      igwTerminal = NULL;ISDOADx9*          g_SDOADx9 = NULL;
ISDOAApp3*         g_SDOAApp = NULL;
ISDOLLogin4*       g_SDOLogin = NULL;
ISDOAAppUtils*     g_SDOAAppUtils = NULL;
ISDOAClientService* g_SDOAClientService = NULL;

这些全局变量用于保存 IGW 的接口指针和 DLL 模块句柄。

3.函数:CloseIGW

void CloseIGW()
{if (g_SDOADx9) {g_SDOADx9->Release();g_SDOADx9 = NULL;}if (g_SDOAApp) {g_SDOAApp->Release();g_SDOAApp = NULL;}if (g_SDOAAppUtils) {g_SDOAAppUtils->Release();g_SDOAAppUtils = NULL;}if (g_SDOAClientService) {g_SDOAClientService->Release();g_SDOAClientService = NULL;}if (g_SDOLogin) {g_SDOLogin->Release();g_SDOLogin = NULL;}if (igwTerminal) {igwTerminal();igwTerminal = NULL;}if (g_hInstIGWDll) {FreeLibrary(g_hInstIGWDll);g_hInstIGWDll = 0;}igwInitialize = NULL;
}

这个函数用于释放所有 IGW 相关的资源和接口。

4.函数:OpenIGW

void OpenIGW()
{// 获取当前程序路径WCHAR strExePath[MAX_PATH] = {0};WCHAR strExeName[MAX_PATH] = {0};WCHAR* strLastSlash = NULL;GetModuleFileNameW(NULL, strExePath, MAX_PATH);strExePath[MAX_PATH-1] = 0;strLastSlash = wcsrchr(strExePath, TEXT('\\'));if (strLastSlash) {StringCchCopyW(strExeName, MAX_PATH, &strLastSlash[1]);*strLastSlash = 0;strLastSlash = wcsrchr(strExeName, TEXT('.'));if (strLastSlash)*strLastSlash = 0;}WCHAR strGameWidgetDll[MAX_PATH] = {0};
#ifdef _WIN64StringCchPrintfW(strGameWidgetDll, MAX_PATH, L"%s\\sdo\\sdologinentry64.dll", strExePath);
#elseStringCchPrintfW(strGameWidgetDll, MAX_PATH, L"%s\\sdo\\sdologinentry.dll", strExePath);
#endifCloseIGW();if (GetFileAttributesW(strGameWidgetDll) != 0xFFFFFFFF) {g_hInstIGWDll = LoadModuleEx(strGameWidgetDll);if (g_hInstIGWDll) {igwInitialize = (LPigwInitialize)GetProcAddress(g_hInstIGWDll, "igwInitialize");igwGetModule = (LPigwGetModule)GetProcAddress(g_hInstIGWDll, "igwGetModule");igwTerminal = (LPigwTerminal)GetProcAddress(g_hInstIGWDll, "igwTerminal");if (igwInitialize && igwGetModule && igwTerminal) {int appId = 88;FILE* f = fopen("./appid.txt", "r");if (f != NULL) {char value[1024] = {0};if (fgets(value, 1024, f)) {appId = atoi(value);};fclose(f);};AppInfo tmpAppInfo = {sizeof(AppInfo),appId,L"龙潭虎穴OnLine",L"0.1.2.0",SDOA_RENDERTYPE_D3D9,1,1,1};if (igwInitialize(SDOA_SDK_VERSION, &tmpAppInfo) == SDOA_OK) {igwGetModule(__uuidof(ISDOADx9), (void**)&g_SDOADx9);igwGetModule(__uuidof(ISDOAApp3), (void**)&g_SDOAApp);igwGetModule(__uuidof(ISDOAAppUtils), (void**)&g_SDOAAppUtils);igwGetModule(__uuidof(ISDOAClientService), (void**)&g_SDOAClientService);igwGetModule(__uuidof(ISDOLLogin4), (void**)&g_SDOLogin);if ((!g_SDOADx9) || (!g_SDOAApp) || (!g_SDOAAppUtils) || (!g_SDOAClientService))CloseIGW();} else {CloseIGW();}} else {CloseIGW();}}}
}

这个函数用于加载 IGW 组件 DLL,并初始化必要的接口。

5.UI 控件和日志处理

#define IDC_BUTTON_SHOWLOGINDIALOG 1
#define IDC_BUTTON_DOLOGIN 2
#define IDC_BUTTON_LOGOUT 3
#define IDC_BUTTON_CODEPAY 4
#define IDC_BUTTON_CODEPAY2 5#define IDC_STATIC_LOG 100#define LOG_LINE_COUNT 5
#define LOG_LINE_HEIGHT 20void Trace(LPCWSTR format, ...);

定义了一些 UI 控件的 ID 和日志的相关参数。

6.登录和登出相关函数

void Logout()
{if (g_SDOLogin) {int code = g_SDOLogin->Logout();Trace(L"ISDOLLoginEx::Logout result[%d]\n", code);}
}void DoLogin()
{if (g_SDOLogin) {int code = g_SDOLogin->DoLogin();Trace(L"ISDOLLoginEx::DoLogin result[%d]\n", code);}
}void ShowLoginDialog()
{onSDOLogin = true;g_SDOAApp->ShowLoginDialog(OnLogin2, 0, 0);
}

这些函数用于处理登录和登出的操作,以及显示登录对话框。

7.登录回调函数

int CALLBACK OnLogin(int nErrorCode, const SDOLLoginResult* pLoginResult, int nUserData, int nReserved)
{SDOLLoginResult loginResult;if (SDOL_ERRORCODE_OK == nErrorCode) {Trace(L"Login success. SessionId[%s] Sndaid[%s] IdentityState[%s] Appendix[%s]\n", pLoginResult->SessionId, pLoginResult->Sndaid, pLoginResult->IdentityState, pLoginResult->Appendix);loginResult = *pLoginResult;ShowWindow(DXUTGetHWND(), SW_SHOW);SetForegroundWindow(DXUTGetHWND());} else if (SDOL_ERRORCODE_LOGINCANCEL == nErrorCode) {Logout();CloseIGW();ExitProcess(0);}return SDOL_LOGINRESULT_CLOSE; // 关闭登录窗口
}BOOL CALLBACK OnLogin2(int nErrorCode, const LoginResult* pLoginResult, int nUserData, int nReserved)
{isSDOLogin = (SDOA_ERRORCODE_OK == nErrorCode);if (isSDOLogin) {loginResult = *pLoginResult;if (g_SDOAApp) {RoleInfo tmpRoleInfo = { sizeof(RoleInfo), L"美貌仙子", 0 };g_SDOAApp->SetRoleInfo(&tmpRoleInfo);}onSDOLogin = false;}if (SDOA_ERRORCODE_CANCEL == nErrorCode) {onSDOLogin = false;}if (SDOA_ERRORCODE_SHOWMESSAGE == nErrorCode) {if (nReserved != 0) {LoginMessage* pCurLoginMsg = (LoginMessage*)nReserved;if (pCurLoginMsg->dwSize >= sizeof(LoginMessage)) {// 错误消息处理}}onSDOLogin = false;}return isSDOLogin; // 登录成功则关闭对话框
}

这些函数是登录操作的回调函数,用于处理登录成功或失败的情况。

8.DXUT 相关回调函数

bool CALLBACK IsDeviceAcceptable(D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat, bool bWindowed, void* pUserContext)
{IDirect3D9* pD3D = DXUTGetD3DObject(); if (FAILED(pD3D->CheckDeviceFormat(pCaps->AdapterOrdinal, pCaps->DeviceType,AdapterFormat, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, BackBufferFormat)))return false;return true;
}bool CALLBACK ModifyDeviceSettings(DXUTDeviceSettings* pDeviceSettings, const D3DCAPS9* pCaps, void* pUserContext)
{return true;
}HRESULT CALLBACK OnCreateDevice(IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext)
{HRESULT hr;V_RETURN(g_DialogResourceManager.OnCreateDevice(pd3dDevice));if (g_SDOADx9) {D3DPRESENT_PARAMETERS d3dpp = DXUTGetPresentParameters();g_SDOADx9->Initialize(pd3dDevice, &d3dpp, FALSE);}return S_OK;
}HRESULT CALLBACK OnResetDevice(IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext)
{HRESULT hr;V_RETURN(g_DialogResourceManager.OnResetDevice());g_LoginDialog.SetLocation(10, 10);g_LoginDialog.SetSize(180, 180);RECT rect;GetClientRect(DXUTGetHWND(), &rect);g_LogDialog.SetLocation(0, rect.bottom - LOG_LINE_COUNT * LOG_LINE_HEIGHT);g_LogDialog.SetSize(rect.right, LOG_LINE_COUNT * LOG_LINE_HEIGHT);for (int i = 0; i < LOG_LINE_COUNT; i++) {CDXUTStatic* pStatic = g_LogDialog.GetStatic(IDC_STATIC_LOG + i);pStatic->SetLocation(0, LOG_LINE_HEIGHT * i);pStatic->SetSize(g_LogDialog.GetWidth(), LOG_LINE_HEIGHT);}if (g_SDOADx9) {D3DPRESENT_PARAMETERS d3dpp = DXUTGetPresentParameters();g_SDOADx9->OnDeviceReset(&d3dpp);}return S_OK;
}void CALLBACK OnFrameMove(IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext)
{
}void CALLBACK OnFrameRender(IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext)
{HRESULT hr;V(pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(0, 45, 50, 170), 1.0f, 0));if (SUCCEEDED(pd3dDevice->BeginScene())) {g_LoginDialog.OnRender(fElapsedTime);g_LogDialog.OnRender(fElapsedTime);if (g_SDOADx9)g_SDOADx9->RenderEx();V(pd3dDevice->EndScene());}
}LRESULT CALLBACK MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool* pbNoFurtherProcessing, void* pUserContext)
{if (g_SDOADx9) {LRESULT lResult;if (g_SDOADx9->OnWindowProc(hWnd, uMsg, wParam, lParam, &lResult) == SDOA_OK) {*pbNoFurtherProcessing = true;return lResult;}}if ((UINT)SDOA_WM_CLIENT_RUN == uMsg) {if (g_SDOAApp) {onSDOLogin = true;g_SDOAApp->ShowLoginDialog(OnLogin2, 0, 0);SDOAWinProperty tmpWinPro;tmpWinPro.nLeft = 10;tmpWinPro.nTop = 10;if (g_SDOAApp->GetWinProperty(L"igwUserLoginDialog", &tmpWinPro) == SDOA_OK) {if (g_SDOAApp->SetWinProperty(L"igwUserLoginDialog", &tmpWinPro) == SDOA_OK) {tmpWinPro.nTop = 10;} else {tmpWinPro.nTop = 20;}}}}if (uMsg == WM_KEYDOWN && wParam == 'F') {DXUTToggleFullScreen();}if (uMsg == WM_TIMER) {}*pbNoFurtherProcessing = g_DialogResourceManager.MsgProc(hWnd, uMsg, wParam, lParam);if (*pbNoFurtherProcessing)return 0;*pbNoFurtherProcessing = g_LoginDialog.MsgProc(hWnd, uMsg, wParam, lParam);if (*pbNoFurtherProcessing)return 0;*pbNoFurtherProcessing = g_LogDialog.MsgProc(hWnd, uMsg, wParam, lParam);if (*pbNoFurtherProcessing)return 0;return 0;
}void CALLBACK OnLostDevice(void* pUserContext)
{g_DialogResourceManager.OnLostDevice();if (g_SDOADx9)g_SDOADx9->OnDeviceLost();
}void CALLBACK OnDestroyDevice(void* pUserContext)
{g_DialogResourceManager.OnDestroyDevice();if (g_SDOADx9)g_SDOADx9->Finalize();
}

这些函数是 DXUT 框架的回调函数,用于处理设备的创建、重置、丢失和销毁等事件,以及渲染和消息处理。

9.日志和 UI 控件初始化

void Trace(LPCWSTR format, ...)
{if (g_LogIndex >= LOG_LINE_COUNT) {for (int i = 0; i < LOG_LINE_COUNT - 1; i++) {CDXUTStatic* pStatic = g_LogDialog.GetStatic(IDC_STATIC_LOG + i);CDXUTStatic* pStatic1 = g_LogDialog.GetStatic(IDC_STATIC_LOG + i + 1);pStatic->SetText(pStatic1->GetText());}g_LogIndex = LOG_LINE_COUNT - 1;}CDXUTStatic* pStatic = g_LogDialog.GetStatic(IDC_STATIC_LOG + g_LogIndex++);if (pStatic) {WCHAR buffer[1024] = {0};va_list args;va_start(args, format);::_vsnwprintf(buffer, _countof(buffer) - 1, format, args);va_end(args);pStatic->SetText(buffer);}
}void CALLBACK OnGUIEvent(UINT nEvent, int nControlID, CDXUTControl* pControl, void* pUserContext)
{switch (nControlID) {case IDC_BUTTON_SHOWLOGINDIALOG:Logout();ShowLoginDialog();break;case IDC_BUTTON_DOLOGIN:DoLogin();break;case IDC_BUTTON_LOGOUT:Logout();break;case IDC_BUTTON_CODEPAY:OpenWindow(L"", L"Pay", L"http://cas.sdo.com/cas/login?service=http://qrcode.sdo.com/qrcode/index?appId=$gid$", 0, 0, 444, 490, L"center|showmodal");break;case IDC_BUTTON_CODEPAY2:OpenWindow(L"", L"扫码支付", L"http://cas.sdo.com/cas/login?gateway=true&service=http%3a%2f%2fqrcode.sdo.com%2fqrcode%2findex%3fappId%3d$gid$%26areaId%3d$gaid$", 0, 0, 449, 460, L"center");break;}
}void InitApp()
{g_LoginDialog.Init(&g_DialogResourceManager);g_LoginDialog.SetCallback(OnGUIEvent);g_LogDialog.Init(&g_DialogResourceManager);g_LogDialog.SetCallback(OnGUIEvent);int iY = 10;g_LoginDialog.AddButton(IDC_BUTTON_SHOWLOGINDIALOG, L"显示登陆框", 10, iY, 80, 26);g_LoginDialog.AddButton(IDC_BUTTON_DOLOGIN, L"登录", 10, iY += 30, 80, 26);g_LoginDialog.AddButton(IDC_BUTTON_LOGOUT, L"注销", 10, iY += 30, 80, 26);g_LoginDialog.AddButton(IDC_BUTTON_CODEPAY, L"扫码支付", 10, iY += 30, 80, 26);g_LoginDialog.AddButton(IDC_BUTTON_CODEPAY2, L"扫码支付(包含区ID)", 10, iY += 30, 80, 26);for (int i = 0; i < LOG_LINE_COUNT; i++) {g_LogDialog.AddStatic(IDC_STATIC_LOG + i, L"", 0, 0, 0, 0);}
}

这些函数用于初始化 UI 控件和处理 GUI 事件。

10.程序入口点

INT WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
#if defined(DEBUG) | defined(_DEBUG)_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
#endifOpenIGW();DXUTSetCallbackDeviceCreated(OnCreateDevice);DXUTSetCallbackDeviceReset(OnResetDevice);DXUTSetCallbackDeviceLost(OnLostDevice);DXUTSetCallbackDeviceDestroyed(OnDestroyDevice);DXUTSetCallbackMsgProc(MsgProc);DXUTSetCallbackFrameRender(OnFrameRender);DXUTSetCallbackFrameMove(OnFrameMove);InitApp();DXUTInit(true, true, true);DXUTSetCursorSettings(true, true);DXUTCreateWindow(L"EmptyProject");DXUTCreateDevice(D3DADAPTER_DEFAULT, true, 1024, 768, IsDeviceAcceptable, ModifyDeviceSettings);HWND hMainWin = DXUTGetHWND();SetTimer(hMainWin, 1, 500, 0);if (igwInitialize) {SetWindowTextW(hMainWin, L"EmptyProject [加载IGW组件成功]");}DXUTMainLoop();if (isSDOLogin && g_SDOAApp) {g_SDOAApp->Logout();}CloseIGW();return DXUTGetExitCode();
}

这是程序的入口点,初始化 DXUT 和 IGW,并进入渲染循环。

11.总结

这段代码展示了一个完整的 Direct3D 9 和 IGW 集成的应用程序框架,包括设备管理、消息处理、UI 控件和登录操作的完整流程。

3、Direct3D 9 相关的部分,包括设备创建、重置、丢失和销毁的完整流程。

1.Direct3D 9 设备创建和管理

Direct3D 应用程序中,设备(Device)是一个核心对象,负责与 GPU 进行交互和渲染操作。下面是 D3D9 设备创建和管理的详细流程。

1. 初始化 Direct3D 和创建设备

设备创建的回调函数:

  • 在 WinMain 函数中,设置了设备创建的回调函数:
DXUTSetCallbackDeviceCreated(OnCreateDevice);
DXUTSetCallbackDeviceReset(OnResetDevice);
DXUTSetCallbackDeviceLost(OnLostDevice);
DXUTSetCallbackDeviceDestroyed(OnDestroyDevice);
  • 这些回调函数会在设备创建、重置、丢失和销毁时被调用。

设备是否可接受的回调函数:

bool CALLBACK IsDeviceAcceptable(D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat, bool bWindowed, void* pUserContext)
{// Typically want to skip backbuffer formats that don't support alpha blendingIDirect3D9* pD3D = DXUTGetD3DObject(); if (FAILED(pD3D->CheckDeviceFormat(pCaps->AdapterOrdinal, pCaps->DeviceType,AdapterFormat, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, BackBufferFormat)))return false;return true;
}
  • 这个函数用于判断设备是否可接受。通常会检查后备缓冲区(BackBuffer)的格式是否支持 Alpha 混合。

修改设备设置的回调函数:

bool CALLBACK ModifyDeviceSettings(DXUTDeviceSettings* pDeviceSettings, const D3DCAPS9* pCaps, void* pUserContext)
{// 可在此处修改设备设置,例如禁用垂直同步// pDeviceSettings->pp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;return true;
}
  • 这个函数在设备创建之前被调用,可以在此修改设备设置,例如禁用垂直同步等。

设备创建和重置的回调函数:

HRESULT CALLBACK OnCreateDevice(IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext)
{HRESULT hr;V_RETURN(g_DialogResourceManager.OnCreateDevice(pd3dDevice));if (g_SDOADx9) {D3DPRESENT_PARAMETERS d3dpp = DXUTGetPresentParameters();g_SDOADx9->Initialize(pd3dDevice, &d3dpp, FALSE);}return S_OK;
}
  • 这个函数在设备创建时被调用。这里主要做了以下工作:
    • 调用 g_DialogResourceManager.OnCreateDevice 来初始化对话框资源管理器。
    • 如果 g_SDOADx9 非空,则初始化 IGW 内部的图形引擎。

设备创建和重置的回调函数:

HRESULT CALLBACK OnResetDevice(IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext)
{HRESULT hr;V_RETURN(g_DialogResourceManager.OnResetDevice());g_LoginDialog.SetLocation(10, 10);g_LoginDialog.SetSize(180, 180);RECT rect;GetClientRect(DXUTGetHWND(), &rect);g_LogDialog.SetLocation(0, rect.bottom - LOG_LINE_COUNT * LOG_LINE_HEIGHT);g_LogDialog.SetSize(rect.right, LOG_LINE_COUNT * LOG_LINE_HEIGHT);for (int i = 0; i < LOG_LINE_COUNT; i++) {CDXUTStatic* pStatic = g_LogDialog.GetStatic(IDC_STATIC_LOG + i);pStatic->SetLocation(0, LOG_LINE_HEIGHT * i);pStatic->SetSize(g_LogDialog.GetWidth(), LOG_LINE_HEIGHT);}if (g_SDOADx9) {D3DPRESENT_PARAMETERS d3dpp = DXUTGetPresentParameters();g_SDOADx9->OnDeviceReset(&d3dpp);}return S_OK;
}
  • 这个函数在设备重置时被调用。主要做了以下工作:
    • 调用 g_DialogResourceManager.OnResetDevice 来重置对话框资源管理器。
    • 0 设置登录对话框和日志对话框的位置和大小。
    • 如果 g_SDOADx9 非空,则通知 IGW 图形引擎设备已重置。

处理设备丢失回调函数:

void CALLBACK OnLostDevice(void* pUserContext)
{g_DialogResourceManager.OnLostDevice();if (g_SDOADx9)g_SDOADx9->OnDeviceLost();
}
  • 这个函数在设备丢失时被调用。主要做了以下工作:
    • 调用 g_DialogResourceManager.OnLostDevice 来处理对话框资源管理器中的设备丢失。
    • 如果 g_SDOADx9 非空,则通知 IGW 图形引擎设备已丢失。

释放设备资源回调函数:

void CALLBACK OnDestroyDevice(void* pUserContext)
{g_DialogResourceManager.OnDestroyDevice();if (g_SDOADx9)g_SDOADx9->Finalize();
}
  • 这个函数在设备销毁时被调用。主要做了以下工作:
    • 调用 g_DialogResourceManager.OnDestroyDevice 来释放对话框资源管理器中的资源。
    • 如果 g_SDOADx9 非空,则调用 g_SDOADx9->Finalize 来释放 IGW 图形引擎的资源。

2. 渲染流程

帧移动更新回调函数:

void CALLBACK OnFrameMove(IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext)
{// 可在此处更新场景逻辑
}
  • 这个函数在每帧移动时被调用,可用于更新场景逻辑。

渲染场景的回调函数帧渲染:

void CALLBACK OnFrameRender(IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext)
{HRESULT hr;V(pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(0, 45, 50, 170), 1.0f, 0));if (SUCCEEDED(pd3dDevice->BeginScene())) {g_LoginDialog.OnRender(fElapsedTime);g_LogDialog.OnRender(fElapsedTime);if (g_SDOADx9)g_SDOADx9->RenderEx();V(pd3dDevice->EndScene());}
}
  • 这个函数在每帧渲染时被调用。主要做了以下工作:
    • 清除渲染目标和 Z 缓冲区。
    • 开始渲染场景。
    • 渲染登录对话框和日志对话框。
    • 如果 g_SDOADx9 非空,则调用 g_SDOADx9->RenderEx 渲染 IGW 图形界面。
    • 结束渲染场景。

3.消息处理

LRESULT CALLBACK MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool* pbNoFurtherProcessing, void* pUserContext)
{if (g_SDOADx9) {LRESULT lResult;if (g_SDOADx9->OnWindowProc(hWnd, uMsg, wParam, lParam, &lResult) == SDOA_OK) {*pbNoFurtherProcessing = true;return lResult;}}if ((UINT)SDOA_WM_CLIENT_RUN == uMsg) {if (g_SDOAApp) {onSDOLogin = true;g_SDOAApp->ShowLoginDialog(OnLogin2, 0, 0);SDOAWinProperty tmpWinPro;tmpWinPro.nLeft = 10;tmpWinPro.nTop = 10;if (g_SDOAApp->GetWinProperty(L"igwUserLoginDialog", &tmpWinPro) == SDOA_OK) {if (g_SDOAApp->SetWinProperty(L"igwUserLoginDialog", &tmpWinPro) == SDOA_OK) {tmpWinPro.nTop = 10;} else {tmpWinPro.nTop = 20;}}}}if (uMsg == WM_KEYDOWN && wParam == 'F') {DXUTToggleFullScreen();}if (uMsg == WM_TIMER) {}*pbNoFurtherProcessing = g_DialogResourceManager.MsgProc(hWnd, uMsg, wParam, lParam);if (*pbNoFurtherProcessing)return 0;*pbNoFurtherProcessing = g_LoginDialog.MsgProc(hWnd, uMsg, wParam, lParam);if (*pbNoFurtherProcessing)return 0;*pbNoFurtherProcessing = g_LogDialog.MsgProc(hWnd, uMsg, wParam, lParam);if (*pbNoFurtherProcessing)return 0;return 0;
}
  • 这个函数用于处理窗口消息。主要做了以下工作:
    • 如果 g_SDOADx9 非空,则将消息传递给 IGW 模块处理。
    • 处理自定义的 SDOA_WM_CLIENT_RUN 消息,显示登录对话框。
    • 处理按键事件(例如切换全屏)。
    • 让对话框资源管理器和各个对话框处理消息。

4. 主程序入口点

INT WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
#if defined(DEBUG) | defined(_DEBUG)_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
#endifOpenIGW();DXUTSetCallbackDeviceCreated(OnCreateDevice);DXUTSetCallbackDeviceReset(OnResetDevice);DXUTSetCallbackDeviceLost(OnLostDevice);DXUTSetCallbackDeviceDestroyed(OnDestroyDevice);DXUTSetCallbackMsgProc(MsgProc);DXUTSetCallbackFrameRender(OnFrameRender);DXUTSetCallbackFrameMove(OnFrameMove);InitApp();DXUTInit(true, true, true);DXUTSetCursorSettings(true, true);DXUTCreateWindow(L"EmptyProject");DXUTCreateDevice(D3DADAPTER_DEFAULT, true, 1024, 768, IsDeviceAcceptable, ModifyDeviceSettings);HWND hMainWin = DXUTGetHWND();SetTimer(hMainWin, 1, 500, 0);if (igwInitialize) {SetWindowTextW(hMainWin, L"EmptyProject [加载IGW组件成功]");}DXUTMainLoop();if (isSDOLogin && g_SDOAApp) {g_SDOAApp->Logout();}CloseIGW();return DXUTGetExitCode();
}
  • 这个函数是程序的入口点。主要做了以下工作:
    • 初始化内存调试标志(在调试模式下)。
    • 调用 OpenIGW 加载 IGW 组件。
    • 设置 DXUT 的各种回调函数。
    • 初始化应用程序的 UI 控件。
    • 初始化 DXUT 并创建窗口和 Direct3D 设备。
    • 设置定时器。
    • 如果 IGW 初始化成功,设置窗口标题。
    • 进入 DXUT 的主循环。
    • 如果登录成功,退出时登出。
    • 释放 IGW 组件。
  • 通过这些步骤,程序完成了 Direct3D 设备的创建、管理和渲染流程,以及与 IGW 组件的集成。

这段代码展示了如何使用 Direct3D 9 和 DXUT 框架来创建一个基本的图形应用程序,并集成了一个名为 IGW 的组件进行登录和支付操作。它涵盖了设备管理、窗口消息处理、资源创建和释放等方面的内容。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/49442.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

P3-AI产品经理-九五小庞

AI产品的数据流向 美团外卖&#xff0c;实时只能调度 美团28分钟送达需求的分析 AI产品常用的算法 常用算法 常见的AI算法解析 自然语言生成NLG语音识别&#xff1a;科大讯飞&#xff0c;通义千问 虚拟现实机器学习平台 决策管理系统生物特征识别技术 RPA(机器人流程自动…

探索 GPT-4o Mini:开发者的新利器

文章目录 探索 GPT-4o Mini&#xff1a;开发者的新利器1. 引言2. GPT-4o Mini 的核心特点3. 使用 GPT-4o Mini 的实际案例3.1 客户支持自动化3.2 内容生成与创作3.3 代码生成与优化 4. 使用体验分享5. 未来展望6. 结论 探索 GPT-4o Mini&#xff1a;开发者的新利器 OpenAI 最新…

UE4-光照重建

当我们拉入新的光源和模型到我们的场景中后&#xff0c;会产生这样的情况&#xff1a; Preview:预览 表示此时由于光照物体所产生的阴影都是预览级别的并不是真正的效果。 方法一&#xff1a; 或者也可以在世界大纲中选中我们的光源&#xff0c;然后将我们的光源改变为可以…

JAVA基本概念(垃圾回收、API)- 10

一、垃圾分代回收机制 1. 垃圾回收针对的是堆内存 2. 对象在堆内存中存储,对象在使用完成之后会在不定的某个时刻被垃圾回收器(GC - Garbage Collector)解析 掉。现阶段回收过程无法手动控制。当调用构造方法的时候,创建好一个对象,因为Java中对每种数据类型都明确 给…

Jdk22新特性

JDK 22 引入了多项新特性,旨在提升 Java 语言的性能、简化开发过程以及增强代码的可读性和可维护性。以下是对 JDK 22 新特性的详细归纳: 核心Java库 外部函数和内存 API (JEP 454):提供了一个纯 Java 应用程序接口,用于替代 JNI(Java Native Interface),以支持直接调…

前端切片下载

要在Vue3前端实现文件切片下载&#xff0c;可以参考以下步骤&#xff1a; 分片函数&#xff1a;将文件分成多个小片段。 生成Blob对象&#xff1a;将片段转换为Blob对象。 创建下载链接&#xff1a;通过Blob对象创建下载链接。 合并下载的片段&#xff1a;下载完成后&#x…

判断字符串,数组方法

判断字符串方法 在JavaScript中&#xff0c;可以使用typeof操作符来判断一个变量是否为字符串。 function isString(value) {return typeof value string; } 判断数组 在JavaScript中&#xff0c;typeof操作符并不足以准确判断一个变量是否为数组&#xff0c;因为typeof会…

深入理解Python中的Pandas库

目录 Pandas简介安装PandasPandas的核心数据结构 SeriesDataFrame 数据加载与存储 从CSV文件读取数据从Excel文件读取数据从SQL数据库读取数据数据存储 数据操作 数据选择数据过滤数据排序数据分组与聚合数据透视表 数据清洗与处理 处理缺失值数据转换数据合并 数据可视化实战…

KingBase 下的 sys_hba.conf 详解

客户端访问KingbaseES数据库,需要建立身份的认证,sys_hba.conf相当于认证的黑白名单,可以通过配置sys_hba.conf允许或拒绝客户端对数据库服务器的访问。 sys_hba.conf原理: 客户端认证是由一个配置文件(通常名为sys_hba.conf并被存放在数据库集簇目录中)控制(HBA表示基…

《昇思25天学习打卡营第25天|第27天》

今天是学习的第二十七天&#xff0c;今天学习的是应用实践篇中计算机视觉中ShuffleNet图像分类。 从对ShuffleNet网络介绍开始学习&#xff0c;模型架构&#xff08;Pointwise Group Convolution&#xff0c;Channel Shuffle&#xff0c;ShuffleNet模块&#xff0c;构建Shuffl…

knowLedge-工具函数返回kb数值转换为KB,MB,GB等单位保留两位小数

1.场景 实现一个工具函数&#xff0c;将后端返回的单位为KB&#xff08;但实际上是kb&#xff0c;即千字节&#xff0c;注意大小写通常表示不同&#xff0c;这里我们按照常见需求处理为KB&#xff09;的数字转换成KB、MB、GB等形式&#xff0c;你可以按照以下步骤进行。这个函数…

【Mybatis整合Oracle】在 xml 文件中 WITH 子句的简单使用

在 Oracle SQL 中&#xff0c;WITH 子句用于定义一个或多个公共表表达式&#xff08;CTE, Common Table Expression&#xff09;&#xff0c;然后可以在主查询中引用这些表达式。WITH 子句通常用于简化复杂查询的结构&#xff0c;增强可读性&#xff0c;并避免重复编写相同的子…

# Redis 入门到精通(九)-- 主从复制(1)

Redis 入门到精通&#xff08;九&#xff09;-- 主从复制&#xff08;1&#xff09; 一、redis 主从复制 – 主从复制简介 1、互联网“三高”架构 高并发高性能高可用 2、你的“Redis”是否高可用&#xff1f; 1&#xff09;单机 redis 的风险与问题 问题1.机器故障  现…

C++ 鼠标轨迹API【神诺科技SDK】

一.鼠标轨迹模拟简介 传统的鼠标轨迹模拟依赖于简单的数学模型&#xff0c;如直线或曲线路径。然而&#xff0c;这种方法难以捕捉到人类操作的复杂性和多样性。AI大模型的出现&#xff0c;使得神诺科技 能够通过深度学习技术&#xff0c;学习并模拟更自然的鼠标移动行为。 二.…

java之对称字符串以及如何优化(链式编程)

import java.util.Scanner;public class ScannerDemo12 {public static void main(String[] args) {Scanner sc new Scanner(System.in);System.out.println("请输入一个字符串");String str sc.next();//链式编程StringBuilder sbnew StringBuilder();sb.append(s…

国内大陆地区huggingface连接不上的解决方案

简介 本文主要介绍国内大陆地区huggingface连接不上的解决方案,希望能对学习大模型的同学们有所帮助。 1. 背景 最近有不少同学反应无法正常下载huggingface的模型文件,亲自尝试使用git clone下载huggingface上的大模型文件时,也同样无法正常下载,以Meta-Llama-3-8B为例…

全国区块链职业技能大赛第九套区块链产品需求分析与方案设计

任务1-1:区块链产品需求分析与方案设计 房屋租赁平台中涉及到租客、房东、区块链租房平台、房屋等参与方,他们需要在区块链租房平台中完成账户注册、身份上链、出租房屋、生成合同等多种业务活动。通过对业务活动的功能分析,可以更好的服务系统的开发流程。基于房屋租赁平台…

数据结构之判断完全二叉树详解与示例(C,C++)

文章目录 一、判断完全二叉树的思路二、C语言实现三、C语言实现四、总结 完全二叉树是一种特殊的二叉树&#xff0c;它满足以下两个条件&#xff1a; 每一层&#xff08;除了最后一层&#xff09;都被严格地填充了节点。 最后一层的节点都尽可能地靠左对齐。 本文将详细介绍如…

undefined reference to rpl_malloc

编译 psmisc 时遇到这个错误&#xff0c;搜索了一下 rpl_malloc&#xff0c; grep -irwn rpl_malloc config.status:877:D["malloc"]" rpl_malloc" Binary file src/killall.o matches autom4te.cache/traces.1:979:m4trace:configure.ac:205: -1- AH_OUT…

微服务(网关路由)

目录 一&#xff1a;网关路由 1&#xff1a;认识网关 2&#xff1a;快速入门 2.1&#xff1a;创建项目 2.2&#xff1a;引入依赖 2.3&#xff1a;启动类 2.4&#xff1a;路由配置 2.5&#xff1a;测试 3&#xff1a;路由过滤 二&#xff1a;网关登录校验 1&…