[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [pygame] OpenGL and blitting



Here's a suggestion, don't do it that way ;)

You want to make a texture, and blit the texture... Here's a start, 
could be done better, but it served my purposes.

###

POWERS = (32, 64, 128, 256, 512, 1024, 2048, 4096)

def nextPower(x):
   for y in POWERS:
     if y >= x:
       return y

def surface_to_opengl_texture(imgsurf, texid=0, scale=0, mipmap=0):
     "load and bind an opengl texture"
     owidth, oheight = imgsurf.get_size()
     width, height = tuple(map(nextPower,imgsurf.get_size()))
     imgstring = pygame.image.tostring(imgsurf, "RGBA", 0)
     if not texid:
       texid = glGenTextures(1)
     glBindTexture(GL_TEXTURE_2D, texid)
     glPixelStorei(GL_PACK_ALIGNMENT, 1)
     glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
     if mipmap:
       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, 
GL_LINEAR_MIPMAP_LINEAR)
     else:
       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP)
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP)
     if owidth == width and oheight == height:
       if mipmap:
         gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, width, height, 
GL_RGBA, GL_UNSIGNED_BYTE, imgstring)
       else:
         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, 
GL_RGBA, GL_UNSIGNED_BYTE, imgstring)
     elif scale:
       if mipmap:
         gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, width, height, 
GL_RGBA, GL_UNSIGNED_BYTE, gluScaleImage(GL_RGBA, owidth, oheight, 
imgstring, width, height, GL_UNSIGNED_BYTE))
       else:
         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, 
GL_RGBA, GL_UNSIGNED_BYTE, gluScaleImage(GL_RGBA, owidth, oheight, 
imgstring, width, height, GL_UNSIGNED_BYTE))
     else:
       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
       glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, 
GL_RGBA, GL_UNSIGNED_BYTE, None)
       glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, owidth, oheight, GL_RGBA, 
GL_UNSIGNED_BYTE, imgstring)
     return (texid, (owidth, oheight), (width, height))


def drawTexture((x, y), texid, (owidth, oheight), (width, height), 
(xres, yres)):
     wv, hv = float(owidth)/float(width), float(oheight)/float(height)
     pMatrix = glGetDoublev( GL_PROJECTION_MATRIX )
     mMatrix = glGetDoublev( GL_MODELVIEW_MATRIX )
     glMatrixMode( GL_PROJECTION )
     glLoadIdentity()
     gluOrtho2D(0, xres, yres, 0)

     glMatrixMode( GL_MODELVIEW )
     glLoadIdentity()

     glTranslatef(x, y, 0)
     glEnable(GL_TEXTURE_2D)

     glBindTexture(GL_TEXTURE_2D, texid)

     glBegin(GL_QUADS)
     glTexCoord2f(0.0, 0.0)
     glVertex2f(0.0, 0.0)
     glTexCoord2f(0.0, hv)
     glVertex2f(0, oheight)
     glTexCoord2f(wv, hv)
     glVertex2f(owidth, oheight)
     glTexCoord2f(wv, 0.0)
     glVertex2f(owidth, 0)
     glEnd()

     glDisable(GL_TEXTURE_2D)

     glMatrixMode( GL_PROJECTION )
     glLoadMatrixd( pMatrix )
     glMatrixMode( GL_MODELVIEW )
     glLoadMatrixd( mMatrix )


class SurfaceTextureClass:
   def __init__(self,surface,screenres,pos=(0,0)):
     self.surface = surface
     self.texinfo = surface_to_opengl_texture(surface)
     self.screenres = screenres
     self.pos = pos

   def delete(self):
     glDeleteTextures([self.texinfo[0]])

   def setRes(self,res):
     self.screenres = screenres

   def draw(self):
     _texinfo = self.texinfo + (self.screenres,)
     drawTexture(self.pos,*_texinfo)

   def pickDraw(self):
     pass

   def moveTo(self,pos):
     self.pos = pos

   def moveBy(self,pos):
     self.pos = (self.pos[0]+pos[0], self.pos[1]+pos[1])

   def updateSurface(self,surfRect=None):
     if not surfRect:
       surfRect = self.surface.get_rect()
     x,y,w,h = surfRect
     mySurf = self.surface
     if not surfRect == self.surface.get_rect():
       mySurf = mySurf.subsurface(surfRect)
     imgstring = pygame.image.tostring(mySurf, "RGBA", 0)
     glBindTexture(GL_TEXTURE_2D, self.texinfo[0])
     glPixelStorei(GL_PACK_ALIGNMENT, 1)
     glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
     glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA, 
GL_UNSIGNED_BYTE, imgstring)


On Monday, Nov 4, 2002, at 14:26 America/New_York, Sami Hangaslammi 
wrote:

>
> What would be the preferred method of blitting pygame surfaces to an
> opengl screen? I couldn't get OPENGLBLIT to work, so I ended up making 
> the
> following function:
>
> def gl_blit(surface, (x,y)):
>     sx,sy = surface.get_size()
>     glMatrixMode(GL_PROJECTION)
>     glPushMatrix()
>     glLoadIdentity()
>     glMatrixMode(GL_MODELVIEW)
>     glPushMatrix()
>     glLoadIdentity()
>     glRasterPos2f(x,y)
>     bytes = pygame.image.tostring(surface,"RGBX",1)
>     glDrawPixels(sx,sy,GL_RGBA,GL_UNSIGNED_BYTE,bytes)
>     glPopMatrix()
>     glMatrixMode(GL_PROJECTION)
>     glPopMatrix()
>     glMatrixMode(GL_MODELVIEW)
>
> It works, but it is REALLY slow (relatively speaking), even with small
> surfaces. Most of the time is spent in glDrawPixels. Commenting it out
> makes things fast again.  I timed it, and glDrawPixels seems to take 
> about
> 1.4 ms. Since my game's whole main loop (draw the 3D scene, read user
> input, calculate movement etc.) takes about 1.6 ms (without 
> glDrawPixels),
> it effectively halves my frames per second.
>
> Any suggestions?
>
> --
> Sami Hangaslammi
>
> ____________________________________
> pygame mailing list
> pygame-users@seul.org
> http://pygame.seul.org

____________________________________
pygame mailing list
pygame-users@seul.org
http://pygame.seul.org