[2.1] DX11 Blitting to cubemaps

Discussion area about developing with Ogre-Next (2.1, 2.2 and beyond)


Post Reply
User avatar
SolarPortal
OGRE Contributor
OGRE Contributor
Posts: 203
Joined: Sat Jul 16, 2011 8:29 pm
Location: UK
x 51
Contact:

[2.1] DX11 Blitting to cubemaps

Post by SolarPortal »

Further to the previous topic (viewtopic.php?f=25&t=93719) and continuing work on the DX11 OgreD3D11HardwarePixelBuffer.cpp, we found that blitting a 2d texture into a cubemap face was crashing and again this has been fixed by changing a simple line of code.

Go to function:

Code: Select all

void D3D11HardwarePixelBuffer::blit(const HardwarePixelBufferSharedPtr &rsrc, const Image::Box &srcBox, const Image::Box &dstBox)
and look for the TEX_TYPE_2D section:

You will notice that dstZ of the CopySubresourceRegion() function is set to mFace whereas in fact mFace is selected by the D3D11CalcSubresource and simply changing the mFace to 0 fixes the blit for 2d textures to a cubemap face..

Code: Select all

case TEX_TYPE_2D:
	{
		mDevice.GetImmediateContext()->CopySubresourceRegion(
				mParentTexture->GetTex2D(),
				D3D11CalcSubresource(static_cast<UINT>(mSubresourceIndex), mFace, mParentTexture->getNumMipmaps() + 1),
				static_cast<UINT>(dstBox.left),
				static_cast<UINT>(dstBox.top),
				0,     // <<<<< ------- this changed from mFace to zero as we are not working with a 3D texture.
				rsrcDx11->mParentTexture->GetTex2D(),
				static_cast<UINT>(rsrcDx11->mSubresourceIndex),
				&srcBoxDx11);
		if (mDevice.isError())
		{
			String errorDescription = mDevice.getErrorDescription();
			OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
				"D3D11 device cannot copy 2d subresource Region\nError Description:" + errorDescription,
				"D3D11HardwarePixelBuffer::blit");
		}
	}
	break;
This then allows cool code like this function we have written to load in 6 different images, generate mip map levels and load all faces and mip maps into a cubemap that can be used as a reflection or skybox texture. Really cool!!!
The resolution of the end reflection or skybox image is adjustable as are the number of mip maps as they are based on the original resolution..

Code: Select all

	
	void PbsMaterialsGameState::createReflection()
	{
		size_t imagewidth = 32;
		size_t imageheight = 32;
		size_t imageDepth = 1;
		Ogre::PixelFormat format = Ogre::PF_A8B8G8R8;

		parentTex = Ogre::TextureManager::getSingleton().createManual("reflectionTest", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, 
			Ogre::TEX_TYPE_CUBE_MAP, imagewidth, imageheight, imageDepth, 11, format);
		
		Ogre::String skyboxNames[6] = {"SunSetFront.png" , "SunSetBack.png", "SunSetRight.png", "SunSetLeft.png", "SunSetUp.png" , "SunSetDown.png"};

		for (size_t i = 0; i < 6; i++){
			Ogre::String texname = skyboxNames[i];
			int face = i;
			switch (i){ case 0: face = 4; break; case 1: face = 5; break; case 2: face = 1; break; case 3: face = 0; break; case 4: face = 2; break; case 5: face = 3; break; }

			Ogre::Image image; image.load(texname, Ogre::ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME);
			image.resize(imagewidth, imageheight);
			image.generateMipmaps(true);
			Ogre::TexturePtr texPtr = Ogre::TextureManager::getSingleton().loadImage("tempsky1", "General", image, Ogre::TEX_TYPE_2D, image.getNumMipmaps(), 1.0, false, Ogre::PF_A8B8G8R8, true);
			
			Ogre::uint8 minMipmaps = std::min<Ogre::uint8>(image.getNumMipmaps(), parentTex->getNumMipmaps());

			for (size_t mip = 0; mip < image.getNumMipmaps(); mip++){
				Ogre::v1::HardwarePixelBufferSharedPtr sourceBuffer = texPtr->getBuffer(0, mip);
				Ogre::v1::HardwarePixelBufferSharedPtr destBuffer = parentTex->getBuffer(face, mip);
				if (sourceBuffer.isNull() || destBuffer.isNull()) { 
					continue; 
				}
				destBuffer->blit(sourceBuffer);
			}
						
			// Remove the temporary texture we used.
			Ogre::TextureManager::getSingleton().remove(texPtr);
		}
	}
DX11 Pixel buffer class is getting some serious ass whooping!! :D

So hope this helps and enjoy :D

Edit: You can apply the texture like other standard 2D textures by calling this on the datablock:

Code: Select all

datablock->setTexture( Ogre::PBSM_REFLECTION, 0, parentTex);
Lead developer of the Skyline Game Engine: https://aurasoft-skyline.co.uk
User avatar
SolarPortal
OGRE Contributor
OGRE Contributor
Posts: 203
Joined: Sat Jul 16, 2011 8:29 pm
Location: UK
x 51
Contact:

Re: [2.1] DX11 Blitting to cubemaps

Post by SolarPortal »

oh, made one more tweak for blitting from cubemap to cubemap

in the TEX_TYPE_2D like before,
change the SrcSubResource from:

Code: Select all

static_cast<UINT>(rsrcDx11->mSubresourceIndex)
to:

Code: Select all

D3D11CalcSubresource(static_cast<UINT>(rsrcDx11->mSubresourceIndex), rsrcDx11->mFace, rsrcDx11->mParentTexture->getNumMipmaps() + 1),
Edit: So for easy merging, here is the case TEX_TYPE_2D: in
function void D3D11HardwarePixelBuffer::blit(....

Code: Select all

case TEX_TYPE_2D:
	{
		mDevice.GetImmediateContext()->CopySubresourceRegion(
			mParentTexture->GetTex2D(),
			D3D11CalcSubresource(static_cast<UINT>(mSubresourceIndex), mFace, mParentTexture->getNumMipmaps() + 1),
			static_cast<UINT>(dstBox.left),
			static_cast<UINT>(dstBox.top),
			
			// << CODE TWEAK BEGIN
			0,
			// << CODE TWEAK END
			
			rsrcDx11->mParentTexture->GetTex2D(),
			
			// << CODE TWEAK BEGIN
			D3D11CalcSubresource(static_cast<UINT>(rsrcDx11->mSubresourceIndex), rsrcDx11->mFace, rsrcDx11->mParentTexture->getNumMipmaps() + 1),
			// << CODE TWEAK END
			
			&srcBoxDx11);
		if (mDevice.isError())
		{
			String errorDescription = mDevice.getErrorDescription();
			OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
				"D3D11 device cannot copy 2d subresource Region\nError Description:" + errorDescription,
				"D3D11HardwarePixelBuffer::blit");
		}
	}
	break;
Lead developer of the Skyline Game Engine: https://aurasoft-skyline.co.uk
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5296
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1278
Contact:

Re: [2.1] DX11 Blitting to cubemaps

Post by dark_sylinc »

Wish granted.
Unlike your other report there is no doubt your fixes are what the code should have been written as in the first place.
User avatar
SolarPortal
OGRE Contributor
OGRE Contributor
Posts: 203
Joined: Sat Jul 16, 2011 8:29 pm
Location: UK
x 51
Contact:

Re: [2.1] DX11 Blitting to cubemaps

Post by SolarPortal »

Excellent. Thanks for merging in :)
Lead developer of the Skyline Game Engine: https://aurasoft-skyline.co.uk
Post Reply