【Directx3D游戏开发】——Directx3D初始化


在了解如何初始化Directx3D之前应该首先懂得如何编写一个windows程序,创建一个windwos程序分为4步:1.设计一个窗口类;2.注册一个窗口类;3.创建窗口;4.显示及更新窗口。

            以下是创建一个最简单的windows窗口的示例,参考自孙鑫的VC++深入详解.

//-------------------------------------------------------------
//-------------by coderLing
//-------------------------------------------------------------

#include <Windows.h>
#include <tchar.h>
#include <iostream>

using namespace std;

//窗口回调函数
LRESULT CALLBACK WinSunProc(
	HWND hwnd,
    UINT uMsg,
	WPARAM wParam,
	LPARAM lParam
);

int WINAPI WinMain(
	HINSTANCE hInstance,
	HINSTANCE hPrevInstance,
	LPSTR lpCmdLine,
	int nCmdShow
)
{
	//设计一个窗口类

	WNDCLASSEX wndcls;
	wndcls.cbSize = sizeof(WNDCLASSEX);
	wndcls.style = CS_HREDRAW | CS_VREDRAW;
	wndcls.lpfnWndProc = WinSunProc;

	wndcls.cbClsExtra = 0;
	wndcls.cbWndExtra = 0;

	wndcls.hInstance = hInstance;
	wndcls.hIcon = LoadIcon(NULL,IDI_ERROR);
	wndcls.hCursor = LoadCursor(NULL,IDC_CROSS);

	wndcls.hbrBackground = 
		                static_cast<HBRUSH>(GetStockObject(BLACK_BRUSH));
	
	
	
	
	wndcls.lpszClassName = L"CoderLing";
	wndcls.lpszMenuName = NULL;
	wndcls.hIconSm = 0;
	
	RegisterClassEx(&wndcls);


	//创建窗口,定义窗口句柄
	HWND hwnd;
	hwnd = CreateWindow(L"CoderLing",
		                L"coderling.com",
						 WS_OVERLAPPEDWINDOW,
						 0,
						 0,
						 600,
						 400,
						 NULL,NULL,hInstance,NULL);


	//显示及刷新窗口
	ShowWindow(hwnd,SW_SHOWNORMAL);
	UpdateWindow(hwnd);

	//定义消息结构体,开始消息循环
	MSG msg;
	while(GetMessage(&msg,NULL,0,0)){
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	return static_cast<int>(msg.wParam);
}


//窗口过程函数
LRESULT CALLBACK WinSunProc(
	HWND hwnd,
	UINT uMsg,
	WPARAM wParam,
	LPARAM lParam
	){
		switch(uMsg){
		case WM_DESTROY:
			PostQuitMessage(0);
			break;
		}

	return 0;
}


//

windows程序基于事件消息驱动,上面代码只对WM_DESTROY消息进行了响应,唔。。。这并不是现在的重点,对于这个过程不了解的话,可以去找一本windows程序设计的书看一看,或者留下你的邮箱。重点是WinMain()函数里的消息循环,一般来说对于windows程序是在WIN_PAINT消息触发了才会发生窗口的重绘,但对于一个fps游戏来说我们希望他在没有消息时也应该自动重绘,所以要对这个消息循环进行修改,如下:

	MSG msg;
		SecureZeroMemory( &msg,sizeof( MSG ) );
		while( msg.message != WM_QUIT )
		{
			if( PeekMessage( &msg,NULL,0U,0U,PM_REMOVE ) )
			{
				TranslateMessage( &msg );
				DispatchMessage( &msg );
			}
			else
			{
				Render();
			}
		}

上面的当窗口没接收到WM_QUIT之前,也就是退出程序之前产生的相应消息进行处理。我们把GetMessage()换成了PeekMessage(),他们的主要区别在于,PeekMessage()函数无论是否接收到消息都会马上返回,这一点对于fps游戏能及时重绘画面十分重要。PeekMessage()接受到消息后就处理消息,当没消息是就重绘整个屏幕,Render() 1s内进行的次数就是FPS了。


   好了,现在才是主题,知道了怎去创建一个windows窗口,现在的任务就是在这个基础之上去初始化Directx3D.这里也分为3个要点:1.创建Directx3D对象;2.配置D3DPRESENT_PARAMETERS结构;3.获取Directx3D设备;4.编写渲染函数。

          1.第一步很简单,我们通过调用Direct3DCreate9( D3D_SDK_VERSION )

IDirect3D9* d3d9;
d3d9 = Direct3DCreate9(D3D_SDK_VESION);

D3D_SDK_VERSION 是此函数的唯一正确参数。

          2.填写D3DPRESENT_PARAMETERS结构,用于获取Directx3D设备。这个结构属性比较多,在这里者填写几个就可以了。

 

D3DPRESENT_PARAMETERS d3dpp;
	SecureZeroMemory(&d3dpp,sizeof(d3dpp));
	d3dpp.Windowed = TRUE; //
	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; //
	d3dpp.BackBufferFormat = D3DFMT_UNKNOWN; //

          3.获取Directx3D设备,通过

HRSULT IDirectx3D::CreateDevice(
                                UNIT Adapter,                                    //用来创建IDirect3D9设备对象的显卡适配器
                                D3DDEVICETYPE DeviceType,                        //设置设备类型,如D3DDEVTYPE_HAL或D3DDEVTYPE_REF
                                HWND hFocusWindow,                               //创建的设备对象所绘制的窗口。
                                DWORD BehaviorFlags,                             //顶点处理方式,如D3DCREATE_HARDWARE_VERTEXPROCESSING
				                                                 //或者D3DCREATE_SOFTWARE_VERTEXPROCESSING
                                D3DPRESENT_PARAMETERS *pPresentationparameters,  //填写一个初始化过的D3DPRESENT_PARAMETERS结构
                                IDirect3DDevice9** ppReturnedDeviceIntface       //返回所创建的设备对象。
                                )

           4.最后是编写渲染函数,在这里我们只是把客户区的背景颜色变为蓝色。

VOID Render()
{
	if(NULL == g_pd3dDevice)
		return ;

	//Clear the backbuffer to a blue color.
	g_pd3dDevice->Clear(0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(0,0,255),1.0f,0);
	//Begin the scene
	if(SUCCEEDED( g_pd3dDevice->BeginScene() ))
	{
		//在此渲染场景里面的对象
		g_pd3dDevice->EndScene();
	}

	//Present the backbuffer contents to the display
	g_pd3dDevice->Present(NULL,NULL,NULL,NULL);
}

至此一个最简单的Directx3D程序就创建完毕了,完整代码如下:

/*---------配置初始化Directx3d---------*/
/*---------by coderLing-----------------/
#include <d3d9.h>

#define WND_NAME L"D3D"
#define WND_TITLE L"First Direct3DApp"

LPDIRECT3D9 g_pD3D = NULL; //use to create the D3DDevcie
LPDIRECT3DDEVICE9 g_pd3dDevice = NULL;  //our rendering device


/*---------初始化Direct3d----------*/
HRESULT InitD3D(HWND hWnd)
{
	//Create the D3D object,which is neededto create the D3DDevice.
	g_pD3D = Direct3DCreate9(D3D_SDK_VERSION);
	if(NULL == g_pD3D)
		return E_FAIL;

	//Set up the structure D3DPRESENT_PARAMETERS
	D3DPRESENT_PARAMETERS d3dpp;
	SecureZeroMemory(&d3dpp,sizeof(d3dpp));
	d3dpp.Windowed = TRUE; //
	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; //
	d3dpp.BackBufferFormat = D3DFMT_UNKNOWN; //

	//Create the direct3D device.
	if( FAILED( g_pD3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,hWnd,
		                 D3DCREATE_SOFTWARE_VERTEXPROCESSING,
						 &d3dpp,&g_pd3dDevice) ) )
	{
		return E_FAIL;
	}

	return S_OK;
}

