On Mar 25, 3:37 pm, Gary Herron <[email protected]> wrote: > Jonathan Hartley wrote: > > On Mar 24, 11:21 pm, Gary Herron <[email protected]> wrote: > > >> Jonathan Hartley wrote: > > >>> I'm wondering whether it's possible to compensate for non-square pixels. > > >>> Using vector graphics drawn from OpenGL, in some resolutions my > >>> circles are wider than they are tall, and in other resolutions they > >>> are taller than they are wide. At my LCD's max, native resolution, the > >>> circles are perfect, and to confirm this, the aspect of this max > >>> screen resolution matches the physical measurements of the screen. > >>> Other resolutions vary in aspect ratio from 1.25 up to 1.7, with a > >>> corresponding distortion to the graphics onscreen. > > >>> I started out trying to compensate for non-square pixels when running > >>> in lower resolutions , by setting my gluOrtho2D params. I assume that > >>> the max available resolution on a display comprises square pixels, and > >>> then compare the current resolution's aspect ratio to this. This works > >>> great, in both fullscreen and windowed mode. > > >>> However, then I switched from Linux to Windows, and on the same > >>> hardware, this time the drivers provide modes which have 'black bars' > >>> down the sides. So the reported resolution does not use the whole > >>> screen real estate. This throws off my 'compenation' calculation, and > >>> in fact pretty much makes it redundant, so I'd like to stop performing > >>> this pixel aspect correction in this case. But I've no idea how to > >>> detect this circumstance from software. > > >>> I guess I could have a manual tweak for pixel aspect ratio, that the > >>> user could set. Meh. > > >>> I assume automating this can't reliably be done, unless someone has > >>> information to the contrary. Ideas, thoughts, etc, welcome. > > >>> Jonathan > > >> Yes, easily done... not with a call for that specific purpose, but > >> OpenGL provides the building blocks necessary to achieve the desired > >> result for any size/shape/number of pixels. > > >> With a call to glViewport, you set the range of pixels you are using, > >> and with a call to one of glFrustum, gluPerspective, glOrtho or > >> gluOrtho2D, you set the range of world space coordinates you wish to use. > > >> In a normal square-pixel situation, the viewport's height/width ratio > >> should equal the frustum's height/width ratio. In non-square-pixel > >> situations, those two ratios will differ. > > >> Equations can be provided if anyone cares to see the specifics ... > > >> Gary Herron > > > Hey Gary, > > > Thanks, yes I did get non-square pixel correction working by changing > > the params to glOrtho2D, as described above. :-) > > > My only outstanding problem is detecting when the graphics driver is > > providing a less-than native resolution with 'black bars' down the > > sides of the screen. In this instance I want to turn off my non-square > > pixel detection. If I can't figure this out, I'll grudgingly settle > > for providing the user with a manual 'my screen as black bars down the > > sides' switch to turn non-square-pixel correction off. But I'm curious > > why I've never seen this anywhere else. Does no-one else do non-square > > pixel correction? This is really the reason I posted all this, in case > > there's something else going on that I've entirely overlooked. > > What you *really* want here -- which you may or may not be able to get > from the driver -- is two bits of information: > * the resolution in each direction, i.e. the number of pixels in each > direction > * the physical dimensions of the display area occupied by those pixels > > With that information, you need not "detect" anything about the shape of > the pixels. Just set your perspective/frustum/ortho height/width ratio > to match the physical dimension height/width ratio, and set your > viewport to match the stated pixel resolution, and you're done. No > need to "detect" or compensate for pixel shapes. > > As a (small inadequate) example of getting the physical dimensions, GLUT > offers these two calls: > glutGet(GLUT_SCREEN_WIDTH_MM) > Width of the screen in millimeters. Zero indicates the width is > unknown or not available. > glutGet(GLUT_SCREEN_HEIGHT_MM) > Height of the screen in millimeters. Zero indicates the height is > unknown or not available. > > Other window systems should be able to provide such information, but I > con't recall how at the moment. > > Gary Herron >
Ahar, thanks Gary! I had no idea such information as physical dimensions might even possibly be available. I'll do a quick straw poll on various hardware and drivers within reach, see if these seem reliable. Thanks! > > Specifically, just in case it helps any future googlers, my code to > > set projection and initial modelview matrices to correct future > > rendering for any screen resolution, aspect ratio, fullscreen or > > bizarrely-shaped windows, and non-square pixels, looks like this > > (forgive the use of a couple of pygame-isms): > > > Class Camera(object): > > > def __init__(self, window): > > self.window = window > > self.x, self.y = (0, 0) # world location camera is centered on > > self.angle = 0.0 # camera can tilt > > self.zoom = 1.0 # distance from centre of screen to nearest > > edge > > # in world co-ords. ie. user can always see > > at > > # least this much of the world in every > > direction. > > > def set_world_projection(self): > > ''' > > Call this to set projection matrix before > > drawing all the in-world game entities > > ''' > > width, height = self.window.size > > aspect = width / height > > > # account for non-square pixels > > aspect *= self.window.getPixelAspect() > > > def getOrtho2DBounds(): > > left = bottom = -self.zoom > > right = top = self.zoom > > if width > height: # widescreen > > left *= aspect > > right *= aspect > > elif width < height: # tallscreen > > bottom /= aspect > > top /= aspect > > return left, right, bottom, top > > > GL.glMatrixMode(GL.GL_PROJECTION) > > GL.glLoadIdentity() > > GLU.gluOrtho2D(*getOrtho2DBounds()) > > > def look_at(self): > > ''' > > Call this to set initial modelview matrix, > > just before drawing all in-world game entities > > ''' > > GL.glMatrixMode(GL.GL_MODELVIEW) > > GL.glLoadIdentity() > > GLU.gluLookAt( > > self.x, self.y, +1.0, > > self.x, self.y, -1.0, > > sin(self.angle), cos(self.angle), 0.0) > > > Where my window.getPixelAspect() looks like: > > > def getPixelAspect(self): > > ''' > > Return the pixel aspect ratio for the current resolution. This > > is the ratio of width to height of a single pixel. So: > > <1.0 represents tall skinny pixels > > =1.0 represents square pixels, > > >1.0 represents short wide pixels > > ''' > > > # Assumption 1: The highest available resolution uses square > > pixels > > # Seems to be true for the native resolutions of my LCD. Use > > this > > # resolution to determine the aspect of the physical screen > > # measurements > > > physWidth, physHeight = self.modes[0] # pygame for 'get > > highest available screen resolution' > > physAspect = physWidth / physHeight > > > # Assumtions 2: The current resolution is using all available > > screen > > # real-estate. So comparing the current resolution aspect with > > the > > # phyAspect will give current pixel aspect ratio. > > > # However, my Windows ATI drivers offer a mode which provides > > # lower-than-native resolutions with black bars around them, > > violating > > # assumtion 2. In this case, this calculation will give the > > wrong > > # answers, and likely is not needed at all. > > > info = display.Info() # pygame for 'get current screen > > resolution' > > pixWidth = info.current_w > > pixHeight = info.current_h > > pixAspect = pixWidth / pixHeight > > > return physAspect / pixAspect -- You received this message because you are subscribed to the Google Groups "pyglet-users" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/pyglet-users?hl=en.
