DirectX Graphics
								中有专门的文字显示接口ID3DXFont, 和GDI中的HFONT的创建类似, 显示文字的函数也和GDI中相同. 使用以下两个函数来创建字体,
						
						
								HRESULT D3DXCreateFont(LPDIRECT3DDEVICE9 pDevice,
						
						
								
										                       INT Height,               
						
						
								
										                       UINT Width,               
						
						
								
										                       UINT Weight,              
						
						
								
										                       UINT MipLevels,           
						
						
								
										                       BOOL Italic,              
						
						
								
										                       DWORD CharSet,            
						
						
								
										                       DWORD OutputPrecision,    
						
						
								
										                       DWORD Quality,            
						
						
								
										                       DWORD PitchAndFamily,     
						
						
								
										                       LPCTSTR pFacename,        
						
						
								
										                       LPD3DXFONT * ppFont);     
						
						
								
										 
								
						
						
								HRESULT D3DXCreateFontIndirect(LPDIRECT3DDEVICE9 pDevice,  
						
						
								
										                               CONST D3DXFONT_DESC * pDesc,
						
						
								
										                               LPD3DXFONT * ppFont);       
						
						
								实际上, ID3DXFont的创建和显示字体还是依赖于GDI的FONT的创建和显示字体的函数的, 所以ID3DXFont显示字体并非是由DirectX Graphics中的Direct3D来完成的, 如果想提高性能, 建议少量的字体显示用9.3.1的方式, 大量的字体显示可事先转换成bitmap.
						
						
								
										 
								
						
						
								
										 
								
						
						
								
										9.4 Pick
								
								
										的例子
								
								
										
												
												
										
								
						
						
								
										 
								
						
						
								9.4.1 game9 project
								代码更新
								
										
										
								
						
						
								
										 
								
						
						
								
										    game9 
								中只是演示了
								Picking, ID3DXLINE
								和文字显示.
						
						
								---------------------------------------------------------------
						
						
								// 
								全局变量, 用来保存4个测试球的半径, 原始圆心位置, 变动圆心位置
						
						
								// 
								最后两个向量是Picking Ray的端点和方向
								
										
										
								
						
						
								FLOAT       g_fRad[4];
						
						
								D3DXVECTOR3 g_vCenter[4];
						
						
								D3DXVECTOR3 g_vTest[4];
						
						
								D3DXVECTOR3 g_pos;
						
						
								D3DXVECTOR3 g_n;
						
						
								
										 
								
						
						
								// game9.cpp, LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
						
						
								// 
								加入对WM_MOUSEHOVER的消息探测, 大概1秒钟的鼠标停顿产生WM_MOUSEHOVER
						
						
								// 
								注意使用WM_MOUSEHOVER 必须定义 #define _WIN32_WINNT  0x0500(0x400以上)
						
						
								
										    
										case WM_MOUSEMOVE:
						
						
								
										        {
						
						
								
										             TRACKMOUSEEVENT tme = { 0 };
						
						
								
										             tme.cbSize = sizeof(TRACKMOUSEEVENT);
						
						
								
										             tme.dwFlags = TME_LEAVE | TME_HOVER;
						
						
								
										             tme.hwndTrack = hWnd;
						
						
								
										             tme.dwHoverTime = 0x0400; 
						
						
								
										             TrackMouseEvent(&tme);
						
						
								
										             
										if (g_bHover)
						
						
								
										             {
						
						
								
										                  g_bHover = FALSE;
						
						
								
										                  g_pGame->EndPick();
						
						
								
										             }
						
						
								
										        }
						
						
								
										        
										break;
						
						
								
										    
										case WM_MOUSEHOVER :
						
						
								
										        {    
						
						
								
										             
										if (g_bHover == FALSE)
						
						
								
										             {
						
						
								
										                  g_bHover = g_pGame->Picking((DWORD)lParam);
						
						
								
										             }
						
						
								
										        }
						
						
								
										        
										break;
						
						
								
										 
								
						
						
								// direct9.cpp, 
								保存Picking Ray的端点和方向, 以为当4个模型自动旋转时有自动Pick的功能
								
										
										
								
						
						
								BOOL CD9Game::Picking(DWORD dwPt)
						
						
								{
						
						
								
										    LONG x = XLPARAM(dwPt);
						
						
								
										    LONG y = YLPARAM(dwPt);
						
						
								
										 
								
						
						
								
										    FLOAT Rx = 0.0;
						
						
								
										    FLOAT Ry = 0.0;
						
						
								
										    FLOAT mx = 0.0;
						
						
								
										    FLOAT my = 0.0;
						
						
								
										 
								
						
						
								
										    D3DVIEWPORT9 mv;
						
						
								
										    D3DXMATRIX   mProj;
						
						
								
										    D3DXMATRIX   mView;
						
						
								
										    m_pD3DDev->GetViewport(&mv);
						
						
								
										    m_pD3DDev->GetTransform(D3DTS_PROJECTION, &mProj);
						
						
								
										    m_pD3DDev->GetTransform(D3DTS_VIEW, &mView);
						
						
								
										    D3DXMatrixInverse(&mView, NULL, &mView);
						
						
								
										 
								
						
						
								
										    mx = mProj(0, 0);
						
						
								
										    my = mProj(1, 1);
						
						
								
										    Rx = (FLOAT)((x * 2.0) - mv.Width) / (mv.Width * mx);
						
						
								
										    Ry = (FLOAT)(mv.Height - (y * 2.0)) / (mv.Height * my);
						
						
								
										 
								
						
						
								
										    g_pos.x = 0.0;
						
						
								
										    g_pos.y = 0.0;
						
						
								
										    g_pos.z = 0.0;
						
						
								
										    g_n.x   = Rx;
						
						
								
										    g_n.y   = Ry;
						
						
								
										    g_n.z   = 1.0;
						
						
								
										    D3DXVec3TransformCoord(&g_pos, &g_pos, &mView);
						
						
								
										    D3DXVec3TransformNormal(&g_n, &g_n, &mView);
						
						
								
										    D3DXVec3Normalize(&g_n, &g_n);
						
						
								
										 
								
						
						
								
										    
										return WhoAmI();
						
						
								}
						
						
								// direct9.cpp, 
								确定当前选中的物体
								
										
										
								
						
						
								BOOL CD9Game::WhoAmI()
						
						
								{
						
						
								
										    BOOL bPick = FALSE;
						
						
								
										    D3DXVECTOR3 v;
						
						
								
										    FLOAT b, c;
						
						
								
										    INT i = 0;
						
						
								
										    
										for (; i < 4; i++)
						
						
								
										    {
						
						
								
										        v = g_pos - g_vTest[i];
						
						
								
										        b = FLOAT(2.0 * D3DXVec3Dot(&g_n, &v));
						
						
								
										        c = D3DXVec3Dot(&v, &v) - g_fRad[i] * g_fRad[i];
						
						
								
										 
								
						
						
								
										        FLOAT del = b * b - 4 * c;
						
						
								
										        
										if (del > 0.0)
						
						
								
										        {
						
						
								
										             del = sqrtf(del);
						
						
								
										             FLOAT x1 = (FLOAT)(( del - b) / 2.0);
						
						
								
										             FLOAT x2 = (FLOAT)((-del - b) / 2.0);
						
						
								
										             
										if ((x1 >= 0.0) || (x2 >= 0.0))
						
						
								
										             {
						
						
								
										                  bPick = TRUE;
						
						
								
										                  
										break;
						
						
								
										             }
						
						
								
										        }
						
						
								
										    }
						
						
								
										    lstrcpyn(g_szPick, g_szObj[i], 512);
						
						
								
										    
										return bPick;
						
						
								}
						
						
								
										 
								
						
						
								// direct9.cpp, 
								渲染物体, 如果自动旋转时有自动Pick
						
						
								VOID CD9Game::Render()
						
						
								{
						
						
								
										    
										if (m_dwRot >= MAXROT)
						
						
								
										    {
						
						
								
										        m_dwRot = 1L;
						
						
								
										    }
						
						
								
										    
										else
										if (m_bRot)
						
						
								
										    {
						
						
								
										        m_dwRot++;
						
						
								
										    }
						
						
								
										    D3DXMATRIX mWorld, mWorldX, mWorldY, mWorldZ;
						
						
								
										    FLOAT rat = m_dwRot * ROT;
						
						
								
										    D3DXMatrixRotationX(&mWorldX, rat);
						
						
								
										    D3DXMatrixRotationY(&mWorldY, rat); 
						
						
								
										    D3DXMatrixRotationZ(&mWorldZ, rat); 
						
						
								
										 
								
						
						
								
										    D3DXMatrixMultiply(&mWorld, &mWorldX, &mWorldY);
						
						
								
										    D3DXMatrixMultiply(&mWorld, &mWorld, &mWorldZ);
						
						
								
										 
								
						
						
								
										    D3DXMATRIX m1, m2, m3, m4;
						
						
								
										    D3DXMatrixMultiply(&m1, &g_m1, &mWorld);
						
						
								
										    D3DXMatrixMultiply(&m2, &g_m2, &mWorld);
						
						
								
										    D3DXMatrixMultiply(&m3, &g_m3, &mWorld);
						
						
								
										    D3DXMatrixMultiply(&m4, &g_m4, &mWorld);
						
						
								
										    
										if (m_bRot)
						
						
								
										    {    // 
								如果自动旋转时有自动Pick
								
										
										
								
						
						
								
										        D3DXVec3TransformCoord(&g_vTest[0], &g_vCenter[0], &m1);
						
						
								
										        D3DXVec3TransformCoord(&g_vTest[1], &g_vCenter[1], &m2);
						
						
								
										        D3DXVec3TransformCoord(&g_vTest[2], &g_vCenter[2], &m3);
						
						
								
										        D3DXVec3TransformCoord(&g_vTest[3], &g_vCenter[3], &m4);
						
						
								
										        WhoAmI();
						
						
								
										    }
						
						
								
										 
								
						
						
								
										    m_pD3DDev->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 
						
						
								
										                     D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
						
						
								
										    m_pD3DDev->BeginScene();
						
						
								
										 
								
						
						
								
										    m_pD3DDev->SetTransform(D3DTS_WORLD, &m1);
						
						
								
										    m_pMeshShip->Render();
						
						
								
										    m_pD3DDev->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
						
						
								
										    m_pMeshSphere->DrawSubset(0);
						
						
								
										    m_pD3DDev->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
						
						
								
										 
								
						
						
								
										    m_pD3DDev->SetTransform(D3DTS_WORLD, &m2);
						
						
								
										    m_pMesh1->DrawSubset(0);
						
						
								
										   
										
										
								
						
						
								
										    m_pD3DDev->SetTransform(D3DTS_WORLD, &m3);
						
						
								
										    m_pMesh2->DrawSubset(0);
						
						
								
										    
										
										
								
						
						
								
										    m_pD3DDev->SetTransform(D3DTS_WORLD, &m4);
						
						
								
										    m_pMesh3->DrawSubset(0);
						
						
								
										   
										// 
								
								画Y轴向上或向下的偏移, X轴向左或向右的偏移
						
						
								
										    D3DXVECTOR2* pLine = g_vy;
						
						
								
										    m_pLine->Begin();
						
						
								
										    m_pLine->Draw(pLine, 8, D3DCOLOR_XRGB(0, 128, 0));
						
						
								
										    pLine += 8;
						
						
								
										    m_pLine->Draw(pLine, 2, D3DCOLOR_XRGB(0, 255, 0));
						
						
								
										    pLine += 2;
						
						
								
										    m_pLine->Draw(pLine, 8, D3DCOLOR_XRGB(0, 128, 0));
						
						
								
										    pLine += 8;
						
						
								
										    m_pLine->Draw(pLine, 2, D3DCOLOR_XRGB(0, 255, 0));
						
						
								
										    m_pLine->End();
						
						
								
										   
										// 
								
								显示每秒帧数和选择物体的类型
								
										
										
								
						
						
								
										    RECT rect = { 16, 16, 512, 48 };
						
						
								
										    wsprintf(g_szFPS, _T("Current FPS : %ld"), g_dwFPS);
						
						
								
										    m_pFont->DrawText(NULL, g_szFPS, -1, &rect, 
						
						
								
										                     DT_NOCLIP | DT_VCENTER, D3DCOLOR_XRGB(0, 128, 0));
						
						
								
										    rect.top = 48;
						
						
								
										    rect.bottom += 32;
						
						
								
										    m_pFont->DrawText(NULL, g_szPick, -1, &rect, DT_NOCLIP, D3DCOLOR_XRGB(0, 128, 0));
						
						
								
										    
										
										
								
						
						
								
										    m_pD3DDev->EndScene();
						
						
								
										    m_pD3DDev->Present(NULL, NULL, NULL, NULL);
						
						
								}
								
										
										
								
						
						
								---------------------------------------------------------------
						
						
								
										 
								
						
						
								9.4.2 game9 project
								说明
								
										
										
								
						
						
								
										 
								
						
						
								
										    
								
								为代码简单, 在鼠标停留在某地一定时间产生
								WM_MOUSEHOVER
								消息时, 才会有Pick功能的调用, 物体类型在左上角显示
								. 
								自动旋转/停止用Space切换, 自动旋转时有自动Picking功能, 也就是鼠标不动, 当物体旋转到鼠标位子将自动识别物体. 
						
						
								
										 
								
						
						
								
										    
								
								识别物体有延迟现象, 作为例子就不改的太复杂了. 还有这种Picking技术是最普通的, 物体少的时候用还不错, 实际的游戏可以使用BSP, 反馈法, 直接映射法等.
						
						
								
										 
								
						
						
								
										
										
								
						
						
								
										
												 
										
								
						
						
								
										
												 
										
								
						
						
								第九集 小结  
						
						
								
										
												 
										
								
						
						
								这一集我们学习了要进行DirectX Graphics 3D编程中的物体Pick和文字显示.