Finding bitmap pixel value at position

edited October 2015 in General discussions
Hi Everyone,

I need to get the pixel value of the object's texture under the mouse. I figured I can go from mouse position to the position in object's frame by using (in pseudo-code)
posInWorld <- orxRender_GetWorldPosition
posInObject <- orxFrame_TransformPosition
posInTexture <- posInObject - orxObject_GetPivot

Now I need the pixel value at posInTexture. The best I could find was orxDisplay_GetBitmapData, but it gets the entire bitmap data, not the data at one point.

I guess the reason why there's no function to fetch the pixel value at a single point is that the data is on the GPU memory and not the main memory. So, I guess I need to read the entire texture and keep it somewhere, is that correct?

OK, I lied at the beginning, I actually need to get the pixel value at some image other than the object's graphic texture. That texture is something like a map of object parts at various points. That texture will never be displayed, so I need to load it separately. What's the cleanest way to do this (especially considering that textures are loaded asynchronously)? Should I orxDisplay_LoadBitmap it, get the bitmap data and then orxDisplay_DeleteBitmap it? Is there a way to read the bitmap directly into a buffer without going through the GPU memory?



  • edited October 2015
    Oh, and a related question: The body-parts texture mentioned in the question will only have a few different pixel values. like 1,2,3 etc. for a small number of parts. Is it possible to avoid using a 32 bit RGBA image for this purpose? Does orx support such bitmaps in any way?
  • edited October 2015
    Right now, you can only retrieve a full texture at a time, using orx's API.
    If you wanted to simply get one pixel instead of the full texture, you can use the OpenGL/ES API yourself, however it remains a very expensive operation, even for a single pixel, as it introduces a synchronization point between CPU and GPU.

    Now if you want to retrieve it once, just after the texture has been loaded, I'd recommend using orxTexture_CreateFromFile and wait for the orxTEXTURE_EVENT_LOAD event. This will work in both async and sync modes.
    You can even wrap all this inside an orxOBJECT for convenience, simply giving the object a dummy group will make sure the texture will never be used for display.

    Now I'm curious, why would you use a texture if you don't intend to send it to the GPU at all? You can surely pack your data in any format without resorting to hacking it as a texture.

    Regardless, only RGB/A 24/32 is recognized by the loader but you can still pack your information at the bit level yourself instead of simply doing it on a per-channel basis, for example having 4 values of 2 bits inside a single channel. But again, if your data is not intended to end up on the GPU, I don't think it's the best way to go.
  • edited October 2015
    Thanks for all the info iarwain :)

    Yes, I imagined it would be a bad idea to query a single pixel from the GPU.

    I'm hacking it as a texture since it's initially a .png file. It's simply a differently colored export of my frames from inkscape. I could still of course convert it to some other format, but I like the fact that .png is compressed, and that I can visualize it if I wanted to. Is there any way to load a .png in orx without going through a texture? I've checked the source code, and loading a texture involves display plugin functions, which are inaccessible to the user, so I thought a texture is the only way to go.
  • edited October 2015
    I see. You can also use any png lib to extract your file directly, like the one that's use with orx: stb_image.
  • edited November 2015
    We have some colour encoded map data saved in PNG and at runtime handle it exactly the way Rom suggested... by reading it into a byte array with a single stb_image function call.
  • edited November 2015
    Thanks for your input joew, I'm a bit reluctant to add external dependencies, since I'm trying to maintain a cross-platform, cross-{desktop,mobile} build configuration. In the end, I went with loading the image as a texture during preload and capturing the data at the texture load event handler.
Sign In or Register to comment.