Rectangles don't have the same size

Started by
11 comments, last by haegarr 13 years, 1 month ago
Hi

I need to display a huge number of rectangles on the screen. (Between 500 and 1000000)
To be more accurate, I'm implementing a viewer which shows the status of a tiled field. Each tile can be in an other state, indicated by it's color.
The whole thing only needs to be in 2D. Therefore I chose an orthogonal projection.

Unfortunately I just faced the problem, that rectangles, which are displayed on the screen, don't have the same size. (OK, it's just one pixel. But especially with small tiles, this could become unacceptable).

The other problem is, that when I zoom out, that not all the gaps between the tiles are drawn (I wouldn't mind if none of them is drawn when zooming out):

badexampleZH0S1.png

I guess, that this is because of a rounding problem inside OpenGL, isn't?
Is there a way how I can avoid this?


Thank you and greetings from Switzerland
Lumanior
Advertisement
You can avoid the lines by removing the gap, making all adjacent tiles share the same exact vertex positions. If you want separator lines when zoomed in, try drawing lines on top of them instead if the zoom-level is close enough.
To make all the tiles the same size, make sure your camera and tile positions are aligned on a full pixel, and not like 10.5 instead of 10.0. This is generally not possible if you allow zooming, but for exactly 100% zoom it shouldn't be a problem if you put all your vertices on integer values and do the same for the camera.
Thank you!
But this would mean a big design change for me, because I wouldn't be able to draw the rectangles with their real size. (for example 2.12 mm)

My hope was, that there is an option, that OpenGL could raster the pixel in an average color, if there are two different rectangles, which are smaller than a pixel.
Is this possible in some way?
Multi-sampling, but that's still an approximation.
...To make all the tiles the same size, make sure your camera and tile positions are aligned on a full pixel, and not like 10.5 instead of 10.0. ...

Err... In the screen space the co-ordinates with .5 are exactly on the center or pixels, while those with .0 lie between pixels. Now considering floating point inaccuracies, one may fall slightly on the left or right of .0, and hence get the co-ordinate on the left or right pixel.Hence, ensure that the co-ordinates are close to .5 if you want pixel perfect rendering.

EDIT: Please read further in this thread. There is a difference between addressing lines/points or else faces ...

[quote name='Erik Rufelt' timestamp='1299747642' post='4783908']...To make all the tiles the same size, make sure your camera and tile positions are aligned on a full pixel, and not like 10.5 instead of 10.0. ...

Err... In the screen space the co-ordinates with .5 are exactly on the center or pixels, while those with .0 lie between pixels. Now considering floating point inaccuracies, one may fall slightly on the left or right of .0, and hence get the co-ordinate on the left or right pixel.Hence, ensure that the co-ordinates are close to .5 if you want pixel perfect rendering.
[/quote]

But this only applies, if I want to draw a rectangle with a size specified in pixel, doesn't it?
But the thing I want to do is: I have rectangles with a size (lets say a width of 0.012) and then I set up the orthoganal projection as followed:
glOrtho(0,0.2,0.2,0,-1.0,1.0);
(0.2 specify the area I want to display. The zooming is done through adjusting this parameters)
The thing I want to achieve is, that either all the lines, or none of them are displayed. Since those lines have got all the same width, this should be possible, right?
Or do I get something completely wrong?

...
But this only applies, if I want to draw a rectangle with a size specified in pixel, doesn't it?
...

It applies ever when the co-ordinate is mapped to a pixel. The question is, however, if you have a possibility to control the co-ordinates accordingly.


...
But the thing I want to do is: I have rectangles with a size (lets say a width of 0.012) and then I set up the orthoganal projection as followed:
glOrtho(0,0.2,0.2,0,-1.0,1.0);
(0.2 specify the area I want to display. The zooming is done through adjusting this parameters)
...

With that set-up you define (speaking of the horizontal dimension only) that the view space co-ordinate 0 should be mapped on the left border of the first pixel of the render target, and that 0.2 in view space should be mapped on the right border of the last pixel in the render target. Assume that the render target is 800 pixels wide, then any view co-ordinate v[sub]x[/sub] gets the pixel co-ordinate
p[sub]x[/sub] := v[sub]x[/sub] / 0.2 * 800

If you render a vertical line exactly at p[sub]x[/sub]=0, you'll see that the line will not appear on screen. If you render it at any 0<p[sub]x[/sub]<=1 you'll see the line at the very left pixel column of the render target. If you render it at any 1<p[sub]x[/sub]<=2 you'll see the line one pixel to the right, and so on.

This means for your co-ordinates in view space, that any line with n*(0.2/800)<v[sub]x[/sub]<=(n+1)*(0.2/800) will appear at pixel column n, where all columns with 0<=n<800 will be visible.

All this happens so when multi-sampling is off, of course.


...
The thing I want to achieve is, that either all the lines, or none of them are displayed. Since those lines have got all the same width, this should be possible, right?
Or do I get something completely wrong?

If you render the lines explicitly, then they will all occur. If you render faces instead, things get a bit more complicated. To avoid overdraw when adjacent faces are rendered, the rightmost pixel in each scanline and the bottommost (or topmost? I'm not sure) pixel of each column will be suppressed. Hence you cannot draw a line by using, say, a quad with a width that results in less than 1 pixel.


My advice is this: Build the tiles so that their co-ordinates in world/view space are seamless. This guarantees that no gaps appear. However, you cannot guarantee that all tiles will have same size as long as you don't adapt the zoom to the render target's pixel amount. Render lines explicitly on top if you want a grid.

All this happens so when multi-sampling is off, of course.


If multi-sampling is on, all the lines will be drawn, but their appearance will be a bit blurry. Is that right?

[quote name='haegarr' timestamp='1299754585' post='4783950']
All this happens so when multi-sampling is off, of course.


If multi-sampling is on, all the lines will be drawn, but their appearance will be a bit blurry. Is that right?
[/quote]
Not necessarily. When looking at multi-sampling as the same method but with a higher resolution, then misses may still happen. They are just less frequent.

The "blurry" appearance comes from the mapping of the higher sample resolution onto the lesser pixel resolution. A pixel will not appear blurry if all its samples have hit the same primitive. If, for example, 2x2 regularly distributed samples are used to compute a pixel by averaging, and p[sub]x[/sub]=0.5, then half of the samples hit the background and the other half hit the primitive, resulting in a 50:50 mix.

[quote name='Lumanior' timestamp='1299757987' post='4783962']
[quote name='haegarr' timestamp='1299754585' post='4783950']
All this happens so when multi-sampling is off, of course.


If multi-sampling is on, all the lines will be drawn, but their appearance will be a bit blurry. Is that right?
[/quote]
Not necessarily. When looking at multi-sampling as the same method but with a higher resolution, then misses may still happen. They are just less frequent.

The "blurry" appearance comes from the mapping of the higher sample resolution onto the lesser pixel resolution. A pixel will not appear blurry if all its samples have hit the same primitive. If, for example, 2x2 regularly distributed samples are used to compute a pixel by averaging, and p[sub]x[/sub]=0.5, then half of the samples hit the background and the other half hit the primitive, resulting in a 50:50 mix.
[/quote]

With other words: There is no other option than drawing the rectangles, resp. the lines between, in pixel coordinates?
Or is it possible to calculate some specific zoom levels depending on the rectangle sizes, which always will lead to a correct representation of the gaps between the rectangles?

This topic is closed to new replies.

Advertisement