Added a copy of SGC
This commit is contained in:
parent
90ff7ceba8
commit
52eb18994d
22 changed files with 3283 additions and 0 deletions
255
sgc/widgets/opengl.py
Normal file
255
sgc/widgets/opengl.py
Normal file
|
@ -0,0 +1,255 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (C) 2011 Sam Bull
|
||||
|
||||
"""
|
||||
Base widget, all widgets inherit from this.
|
||||
|
||||
"""
|
||||
|
||||
from pygame.locals import Rect
|
||||
from OpenGL.GL import *
|
||||
import FTGL
|
||||
|
||||
from ..surface import SurfaceBase
|
||||
|
||||
|
||||
class OpenGLImage(SurfaceBase):
|
||||
"""
|
||||
Class used to emulate the interface of Surface for OpenGL drawing.
|
||||
|
||||
Functions should be used in the same manner as pygame.Surface.
|
||||
Differences are shown in documentation, otherwise assume it to
|
||||
function the same as the equivalent pygame.Surface function.
|
||||
|
||||
"""
|
||||
def __init__(self, surf, parent=None, **kwargs):
|
||||
self._a = None
|
||||
self._lock = False
|
||||
self.display_list = []
|
||||
self._children = []
|
||||
if parent:
|
||||
self._parent = parent # Parent surface used for _abs
|
||||
else:
|
||||
self._parent = self._default_screen
|
||||
|
||||
self._rect = Rect((0,0), (0,0))
|
||||
if isinstance(surf, (tuple,list)):
|
||||
self._rect.size = surf
|
||||
elif isinstance(surf, OpenGLFont):
|
||||
self._rect.size = (surf.size)
|
||||
self.display_list.extend(surf.display_list)
|
||||
elif isinstance(surf, OpenGLImage):
|
||||
self._rect = surf._rect
|
||||
self._a = surf._a
|
||||
self.display_list = surf.display_list
|
||||
self._children = surf._children
|
||||
|
||||
def blit(self, surf, pos=None):
|
||||
assert isinstance(surf, OpenGLImage)
|
||||
if surf not in self._children:
|
||||
if pos is not None: surf.pos = pos
|
||||
surf._parent = self
|
||||
self._children.append(surf)
|
||||
|
||||
def draw(self):
|
||||
glLoadIdentity()
|
||||
if self.rect.w <= self._parent.rect.w and \
|
||||
self.rect.h <= self._parent.rect.h:
|
||||
# Mask the area, so nothing is drawn outside surface area.
|
||||
bottom = self._default_screen.h - self.rect_abs.bottom
|
||||
glScissor(self.rect_abs.x, bottom,
|
||||
self.rect.w+1, self.rect.h+1)
|
||||
glTranslatef(self.pos_abs[0], self.pos_abs[1], 0)
|
||||
for dl,col in self.display_list:
|
||||
if col is not None: glColor(col[0], col[1], col[2], self.a)
|
||||
glCallList(dl)
|
||||
for child in self._children:
|
||||
child.draw()
|
||||
|
||||
def fill(self, col=0, rect=None, special_flags=0):
|
||||
"""If col == 0 and rect is None, clears image with no fill."""
|
||||
if rect is None:
|
||||
# Clear the surface
|
||||
self.display_list = []
|
||||
self._children = []
|
||||
rect = Rect((0,0), self.size)
|
||||
if col != 0:
|
||||
col = [c/255. for c in col]
|
||||
dl = glGenLists(1)
|
||||
glNewList(dl, GL_COMPILE)
|
||||
glRectfv(rect.topleft, rect.bottomright)
|
||||
glEndList()
|
||||
self.display_list.append((dl, col))
|
||||
|
||||
def copy(self):
|
||||
return OpenGLImage(self)
|
||||
|
||||
def get_size(self):
|
||||
return self.size
|
||||
|
||||
def set_alpha(self, alpha):
|
||||
self._a = alpha/255.
|
||||
|
||||
def set_at(self, vertex, col):
|
||||
col = [c/255. for c in col]
|
||||
|
||||
if self._lock:
|
||||
glColor(*col)
|
||||
else:
|
||||
dl = glGenLists(1)
|
||||
glNewList(dl, GL_COMPILE)
|
||||
glBegin(GL_POINTS)
|
||||
|
||||
glVertex(vertex)
|
||||
|
||||
if not self._lock:
|
||||
glEnd()
|
||||
glEndList()
|
||||
surf.display_list.append((dl, col))
|
||||
|
||||
def lock(self):
|
||||
"""
|
||||
Should only be used for multiple set_at() calls.
|
||||
Should not be used in conjuction with the draw functions.
|
||||
|
||||
"""
|
||||
self._lock = True
|
||||
self._lock_dl = glGenLists(1)
|
||||
glNewList(self._lock_dl, GL_COMPILE)
|
||||
glBegin(GL_POINTS)
|
||||
|
||||
def unlock(self):
|
||||
glEnd()
|
||||
glEndList()
|
||||
self.display_list.append((self._lock_dl, None))
|
||||
del self._lock_dl
|
||||
self._lock = False
|
||||
|
||||
def replace(self, surf, **kwargs):
|
||||
self._rect.size = surf.size
|
||||
self.display_list = surf.display_list[:]
|
||||
self._children = surf._children[:]
|
||||
|
||||
@property
|
||||
def a(self):
|
||||
if self._a is not None:
|
||||
return self._a
|
||||
else:
|
||||
return self._parent.a
|
||||
|
||||
# --- Dummy methods. Ignore. ---
|
||||
|
||||
def __call__(self):
|
||||
return self
|
||||
|
||||
def set_colorkey(self, col):
|
||||
pass
|
||||
|
||||
class OpenGLFont():
|
||||
"""
|
||||
Wraps the FTGL.TextureFont to allow it to be added
|
||||
to an OpenGLImage object in the same manner as pygame.Font.
|
||||
|
||||
"""
|
||||
def __init__(self, font, size):
|
||||
self._children = []
|
||||
self.font = FTGL.TextureFont(font)
|
||||
self.font.FaceSize(16)
|
||||
self.y_offset = self.font.line_height * .75
|
||||
|
||||
def render(self, text, antialias, color, background=None):
|
||||
text = text.encode()
|
||||
col = [c/255. for c in color]
|
||||
dl = glGenLists(1)
|
||||
self.size = (self.font.Advance(text), self.font.line_height)
|
||||
glNewList(dl, GL_COMPILE)
|
||||
glPushMatrix()
|
||||
# Flip text right way up
|
||||
glMultMatrixf((1, 0, 0, 0,
|
||||
0,-1, 0, 0,
|
||||
0, 0, 1, 0,
|
||||
0, self.y_offset, 0, 1))
|
||||
self.font.Render(text)
|
||||
glPopMatrix()
|
||||
glEndList()
|
||||
self.display_list = [(dl, col)]
|
||||
return self
|
||||
|
||||
class Draw():
|
||||
"""
|
||||
Class to emulate the pygame.draw module.
|
||||
Functions should work in the same manner.
|
||||
|
||||
"""
|
||||
def rect(self, surf, col, rect, width=0):
|
||||
col = [c/255. for c in col]
|
||||
dl = glGenLists(1)
|
||||
glNewList(dl, GL_COMPILE)
|
||||
if not width:
|
||||
glRectfv(rect.topleft, rect.bottomright)
|
||||
else:
|
||||
if width > 1: width -= 1
|
||||
hw = width/2.
|
||||
glLineWidth(width)
|
||||
glBegin(GL_LINES)
|
||||
glVertex(rect.x, rect.y + hw)
|
||||
glVertex(rect.right - width, rect.y + hw)
|
||||
# (hw%1) fixes line rendering off by a pixel
|
||||
glVertex(rect.right - hw, rect.y + (hw%1))
|
||||
glVertex(rect.right - hw, rect.bottom - width + (hw%1))
|
||||
glVertex(rect.right, rect.bottom - hw)
|
||||
glVertex(rect.x + width, rect.bottom - hw)
|
||||
glVertex(rect.x + hw, rect.bottom)
|
||||
glVertex(rect.x + hw, rect.y + width)
|
||||
glEnd()
|
||||
glEndList()
|
||||
surf.display_list.append((dl, col))
|
||||
|
||||
def polygon(self, surf, col, pointlist, width=0):
|
||||
"""
|
||||
With width == 0, can only draw convex polygons. Be careful of
|
||||
the order of vertices if it draws differently than pygame.
|
||||
|
||||
"""
|
||||
col = [c/255. for c in col]
|
||||
dl = glGenLists(1)
|
||||
glNewList(dl, GL_COMPILE)
|
||||
if not width:
|
||||
glBegin(GL_POLYGON)
|
||||
for v in pointlist:
|
||||
glVertex(v)
|
||||
glEnd()
|
||||
glEndList()
|
||||
surf.display_list.append((dl, col))
|
||||
|
||||
def circle(self, surf, col, pos, radius, width=0):
|
||||
col = [c/255. for c in col]
|
||||
dl = glGenLists(1)
|
||||
glNewList(dl, GL_COMPILE)
|
||||
if not width:
|
||||
glEnable(GL_POINT_SMOOTH)
|
||||
glHint(GL_POINT_SMOOTH_HINT, GL_NICEST)
|
||||
glPointSize(radius*2)
|
||||
glBegin(GL_POINTS)
|
||||
glVertex(pos)
|
||||
glEnd()
|
||||
glDisable(GL_POINT_SMOOTH)
|
||||
glPointSize()
|
||||
glEndList()
|
||||
surf.display_list.append((dl, col))
|
||||
|
||||
def line(self, surf, col, start_pos, end_pos, width=1):
|
||||
col = [c/255. for c in col]
|
||||
dl = glGenLists(1)
|
||||
glNewList(dl, GL_COMPILE)
|
||||
glLineWidth(width)
|
||||
glBegin(GL_LINES)
|
||||
glVertex(start_pos)
|
||||
glVertex(end_pos)
|
||||
glEnd()
|
||||
glEndList()
|
||||
surf.display_list.append((dl, col))
|
||||
|
||||
# Export Draw functions
|
||||
draw = Draw()
|
Loading…
Add table
Add a link
Reference in a new issue