Histogram

Hello, I want to use the OpenGL histogram to compute the area of each triangle. So, I give a different color for every triangle and then compute the histogram. The problem is that I only have 1020 colors (256 + 256 + 256 + 256) - 4 (RGBA) ( - 4 is due to the background) and I have to do several rendering passes, because I’m trying to render an object about 5400 triangles.
The first idea that comes to my mind is to use a pixel format RGBA16 so I’ll have more colors (65536 + 65536 + 65536 + 65536). I don’t know if it is possible. Previously I’ve used the pbuffer extensions for creating a buffer with this features:

    WGL_DRAW_TO_PBUFFER_ARB,
    GL_TRUE,
    WGL_SUPPORT_OPENGL_ARB,
    GL_TRUE,
    WGL_FLOAT_COMPONENTS_NV,
    GL_TRUE,
    WGL_RED_BITS_ARB,
    16,
    WGL_GREEN_BITS_ARB,
    16,
    WGL_BLUE_BITS_ARB,
    16,
    WGL_ALPHA_BITS_ARB,
    16,
    WGL_DEPTH_BITS_ARB,
    24,

And then I’ve tried this.

activate_pbuffer();

// clear all pixels.
glClear( GL_COLOR_BUFFER_BIT );

renderGeometry();

glHistogram(GL_HISTOGRAM, 65536, GL_RGBA16, GL_TRUE);

glEnable(GL_HISTOGRAM);

// Perform the pixel operation
glCopyPixels(0, 0, width, height, GL_COLOR);

glGetHistogram(GL_HISTOGRAM, GL_FALSE, GL_RGBA, GL_UNSIGNED_INT, histoGram);

glResetHistogram(GL_HISTOGRAM);
glDisable(GL_HISTOGRAM);

deactivate_pbuffer();

But it doesn’t work. Any idea?
Thank you in advance.

Originally posted by castellp:
Hello, I want to use the OpenGL histogram to compute the area of each triangle.
Don’t. Do the math yourself.

area_of_triangle:=0.5width_of_triangleheight_of_triangle

The width is the length of one transformed triangle edge (pick one). Let’s say A’B’.
The height is |p*(C’-A’)|, or, just as well, |p*(C’-B’)|, where p is a unit vector perpendicular to A’B’.

A’, B’ and C’ are the vertices’ 2D positions after MVP transformation, perspective divide and viewport transformation. Because this is a 2D operation, there are only two possible p for any given vector, and by taking the absolute magnitude of the result, any difference that might make will be eliminated.

Just for the record, you have a bit more than 4 Billion colors. Thats 256 * 256 * 256 * 256 - 1, because you can use every combination of red, green, blue and alpha once except background.

Do you want the whole area of each triangle, or only the visible area? If you want the whole area, use the method described by zeckensack, it is much faster.

Originally posted by castellp:

But it doesn’t work. Any idea?
Thank you in advance.

The maximum possible histogram size is implementation-dependent. Do a glGetError after your histogram setup to make sure it actually works. The ones I’ve seen (but hat was on sgi a long time ago) were 4096 max, and that seemed a pretty reasonable size.

The question is whether histogram is really faster than reading the image and doing it yourself. Histogram is such a rarely function that I’d honestly be a little surprised to see it implemented in hardware on gaming cards.

Originally posted by Overmind:
Just for the record, you have a bit more than 4 Billion colors. Thats 256 * 256 * 256 * 256 - 1, because you can use every combination of red, green, blue and alpha once except background.

No, not if you use the histogram. That only stores the number of pixels with a certain R/G/B/A value. Doing what you’re proposing would necessitate a 4 GB buffer for the histogram on the card. I’d like to have a card like that (you can never have too much texture memory for volumes :wink: ), but the nVidias don’t do that yet.


Do you want the whole area of each triangle, or only the visible area? If you want the whole area, use the method described by zeckensack, it is much faster.

The advantage of the pixel-based method is that it respects occlusions. Doing that on the geometry becomes messy quickly.

Why don’t use occlusion query for each triangle?

First, render scene normaly, then render again (with color mask, disable depth write, enable depth test) but this time with occlusion query?

yooyo

Originally posted by dirk:
The advantage of the pixel-based method is that it respects occlusions. Doing that on the geometry becomes messy quickly.
Yep.
FWIW, the math approach will always slightly disagree with a rasterizer anyway, even if there’s no occlusion, because a rasterizer won’t resolve anything smaller than a pixel or multisample thingy.

It depends on which version of the area is required. If it’s just “area of triangle”, IMO math is the correct approach. If OTOH it’s “are of triangle as it would be rendered”, occlusion queries are a very good idea.

In either case I don’t think there’s a good enough reason to proceed with the GL histogram.

I’m sorry, I have explained wrongly what I want to compute is just the area of the visible triangles. Thank you.

Originally posted by zeckensack:
[b] [quote]Originally posted by castellp:
Hello, I want to use the OpenGL histogram to compute the area of each triangle.
Don’t. Do the math yourself.

area_of_triangle:=0.5width_of_triangleheight_of_triangle

The width is the length of one transformed triangle edge (pick one). Let’s say A’B’.
The height is |p*(C’-A’)|, or, just as well, |p*(C’-B’)|, where p is a unit vector perpendicular to A’B’.

A’, B’ and C’ are the vertices’ 2D positions after MVP transformation, perspective divide and viewport transformation. Because this is a 2D operation, there are only two possible p for any given vector, and by taking the absolute magnitude of the result, any difference that might make will be eliminated.[/b][/QUOTE]

Looks to me like yooyo provided you with a suitable answer.

Nico

Why don’t use occlusion query for each triangle?

First, render scene normaly, then render again (with color mask, disable depth write, enable depth test) but this time with occlusion query?

yooyo
I think yooyo is right - that’s the easiest way to do it (in my opinion) - if you use the ARB extension it will return the number of visible pixels for each triangle and that’s what you want, istn’t it?

-AnselmG