[DirectX] RenderTarget XXL (larger than screen size)

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
Frosty Topaz
Posts: 107
Joined: Sat Nov 04, 2006 9:42 pm

Post by Frosty Topaz »

Pardon me if this is a bit of a nubbish question but... would it be possible to do this also with OpenGL? I've not worked extensively with either DirectX or OpenGL so I don't know.

The project I'm working on is multi-platform so OpenGL support is a must for me and I have a bunch of post-process effects I'd love to not have distorted.

If some coding is required to make it work with OpenGL and someone wants to point me in the right direction to start I'm willing to do it myself, but I don't want to go and reinvent the wheel.
Frosty Topaz
=========
It isn't easy being ice-encrusted aluminum silicate fluoride hydroxide...
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

OpenGL already supports custom depth buffers in case the FBO extension is supported. Otherwise it's not possible (besides some update code posted by Nadro in the bug forum for a wider range of extensions).
vi-wer
Posts: 93
Joined: Sun May 20, 2007 7:15 pm
Location: Germany
Contact:

Post by vi-wer »

It's been some time but now here's an update. This time I made a class that can be added to any Irrlicht version in 3 steps. Copy the files into the source directory and follow the instructions in CD3D9DepthResizer.h.
This one's only for DirectX9. I could have made one for DirectX8 too but I don't have the DX8 SDK to test it. But it should not be a problem to alter the code for the use wth DX8. Maybe I'll post one later. :wink:

CD3D9DepthResizer.h

Code: Select all

// Depth Buffer Resizer
// (C) by Viktor W.
// vi-wer.de.tl
// For use with the Irrlicht Engine (any Version) Direct3D9 Driver

/*
 * Usage:
 * 1. Derive CD3D9Driver class from CD3D9DepthResizer (add header)
 * 2. Replace size check from setRenderTarget() (CD3D9Driver.cpp):
 *
 *      if (texture && (tex->getSize().Width > ScreenSize.Width ||
 *          tex->getSize().Height > ScreenSize.Height ))
 *
 *  with
 *
 *      if( !CheckDepthStencilSize(texture) )
 *
 *
 * 3. Change createRenderTargetTexture() (CD3D9Driver.cpp) content to this:
 *
 *       ITexture *texture = new CD3D9Texture(this, size, name);
 *       CheckRenderTarget( texture, pID3DDevice );
 *       return texture;
 *
 * 4. Compile the Engine and have fun!
 */
#ifndef CD3D9DEPTHRESIZER_H
#define CD3D9DEPTHRESIZER_H


#include "IrrCompileConfig.h"

#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_

#ifdef _IRR_WINDOWS_
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif

#include "CNullDriver.h"
#include "ITexture.h"
#include <d3d9.h>


namespace irr
{
namespace video
{

    // DepthStencilBuffer resizer class
    class CD3D9DepthResizer
    {
        public:
            CD3D9DepthResizer();
            virtual ~CD3D9DepthResizer();

            bool CheckRenderTarget(const ITexture *pTexture,IDirect3DDevice9* pDevice);
            bool CheckDepthStencilSize(const ITexture *pTexture);


        private:
            core::dimension2d<s32> CurrentDepthBufferSize;
    };

}
}
#endif // _IRR_COMPILE_WITH_DIRECT3D_9_
#endif // CD3D9DEPTHRESIZER_H
CD3D9DepthResizer.cpp

Code: Select all

// Depth Buffer Resizer
// (C) by Viktor W.
// vi-wer.de.tl
// For use with the Irrlicht Engine (any Version)

#include "CD3D9DepthResizer.h"
#include "os.h"


#define _IRR_DONT_DO_MEMORY_DEBUGGING_HERE

#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_

using namespace irr;
using namespace video;



CD3D9DepthResizer::CD3D9DepthResizer()
{
    CurrentDepthBufferSize.Width = -1;
    CurrentDepthBufferSize.Height = -1;
}

CD3D9DepthResizer::~CD3D9DepthResizer()
{
    //dtor
}

/** @brief CheckTexture
  *
  * Will check current Depth Buffer Size an create a new one if necessary
  */
