[D3D9] 红龙书 - 优化纹理映射的源码 (源码渲染纹理的效果很模糊)
2017-04-24 13:28
417 查看
注意:阅读本文时,需要读者具有D3D9纹理渲染的基础。
红龙书第六章,介绍了纹理映射的知识。但是运行书中的纹理矩形demo(工程名TexQuad)时,发现图片显示模糊,尝试修改D3DSAMP_MINFILTER和D3DSAMP_MAGFILTER的值后 效果依旧不理想 。
经过调查与编码验证,发现显示图片时如果使用离屏表面,就不会有以上问题。书中TexQuad工程的逻辑就不阐述了 感兴趣的可以自己研究一下,本文重点介绍离屏表面的方法。
需要定义的相关变量如下:
本文重点介绍:初始化D3D、渲染一帧图像。(文中只会提及与离屏表面相关的逻辑,需要读者具有纹理渲染的基础)。
1、初始化D3D对象
(1)初始化D3D设备对象、纹理对象、顶点缓冲(宽高使用显示器宽高,而不是使用预览窗口的宽高。如果有多个显示器 则使用最大的宽高)
注意需要调用 如下代码:
(1)获取到一帧图像, 将数据写入到离屏表面m_pOffscreenSurface中
关键词:LPDIRECT3DSURFACE9::LockRect、memcpy、LPDIRECT3DSURFACE9::UnlockRect
(2)将离屏表面的数据,复制到m_pTexture9
关键词: LPDIRECT3DTEXTURE9::GetSurfaceLevel、LPDIRECT3DDEVICE9::StretchRect
如果预览窗口的宽或高,大于初始化D3D对象时的宽高(即m_szD3DResolution),那么调用LPDIRECT3DDEVICE9::StretchRect时会失败。
所以要满足一个要求:m_hPreview.width <= m_szD3DResolution.cx && m_hPreview.height <= m_szD3DResolution.cy。
通常可以使用最大显示器的宽高来初始化D3D,因为一般来说,很少有应用程序中预览窗口的宽高,会大于显示器宽高的情况。
红龙书第六章,介绍了纹理映射的知识。但是运行书中的纹理矩形demo(工程名TexQuad)时,发现图片显示模糊,尝试修改D3DSAMP_MINFILTER和D3DSAMP_MAGFILTER的值后 效果依旧不理想 。
经过调查与编码验证,发现显示图片时如果使用离屏表面,就不会有以上问题。书中TexQuad工程的逻辑就不阐述了 感兴趣的可以自己研究一下,本文重点介绍离屏表面的方法。
需要定义的相关变量如下:
HWND m_hPreview; // 预览窗口的句柄 SIZE m_szD3DResolution; // 初始化D3D设备的宽高 (通常使用显示器的宽高 如果有多个显示器 则使用最大的宽高) LPDIRECT3D9 m_pDirect3D9; // D3D9对象 LPDIRECT3DDEVICE9 m_pDevice9; // 宽高使用m_szD3DResolution LPDIRECT3DTEXTURE9 m_pTexture9; // 宽高使用m_szD3DResolution LPDIRECT3DVERTEXBUFFER9 m_pVertexBuffer9; // 顶点缓冲区 SIZE m_szVideoResolution; // 视频数据的宽高(与预览窗口宽高无关) LPDIRECT3DSURFACE9 m_pOffscreenSurface; // 缓冲离屏表面,临时保存一帧图像的数据 宽高使用m_szVideoResolution
本文重点介绍:初始化D3D、渲染一帧图像。(文中只会提及与离屏表面相关的逻辑,需要读者具有纹理渲染的基础)。
1、初始化D3D对象
(1)初始化D3D设备对象、纹理对象、顶点缓冲(宽高使用显示器宽高,而不是使用预览窗口的宽高。如果有多个显示器 则使用最大的宽高)
注意需要调用 如下代码:
m_pDevice9->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); m_pDevice9->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);(2)初始化离屏表面m_pOffscreenSurface(宽高使用视频帧的宽高值)
D3DDISPLAYMODE dm = {}; m_pDirect3D9->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &dm); m_pDevice9->CreateOffscreenPlainSurface(m_szVideoResolution.cx, m_szVideoResolution.cy, dm.Format, D3DPOOL_DEFAULT, &m_pOffscreenSurface, NULL);2、渲染一帧图像
(1)获取到一帧图像, 将数据写入到离屏表面m_pOffscreenSurface中
关键词:LPDIRECT3DSURFACE9::LockRect、memcpy、LPDIRECT3DSURFACE9::UnlockRect
BOOL CD3D9Render::WriteOffscreenSurface(BYTE* pData) { if (!m_bInited || !pData) return FALSE; D3DLOCKED_RECT lockRect = {}; if (FAILED(m_pOffscreenSurface->LockRect(&lockRect, NULL, 0))) return FALSE; BYTE* pDest = (BYTE*)lockRect.pBits; int nStride = m_szVideoResolution.cx * 4; // 4 : ARGB assert(lockRect.Pitch == nStride); for (LONG i = 0; i < m_szVideoResolution.cy; i++) { memcpy(pDest + (i * nStride), pData + (i * nStride), nStride); } m_pOffscreenSurface->UnlockRect(); return TRUE; }
(2)将离屏表面的数据,复制到m_pTexture9
关键词: LPDIRECT3DTEXTURE9::GetSurfaceLevel、LPDIRECT3DDEVICE9::StretchRect
RECT rcSrc = {0, 0, m_szVideoResolution.cx, m_szVideoResolution.cy}; LPDIRECT3DSURFACE9 pSurface9 = NULL; m_pTexture9->GetSurfaceLevel(0, &pSurface9); CRect rcDst; GetClientRect(m_hPreview, &rcDst); // 如果预览窗口的宽高 大于初始化D3D时的宽高 StretchRect会调用失败 assert(rcDst.width <= m_szD3DResolution.cx && rcDst.height <= m_szD3DResolution.cy); m_pDirect3DDevice9->StretchRect(m_pOffscreenSurface, &rcSrc, // source pSurface9, &rcDst, // dest D3DTEXF_LINEAR);(3)实际的渲染函数调用,逻辑与普通的纹理渲染是相同的(可以参考TexQuad的逻辑)
m_pDevice9->BeginScene m_pDevice9->SetTexture(0, m_pTexture9) m_pDevice9->DrawPrimitive m_pDevice9->EndScene m_pDevice9->Present注意
如果预览窗口的宽或高,大于初始化D3D对象时的宽高(即m_szD3DResolution),那么调用LPDIRECT3DDEVICE9::StretchRect时会失败。
所以要满足一个要求:m_hPreview.width <= m_szD3DResolution.cx && m_hPreview.height <= m_szD3DResolution.cy。
通常可以使用最大显示器的宽高来初始化D3D,因为一般来说,很少有应用程序中预览窗口的宽高,会大于显示器宽高的情况。
相关文章推荐
- 探cocos2dx裁剪结点、拖尾效果、进度效果、渲染纹理实现(misc_nodes),源码版本(2.2.3)
- 简单实现了一下类似环境映射的光照效果渲染
- 论坛源码推荐(3月27日):导航栏抽屉视图 背景滚动模糊效果
- [D3D9] D3DFVF_XYZ、D3DFVF_XYZRHW 的区别 (以纹理渲染的代码举例说明)
- android 使用OPENGL ES实现纹理拉伸效果-纹理映射基础
- android 使用OPENGL ES实现三角形纹理贴图效果-纹理映射基础
- OpenGL纹理映射和光照效果
- Android 高斯模糊效果从319ms到3ms的优化实现
- WorldWind源码剖析系列:WorldWind实时确定、更新、初始化和渲染地形和纹理数据
- [译]Android高级技巧: Renderscript优化模糊效果
- 无需越狱 无需ROOT Android手机映射到电脑玩手机网游,做手机办公(有源码及效果视频下载)
- cocos2d-x 优化(纹理渲染优化、资源缓存、内存优化)
- cocos2d-x 优化(纹理渲染优化、资源缓存、内存优化)
- cocos2d-x 优化(纹理渲染优化、资源缓存、内存优化)
- cocos2d-x 优化(纹理渲染优化、资源缓存、内存优化)
- 论坛源码推荐(3月3日):多样式图表组件 动态背景模糊的侧边栏菜单效果
- 三角形状的点阵模糊效果iOS源码
- Cocos2d-x 3.x RenderTexture渲染纹理源码分析
- 优化transform在过渡效果中出现文字模糊和抖动问题
- 关于OpenGL透明纹理渲染出来效果不正确的问题