Jump to content
  • Advertisement
Sign in to follow this  

How to render skybox, then save to a texture?

This topic is 1076 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Is there possible to render a skybox, then save to a texture? I successfully rendered a skybox, but I failed to save to a texture. Everything is okay when I render something else and save to a texture.


Is there anybody experienced this problem?





Share this post

Link to post
Share on other sites

Yes this is possible I am assuming you will want to use the resulting texture for something else afterwards in the game. IN that case you will want to do an offscreen render of the sky box into a render target.


Both these tutorials show how this works.




In general it works by replacing the backbuffer with a different rendertarget that you have created. You first ask for the back buffer reference, keep this arround because you will want to restore this after you have drawn to your texture. You then set your new Rendertarget as the back buffer and draw the scene that you want to have displayed in that texture. Restore the orginal back buffer and render the scene that should be seen as the game and use the RenderTarget you created as an input texture to the object you want to show it on or use it for.

Share this post

Link to post
Share on other sites

Thanks for the replys. When I saved the rendering result, a skybox, to a texture, returned value is S_OK but the texture is black.


I have done the same thing NightCreature83, but the output texture is black. I have also tried with an example downloaded from http://www.braynzarsoft.net/index.php?p=D3D11CUBEMAP and the output texture also black.


This is a C++ code for saving to a texture

        HRESULT hr;
	ID3D11Resource *backbufferRes;

	D3D11_TEXTURE2D_DESC texDesc;
	texDesc.ArraySize = 1;
	texDesc.BindFlags = 0;
	texDesc.CPUAccessFlags = 0;
	texDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
	texDesc.Width = width;  // must be same as backbuffer
	texDesc.Height = height; // must be same as backbuffer
	texDesc.MipLevels = 1;
	texDesc.MiscFlags = 0;
	texDesc.SampleDesc.Count = 1;
	texDesc.SampleDesc.Quality = 0;
	texDesc.Usage = D3D11_USAGE_DEFAULT;

	ID3D11Texture2D *texture;
	HR(pd3dDevice->CreateTexture2D(&texDesc, 0, &texture));
	pd3dImmediateContext->CopyResource(texture, backbufferRes);

	hr = D3DX11SaveTextureToFile(pd3dImmediateContext, texture, D3DX11_IFF_JPG, L"test1.jpg");
Edited by steven166

Share this post

Link to post
Share on other sites

If you want to use the texture as a render target you have to bind it that way  my cube descriptors look like this:

    D3D11_TEXTURE2D_DESC cubeDesc;
    ZeroMemory(&cubeDesc, sizeof(D3D11_TEXTURE3D_DESC));
    cubeDesc.Width = cubeMapWidhtHeight;
    cubeDesc.Height = cubeMapWidhtHeight;
    cubeDesc.MipLevels = 0;
    cubeDesc.ArraySize = 6;
    cubeDesc.SampleDesc.Count = 1;
    cubeDesc.SampleDesc.Quality = 0;
    cubeDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    cubeDesc.Usage = D3D11_USAGE_DEFAULT;
    cubeDesc.CPUAccessFlags = 0;

I am generating a cubemap in my game so thats why the array size is 6 and miscflags are set to be a texturecube.


Just for completeness here is how I setup my descriptors for the RTV and SRV which are used for rendering to it and using it as a texture in game:

//Should create a 6 2D rts here instead
rtDesc.Format = cubeDesc.Format;
rtDesc.Texture2DArray.FirstArraySlice = 0;
rtDesc.Texture2DArray.ArraySize = 6;
rtDesc.Texture2DArray.MipSlice = 0;

// Create the shader resource view for the cubic env map
ZeroMemory(&srvDesc, sizeof(srvDesc));
srvDesc.Format = cubeDesc.Format;
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
srvDesc.TextureCube.MipLevels = 1;
srvDesc.TextureCube.MostDetailedMip = 0;
Edited by NightCreature83

Share this post

Link to post
Share on other sites

btw if you do no rendering between the texture creation, copy and save operation there is nothing in the back buffer and it will be black or what was there last frame. If you do this after the call to clear the bufffer the texture will have the color of the clear color.


You will want to do that copy just before the present call and do the save after the present because a read back from GPU to disc is a costly operation.


Also read the remarks on this topic: https://msdn.microsoft.com/en-us/library/windows/desktop/ff476392%28v=vs.85%29.aspx because the CopyResource call comes with a few requirements that you have to obey for it to work correctly.

Edited by NightCreature83

Share this post

Link to post
Share on other sites

I successfully save to a texture (for testing), but when I bind it as a shader resource view to the next pass the color background is just one solid color and changed as camera moving.


This is C++ source code:

        textureDesc.Width = mClientWidth;
	textureDesc.Height = mClientHeight;
	textureDesc.MipLevels = 1;
	textureDesc.ArraySize = 1;
	//textureDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
	textureDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
	textureDesc.SampleDesc.Count = 1;
	textureDesc.Usage = D3D11_USAGE_DEFAULT;
	textureDesc.CPUAccessFlags = 0;
	textureDesc.MiscFlags = 0;
	textureDesc.SampleDesc.Count = 1;
	V_RETURN(md3dDevice->CreateTexture2D(&textureDesc, NULL, &m_pBackgroundTexture));

	// Setup the description of the render target view.
	renderTargetViewDesc.Format = textureDesc.Format;
	renderTargetViewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
	renderTargetViewDesc.Texture2D.MipSlice = 0;

	// Create the render target view.
	V_RETURN(md3dDevice->CreateRenderTargetView(m_pBackgroundTexture, &renderTargetViewDesc, &m_pBackgroundRTV));

	// Setup the description of the shader resource view.
	shaderResourceViewDesc.Format = textureDesc.Format;
	shaderResourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
	shaderResourceViewDesc.Texture2D.MostDetailedMip = 0;
	shaderResourceViewDesc.Texture2D.MipLevels = 1;

	// Create the shader resource view.
	V_RETURN(md3dDevice->CreateShaderResourceView(m_pBackgroundTexture, &shaderResourceViewDesc, &m_pBackgroundSRV));
Edited by steven166

Share this post

Link to post
Share on other sites

When you bind the SRV you need to make sure you are no longer using the RTV, if you have the DX runtime setup to use the debug version and set the output to warnings, you will get a warning in the output when the SRV is still being used as a RTV.

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!