how to set rendertarget to texture map?
hi,
you do it like this:
if you want to use multisampling, then it is more difficult, but I can post that one too, if you are interested.
kp
you do it like this:
IDirect3DTexture9* m_texture;IDirect3DSurface9* m_surface;HRESULT hr = pd3dDevice->CreateTexture(m_width, m_height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &m_texture, NULL);m_texture->GetSurfaceLevel(0, &m_surface);pd3dDevice->SetRenderTarget(0, m_surface);
if you want to use multisampling, then it is more difficult, but I can post that one too, if you are interested.
kp
Just one thing to add... Remember to call Release() on the surface you obtained from GetSurfaceLevel() or you get a memory leak.
-Mezz
-Mezz
Quote:Original post by kovacsp
if you want to use multisampling, then it is more difficult, but I can post that one too, if you are interested.
In DX SDK samples they suggest you cannot use texture RTs with multisampling, so they use another Z-buffer that matches their texture RT. Have you got another workaround?
~def
I've heard that the easiest way if you want mutlisampling, just draw to the main backbuffer and copy it.
Quote:Original post by deffer
Isn't that, like, horribly slow? Just a thought...
You mean copying backbuffer to texture? No, it's not. Only if you copy lots of large textures per frame, it starts to get slow.
here is my code that was suggested by this post on the directx dev mailing list:
See Re: [DIRECTXDEV] How to use Multisampling with Textures? from Chuck Walbourn
September 28, 2004 at DIRECTXDEV@DISCUSS.MICROSOFT.COM
RenderTarget.hpp
RenderTarget.cpp
Now, using this class, you can write eg.:
and then, when you want to use the contents of the off-screen render target as a texture, you simply write:
Oh, almost forgot: when using this thing, I always reuse the default, multisampled depth buffer (in case multisampling is switched on, anyway it is simple). You cannot use a non-multisampled backbuffer with a multisampled rendertarget.
Please avoid the company-specific parts in the source, like CCASSERT. Sorry for that!
I don't know where, but I read thet StretchRect() is a pretty fast function. But I might be wrong. Anyway, as far as I know, this is the only way to go, and it works well for me.
Hope this helps!
kp
See Re: [DIRECTXDEV] How to use Multisampling with Textures? from Chuck Walbourn
September 28, 2004 at DIRECTXDEV@DISCUSS.MICROSOFT.COM
RenderTarget.hpp
#pragma once#include "DirectXCommon.hpp"namespace DX{class RenderTarget {private: bool m_isValid; bool m_multisampled; IDirect3DTexture9* m_texture; IDirect3DSurface9* m_surface; IDirect3DDevice9* m_pd3dDevice; int m_width, m_height; DDRENDERING_VIEW* m_rView; void CopyMultisampledRenderTarget(void);public: RenderTarget(DDRENDERING_VIEW* p_rView); ~RenderTarget(); bool IsValid() { return(m_isValid); } void Create(IDirect3DDevice9* p_pd3dDevice, int p_width, int p_height, bool p_multisampled, D3DMULTISAMPLE_TYPE p_multisampleType = D3DMULTISAMPLE_NONE, DWORD p_multisampleQuality = 0); IDirect3DTexture9* GetAsTexture(); IDirect3DSurface9* GetAsSurface(); void Release(); void SaveToBmp(CString p_filename);};} // namespace DX
RenderTarget.cpp
#include "stdafx_DXM.h"#include "RenderTarget.hpp"#include "dxutil.h"namespace DX{//-----------------------------------------------------------------------------RenderTarget::RenderTarget(DDRENDERING_VIEW* p_rView){ m_isValid = false; m_rView = p_rView; m_texture = NULL; m_surface = NULL;}//-----------------------------------------------------------------------------RenderTarget::~RenderTarget(){ if (m_isValid) { Release(); }}//-----------------------------------------------------------------------------void RenderTarget::Create(IDirect3DDevice9* p_pd3dDevice, int p_width, int p_height, bool p_multisampled, D3DMULTISAMPLE_TYPE p_multisampleType, DWORD p_multisampleQuality){ CCASSERT(!m_isValid); // to ensure it is not created twice m_pd3dDevice = p_pd3dDevice; m_multisampled = p_multisampled; m_width = p_width; m_height = p_height; HRESULT hr; // create texture hr = m_pd3dDevice->CreateTexture(m_width, m_height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &m_texture, NULL); CCASSERT_MSG(hr == S_OK, "RenderTarget::CreateTexture() failed"); if (hr == D3DERR_OUTOFVIDEOMEMORY) { UserAlertOutOfVideoMemory(m_rView); } if (!m_multisampled) { // get surface m_texture->GetSurfaceLevel(0, &m_surface); } else { // create multisampled render target hr = m_pd3dDevice->CreateRenderTarget(m_width, m_height, D3DFMT_X8R8G8B8, p_multisampleType, p_multisampleQuality, false, &m_surface, NULL); CCASSERT_MSG(hr == S_OK, "RenderTarget::CreateRenderTarget() failed"); if (hr == D3DERR_OUTOFVIDEOMEMORY) { UserAlertOutOfVideoMemory(m_rView); } } m_isValid = true;}//-----------------------------------------------------------------------------IDirect3DTexture9* RenderTarget::GetAsTexture(){ CCASSERT(m_isValid); if (!m_multisampled) { // nothing } else { CopyMultisampledRenderTarget(); } return(m_texture);}//-----------------------------------------------------------------------------void RenderTarget::CopyMultisampledRenderTarget(void){ // copy contents of multisampled surface to the non-multisampled texture // See Re: [DIRECTXDEV] How to use Multisampling with Textures? from Chuck Walbourn // September 28, 2004 at DIRECTXDEV@DISCUSS.MICROSOFT.COM // http://discuss.microsoft.com/SCRIPTS/WA-MSD.EXE?A2=ind0409d&L=directxdev&D=1&F=&S=&P=16081 IDirect3DSurface9* surfaceOfTexture; m_texture->GetSurfaceLevel(0, &surfaceOfTexture); m_pd3dDevice->StretchRect(m_surface, NULL, surfaceOfTexture, NULL, D3DTEXF_LINEAR); surfaceOfTexture->Release();}//-----------------------------------------------------------------------------IDirect3DSurface9* RenderTarget::GetAsSurface(){ CCASSERT(m_isValid); return(m_surface);}//-----------------------------------------------------------------------------void RenderTarget::Release(){ //CCASSERT(m_isValid); SAFE_RELEASE(m_texture); SAFE_RELEASE(m_surface); m_isValid = false;}//-----------------------------------------------------------------------------void RenderTarget::SaveToBmp(CString p_filename){ if (m_multisampled) { CopyMultisampledRenderTarget(); } D3DXSaveTextureToFile(p_filename, D3DXIFF_BMP, m_texture, NULL);}} // namespace DX
Now, using this class, you can write eg.:
m_sceneAmbientRenderTarget.Create(pd3dDevice, p_desc.Width, p_desc.Height, true, d3dParams.MultiSampleType, d3dParams.MultiSampleQuality);...pd3dDevice->SetRenderTarget(0, m_sceneAmbientRenderTarget.GetAsSurface());
and then, when you want to use the contents of the off-screen render target as a texture, you simply write:
pd3dDevice->SetTexture(0, p_sceneAmbientRenderTarget.GetAsTexture());
Oh, almost forgot: when using this thing, I always reuse the default, multisampled depth buffer (in case multisampling is switched on, anyway it is simple). You cannot use a non-multisampled backbuffer with a multisampled rendertarget.
Please avoid the company-specific parts in the source, like CCASSERT. Sorry for that!
I don't know where, but I read thet StretchRect() is a pretty fast function. But I might be wrong. Anyway, as far as I know, this is the only way to go, and it works well for me.
Hope this helps!
kp
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement