DXUT源码阅读笔记

14.GetCapture()

函数功能:该函数取得捕获了鼠标的窗口(如果存在)的句柄。在同一时刻,只有一个窗口能捕获鼠标;此时,该窗口接收鼠标的输入,无论光标是否在其范围内。
函数原型:HWND GetCapture(VOID)
参数:无。
返回值:返回值是与当前线程相关联的捕获窗口的句柄。如果当前线程里没有窗口捕获到鼠标,则返回NULL。
备注:返回NULL并不意味着系统里没有其他进程或线程捕获到鼠标,只表示当前线程没有捕获到鼠标。

13. 控件什么时候与Element绑定?

1.声明Dialog

2.将Dialog与DialogResourceManager绑定

3.将Dialog与对应的回调函数OnGuiEvent绑定

4.给Dialog添加控件Dialog.AddXXXX()        XXXX表示各种控件的名称,比如Button, CheckBox,Slider之类

5.在AddXXXX函数为控件申请内存,并调用CDXUTDialog::AddControl()

6.CDXUTDialog::AddControl()会将刚才申请的控件放到Dialog的控件列表中, 并且放进去之前调用CDXUTDialog::InitControl()

7.在InitControl中遍历Dialog的Element列表(m_DefaultElements), 找出所有属于该控件的Element将他们绑定到控件上(使用CDXUTControl::SetElement函数进行绑定操作)

8.使用CDXUTControl::SetElement函数的写法有点奇怪的,要弄懂。

12.Warning C4005 重复宏定义

遇到此警告,可以进行屏蔽处理

在重复的头文件前面中添加

#pragma warning(disable:4005)即可

11.Effect框架修改变量的两种方法

 //
g_pEffect->SetVector( "g_MaterialDiffuseColor", ( D3DXVECTOR4* )&colorMtrlDiffuse ); //2
// To read or write to D3DX effect variables we can use the string name
// instead of using handles, however it improves perf to use handles since then
// D3DX won't have to spend time doing string compares
g_hTime = g_pEffect->GetParameterByName( NULL, "g_fTime" );
g_pEffect->SetFloat( g_hTime, ( float )fTime );

10.shader文件的读取方式,目前知道4种

  1.HLSL写在effect的fx文件中(不使用fxc编译)

    如果不使用fxc编译的话,不要将fx文件放进项目目录中,否者编译器(vs2015)无法编译通过

    错误信息如下

 warning X3206: implicit truncation of vector type
>FXC : error X3501: 'main': entrypoint not found
>
> compilation failed; no code produced
     ID3DXEffect*                g_pEffect = NULL;       // D3DX effect interface
//可以使用 |= 运算符为dwShaderFlags添加标记
DWORD dwShaderFlags = D3DXFX_NOT_CLONEABLE;
#ifdef DEBUG_VS
dwShaderFlags |= D3DXSHADER_FORCE_VS_SOFTWARE_NOOPT;
#endif
#ifdef DEBUG_PS
dwShaderFlags |= D3DXSHADER_FORCE_PS_SOFTWARE_NOOPT;
#endif WCHAR str[MAX_PATH];
V_RETURN( DXUTFindDXSDKMediaFileCch( str, MAX_PATH, L"BasicHLSL.fx" ) ); // If this fails, there should be debug output as to
// why the .fx file failed to compile
V_RETURN( D3DXCreateEffectFromFile( pd3dDevice, str, NULL, NULL, dwShaderFlags, NULL, &g_pEffect, NULL ) );

  2.使用fxc.exe编译hlsl文件,程序运行时直接调用二进制代码,具体例子参考Direct3D9的CompiledEffect样例

 ID3DXEffect*                g_pEffect = NULL;       // D3DX effect interface
TCHAR str[MAX_PATH];
hr = DXUTFindDXSDKMediaFileCch( str, MAX_PATH, TEXT( "CompiledEffect.fxo" ) );
if( FAILED( hr ) ) { MessageBox(............, MB_OK); return E_FAIL; } V_RETURN( D3DXCreateEffectFromFile( pd3dDevice, str, NULL, NULL, D3DXFX_NOT_CLONEABLE, NULL, &g_pEffect, NULL ) );

  3.Shader写在txt文件中,调用函数读取.

  4.在代码里直接将shader写在数组中,dxut中箭头的绘制采用的就是这种方法

9.when the 5th args of DrawText which is a member function of ID3DXFont is specified to be DT_CALCRECT, DrawText would return a RECT that is wide enough to contain the Text , and , returns at the 4th args unless the Rect could contain the Text.

8.

 #if 1