bool CD3D9DepthResizer::CheckRenderTarget(const ITexture *pTexture, IDirect3DDevice9* pDevice)
{
    if( !pTexture || !pDevice )
    {
        os::Printer::log("Could not resize DepthBuffer",ELL_ERROR);
        return false;
    }

    IDirect3DSurface9* pOldZBuffer;
    D3DSURFACE_DESC desc;
    if( FAILED(pDevice->GetDepthStencilSurface(&pOldZBuffer) ) )
        return false;

    pOldZBuffer->GetDesc(&desc);
    core::dimension2d<s32> needSize = pTexture->getSize();

    if( desc.Width < needSize.Width ||
        desc.Height < needSize.Height )
    {
        // create new ZBuffer
        IDirect3DSurface9* pNewZBuffer;
        HRESULT hr = pDevice->CreateDepthStencilSurface( needSize.Width,
                                                       needSize.Height,
                                                       desc.Format,
                                                       desc.MultiSampleType,
                                                       desc.MultiSampleQuality,
                                                       TRUE,
                                                       &pNewZBuffer,
                                                       NULL);

        if( hr == D3DERR_OUTOFVIDEOMEMORY )
        {
            os::Printer::log("Could not resize DepthBuffer: out of video memory",ELL_ERROR);
            pOldZBuffer->Release();
            return false;
        }
        else if( hr == E_OUTOFMEMORY )
        {
            os::Printer::log("Could not resize DepthBuffer: out of memory",ELL_ERROR);
            pOldZBuffer->Release();
            return false;
        }
        else if( FAILED(hr) )
        {
            char buffer[128];
            sprintf(buffer,"Could not resize DepthBuffer to %ix%i",needSize.Width,needSize.Height);
            os::Printer::log(buffer,ELL_ERROR);
            pOldZBuffer->Release();
            return false;
        }

        // set new ZBuffer
        if( FAILED(pDevice->SetDepthStencilSurface(pNewZBuffer)) )
        {
            os::Printer::log("Could not set new DepthBuffer",ELL_ERROR);
            pOldZBuffer->Release();
            pNewZBuffer->Release();
            return false;
        }

        pNewZBuffer->Release();

        // set new size
        CurrentDepthBufferSize = needSize;
    }
    else if( CurrentDepthBufferSize.Width < 0 ||
                CurrentDepthBufferSize.Height < 0 )
    {
        CurrentDepthBufferSize.Width = desc.Width;
        CurrentDepthBufferSize.Height = desc.Height;
    }

    // release old ZBuffer
    pOldZBuffer->Release();

    return true;
}


/** @brief CheckDepthSize
  *
  * Check current depth buffer size with the necessary
  */
bool CD3D9DepthResizer::CheckDepthStencilSize(const ITexture *pTexture)
{
    // Texture might be default render target,
    // let's return true ^_^
    if( !pTexture )
        return true;

    if( CurrentDepthBufferSize.Width < 0 )
        return false;

    core::dimension2d<s32> needSize = pTexture->getSize();

    if( CurrentDepthBufferSize.Width < needSize.Width ||
        CurrentDepthBufferSize.Height < needSize.Height )
        return false;

    return true;
}


#endif //_IRR_COMPILE_WITH_DIRECT3D_9_
Last edited by vi-wer on Wed Jun 25, 2008 9:46 am, edited 2 times in total.
Yoran
Site Admin
Posts: 96
Joined: Fri Oct 07, 2005 8:55 am
Location: The Netherlands
Contact:

Post by Yoran »

Thanks vi-wer.
once i get a working dx9sdk again i'll try compiling it in.
It was very tedious to apply the large rtt patch everytime i updated the svn
vi-wer
Posts: 93
Joined: Sun May 20, 2007 7:15 pm
Location: Germany
Contact:

Post by vi-wer »

This one's a 'might-work' DX8 Driver version of the DepthResizer. It compiled but I could not fully test it due to some missing DX8 libs. I hope someone can confirm its functionality.

CD3D8DepthResizer:

Code: Select all

// Depth Buffer Resizer
// (C) by Viktor W.
// vi-wer.de.tl
// For use with the Irrlicht Engine (any Version) Direct3D8 Driver

/*
 * Usage:
 * 1. Derive CD3D8Driver class from CD3D8DepthResizer (add header)
 * 2. Replace size check from setRenderTarget() (CD3D8Driver.cpp):
 *
 *      if (texture && (tex->getSize().Width > ScreenSize.Width ||
 *          tex->getSize().Height > ScreenSize.Height ))
 *
 *  with
 *
 *      if( !CheckDepthStencilSize(texture) )
 *
 *
 * 3. Change createRenderTargetTexture() (CD3D8Driver.cpp) content to this:
 *
 *       ITexture *texture = new CD3D8Texture(this, size, name);
 *       CheckRenderTarget( texture, pID3DDevice );
 *       return texture;
 *
 * 4. Compile the Engine and have fun!
 */
#ifndef CD3D8DEPTHRESIZER_H
#define CD3D8DEPTHRESIZER_H


#include "IrrCompileConfig.h"

#ifdef _IRR_COMPILE_WITH_DIRECT3D_8_

#ifdef _IRR_WINDOWS_
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif

#include "CNullDriver.h"
#include "ITexture.h"
#include <d3d8.h>


namespace irr
{
namespace video
{

    // DepthStencilBuffer resizer class
    class CD3D8DepthResizer
    {
        public:
            CD3D8DepthResizer();
            virtual ~CD3D8DepthResizer();

