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.
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.