Jump to content


Getting color info from HDR texture


4 replies to this topic

#1 starstutter

    Senior Member

  • Members
  • PipPipPipPip
  • 1039 posts

Posted 30 January 2008 - 04:57 PM

D3DLOCKED_RECT sRect;
lightMap ->LockRect(0, &sRect, NULL, NULL);
D3DXFLOAT16 *bytes = (D3DXFLOAT16*)sRect.pBits;


for(int y=0;y<128;y++)
     for(int x=0;x<128;x++)
    {
        D3DXFLOAT16 *b = bytes + y * (sRect.Pitch / 4) + x;

					
        if (*b > 0)
        {
              uvCount++;
              flat[2].pixPos[uvCount].x = *b.r;
              flat[2].pixPos[uvCount].y = *b.g;
              flat[2].pixPos[uvCount].z = *b.b;
        }

    }
						
lightMap->UnlockRect(0);

Some may look at the code above and say "What an idiot..." But, I have no clue what to do next. It's one of those little tidbits on google that seems to be impossible to find without some key word.

I can get the pixel information out of this floating point texture, but I don't seem to be able to access the specific color channels (rgb and a). Is there a special variable declaration I need? Is it possible to use a vector? I was told I needed to use D3DXFLOAT16 to get the info out.

#2 Reedbeta

    DevMaster Staff

  • Administrators
  • 4979 posts
  • LocationBellevue, WA

Posted 30 January 2008 - 05:49 PM

What's the 4 for that you're dividing into sRect.Pitch? I'm assuming the pitch is in bytes, and you're trying to convert it into a number of D3DXFLOAT16s, so you should divide by sizeof(D3DXFLOAT16), which is 2? Also, I'm not sure what *b.r, *b.g, and *b.b are intended to be, since according to MSDN, the D3DXFLOAT16 structure only contains a single 16-bit value, not an RGB tuple. You'll presumably need to access b[0], b[1], and b[2] (or maybe b[3], b[2], and b[1] depending on endianness) to get the components, since b is a pointer into the image data.

Also, please use the [code][/code] tags when you post code, so that it keeps the indentation.
reedbeta.com - developer blog, OpenGL demos, and other projects

#3 starstutter

    Senior Member

  • Members
  • PipPipPipPip
  • 1039 posts

Posted 30 January 2008 - 06:27 PM

Thanks for the response,

Well, the "/ 4" was a piece of information that I got from another forum. It was someone asking about getting info from a floating point texture, but kept getting an overflow. Someone then told him that he needed to divide it by 4. The same thing was happening to me, so I tried it and suddenly it worked. Why, dunno... Maybe I actually sprung another problem.

Yes, the FLOAT16 is just one value, which is my problem. But according to the same resource, I have to extract the information this way (although it's possible I misunderstood) and nothing else has worked so far.

Quote

You'll presumably need to access b[0], b[1], and b[2] (or maybe b[3], b[2], and b[1] depending on endianness) to get the components, since b is a pointer into the image data.


Is that the literal instructions (accessing the pointer as if it were an array), or is that pseudo-code for something else. Interacting with data taken from textures and the GPU is a very new concept to me and I'm still having much trouble with understanding exactly how information is stored and accessed.

EDIT: Oh, and if it matters at all, speed is preferred, but is not necessary. This is to be used in pre-computation. I'll take any method to just get it working.

#4 Reedbeta

    DevMaster Staff

  • Administrators
  • 4979 posts
  • LocationBellevue, WA

Posted 30 January 2008 - 09:02 PM

Well, I don't see how b.r, b.g, and b.b even compiles. According to the definition of the structure on MSDN, those members don't even exist, so I don't see how you could use them. b[0], b[1], and b[2] are the literal code, yes.

The texture is just laid out in memory as a big array, row by row, pixel by pixel. The pitch is the number of bytes in a single row (usually this is just the image width times the bytes per pixel, but sometimes it is more due to memory layout issues). Within each pixel there are four D3DXFLOAT16 components, representing the four channels (R, G, B, and A, though I'm not positive in which order they'll be stored). It's really quite simple once you understand it. You'll generally access the array using an index of the form [y * pitch / sizeof(D3DXFLOAT16) + x * components_per_pixel]. For example,
for (int y = 0; y < height; ++y)
{
    for (int x = 0; x < width; ++x)
    {
        // we make a pointer to the beginning of the current pixel for convenience
        D3DXFLOAT16 *pixel = bytes + y * pitch / sizeof(D3DXFLOAT16) + x * 4;  // the 4 is for 4 components per pixel, i.e. RGBA
        // now we can access this pointer to get the specific components
        do_something_with(pixel[0], pixel[1], pixel[2], pixel[3]);
    }
}
If you just sit down with a pencil and paper and do a few examples to see how that works, I'm sure you'll get it.
reedbeta.com - developer blog, OpenGL demos, and other projects

#5 starstutter

    Senior Member

  • Members
  • PipPipPipPip
  • 1039 posts

Posted 30 January 2008 - 10:56 PM

is there anything you DON'T know? lol, thanks a lot, it works bit similar to how I thought. I was having trouble determining how "pitch" worked, but now I see.

Thanks, you've been a huge help.





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users