/*------释放所有Direct3d资源------*/
VOID Cleanup()
{
	if(NULL != g_pd3dDevice)
		g_pd3dDevice->Release();
	
	if(NULL != g_pD3D)
		g_pD3D->Release();
}

/*------绘制窗口---------*/
VOID Render()
{
	if(NULL == g_pd3dDevice)
		return ;

	//Clear the backbuffer to a blue color.
	g_pd3dDevice->Clear(0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(0,0,255),1.0f,0);
	//Begin the scene
	if(SUCCEEDED( g_pd3dDevice->BeginScene() ))
	{
		//在此渲染场景里面的对象
		g_pd3dDevice->EndScene();
	}

	//Present the backbuffer contents to the display
	g_pd3dDevice->Present(NULL,NULL,NULL,NULL);
}

/*--------消息处理函数------------*/
LRESULT WINAPI MsgProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
    switch( msg )
    {
        case WM_DESTROY:
            Cleanup();
            PostQuitMessage( 0 );
            return 0;

        case WM_PAINT:
            Render();
            ValidateRect( hWnd, NULL );
            return 0;
    }

    return DefWindowProc( hWnd, msg, wParam, lParam );
}

/*---------主函数----------*/
INT WINAPI WinMain(HINSTANCE hInst,HINSTANCE,LPSTR,int)
{
	//Register the window class
	WNDCLASSEX wc = { sizeof(WNDCLASSEX),CS_CLASSDC,MsgProc,0L,0L,
	                  GetModuleHandle(NULL),NULL,NULL,NULL,NULL,
	                  WND_NAME,NULL};
	RegisterClassEx( &wc );

	//Create the application window
	HWND hWnd = CreateWindow( WND_NAME,WND_TITLE,WS_OVERLAPPEDWINDOW,100,100,300,300,
		                      GetDesktopWindow(),NULL,wc.hInstance,NULL );

	if( SUCCEEDED( InitD3D( hWnd ) ) )
	{
		ShowWindow( hWnd,SW_SHOWDEFAULT );
		UpdateWindow( hWnd );

		MSG msg;
		SecureZeroMemory( &msg,sizeof( MSG ) );
		while( msg.message != WM_QUIT )
		{
			if( PeekMessage( &msg,NULL,0U,0U,PM_REMOVE ) )
			{
				TranslateMessage( &msg );
				DispatchMessage( &msg );
			}
			else
			{
				Render();
			}
		}
	}

	UnregisterClass( WND_NAME,wc.hInstance );
}



