Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Page 1 of 2 12 LastLast
Results 1 to 10 of 18

Thread: Hiding a bitmap

  1. #1
    Advanced Member Frequent Contributor
    Join Date
    Dec 2005
    Location
    Italy
    Posts
    656

    Hiding a bitmap

    Hi All,


    Here is today's question:

    We need to draw a label (square bitmap containing a number) for numbering each cube vertex. The cube is shaded.

    We managed to draw the bitmap in each corner converting world coords in screen coords but we don't know how to hide the labels behind the cube.

    How can be done?


    Thanks,

    Alberto

  2. #2
    Advanced Member Frequent Contributor yooyo's Avatar
    Join Date
    Apr 2003
    Location
    Belgrade, Serbia
    Posts
    883

    Re: Hiding a bitmap

    Use gluProject call to get proper screen coordinates. Now, readback depth value at specific point and check against projected value. If projected value is smaller than readed depth (means closer to viewer) then draw string.

    gluProject returns screen x, y coordinate of projected point and screen depth (0..1).

  3. #3
    Advanced Member Frequent Contributor
    Join Date
    Dec 2005
    Location
    Italy
    Posts
    656

    Re: Hiding a bitmap

    Thanks yooyo,

    How do I "read back depth value at specific point" ?

    Thanks,

    Alberto

  4. #4
    Member Regular Contributor remdul's Avatar
    Join Date
    Mar 2004
    Location
    The Netherlands
    Posts
    335

    Re: Hiding a bitmap

    Use glReadPixels, read back one pixel (or more than one if you wan to smoothly fade out depending on how much of the vertex is visible) from the depth buffer. Draw glPoints to the depth buffer before you call read them back (use glPointSize(2) to avoid accuracy problems with gluProject, if any).

    glReadPixels will induce a pipeline stall though. If you want fastest possible performance, I would suggest to render the labels as sprites (GL_QUADS or perhaps point sprites) in the scene at a constant size (relative to screen), and take advantage of depth-testing.

    If the cube is wireframe, use glColorMask to disable color buffer rendering, and 'bake' the solid cube to the z-buffer. Then enable color rendering again, and draw the labels.

    You may want to use polygon offset to avoid intersection of the sprites with the cube.

    Another alternative is to use occlusion queries, rather than glReadPixels.

  5. #5
    Advanced Member Frequent Contributor
    Join Date
    Dec 2005
    Location
    Italy
    Posts
    656

    Re: Hiding a bitmap

    I need to test only one pixel the one where the label is attached.

    Why should I draw points? It isn't enough to read the pixel depth and compare it with the label anchor 3D point?

    Thanks.

    Alberto

  6. #6
    Member Regular Contributor remdul's Avatar
    Join Date
    Mar 2004
    Location
    The Netherlands
    Posts
    335

    Re: Hiding a bitmap

    It highly depends on rasterization of the depth at the vertex positions, and how accurate your 'world to screen coordinate' projection function is (but to a lesser degree). If the depth changes alot between frames, the tags may flicker.

    I've implemented something similar before. Slight differences in the rasterized vs. projected depth coordinates caused the tags to flicker, because the depth value would one frame be deeper (invisible), and the next to be exactly the same or larger (visible). Because the distribution of the depth buffer is non-linear, you can't simply add a depth margin to counter this.

    I did not use the projected winZ component returned by gluProject, as it is in linear space, and the depth buffer is non-linear. You could probably use winZ to calculate it proper, but you have to get the exact formula that the GL implementation uses or add a margin.

    If I recall correctly, I did it like this:
    1) render visible scene
    2) disable color buffer rendering (glColorMask) and clear depth buffer
    3) glPointSize(3), to take in account inaccuracy of project function and badly implemented rasterization (read Intel graphics drivers)
    4) render vertices as GL_POINTS to depth buffer
    5) loop through vertices and project these to get the screen coordinates, store these
    6) loop through vertices and read back depth from z-buffer, store this
    7) render occluder (e.g. solid cube)
    8) loop through vertices second time, and read back depth, store as well
    9) setup 2d view projection (for 2d font/tag drawing etc)
    10) loop through vertices and do the depth compare, if visible draw tag, if invisible skip

    I had a structure for each vertex something like this:

    struct vert
    {
    vec3 pos; // world space position
    int screen_x; // projected screen space X
    int screen_y; // projected screen space Y
    float depth_1; // read back depth at screen space X,Y before occluder is drawn
    float depth_2; // read back depth at screen space X,Y after occluder is drawn
    };

    Keep in mind this way vertices may also occlude other vertices (in my case this was desirable), but can be avoided if you dot he whole process for vertices individually (not recommended!).

    As you can see, lots of glReadPixels with means lots of stalls. In my application this was ok, as it wasn't real-time.

    IMO, better to draw the tags into the 3d scene, if that is ok for your purposes. It is faster and relies less on the assumed correctness of the GL implementation. You just need to make sure the tags are scaled properly with respect to the eye position and it will work efficiently.

  7. #7
    Advanced Member Frequent Contributor
    Join Date
    Dec 2005
    Location
    Italy
    Posts
    656

    Re: Hiding a bitmap

    Hi remdul,


    Thanks for your detailed description: looks not trivial btw.

    We thought a lot about doing it in 3D but the problem is we want labels always parallel to screen and of the same size.


    Thanks,

    Alberto

  8. #8
    Junior Member Regular Contributor
    Join Date
    Feb 2006
    Location
    greece
    Posts
    183

    Re: Hiding a bitmap

    You may also use point sprites with textures for the numbers and maybe offset the depth coordinate a little at the fragment shader to account for depth fighting at the front of the cube.
    while(1){keyboardsolo(FORTE, BPM_190);}

  9. #9
    Super Moderator OpenGL Lord
    Join Date
    Dec 2003
    Location
    Grenoble - France
    Posts
    5,655

    Re: Hiding a bitmap

    As explained remdul, going for full 3D is less fragile.
    Point sprites are nice but not always available, and some implementations have bugs.

    Search for 'opengl billboarding', this is pretty common.

  10. #10
    Advanced Member Frequent Contributor
    Join Date
    Dec 2005
    Location
    Italy
    Posts
    656

    Re: Hiding a bitmap

    ZbuffeR,


    I gave a look to the billboarding concept and still I think we don't need it: mainly because we need the same scale for each label (drawn like a semitransparent bitmap). Btw if billboarding is easiear to implement we must think of it.

    To make everybody understand better our problem I add an image: TankNodes.jpg (hidden labels must not be drawn)

    What do you think? Should we go for remdul apprach or for billboarding?


    Thanks so much again guys.

    Alberto


Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •