posts - 36, comments - 30, trackbacks - 0, articles - 0

D3D技术小技巧汇总(追加中)

Posted on 2007-08-23 11:17 vcommon 阅读(3405) 评论(1)  编辑 收藏 引用

16:使用sprite写字,没有Disable Z buffer,D3DRS_ZWRITEENABLE.
结果出现了ERROR_SECTOR_NOT_FOUND的错误.
写字流程--SetRenderTarget,Sprite->Begin,Sprite->End

15:StretchRect 总是失败.
结论.,必须是D3DUSAGE_RENDERTARGET和D3DPOOL_DEFAULT的texture.由于没有设置D3DUSAGE_RENDERTARGET,导致失败.

14: m_pSprite->Begin
如果字也alpha的话,很有可能出问题.字体模糊不清.

13:D3DXFilterTexture
D3DXFillTexture是一个简单的方式去FillTexture,但是不一定好用在大规模copy的地方。适合简单生成纹理。

12:D3DXLoadSurfaceFromMemory
如果surface是一个D3DPOOL_DEFAULT的话,这个函数比LockRect,一个字节一个字节的copy还慢。


11:SetRenderState( D3DRS_SRCBLENDALPHA,D3DBLEND_SRCALPHA);
SetRenderState( D3DRS_DESTBLENDALPHA , D3DBLEND_INVSRCALPHA  );是默认选项
不小心改成了
SetRenderState( D3DRS_SRCBLENDALPHA,D3DBLEND_SRCALPHA);
SetRenderState( D3DRS_DESTBLENDALPHA , D3DBLEND_DESTALPHA  );
后,发现和背景alpha的时候经常受背景影响,出现虚边和毛边。找了一天,终于找到原因。

10:DirectShow版本在VC6和VS2005上无法编译等原因.
#define POINTER_64 __ptr64

9:#define D3D_DEBUG_INFO

在最前

如果使用了stdafx.h,一定要Create Precompiled Header (/Yc)
如果使用Use Precompiled Header (/Yu),那么stdafx.h早已经include了d3d9.h,所以这个define其实一直都没有被加上.

在decontrol panel里打开d3d的debug,能看到更多的debug信息.大多是关于错误等信息的.

 8:stl 
map<string,string>然后发生:
include\functional(139) : error C2784: 'bool std::operator <(const std::_Tree<_Traits> &,const std::_Tree<_Traits> &)' : could not deduce template argument for 'const std::_Tree<_Traits> &' from 'const std::string'
原因少include<string>

 

7:performance:
  LARGE_INTEGER freq;
  BOOL ret = QueryPerformanceFrequency(&freq);
QueryPerformanceCounter(&counter_end);
int((counter_end.QuadPart-counter_start.QuadPart)/(freq.QuadPart/10000000))
//1000是ms

8:D3DXCreateTexture,create的height可能和设置的不一样,因为还要对齐。所以要用GetSurfaceLevel和GetDesc来得到他的宽高,然后填充,否则就会有花的一块。

7:disable lighting.如果没有disable,就必须要设置材质和贴图才能看到东东的贴图。

6:if(PeekMessage( &msg, NULL, 0, 0 ,PM_REMOVE) )的参数问题.
if(PeekMessage( &msg, Hwnd, 0, 0 ,PM_REMOVE) )将收不到很多消息如WM_QUIT。

5:Ogre
Ogre的font画是使用OverlayManager完成的.TextAreaOverlayElement,HardwareBuffer,D3D9HardwareVertexBuffer::lockImpl,mlpD3DBuffer->Lock.Ogre::Font最终依然使用FT_Load_Char来完成,将char转化Material。OverlayElement::_updateRenderQueue,const_cast<Renderable*>(rend)->getRenderOperation(ro);TextAreaOverlayElement::getRenderOperation,
setcapture("title"),其实是保存了一个RenderOperation,由render线程,scencemanger等获得并render.D3D9RenderSystem::_render(const RenderOperation& op),最后由hr = mpD3DDevice->DrawPrimitive画出三角形。TextAreaOverlayElement::initialise则是初始化这群三角形。hr = mpD3DDevice->SetStreamSource(static_cast<UINT>(VertexBufferBinding)

4:CEGUI
CEGUI的font画法也是使用FreeType字体库FreeTypeFont::rasterize来生成一个image的对象。FT_Load_Char,drawGlyphToBuffer完成了所有的工作。

3:ID3DXSprite和3D图形
ID3DXSprite自己是有排序的,所以画的时候有先后顺序.
但和3D融合不很好,不知道怎么把3D放到ID3DXSprite前边,估计不行.

2:WM_SIZE
窗口缩放的时候,分辨率不变,会引起失真.
所以在WM_SIZE的时候要m_pd3dDevice->Reset( &m_d3dpp );
m_d3dpp 使用最新的width和height就可以了.
但是所有的object都要重新分配,这就需要很多的工作了.

1: 鼠标选取。
D3DX有个方法D3DXIntersect,ogre也准许同样技巧

CompositorInstance::collectPasses
http://www.codercorner.com/Opcode.htm
OPCODE - Optimized Collision Detection
IntersectTriangle:

orginPoint + T*Dir = V1 + U*(V2-V1) + V*(V3-V1); 两边乘以 (v2 - v1) X (v3 - v1) 消去u, v ,就能解得T, 乘以 Dir X (V2 -v1) 计算 V, 乘以 Dir X (v2 - v1)!

the Above is relation function:
t(distance from intersct point to ray.p0)
u,v are barycentric coord!

so we have triangle plane : V = V0 + u * edge1 + v * edge2
and ray - line : P = orig + t * dir
so:
V0 + u * edge1 + v * edge2 = orig + t * dir

t = (V0 - orig)(edge1 X edge2) / dir * (edeg1 X edge2) // X is cross product
u = (orig - V0) * (dir X edge2) / edge1 * (dir X edge2)
v = (orig - V0) * (dir X edge1) / edge2 * (dir X edge1)

we make some tranform By below quation
A * (B X C) = B * (C X A ) = C * (A X B)

t = edge2 * ((orig - V0 ) X edge1) / edge1 * (dir X edge2)
u = (orig - v0) * (dir X edge2) / edge1 * (dir X edge2)
v = dir * ((orig - V0) X edge1) / edge1 * (dir X edge2)

so this equation we only need 2 cross product operation!

参考文献<<用OpenGL实现射线拣取对象程序设计>>
http://softsurfer.com/Archive/algorithm_0105/algorithm_0105.htm

×----×---
基础知识
计算两个3-D向量的点乘 D3DXVec3Dot
计算两个3-D向量叉乘 D3DXVec3Cross
点乘 abcosθ,所以=0,垂直
叉乘 x1/x2 = y1/y2 = z1/z2,平行

(叉乘ab)点乘c=0,共面

只有注册用户登录后才能发表评论。