            bool CheckRenderTarget(const ITexture *pTexture,IDirect3DDevice8* pDevice);
            bool CheckDepthStencilSize(const ITexture *pTexture);


        private:
            core::dimension2d<s32> CurrentDepthBufferSize;
    };

}
}
#endif // _IRR_COMPILE_WITH_DIRECT3D_8_
#endif // CD3D8DEPTHRESIZER_H
CD3D8DepthResizer:

Code: Select all

// Depth Buffer Resizer
// (C) by Viktor W.
// vi-wer.de.tl
// For use with the Irrlicht Engine (any Version)

#include "CD3D8DepthResizer.h"
#include "os.h"


#define _IRR_DONT_DO_MEMORY_DEBUGGING_HERE

#ifdef _IRR_COMPILE_WITH_DIRECT3D_8_

using namespace irr;
using namespace video;



CD3D8DepthResizer::CD3D8DepthResizer()
{
    CurrentDepthBufferSize.Width = -1;
    CurrentDepthBufferSize.Height = -1;
}

CD3D8DepthResizer::~CD3D8DepthResizer()
{
    //dtor
}

/** @brief CheckTexture
  *
  * Will check current Depth Buffer Size an create a new one if necessary
  */
bool CD3D8DepthResizer::CheckRenderTarget(const ITexture *pTexture, IDirect3DDevice8* pDevice)
{
    if( !pTexture || !pDevice )
    {
        os::Printer::log("Could not resize DepthBuffer",ELL_ERROR);
        return false;
    }

    IDirect3DSurface8* pOldZBuffer;
    D3DSURFACE_DESC desc;
    if( FAILED(pDevice->GetDepthStencilSurface(&pOldZBuffer) ) )
        return false;

    pOldZBuffer->GetDesc(&desc);
    core::dimension2d<s32> needSize = pTexture->getSize();

    if( desc.Width < needSize.Width ||
        desc.Height < needSize.Height )
    {
        // create new ZBuffer
        IDirect3DSurface8* pNewZBuffer;
        HRESULT hr = pDevice->CreateDepthStencilSurface( needSize.Width,
                                                       needSize.Height,
                                                       desc.Format,
                                                       desc.MultiSampleType,
                                                       &pNewZBuffer);

        if( hr == D3DERR_OUTOFVIDEOMEMORY )
        {
            os::Printer::log("Could not resize DepthBuffer: out of video memory",ELL_ERROR);
            pOldZBuffer->Release();
            return false;
        }
        else if( FAILED(hr) )
        {
            char buffer[128];
            sprintf(buffer,"Could not resize DepthBuffer to %ix%i",needSize.Width,needSize.Height);
            os::Printer::log(buffer,ELL_ERROR);
            pOldZBuffer->Release();
            return false;
        }

        // set new ZBuffer
        if( FAILED(pDevice->SetRenderTarget(NULL,pNewZBuffer)) )
        {
            os::Printer::log("Could not set new DepthBuffer",ELL_ERROR);
            pOldZBuffer->Release();
            pNewZBuffer->Release();
            return false;
        }

        pNewZBuffer->Release();

        // set new size
        CurrentDepthBufferSize = needSize;
    }
    else if( CurrentDepthBufferSize.Width < 0 ||
                CurrentDepthBufferSize.Height < 0 )
    {
        CurrentDepthBufferSize.Width = desc.Width;
        CurrentDepthBufferSize.Height = desc.Height;
    }

    // release old ZBuffer
    pOldZBuffer->Release();

    return true;
}


/** @brief CheckDepthSize
  *
  * Check current depth buffer size with the necessary
  */
bool CD3D8DepthResizer::CheckDepthStencilSize(const ITexture *pTexture)
{
    // Texture might be default render target,
    // let's return true ^_^
    if( !pTexture )
        return true;

    if( CurrentDepthBufferSize.Width < 0 )
        return false;

    core::dimension2d<s32> needSize = pTexture->getSize();

    if( CurrentDepthBufferSize.Width < needSize.Width ||
        CurrentDepthBufferSize.Height < needSize.Height )
        return false;

    return true;
}


#endif //_IRR_COMPILE_WITH_DIRECT3D_8_
Nadro
Posts: 1648
Joined: Sun Feb 19, 2006 9:08 am
Location: Warsaw, Poland

Post by Nadro »

This is very useful stuff for Irrlicht:) I think than it will should merge with Irrlicht 1.5;)
Library helping with network requests, tasks management, logger etc in desktop and mobile apps: https://github.com/GrupaPracuj/hermes
impulse3d
Posts: 17
Joined: Wed Jun 04, 2008 7:23 pm

Post by impulse3d »

Thank you vi-wer! This is a tremendously useful piece of code! :D
Post Reply