[visionegg] Re: anti-aliasing of FilledCircle
- From: Gijs Plomp <gplomp@xxxxxxxxxxxxxx>
- To: visionegg@xxxxxxxxxxxxx
- Date: Wed, 22 Feb 2006 15:03:50 +0900
I was lucky and had some help already. We changed the FilledCircle code
in MoreStimuli.py so that it now does anti-aliasing, just like Target2D.
Maybe this could be incorporated a future versions?
New code below, thanks entirely to Peter Jurica:
class FilledCircle(VisionEgg.Core.Stimulus):
"""A circular stimulus, typically used as a fixation point.
(Note, this implementation almost certainly could be made faster
using display lists.)
Parameters
==========
anchor -- how position parameter is used (String)
Default: center
color -- color (AnyOf(Sequence3 of Real or Sequence4 of Real))
Default: (1.0, 1.0, 1.0)
num_triangles -- number of triangles used to draw circle (Integer)
Default: 51
on -- draw? (Boolean)
Default: True
position -- position in eye coordinates (AnyOf(Sequence2 of Real
or Sequence3 of Real or Sequence4 of Real))
Default: (320.0, 240.0)
radius -- radius in eye coordinates (Real)
Default: 2.0
"""
parameters_and_defaults = VisionEgg.ParameterDefinition({
'on':(True,
ve_types.Boolean,
'draw?'),
'color':((1.0,1.0,1.0),
ve_types.AnyOf(ve_types.Sequence3(ve_types.Real),
ve_types.Sequence4(ve_types.Real)),
'color'),
'anti_aliasing':(True,
ve_types.Boolean),
'position' : ( ( 320.0, 240.0 ), # in eye coordinates
ve_types.AnyOf(ve_types.Sequence2(ve_types.Real),
ve_types.Sequence3(ve_types.Real),
ve_types.Sequence4(ve_types.Real)),
'position in eye coordinates'),
'anchor' : ('center',
ve_types.String,
'how position parameter is used'),
'radius':(2.0,
ve_types.Real,
'radius in eye coordinates'),
'num_triangles':(51,
ve_types.Integer,
'number of triangles used to draw circle'),
})
__slots__ = VisionEgg.Core.Stimulus.__slots__ + (
'_gave_alpha_warning',
)
def __init__(self,**kw):
VisionEgg.Core.Stimulus.__init__(self,**kw)
self._gave_alpha_warning = 0
def draw(self):
p = self.parameters # shorthand
if p.on:
# calculate center
center = VisionEgg._get_center(p.position,p.anchor,(p.radius,
p.radius))
gl.glDisable(gl.GL_DEPTH_TEST)
gl.glDisable(gl.GL_TEXTURE_2D)
gl.glDisable(gl.GL_BLEND)
gl.glColorf(*p.color)
# Build filled circle from points
# gl.glBegin(gl.GL_POINTS)
# radius = int(math.ceil(p.radius))
# for i in range(-radius, radius):
# for j in range(-radius, radius):
# if(i * i + j * j < radius * radius):
# gl.glVertex3f(p.position[0] + i, p.position[1] +
j, 0.0)
# gl.glEnd() # GL_POINTS
# Build filled circle from triangles (this is typically faster
# then the commented code above with the points)
gl.glBegin(gl.GL_TRIANGLE_FAN)
gl.glVertex3f(p.position[0], p.position[1], 0.0)
angles =
Numeric.arange(p.num_triangles)/float(p.num_triangles)*2.0*math.pi
verts = Numeric.zeros( (p.num_triangles,2), Numeric.Float )
verts[:,0] = p.position[0] + p.radius * Numeric.cos(angles)
verts[:,1] = p.position[1] + p.radius * Numeric.sin(angles)
for i in range(verts.shape[0]):
gl.glVertex2fv(verts[i])
gl.glVertex2fv(verts[0])
gl.glEnd() # GL_TRIANGLE_FAN
if p.anti_aliasing:
if not self._gave_alpha_warning:
if len(p.color) > 3 and p.color[3] != 1.0:
logger = logging.getLogger('VisionEgg.Arrow')
logger.warning("The parameter anti_aliasing is "
"set to true in the Arrow "
"stimulus class, but the color "
"parameter specifies an alpha "
"value other than 1.0. To "
"acheive anti-aliasing, ensure "
"that the alpha value for the "
"color parameter is 1.0.")
self._gave_alpha_warning = 1
# We've already drawn a filled polygon (aliased), now redraw
# the outline of the polygon (with anti-aliasing). (Using
# GL_POLYGON_SMOOTH results in artifactual lines where
# triangles were joined to create quad, at least on some
OpenGL
# implementations.)
# Calculate coverage value for each pixel of outline
# and store as alpha
gl.glEnable(gl.GL_LINE_SMOOTH)
# Now specify how to use the alpha value
gl.glBlendFunc(gl.GL_SRC_ALPHA,gl.GL_ONE_MINUS_SRC_ALPHA)
gl.glEnable(gl.GL_BLEND)
# Draw a second polygon in line mode, so the edges are
anti-aliased
gl.glPolygonMode(gl.GL_FRONT_AND_BACK,gl.GL_LINE)
gl.glBegin(gl.GL_TRIANGLE_FAN)
gl.glVertex3f(p.position[0], p.position[1], 0.0)
angles =
Numeric.arange(p.num_triangles)/float(p.num_triangles)*2.0*math.pi
verts = Numeric.zeros( (p.num_triangles,2), Numeric.Float )
verts[:,0] = p.position[0] + p.radius * Numeric.cos(angles)
verts[:,1] = p.position[1] + p.radius * Numeric.sin(angles)
for i in range(verts.shape[0]):
gl.glVertex2fv(verts[i])
gl.glVertex2fv(verts[0])
gl.glEnd() # GL_TRIANGLE_FAN
# Set the polygon mode back to fill mode
gl.glPolygonMode(gl.GL_FRONT_AND_BACK,gl.GL_FILL)
gl.glDisable(gl.GL_LINE_SMOOTH)
======================================
The Vision Egg mailing list
Archives: http://www.freelists.org/archives/visionegg
Website: http://www.visionegg.org/mailinglist.html
- Follow-Ups:
- [visionegg] Re: anti-aliasing of FilledCircle
- From: Andrew Straw
- References:
- [visionegg] anti-aliasing of FilledCircle
- From: Gijs Plomp
Other related posts:
- » [visionegg] anti-aliasing of FilledCircle
- » [visionegg] Re: anti-aliasing of FilledCircle
- » [visionegg] Re: anti-aliasing of FilledCircle
- [visionegg] Re: anti-aliasing of FilledCircle
- From: Andrew Straw
- [visionegg] anti-aliasing of FilledCircle
- From: Gijs Plomp