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.

Reply via email to