Re: [UFO-devel] Patch: ufo::UGL_Graphics::mapToDevice()
Status: Beta
Brought to you by:
schmidtjf
|
From: Andreas B. <b_...@gm...> - 2006-04-23 10:28:25
|
Hi again On Tuesday 11 April 2006 18:43, Johannes Schmidt wrote: > You really should set up your own projection matrix when using that. > The current ugl_graphics code adds 0.375f to coordinates according to > OpenGL red book Appendix H. Indeed, that explains a lot. Why is that not documented at all? Neither in any API docs, nor in the actual source code.. I find it very unintuitive, that a projection matrix of size (width+1, height+1) is set up. It makes obviously sense, but if such things happen without letting the user know, it has some pretty unuseful effects (as my patches show). Ok, so a (width+1,height+1) projection is of course correct, as ufo always adds an offset to the specified (integer) coordinates, i.e. my patches are broken. > > > This sounds very reasonable, too. > > > > > > On the other side, every 2D setup I have seen so far uses this approach > > > with 0, 0 and width, height (well, they could be wrong, too). > > > > Every? Examples? > > Just a few: > > OpenGL FAQ on opengl.org: > gluOrtho2D (0, windowWidth, 0, windowHeight); You have taken this line out of context (see below). > OpenGL red book Appendix H btw: in my copy it's still Appendix G. This is about the appendix "Programming Tips". > gluOrtho2D(0, width, 0, height); Again out of context. [...] I haven't checked the other references, but since the redbook is the primary source for most informations, I'd expect that most of them discuss exactly the same issue. The thing that you lacked to quote was the important part of this code, as it justifies, why a "wrong" projection matrix is used: glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0.375, 0.375, 0.0); So you setup a projection matrix on a 2d area with size (width+1, height+1) and then add an offset of 0.375 to all coordinates. It makes sense when you think about the fact that (in order to achieve pixel exact operations) for some operations you need to use 0.0, and for some operations you need to use 0.5 as coordinates for pixel 0 (or the center of it). The idea of the larger projection along with the offset is, that it is a good compromise, i.e. you can always use 0.0, no matter which operation you currently use. That makes indeed sense, however I still don't understand the way you use it. You setup a projection matrix of size (width+1, height+1) (btw: I'd add a comment about this here!) but then you do NOT add the translation to the modelview matrix. Instead you add that translation in every operation that might need the translation. Why do you do that? If you modify every operation anyway, then you could simply use the normal projection matrix and add the correct offset (instead of the 0.375 compromise) to every operation. So why do you add the 0.375 to every separate operation? Other than that I can now agree that both of my patches are broken and that ufo cvs _does_ behave correctly. > > > And I have seen that the width should be right - left which leads to: > > > > Where have you seen that? > > Can't remember where it was used in this case, but this is also the usual > definition when using the RECT structure on windows. > Just search MSDN. I find that pretty hard to believe, it would be _very_ unusual. Two examples: * file:///usr/share/qt3/doc/html/qrect.html#width * your own code: includes/ufo/util/urectangle.hpp: from contains() you can see that points with pos.x=x+w are not inside of the rect anymore, i.e. right:=x+w-1 > > It would be _possible_ to use such a definition, but very unlikely. This > > could mean two things only: > > a) width := (number of pixels in between right and left) - 1 > > -> this is imho a very unusual definition. In particular that means that > > if right==left (i.e. exactly one pixel), then width==0, which is pretty > > inintuitive. > > --> I am pretty sure OpenGL doesn't use that. If it does, your > > glViewport() call before the glOrtho() call is broken :-) > > b) right := leftmost pixel to the right of the rect that is _not_ > > visible. -> again, possible, but unintuitive definition. In particular > > this means that right is completely different to left, as left is clearly > > defined as the first pixel that is _inside_ the rect. > > Remember: We talk about a projection matrix. > OpenGL doesn't know what pixels are in this state of processing vertex > data. Left, right, etc. define clipping planes. If you create a projection matrix of size (w,h) on a window with (w,h) then I think it's pretty obvious, how positions inside the projection matrix are supposed to be projected onto the window :-) And indeed they will be! -> The problem discussed above comes only from the fact that in OpenGL some operations require e.g. glRect(0, 0, 1, 1) to fill pixel (0,0) but some (e.g. points) require (0.5,0.5) to hit exactl pixel (0,0). The offset of 0.375 solves this problem, but it of course requires to have a larger width and height. > Regards, > Johannes CU Andi |