I am working in a pyglet script which displays an animation, it works as expected in Windows, but when I execute it in osx I only get a blank screen.
I know it works because I've put print statements in on_draw()
and other functions and those are shown in the terminal, but the pyglet window does not display anything.
I am forcing the execution of the 32 bit python with the command defaults write com.apple.versioner.python Prefer-32-Bit -bool yes
, and I have executed without a problem another pyglet script which also displayed an animation.
I do not understand the problem, because this script, as I said, works in Windows. The code is the following:
import pyglet
from pyglet.gl import *
from pyglet.window import mouse, key
import math
import time
import ConfigParser
import numpy as np # for randomize the trials
import sys # debuging purposes
import os
## Create pyglet window
# Get screens
screens = pyglet.window.get_platform().get_default_display().get_screens()
allowstencil = pyglet.gl.Config(stencil_size=8)
# Create window (not visible at start)
myWindow = pyglet.window.Window(config=allowstencil,fullscreen=False,screen=screens[0], visible = 0)
## Functions definition
def create_filename():
## Create output data file name
# Get subject and time information
exp_name = 'pythonMigration'
time_string = time.strftime("%y.%m.%d_%H.%M.%S", time.localtime())
subject_name = "Name"
textfilename = (exp_name + '_' + subject_name + '_' + time_string + '.txt')
# Save output file in the folder "data"
out_file_name = os.path.join('data', textfilename)
return out_file_name
def ConfigFileToStruct(configfilename):
# ConfigFileToStruct receives the string of the name of the configuration file to be read.
# It will return a dict variable with the configuration parameters and values
# config_struct will be the dict struture where all the configuration parameters will be stored
config_struct = {}
# Initialize configParser
config = ConfigParser.RawConfigParser()
# Read file named configfilename
config.read(configfilename)
# Read sections of configuration file
sectionlist = config.sections()
# Read options of each section
# optionlist will be an AxB array, where A is not defined and B is the len(sectionlist)
optionlist = [[] for x in range(len(sectionlist))]
for i in range(len(sectionlist)):
# Read variables (options) from configuration file
optionlist[i] = config.options(sectionlist[i])
# Fill structure with sections
config_struct[sectionlist[i]] = {}
# Fill sections of structure with variables and values
for j in range(len(optionlist[i])):
config_struct[sectionlist[i]][optionlist[i][j]] = config.getfloat(sectionlist[i], optionlist[i][j])
return(config_struct) #end of readconfigFile function
def load_trial_parameters(trialsfile,trial):
# trialsfile is the struct previously loaded by ConfigFileToStruct()
# trial is the number of the trial to load parameters from
global mylambda1, duty_cycle1, orientation1, speed1
global mylambda2, duty_cycle2, orientation2, speed2
global timeCurrentTrial
## GRATING PARAMETERS
mylambda1 = trialsfile[str(trial)]["wavelength1"]
duty_cycle1 = trialsfile[str(trial)]["duty_cycle1"]
orientation1 = trialsfile[str(trial)]["orientation1"]
speed_pix = trialsfile[str(trial)]["speed1"]
speed1 = speed_pix / math.cos(math.radians(orientation1))
#grating2
mylambda2 = trialsfile[str(trial)]["wavelength2"]
duty_cycle2 = trialsfile[str(trial)]["duty_cycle2"]
orientation2 = trialsfile[str(trial)]["orientation2"]
speed_pix = trialsfile[str(trial)]["speed2"]
speed2 = speed_pix / math.cos(math.radians(orientation2))
# other parameters
timeCurrentTrial = trialsfile[str(trial)]["time"]
def load_config_parameters(config):
# config is the struct previously loaded by ConfigFileToStruct()
# Declare variables, all are global, this function if for clearity purposes
global x0_pix, y0_pix
global ysize_cm, aperture_color, numTheta, deltaTheta, x1, y1, apertRad_pix
global x2, y2
global red_color, cyan_color
global stereo1, stereo2
global fixp_color, surrp_color
global time_fixp
# calculate x, y center coordinates in pixels
x0_myW = 0 # note that we consider center of screen to be 0,0 in My World Coordinates
y0_myW = 0
x0_pix = ((x0_myW/0.5) + 1)/2 * myWindow.width # center of screen; assuming myW width max == 0.5; this equation derived with Nava
y0_pix = ((y0_myW/0.5) + 1)/2 * myWindow.height # center of screen # assuming myW height max == 0.5
# calculate radius; we want an aperture with a 13 deg diameter or 6.5 deg radius @ view dist of 57cm
# ysize_cm = config["screen_parameters"]["ysize_cm"] #@@ TO-DO this will be set as a config param @@ and will change depending on monitor!!
# apertDiam_cm = config["radius"]["aperture"]
# apertRad_myW = (apertDiam_cm/ysize_cm) / 2 # determine radius value in My World with reference to 0,0 center
# apertRad_pix = (((apertRad_myW/0.5) + 1)/2 * myWindow.height) - y0_pix
apertureDiv = config["aperture_size"]["proportion"]
apertRad_pix = myWindow.height / apertureDiv
## APERTURE PARAMETERS
# Calculate circle for aperture
aperture_color = (config["aperture_color"]["red"], config["aperture_color"]["green"], config["aperture_color"]["blue"])
numTheta = int(config["radius"]["numtheta"])
deltaTheta = 2 * math.pi / numTheta # == 0.0698
#
## GRATING PARAMETERS
#grating1
x1 = x0_pix - apertRad_pix
y1 = y0_pix - apertRad_pix
stereo1 = config["stereo"]["grating1"]
#grating2
x2 = x0_pix + apertRad_pix
y2 = y0_pix + apertRad_pix
stereo2 = config["stereo"]["grating2"]
## COLOR PARAMETERS
red_color = (config["red_color"]["red"], config["red_color"]["green"], config["red_color"]["blue"])
cyan_color = (config["cyan_color"]["red"], config["cyan_color"]["green"], config["cyan_color"]["blue"])
# fixation point color
fixp_color = (config["fixp_color"]["red"], config["fixp_color"]["green"], config["fixp_color"]["blue"])
surrp_color = (config["surrp_color"]["red"], config["surrp_color"]["green"], config["surrp_color"]["blue"])
# fixation point time beginning trials
time_fixp = config["time"]["time_fixp"]
@myWindow.event
def on_mouse_press(x, y, button, modifiers):
# On_mouse_press will be executed each time a mouse button is pressed
global count, datatime, dataclick, datatrial
global show_stim, show_trial_menu, trial, clockTrial, show_welcome
global show_trial_menu_release, show_welcome_release
timeNow = time.clock() - clockTrial
if show_stim:
if button == mouse.LEFT:
datatrial[count] = trials_array[trial_counter]
dataclick[count] = '-1'
datatime[count] = timeNow - time_fixp
if button == mouse.RIGHT:
datatrial[count] = trials_array[trial_counter]
dataclick[count] = '1'
datatime[count] = timeNow - time_fixp
count += 1
elif show_trial_menu:
show_trial_menu_release = 1
elif show_welcome:
show_welcome_release = 1
@myWindow.event
def on_mouse_release(x, y, button, modifiers):
# On_mouse_release will be executed each time a mouse button is release
global count, dataclick, datatime, datatrial
global show_stim, show_trial_menu, trial, clockTrial, show_welcome, trial_counter
global show_trial_menu_release, show_welcome_release
timeNow = time.clock() - clockTrial
if show_stim:
if button == mouse.LEFT:
datatrial[count] = trials_array[trial_counter]
dataclick[count] = '-2'
datatime[count] = timeNow - time_fixp
if button == mouse.RIGHT:
datatrial[count] = trials_array[trial_counter]
dataclick[count] = '2'
datatime[count] = timeNow - time_fixp
count += 1
elif show_trial_menu & show_trial_menu_release:
show_trial_menu_release = 0
show_stim = 1
show_trial_menu = 0
trial = trial + 1
trial_counter = trial_counter + 1
clockTrial = time.clock()
elif show_welcome & show_welcome_release:
show_welcome_release = 0
show_welcome = 0
show_stim = 1
clockTrial = time.clock()
@myWindow.event
def on_close():
#on_close is executed when mywindow is closed
close_nicely()
def close_nicely():
#Write data to text file
for i in range(count):
with open(out_file_name, 'a') as txtfile:
txtfile.write(str(i) +'\t'+ str(datatime[i]) +'\t'+ str(dataclick[i]) +'\t'+ str(datatrial[i]) + '\n')
print("closed nicely :)")
myWindow.clear()
myWindow.close()
def drawCircle(radius, circle_color, x, y):
global numTheta, deltaTheta
glColor3f( circle_color[0] , circle_color[1], circle_color[2])
for i in range (0, numTheta):
cx1 = x + radius * math.sin(deltaTheta * i)
cy1 = y + radius * math.cos(deltaTheta * i)
cx2 = x + radius * math.sin(deltaTheta * (i+1))
cy2 = y + radius * math.cos(deltaTheta * (i+1))
glBegin( GL_TRIANGLES )
glVertex2f(x, y )
glVertex2f(cx1 , cy1 )
glVertex2f(cx2 , cy2 )
glEnd()
def drawAperture():
global aperture_color, numTheta, deltaTheta, x0_pix, y0_pix, apertRad_pix
# Do we need the stencil commands in here? It does not change if I delete them
# Enable stencil
glClearStencil(0x0)
glEnable(GL_STENCIL_TEST)
#define the region where the stencil is 1
glClear(GL_STENCIL_BUFFER_BIT)
glStencilFunc(GL_ALWAYS, 0x1, 0x1) #Always pass stencil functions test
glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE) #Replace stencil value with reference value
drawCircle(apertRad_pix, aperture_color, x0_pix, y0_pix)
def drawGrating(x, y, fill_color, orientation, mylambda, duty_cycle):
bar_length = 1500
radio_aux = (2 * apertRad_pix) + mylambda #diameter
num_bars = int(1 + math.floor(radio_aux / mylambda))+3
glStencilFunc (GL_EQUAL, 0x1, 0x1)
glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP)
glLoadIdentity() #replace current matrix with the identity matrix
glTranslatef(x, y, 0)
glRotatef(orientation,0,0,1)
glTranslatef(-x, -y, 0)
glColor3f( fill_color[0] , fill_color[1], fill_color[2] )
glBlendFunc(GL_ZERO, GL_SRC_COLOR)
for i in range(num_bars):
x1 = mylambda * i + x
x2 = (duty_cycle * mylambda) + (mylambda * i + x)
glBegin(GL_QUADS)
glVertex2f(x1, y - bar_length)
glVertex2f(x1, y + bar_length)
glVertex2f(x2, y + bar_length)
glVertex2f(x2, y - bar_length)
glEnd()
# glRotatef(-orientation, 0, 0, 1)#Is it necessary?
glBlendFunc(GL_ONE, GL_ZERO)
glLoadIdentity()
def update_frames(dt):
global x1, x2, timetrial, clockTrial, trial, show_stim, show_trial_menu
timeNow = time.clock()
if (show_stim) & ((timeNow-clockTrial) < (timeCurrentTrial + time_fixp)):
# Load trial parameters
load_trial_parameters(trialsfile,trials_array[trial_counter])
motion_cycle1 = mylambda1/(math.cos(math.radians(orientation1)))
motion_cycle2 = mylambda2/(math.cos(math.radians(orientation2)))
initialpos1 = myWindow.width/2 - apertRad_pix - mylambda1/2
initialpos2 = myWindow.width/2 - apertRad_pix + mylambda2/2
# update position of grating 1:
x1 = initialpos1 + math.fmod(speed1*(timeNow-clockTrial), motion_cycle1)
# update position of grating 2:
x2 = initialpos2 + math.fmod(speed2*(timeNow-clockTrial), motion_cycle2)
elif ((show_stim) & (trial_counter < numtrials)):
show_stim = 0
show_trial_menu = 1
elif ((show_stim == 0) & (trial_counter == numtrials-1)):
close_nicely()
pass
@myWindow.event
def on_draw():
print "on draw"
if show_stim:
# For each frame of the stimulus:
# clear the window
myWindow.clear()
load_trial_parameters(trialsfile, trials_array[trial_counter])
# Enable blending
glEnable(GL_BLEND)
pyglet.gl.glClearColor( 0.6, 0.6, 0.6, 0 )
# Enable stencil
glClearStencil(0x0)
glEnable(GL_STENCIL_TEST)
# define the region where the stencil is 1
glClear(GL_STENCIL_BUFFER_BIT)
glStencilFunc(GL_ALWAYS, 0x1, 0x1) #Always pass stencil functions test
glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE) #Replace stencil value with reference value
# draw Aperture
drawCircle(apertRad_pix, aperture_color, x0_pix, y0_pix)
# draw Fixation point and fixation surround
drawCircle(apertRad_pix/15, fixp_color, x0_pix, y0_pix)
drawCircle(apertRad_pix/80, surrp_color, x0_pix, y0_pix)
if (time.clock()-clockTrial)>time_fixp:
# draw gratings
Red = red_color
Cyan = cyan_color
drawGrating(x1 + stereo1, y1, Cyan, orientation1, mylambda1, duty_cycle1)
drawGrating(x1 - stereo1, y1, Red, orientation1, mylambda1, duty_cycle1)
drawGrating(x2 + stereo2, y2, Red, orientation2, mylambda2, duty_cycle2)
drawGrating(x2 - stereo2, y2, Cyan, orientation2, mylambda2, duty_cycle2)
glBlendFunc(GL_ONE, GL_ZERO)
elif show_trial_menu:
# For each frame of the in-between trials window
myWindow.clear()
#define the region where the stencil is 1
glClear(GL_STENCIL_BUFFER_BIT)
glStencilFunc(GL_ALWAYS, 0x1, 0x1) #Always pass stencil functions test
glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE) #Replace stencil value with reference value
labelInterval.draw()
elif show_welcome:
# For each frame of the welcome window
myWindow.clear()
glEnable(GL_BLEND)
pyglet.gl.glClearColor( 0.6, 0.6, 0.6, 0 )
labelWelcome.draw()
################################################################################################
## Main
################################################################################################
if __name__ == "__main__":
## Check command-line arguments
if len(sys.argv)>1:
confignamefile = sys.argv[1]
trialsnamefile = sys.argv[2]
print("input received")
else:
print("no input received")
confignamefile = "cfgfile.txt"
trialsnamefile = "trialsfile.txt"
# Load configuration parameters
config = ConfigFileToStruct(confignamefile)
if not config:
print("CONFIG FILE EMPTY")
else:
print("CONFIG FILE LOADED")
# Load trials file parameters
trialsfile = ConfigFileToStruct(trialsnamefile)
if not trialsfile:
print("TRIALS FILE EMPTY")
sys.exit()
else:
print("TRIALS FILE LOADED")
numtrials = len(trialsfile)
## Initialize states of on_draw()
show_welcome = 1
show_stim = 0
show_start_menu = 0
show_trial_menu = 0
show_trial_menu_release = 0
## Load parameters
randomize_trials = 1
if randomize_trials:
trials_array = np.random.permutation(numtrials) # goes from 0 to numtrials in random order
else:
trials_array = range(numtrials) # no random
trial = 0
trial_counter = 0
load_config_parameters(config)
load_trial_parameters(trialsfile,trials_array[trial_counter])
## Create output data file name
out_file_name = create_filename()
# Necessary variables for the data file
count = 0
dataclick = [0]*15000
datatime = [0]*15000
datatrial = [0]*15000
## Message that will be shown between trials
labelInterval = pyglet.text.Label("Click the mouse to start the next trial", font_name = 'Arial',
font_size = 20, x = myWindow.width/2, y = myWindow.height/2,
anchor_x = "center", anchor_y = "center")
## Message that will be shown at startup
textWelcome = "\t\t\t\tWelcome\n RIGHT click: Grating to the right is in front\n LEFT click: Grating to the left is in front\n\n LEFT click to start"
labelWelcome = pyglet.text.Label(textWelcome,
font_name = 'Arial', font_size = 20, x = myWindow.width/2, y = myWindow.height/2,
multiline = True, width=600, anchor_x = "center", anchor_y = "center")
## Run stimulus
# Set stimulus window to visible and mouse not visible
myWindow.set_visible(1)
myWindow.set_mouse_visible(0)
# initialize clock
clockTrial = time.clock() # this clock will be reset for each trial
framerate = 1/60.0
pyglet.clock.schedule_interval(update_frames,framerate)
pyglet.app.run()
Could anybody help me to find out what am I doing wrong in this code?
This is a (working) example code where flip is utilized:
import pyglet
from pyglet.gl import *
from math import radians, cos, sin, degrees, atan2
from time import time
from os.path import abspath
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
glEnable(GL_LINE_SMOOTH)
glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE)
pyglet.options['audio'] = ('alsa', 'openal', 'silent')
key = pyglet.window.key
class BasicObject(pyglet.sprite.Sprite):
def __init__(*args, **dictWars):
if type(args) == tuple and len(args) == 2 and len(dictWars) == 0 and type(args[1]) == dict:
args, dictWars = args
self = args[0]
self.name = args[1]
self.render = True
self.anchor = 'center'
self.last_update = time()
self.texture = pyglet.image.load(abspath(dictWars['texture']))
super(BasicObject, self).__init__(self.texture)
self.x, self.y = 0, 0
self.rotation = 0
if 'x' in dictWars:
self.x = dictWars['x']
if 'y' in dictWars:
self.y = dictWars['y']
def swap_image(self, image, filePath=True):
if filePath:
self.texture = pyglet.image.load(abspath(image))
else:
self.texture = image
self.image = self.texture
def draw_line(self, xy, dxy, color=(0.2, 0.2, 0.2, 1)):
glColor4f(color[0], color[1], color[2], color[3])
glBegin(GL_LINES)
glVertex2f(xy[0], xy[1])
glVertex2f(dxy[0], dxy[1])
glEnd()
def rotate(self, deg):
self.image.anchor_x = self.image.width / 2
self.image.anchor_y = self.image.height / 2
self.rotation = self.rotation+deg
if self.anchor != 'center':
self.image.anchor_x = 0
self.image.anchor_y = 0
def click(self):
print('Clicked:',self.name)
def work(self, *args):
if time() - self.last_update > 0.1:
self.rotate(10)
def click_check(self, x, y):
if x > self.x and x < (self.x + self.width):
if y > self.y and y < (self.y + self.height):
return self
def _draw(self):
self.work()
# self.draw_line((x,y), (dx, dy))
self.draw()
class GUI(pyglet.window.Window):
def __init__(self):
super(GUI, self).__init__(640,340, caption='My app')
self.alive = True
self.keys_down = {}
self.myImage = BasicObject('TestImage', texture='/path/to/texture.png')
def render(self, *args):
pyglet.gl.glClearColor(1, 1, 1, 1)
self.clear()
# .. This is where you draw your objects, for instance
self.myImage._draw()
self.flip()
def on_draw(self):
self.render()
def on_close(self):
self.alive = False
def on_key_press(self, symbol, modkey):
self.keys_down[symbol] = time()
def on_key_release(self, symbol, modkey):
if symbol in self.keys_down:
del(self.keys_down[symbol])
def on_mouse_release(self, x, y, button, modifiers):
pass
def on_mouse_press(self, x, y, button, modifiers):
print(button,'pressed',(x,y))
def on_mouse_motion(self, x, y, dx, dy):
pass
def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
pass
def run(self):
while self.alive:
event = self.dispatch_events()
for symbol in self.keys_down:
if symbol == key.ESCAPE:
self.alive = None
break
elif symbol == key.LEFT:
pass #Arrowkey Left
elif symbol == key.RIGHT:
pass #Arrowkey Right
elif symbol == key.UP:
pass #Arrowkey Up
elif symbol == key.DOWN:
pass #Arrowkey Down
elif symbol == 65515:
pass # Win key
else:
print(symbol)
self.render()
if __name__ == '__main__':
x = GUI()
pyglet.clock.set_fps_limit(120)
x.run()
This is also the code i use in all my projects, something that's been evolving to fit my needs but also something that's proved to be working in most scenarios.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.