我用 OpenGL 画了大约 20 个圆圈。每个圆圈有 2 条线,约 10 段,它们都有不同的颜色和长度。FPS ~=4。我怎样才能更快地做到这一点?我在 Ubuntu 上使用 Python 3
代码:
class ScreenOpenGL(Screen):
def __init__(self,layers,layers_lock):
""" Инициализирует экран и запускает его, потом всю программу """
Screen.__init__(self,"OpenGL",layers,layers_lock)
self.window = 0
self.quad = None
self.keypress = []
print("Fuck")
# self.infoScreen = ScreenCursesInfo()
self.infoScreen = ScreenStandartInfo()
GLUT.glutInit(sys.argv)
GLUT.glutInitDisplayMode(GLUT.GLUT_RGBA | GLUT.GLUT_DOUBLE | GLUT.GLUT_ALPHA | GLUT.GLUT_DEPTH)
GLUT.glutInitWindowSize(640, 480)
GLUT.glutInitWindowPosition(400, 400)
self.window = GLUT.glutCreateWindow(b"Project Evoluo alpha")
GLUT.glutDisplayFunc(self._loop) # Функция, отвечающая за рисование
GLUT.glutIdleFunc(self._loop) # При простое перерисовывать
GLUT.glutReshapeFunc(self._resize) # изменяет размеры окна
GLUT.glutKeyboardFunc(self._keyPressed) # Обрабатывает нажатия
self._initGL(640, 480)
field_params(640, 480)
print("Fuck")
def run(self):
# для threading
GLUT.glutMainLoop()
def _initGL(self,Width,Height):
GL.glShadeModel(GL.GL_SMOOTH);
GL.glClearColor(0.0, 0.0, 0.0, 0.0) # This Will Clear The Background Color To Black
GL.glClearDepth(1.0) # Enables Clearing Of The Depth Buffer
GL.glDepthFunc(GL.GL_LESS) # The Type Of Depth Test To Do
GL.glHint(GL.GL_LINE_SMOOTH_HINT, GL.GL_NICEST)
GL.glEnable(GL.GL_BLEND); # Enable Blending
GL.glLineWidth(1.);
GL.glDisable(GL.GL_LINE_SMOOTH)
GL.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);
self.width = Width
self.height = Height
self.quad = GLU.gluNewQuadric()
GLU.gluQuadricNormals(self.quad, GLU.GLU_SMOOTH)
GLU.gluQuadricTexture(self.quad, GL.GL_TRUE)
def _resize(self,Width,Height):
if Height == 0:
Height = 1
self.width = Width
self.height = Height
field_params(Width,Height)
GL.glViewport(0, 0, Width, Height) # Reset The Current Viewport And Perspective Transformation
GL.glMatrixMode(GL.GL_PROJECTION)
GL.glLoadIdentity()
GL.glOrtho(0.0,Width,0.0,Height,-1.0,1.0)
GL.glMatrixMode(GL.GL_MODELVIEW) # Select The Modelview Matrix
GL.glLoadIdentity()
def update(self):
GLUT.glutSwapBuffers()
def clear(self):
GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT)
GL.glLoadIdentity() # Reset The View
def write(self,pos,str):
pass
def __del__(self):
del(self.infoScreen)
GLUT.glutDestroyWindow(self.window)
self._end()
# sys.exit()
def getch(self):
if self.keypress != []:
# print
return self.keypress.pop(-1)[0]
else:
return None
def _keyPressed(self,*args):
if args != None:
self.keypress.append(args)
print(self.keypress)
def _draw_prepare(self):
del(self._layers)
self._layers = []
for layer in layers:
if layer.__class__ == LayerObjects:
self._layers.append([layer.type,copy.deepcopy(layer.get_objs()),copy.copy(layer._attacked)])
def draw_eyes(self,vis,r_max,dphi):
for x in range(0,7):
GLU.gluPartialDisk(self.quad,
1,
vis[x][0] * r_max,
5,
3,
- ((x - 3) * 15 + 7.5 + dphi / pi * 180) + 90,
15)
def draw_sensitivity(self,sens,r_max,dphi):
for x in range(0,5):
GLU.gluPartialDisk(self.quad,
1,
sens[x] * r_max,
5,
3,
- (52.5 + (x+1) * 51 + dphi / pi * 180) + 90,
51)
pass
def draw_obj(self,obj,_id,pos,circle,lines,attacked):
# Кружок
GL.glLoadIdentity()
GL.glTranslatef(pos[0]-1,pos[1]-1,0)
red,green,blue = obj.color # берём цвет
GL.glColor3f(red,green,blue)
GLU.gluDisk(self.quad,*circle)
#Глазки
GL.glColor3f(1-red,1-green,1-blue)
try:
eyes = obj.eyes
except NameError:
pass
else:
self.draw_eyes(obj.eyes.eyes,obj.radius * k_screen,obj.pos[1])
# Прикосновения
GL.glColor3f(1,0,0)
try:
sensitivity = obj.sensitivity
except NameError:
pass
else:
self.draw_sensitivity(obj.sensitivity._sens,obj.radius * k_screen,obj.pos[1])
# Полосочки
GL.glBegin(GL.GL_LINES)
for color,x,y in lines:
GL.glColor3f(*color)
GL.glVertex3f(0,0,0)
GL.glVertex3f(x,y,0)
GL.glEnd()
def draw(self,layer):
global width,height
if layer[0] == "Layer Objects":
attacked = layer[2]
for obj in layer[1]:
#Стрелочки-направления
pos = [int(x) for x in obj.get_pos_screen()]
positions = [pos,]
radius_scr = obj.radius * k_screen
att = Vector(radius_scr * (1 +obj._attack_range*obj._attack),
obj.pos[1],
isPolar = True
)
speed = obj.speed[0] * k_screen * 5
if pos[0] < radius_scr:
positions.append([pos[0] + self.width,pos[1]])
if pos[0] + radius_scr > self.width:
positions.append([pos[0] - self.width,pos[1]])
if pos[1] < radius_scr:
positions.append([pos[0],pos[1] + self.height])
if pos[1] + radius_scr > self.height:
positions.append([pos[0],pos[1] - self.height])
for ps in positions:
self.draw_obj(obj,obj._id, ps , [0,obj.radius*k_screen,20,1], [ [ (1,0,0) , att.x, att.y ], [ (0,0,1) , speed.x, speed.y] ] , attacked)
self.infoScreen.draw()
功能代码,绘制:
def _draw_prepare(self):
""" Копирует из глобальной переменной всё, что ей нужно """
self._layers = copy.deepcopy(layers)
def _loop(self):
global tick
if (self.ch == b'q') or (self.ch == b'\xb1') or (self.ch == 27) or (self.ch == 113):
isEnd = True
self.__del__()
del(self)
return 0
elif (self.ch == b's'):
self._is_draw = not self._is_draw
print("changed to %d" %self._is_draw)
else:
if (self.last_tick != tick) and (self._is_draw):
self.layers_lock.acquire(1)
self._draw_prepare()
self.layers_lock.release()
self.last_tick = tick
# рисует сцену
return self._main()
def _main(self):
global tick
self.clear()
if self._is_draw:
for layer in self._layers:
self.draw(layer)
self.update()
self.ch = self.getch()