Step by Step~~~~~~~~~~

### RT-DETRv3 网络结构分析 RT-DETRv3 是一种基于 Transformer 的实时端到端目标检测算法,其核心在于通过引入分层密集正监督方法以及一系列创新性的训练策略,解决了传统 DETR 模型收敛慢和解码器训练不足的问题。以下是 RT-DETRv3 的主要网络结构特点: #### 1. **基于 CNN 的辅助分支** 为了增强编码器的特征表示能力,RT-DETRv3 引入了一个基于卷积神经网络 (CNN) 的辅助分支[^3]。这一分支提供了密集的监督信号,能够与原始解码器协同工作,从而提升整体性能。 ```python class AuxiliaryBranch(nn.Module): def __init__(self, in_channels, out_channels): super(AuxiliaryBranch, self).__init__() self.conv = nn.Conv2d(in_channels, out_channels, kernel_size=3, padding=1) self.bn = nn.BatchNorm2d(out_channels) def forward(self, x): return F.relu(self.bn(self.conv(x))) ``` 此部分的设计灵感来源于传统的 CNN 架构,例如 YOLO 系列中的 CSPNet 和 PAN 结构[^2],这些技术被用来优化特征提取效率并减少计算开销。 --- #### 2. **自注意力扰动学习策略** 为解决解码器训练不足的问题,RT-DETRv3 提出了一种名为 *self-att 扰动* 的新学习策略。这种策略通过对多个查询组中阳性样本的标签分配进行多样化处理,有效增加了阳例的数量,进而提高了模型的学习能力和泛化性能。 具体实现方式是在训练过程中动态调整注意力权重分布,确保更多的高质量查询可以与真实标注 (Ground Truth) 进行匹配。 --- #### 3. **共享权重解编码器分支** 除了上述改进外,RT-DETRv3 还引入了一个共享权重的解编码器分支,专门用于提供密集的正向监督信号。这一设计不仅简化了模型架构,还显著降低了参数量和推理时间,使其更适合实时应用需求。 ```python class SharedDecoderEncoder(nn.Module): def __init__(self, d_model, nhead, num_layers): super(SharedDecoderEncoder, self).__init__() decoder_layer = nn.TransformerDecoderLayer(d_model=d_model, nhead=nhead) self.decoder = nn.TransformerDecoder(decoder_layer, num_layers=num_layers) def forward(self, tgt, memory): return self.decoder(tgt=tgt, memory=memory) ``` 通过这种方式,RT-DETRv3 实现了高效的目标检测流程,在保持高精度的同时大幅缩短了推理延迟。 --- #### 4. **与其他模型的关系** 值得一提的是,RT-DETRv3 并未完全抛弃经典的 CNN 技术,而是将其与 Transformer 结合起来形成混合架构[^4]。例如,它采用了 YOLO 系列中的 RepNCSP 模块替代冗余的多尺度自注意力层,从而减少了不必要的计算负担。 此外,RT-DETRv3 还借鉴了 DETR 的一对一匹配策略,并在此基础上进行了优化,进一步提升了小目标检测的能力。 --- ### 总结 综上所述,RT-DETRv3 的网络结构主要包括以下几个关键组件:基于 CNN 的辅助分支、自注意力扰动学习策略、共享权重解编码器分支以及混合编码器设计。这些技术创新共同推动了实时目标检测领域的发展,使其在复杂场景下的表现更加出色。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值