D3D中透明渲染的总结

1.渲染的先决条件
打开ALPHA渲染
m_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, true);

 

对于通过程序顶点构造的多边形渲染时必须开启ALPHA通道
m_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);

设置为普通Alpha混合
m_pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
m_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); 

2.Mesh透明渲染时
修改材质的Diffuse的Alpha值
D3DMATERIAL9* mat
mat.Diffuse.a=...;

开灯渲染
m_pd3dDevice->SetRenderState(D3DRS_LIGHTING,true);

3.顶点多边形透明渲染
修改VB所指向的TLF顶点格式的Color(自己定义的)
struct TLV
{
   float x,y,z;
   DWORD color;
   float u,v;
}* pVertices;

m_pVB->Lock(0, m_dwVertexCount*sizeof(TLV), (void * *) &pVertices, 0);
for( DWORD i=0;i< m_dwVertexCount; i++)
{
      (pVertices+i)->dwColor=m_dwColor;
}
m_pVB->Unlock();

顶点多边形透明渲染必须关灯渲染
m_pd3dDevice->SetRenderState(D3DRS_LIGHTING,false);

4.调节渲染次序
  从半透明混合的原理知道,首先需要一个基础颜色,然后和另一个颜色进行混合。而在有时将3D物体渲染次序和在3D空间里的位置搞错时,就会发现透明物体后面的物体会消失的情况。这就需要对透明物体进行排序。
  排序所基于的原则是:
  远的物体先画,近的物体后画。
  先画不透明体,再画透明物体。

这里远的物体指的是离摄像机远的物体,这里只简单介绍得到物体远近的方法
构造8个视锥平面的顶点
通过PROJECTION矩阵映射到世界矩阵
从顶点构造出视锥体的XY平面(靠摄像机最近的XY平面)
将物体的XYZ代入下式即可得出距离视锥平面的远近了
D3DXPLANE plane;
plane.a*x+plane.b*y+plane.c*z+plane.d
结果为正时表示在摄像机前方,反之在后方

具体视锥面操作可以参考DXSDK里的Culling例子

要将 Qt 视频渲染透明窗口上,可以使用 Direct3D 来实现。以下是大致步骤: 1. 创建一个透明窗口(设置窗口样式为 WS_EX_LAYERED 并调用 SetLayeredWindowAttributes 函数设置透明度)。 2. 创建一个 Direct3D 设备,并在其创建一个纹理。 3. 将 Qt 视频渲染到这个纹理上(可以使用 QAbstractVideoSurface 类)。 4. 使用 Direct3D 将该纹理渲染透明窗口上。 具体实现可以参考以下代码: ```cpp // 创建透明窗口 HWND hwnd = CreateWindowEx( WS_EX_LAYERED | WS_EX_TRANSPARENT | WS_EX_TOPMOST, L"myWindowClass", L"My Transparent Window", WS_POPUP, 0, 0, 800, 600, NULL, NULL, hInstance, NULL); // 设置窗口透明度 SetLayeredWindowAttributes(hwnd, 0, 255, LWA_ALPHA); // 创建 Direct3D 设备和纹理 IDirect3D9* d3d = Direct3DCreate9(D3D_SDK_VERSION); IDirect3DDevice9* device = NULL; D3DPRESENT_PARAMETERS parameters = {0}; parameters.Windowed = TRUE; parameters.SwapEffect = D3DSWAPEFFECT_DISCARD; parameters.BackBufferFormat = D3DFMT_UNKNOWN; d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &parameters, &device); IDirect3DTexture9* texture = NULL; device->CreateTexture(width, height, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL); // 将 Qt 视频渲染到纹理上 MyVideoSurface* surface = new MyVideoSurface(texture); QMediaPlayer* player = new QMediaPlayer; player->setVideoOutput(surface); player->setMedia(QUrl::fromLocalFile("myvideo.mp4")); player->play(); // 渲染纹理到透明窗口上 device->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0, 0, 0, 0), 1.0f, 0); device->BeginScene(); LPDIRECT3DSURFACE9 backbuffer = NULL; device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer); device->StretchRect(texture, NULL, backbuffer, NULL, D3DTEXF_NONE); device->EndScene(); device->Present(NULL, NULL, NULL, NULL); ``` 其,MyVideoSurface 类是继承自 QAbstractVideoSurface 的自定义类,用于将视频渲染到 Direct3D 纹理上。具体实现可以参考 Qt 官方文档。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值