Re: [PyOpenGL-Users] Texture Blitting?
Brought to you by:
mcfletch
From: Jasper P. <ja...@pe...> - 2003-03-06 13:41:21
|
On Thu, 6 Mar 2003, Rene Dudfield wrote: > I'm interested in what you've been doing with blitting > in pygame. If you posted your code, I'd like to play > around with it. > > A while ago I wrote a pygame.sprite implementation > which used opengl. The idea was to be able to switch > renderers. It has a number of problems, but kind of > works ok for some games. > > Be good to get something which works well and fast on > different computers/games. I won't claim it's fast, but it should be cross platform! > Again, if I could have a look at your code I'd like to > play around with it :) Sure, although the code is pretty rough, and just a simple an extension cleanup of code I found on the net. It can be a pain in the ass to figure out the proper opengl chants without an example! In short SurfaceTexture manages a surface that is tied to an opengl texture, with methods for blitting images to it, and for reverting to the original image. The texture binding and drawing code is "static" so that it can be freely used by other code. -Jasper # This Module is modified from Bob Ippolito's code, found in pygame mail list archives from OpenGL.GL import * from OpenGL.GLU import * from pygame.locals import * import pygame POWERS = (32, 64, 128, 256, 512, 1024, 2048, 4096) def nextPower(x): for y in POWERS: if y >= x: return y def surfaceToOglTexture( imgsurf, texture=glGenTextures(1), scale=0, mipmap=0 ): """Bind an image to opengl texture""" owidth, oheight = imgsurf.get_size() width, height = tuple( map( nextPower,imgsurf.get_size() ) ) imageStr = pygame.image.tostring( imgsurf, "RGBA", 0 ) glBindTexture( GL_TEXTURE_2D, texture ) glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP ) glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP ) glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ) if mipmap: glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR ) gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGBA, owidth, oheight, GL_RGBA, GL_UNSIGNED_BYTE, imageStr ) else: glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ) if scale: image = gluScaleImage( GL_RGBA, owidth, oheight, imageStr, width, height, GL_UNSIGNED_BYTE ) glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image ) else: 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, imageStr ) return texture def drawTexture( (x,y), (w,h), texture, (screenXRes,screenYRes) ): """Draw a Quad in Orthogonal mode with the specified texture""" pMatrix = glGetDoublev( GL_PROJECTION_MATRIX ) mMatrix = glGetDoublev( GL_MODELVIEW_MATRIX ) glMatrixMode( GL_PROJECTION ) glLoadIdentity() gluOrtho2D( 0, screenXRes, screenYRes, 0 ) glMatrixMode( GL_MODELVIEW ) glLoadIdentity() glTranslatef( x, y, 0 ) glEnable( GL_TEXTURE_2D ) glBindTexture( GL_TEXTURE_2D, texture ) glBegin( GL_QUADS ) glTexCoord2f( 0.0, 0.0 ) ; glVertex2f( 0.0, 0.0 ) glTexCoord2f( 0.0, 1.0 ) ; glVertex2f( 0.0, h ) glTexCoord2f( 1.0, 1.0 ) ; glVertex2f( w, h ) glTexCoord2f( 1.0, 0.0 ) ; glVertex2f( w, 0.0 ) glEnd() glDisable( GL_TEXTURE_2D ) glMatrixMode( GL_PROJECTION ) glLoadMatrixd( pMatrix ) glMatrixMode( GL_MODELVIEW ) glLoadMatrixd( mMatrix ) class SurfaceTexture: """A class for drawing and blitting 'sprites' to images as textures in OpenGL""" def __init__( self, surface, screenRes, size=None, pos=(0,0), scale=0, mipmap=0 ): self.surface = surface.convert() self.texture = surfaceToOglTexture( surface, scale=scale, mipmap=mipmap ) self.screenRes = screenRes self.pos = pos if size: self.size = size else: self.size = screenRes self.original = surface.convert() self.dirtyRects = [] def delete( self ): glDeleteTextures( [self.texture] ) def moveTo( self, pos ): self.pos = pos def moveBy( self, pos ): self.pos = ( self.pos[0]+pos[0], self.pos[1]+pos[1] ) def draw( self ): drawTexture( self.pos, self.size, self.texture, self.screenRes ) def blit( self, sprites ): self.surface.lock() for sprite in sprites: self.surface.blit( sprite.image, sprite.rect ) self.surface.unlock() self.dirtyRects.extend( [sprite.rect for sprite in sprites] ) def clear( self, sprites ): self.surface.lock() for sprite in sprites: self.surface.blit( self.original.subsurface( sprite.rect ), sprite.rect ) self.surface.unlock() self.dirtyRects.extend( [sprite.rect for sprite in sprites] ) def updateTexture( self ): for rect in self.dirtyRects: subSurf = self.surface.subsurface( rect ) imageStr = pygame.image.tostring( subSurf, "RGBA", 0 ) x,y,w,h = rect glBindTexture( GL_TEXTURE_2D, self.texture ) glTexSubImage2D( GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, imageStr ) self.dirtyRects = [] |