Thread: [PyOpenGL-Users] Texture Blitting?
Brought to you by:
mcfletch
From: Jasper P. <ja...@pe...> - 2003-03-05 11:20:23
|
I've just recently started to use pygame, and am rendering in OpenGL as that allows smooth full screen scrolling without blitting, zooming, etc. However, I still want to change "texture" surfaces, and thus need to blit to them. This seems simple enough in concept, once you know about OpenGL's glTexSubImage2d(), but I'm getting strange behavior... My texture updates work, except on mipmapped textures -- then they seem to "blend" with the original surface. Even weirder, if multiple blits target the same "texels", only the latest blit is "blended" with the original image!? Obviously I'm missing something... Does anyone know how to make this work correctly with mipmapping? I tried changing the "level" argument to glTexSubImage2d(), as it's docs allude to a connection with mipmapping, but that just crashes. -Jasper |
From: <il...@ya...> - 2003-03-06 00:49:08
|
Hello, 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. Again, if I could have a look at your code I'd like to play around with it :) --- Jasper Phillips <ja...@pe...> wrote: > I've just recently started to use pygame, and am > rendering in OpenGL as that > allows smooth full screen scrolling without > blitting, zooming, etc. However, > I still want to change "texture" surfaces, and thus > need to blit to them. > This seems simple enough in concept, once you know > about OpenGL's > glTexSubImage2d(), but I'm getting strange > behavior... > > My texture updates work, except on mipmapped > textures -- then they seem to > "blend" with the original surface. Even weirder, if > multiple blits target > the same "texels", only the latest blit is "blended" > with the original > image!? Obviously I'm missing something... > > Does anyone know how to make this work correctly > with mipmapping? I tried > changing the "level" argument to glTexSubImage2d(), > as it's docs allude > to a connection with mipmapping, but that just > crashes. > > -Jasper __________________________________________________ Do You Yahoo!? Everything you'll ever need on one web page from News and Sport to Email and Music Charts http://uk.my.yahoo.com |
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 = [] |