gmmo
gmmo

Reputation: 2801

How do I create a texture 3d programatically?

I am trying to create a texture3d programatically but I am not really understanding how it is done. Should each slice of the texture be a subresource? This what I am trying to do, but it is not working:

// Create texture3d
const int32 cWidth = 6;
const int32 cHeight = 7;
const int32 cDepth = 3;

D3D11_TEXTURE3D_DESC desc;
desc.Width                  = cWidth;
desc.Height                 = cHeight;
desc.MipLevels              = 1;
desc.Depth                  = cDepth;
desc.Format                 = DXGI_FORMAT_R32G32B32A32_FLOAT;
desc.Usage                  = D3D11_USAGE_DEFAULT;
desc.BindFlags              = D3D11_BIND_RENDER_TARGET;
desc.CPUAccessFlags         = 0;
desc.MiscFlags              = 0;

const uint32 bytesPerPixel = 4;
uint32 sliceSize = cWidth*cHeight*bytesPerPixel;
float  tex3d[cWidth*cHeight*cDepth];

memset(tex3d, 0x00, sizeof(tex3d));
uint32 colorIndex = 0;

for (uint32 depthCount = 0; depthCount<depthSize; depthCount++)
{
    for (uint32 ii=0; ii<cHeight; ii++)
    {
        for (uint32 jj=0; jj<cWidth; jj++)
        {
            // Add some dummy color
            tex3d[colorIndex++] = 1.f;
            tex3d[colorIndex++] = 0.f;
            tex3d[colorIndex++] = 1.f;
            tex3d[colorIndex++] = 0.f;
        }
    }
}

D3D11_SUBRESOURCE_DATA initData[cDepth] = {0};

uint8 *pMem = (uint8*)tex3d;

// What do I pass here? Each slice?
for (uint32 depthCount = 0; depthCount<depthSize; depthCount++)
{
    initData[depthCount].pSysMem            = static_cast<const void*>(pMem);
    initData[depthCount].SysMemPitch        = static_cast<UINT>(sliceSize);  // not sure
    initData[depthCount].SysMemSlicePitch   = static_cast<UINT>(sliceSize);  // not sure

    pMem += sliceSize;
}

ID3D11Texture3D* tex = nullptr;
hr = m_d3dDevice->CreateTexture3D(&desc, &initData[0], &tex);

ID3D11RenderTargetView  *pRTV = nullptr;
hr = m_d3dDevice->CreateRenderTargetView(tex, nullptr, &pRTV);

This creates the texture but when I gives me 1 sub-resource? Should it be 3?

I looked at this article, but it refers to texture2d;

D3D11: Creating a cube map from 6 images

If anyone has some snipped of a code that works, I'd like to take a look.

thx!

Upvotes: 2

Views: 3392

Answers (1)

Andon M. Coleman
Andon M. Coleman

Reputation: 43319

In Direct3D, 3D textures are laid out such that sub-resources are mipmap levels. Each mipmap level contains 1/2 as many slices as the previous, but in this case you only have 1 mipmap LOD, so you will only have 1 subresource (containing 3 slices).

As for the pitch, SysMemPitch is the number of bytes between rows in each image slice (cWidth * bytesPerPixel assuming you tightly pack this). SysMemSlicePitch is the number of bytes between 2D slices (cWidth * cHeight * bytesPerPixel). Thus, the memory for each mipmap needs to be arranged as a series of 2D images with the same dimensions.

Upvotes: 2

Related Questions