Reading from a floating point texture resource

Started by
5 comments, last by Nik02 7 years, 2 months ago

HI, im trying to read data from a mapped resource that is in FLOAT_32 format

the texture is 4096*4096.. I'm trying to read into a 2D array of floats like this : heightmap_array[4096][4096]....

it seems to work ok, but I suspect something is wrong..because it seems to be too low res or something: (but the file doesn't have mipmaps) the problem might be in this line:

int rowStart = mappedResource.RowPitch*(row / sizeof(float));

not sure if this is really right.. meaning the sizeof(float) part.. is that needed? however without it, it seems to not get enough data to fill the array

void load_heightmap()
{
int heightmapsize = 4096;
D3D11_MAPPED_SUBRESOURCE mappedResource;
d3d11DevCon->Map(heightmap_res, NULL, D3D11_MAP_READ, NULL, &mappedResource);
float *sptr =(float*)(mappedResource.pData);
if (!sptr)
{
d3d11DevCon->Unmap(heightmap_res, 0);
heightmap_res->Release();
MessageBox(NULL, L"Error mapping heightmap data",
L"Error", MB_OK | MB_ICONERROR);
return;
}
// Loop through all pixels in texture and copy to output buffer
for (int row = 0; row < heightmapsize; row++)
{
int rowStart = mappedResource.RowPitch*(row / sizeof(float));
for (int col = 0; col < heightmapsize; col++)
{
heightmap_array[col][row] = sptr[(rowStart + col)];
}
}
d3d11DevCon->Unmap(heightmap_res, 0);
heightmap_res->Release();
}

Advertisement

OK, it figures I solve the issue immediately after i post my question....however, I still dont know why its happening...

I found that changing this line:

int rowStart = mappedResource.RowPitch*(row/sizeof(float)); to

int rowStart = mappedResource.RowPitch*(row*0.25);

solves the problem, now all seems to be right...anyone understand whats going on here? Is there anything I need to be aware of?

So you're reading from the mapped data using a pointer of type "float", but "RowPitch" is in bytes. You can make this a bit easier by working with a byte pointer instead of a float pointer, so that you can perform your arithmetic in terms of bytes instead of 4-byte floats. Try something like this

uint8_t* sptr = (uint8_t*)(mappedResource.pData);

for(int row = 0; row < heightmapsize; row++)
{
    float* rowStart = (float*)(sptr + (mappedResource.RowPitch * row))
    for (int col = 0; col < heightmapsize; col++)
    {
        heightmap_array[col][row] = rowStart[col];
    }
}

row/sizeof(float) is an integer division :)

Niko Suni

row/sizeof(float) is an integer division :)

This is the real answer right here. That is an integer divide, and putting it in parentheses causes it to be evaluated in full before evaluating the rest of the expression.

To get it to work as intended you need to remove the parentheses, turning


int rowStart = mappedResource.RowPitch*(row/sizeof(float));

into


int rowStart = mappedResource.RowPitch*row/sizeof(float);

Ok guys, I think i understand better now.. its working fine now. Thanks

The code that MJP posted is more efficient, though, as it does not use any divisions and only integer math :)

Niko Suni

This topic is closed to new replies.

Advertisement