// Pass in DT_NOCLIP so we don't have to calc the bottom/right of the rect
SetRect( &rc, , , , );
g_pFont->DrawText( NULL, L"This is a trivial call to ID3DXFont::DrawText", -, &rc, DT_NOCLIP,
D3DXCOLOR( 1.0f, 0.0f, 0.0f, 1.0f ) );
#else
// If you wanted to calc the bottom/rect of the rect make these 2 calls
SetRect( &rc, , , , );
g_pFont->DrawText( NULL, L"This is a trivial call to ID3DXFont::DrawText", -, &rc, DT_CALCRECT, D3DXCOLOR( 1.0f, 0.0f, 0.0f, 1.0f ));
g_pFont->DrawText( NULL, L"This is a trivial call to ID3DXFont::DrawText", -, &rc, , D3DXCOLOR( 1.0f, 0.0f, 0.0f, 1.0f ));
#endif

执行上半部分, 下半部分被注释掉。

若将#if 1中的1改为0,则上半部分被注释,执行下半部分。

7.DXUTCamera.h  中的Class CBaseCamera内部有两组类似的数据成员

Protected:
D3DXVECTOR3 m_vDefaultEye; // Default camera eye position
D3DXVECTOR3 m_vDefaultLookAt; // Default LookAt position
D3DXVECTOR3 m_vEye; // Camera eye position
D3DXVECTOR3 m_vLookAt; // LookAt position

注释上写了Default,但是看不明白有什么区别。

所以查找了所有引用m_vDefaultEye的地方,发现在SetViewParams和Reset函数中被使用。

而m_vEye则出现在SetViewParams和FrameMove中。

6. DXUT中MsgProc, OnFrameMove函数都可以用来更新下一帧数据。MsgProc根据用户的输入更新,OnFrameMove没有输入也能自动更新。

1.GetSet方法的宏定义简便写法

//DXUT.cpp_Line50
#define SET_ACCESSOR( x, y ) inline void Set##y( x t ) { DXUTLock l; m_state.m_##y = t; };
#define GET_ACCESSOR( x, y ) inline x Get##y() { DXUTLock l; return m_state.m_##y; };
#define GET_SET_ACCESSOR( x, y ) SET_ACCESSOR( x, y ) GET_ACCESSOR( x, y )

 

使用时将x替换为形参,y替换为类中某个变量的后缀(例: m_state.m_D3D的后缀为D3D)

//example
GET_SET_ACCESSOR( IDirect3D9*, D3D9 );

  

2. #define中的 "##"

##是一个连接符号,用于把参数连在一起 #是“字符串化”的意思。出现在宏定义中的#是把跟在后面的参数转换成一个字符串

#define paster( n ) printf( "token " #n" = %d\n ", token##n )

所以paster(9);就是相当于 printf("token 9 = %d\n",token9);

3.DXUTLock l;

//DXUT.cpp_Line32
class DXUTLock
{
public:
inline DXUTLock()
{
if( g_bThreadSafe ) EnterCriticalSection( &g_cs );
}
inline ~DXUTLock()
{
if( g_bThreadSafe ) LeaveCriticalSection( &g_cs );
}
};

不了解线程安全方面的东西,看百度百科大概了解了一下

EnterCriticalSection()

多个线程操作相同的数据时,一般是需要按顺序访问的,否则会引导数据错乱,无法控制数据,变成随机变量。为解决这个问题,就需要引入互斥变量,让每个线程都按顺序地访问变量。这样就需要使用EnterCriticalSection和LeaveCriticalSection函数。

4.指针、com接口安全释放 宏定义

//DXUT.h_Line117
#ifndef SAFE_DELETE
#define SAFE_DELETE(p) { if (p) { delete (p); (p)=NULL; } }
#endif
#ifndef SAFE_DELETE_ARRAY
#define SAFE_DELETE_ARRAY(p) { if (p) { delete[] (p); (p)=NULL; } }
#endif
#ifndef SAFE_RELEASE
#define SAFE_RELEASE(p) { if (p) { (p)->Release(); (p)=NULL; } }
#endif

注意动态数组的释放(SAFE_DELETE_ARRAY) 比较特别,当释放一个指向数组的指针时,空方括号是必需的。它指示编译器此指针指向一个对象数组的第一个元素。

                                                 ——C++Primer 5th  P425, 释放动态数组

5.chm文档内不能搜索的话,打开运行(win+R),输入regsvr32 itircl.dll 即可。

如果是打不开,或打开出错的话,打开运行(win+R),输入

regsvr32 hhctrl.ocx

regsvr32 itss.dll //打开chm需要的协议

  • regsvr32 itircl.dll //这个很重要,是关于全文搜索的。
  • 如果chm格式文件出现“网页不能浏览”的错误,在该文档上点击鼠标右键,解除锁定即可。
上一篇:jquery mobile 方法收集.


下一篇:python generator: next , sent(msg)区别