def loadWaterMap(self): origSources = self.fluid_sim.sources sources = set() for source in origSources: oldr = source[0] oldc = source[1] sources.add((oldr * SUBDIVIDE_FACTOR, oldc * SUBDIVIDE_FACTOR)) fluid = [] for sdr in range(SIM_SIZE * SUBDIVIDE_FACTOR): fluid.append([]) for sdc in range(SIM_SIZE * SUBDIVIDE_FACTOR): fluid[sdr].append([]) for r in range(SIM_SIZE): for c in range(SIM_SIZE): subdivCell = self.fluid_sim.subdivParticles( r, c, SUBDIVIDE_FACTOR) for cr in range(SUBDIVIDE_FACTOR): for cc in range(SUBDIVIDE_FACTOR): for particle in subdivCell[cr][cc]: fluid[r * SUBDIVIDE_FACTOR + cr][c * SUBDIVIDE_FACTOR + cc].append(particle) minV = rasterizer.np.array([255, 255, 255, 255]) maxV = rasterizer.np.array([0, 0, 255, 255]) sourceAlt = rasterizer.np.array([127, 127, 0, 0]) data = rasterizer.fluid_to_texture(fluid, SIM_SIZE*SUBDIVIDE_FACTOR, SIM_SIZE*SUBDIVIDE_FACTOR, \ float(RENDER_MAX), minV, maxV, sources, sourceAlt) glActiveTexture(GL_TEXTURE1_ARB) return texture.Texture( PIL.Image.frombuffer( "RGBA", (SIM_SIZE * SUBDIVIDE_FACTOR, SIM_SIZE * SUBDIVIDE_FACTOR), data))
class TestContext(BaseContext): def OnInit(self): """Load the image on initial load of the application""" global multitexture multitexture = self.extensions.initExtension("GL.ARB.multitexture") if not multitexture: print 'GL_ARB_multitexture not supported!' sys.exit(1) self.image = self.loadImage("nehe_wall.bmp") self.lightmap = self.loadLightMap("lightmap1.jpg") def loadImage(self, imageName="nehe_wall.bmp"): """Load an image from a file using PIL. This is closer to what you really want to do than the original port's crammed-together stuff that set global state in the loading method. Note the process of binding the texture to an ID then loading the texture into memory. This didn't seem clear to me somehow in the tutorial. """ try: from PIL.Image import open except ImportError, err: from Image import open multitexture.glActiveTextureARB(multitexture.GL_TEXTURE0_ARB) return texture.Texture(open(imageName))
def loadImage(self, imageName="nehe_wall.bmp"): """Load an image from a file using PIL.""" try: from PIL.Image import open except ImportError: from Image import open glActiveTexture(GL_TEXTURE0_ARB) return texture.Texture(open(imageName))
def loadLightMap(self, imageName="lightmap1.jpg"): """Load an image from a file using PIL as a lightmap (greyscale) """ try: from PIL.Image import open except ImportError: from Image import open glActiveTextureARB(GL_TEXTURE1) return texture.Texture(open(imageName))
def loadImage(self, imageName="nehe_wall.bmp"): """Load an image file as a 2D texture using PIL """ try: from PIL.Image import open except ImportError as err: from Image import open im = texture.Texture(open(imageName)) return im
def loadLightMap(self, imageName="lightmap1.jpg"): """Load an image from a file using PIL as a lightmap (greyscale) """ try: from PIL.Image import open except ImportError as err: from Image import open multitexture.glActiveTextureARB(multitexture.GL_TEXTURE1_ARB) glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE) return texture.Texture(open(imageName))
def loadImage(self, imageName="nehe_wall.bmp"): """Load an image from a file using PIL. This is closer to what you really want to do than the original port's crammed-together stuff that set global state in the loading method. Note the process of binding the texture to an ID then loading the texture into memory. This didn't seem clear to me somehow in the tutorial. """ try: from PIL.Image import open except ImportError as err: from Image import open multitexture.glActiveTextureARB(multitexture.GL_TEXTURE0_ARB) return texture.Texture(open(imageName))
def render(self): """Render this texture to the context""" if self.texture is None: format = [0, GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_RGB, GL_RGBA][self.components] self.texture = texture.Texture(format=format) x, y, d = self.size() self.texture.store(d, format, x, y, None) self.texture() needs = self.need_updates[:] del self.need_updates[:len(needs)] for need in needs: need = need() if need is not None: need.update(self.texture) return self.texture
def test_texture(self): """Test texture (requires OpenGLContext and PIL)""" try: from OpenGLContext import texture import Image from OpenGL.GLUT import glutSolidTeapot except ImportError: pass else: assert glutSolidTeapot glEnable(GL_TEXTURE_2D) ourTexture = texture.Texture( Image.open(os.path.join(HERE, "yingyang.png"))) ourTexture() result = glGetTexImageub(GL_TEXTURE_2D, 0, GL_RGBA) assert isinstance(result, bytes), type(result) result = glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE) assert isinstance(result, bytes), type(result) glEnable(GL_LIGHTING) glEnable(GL_LIGHT0) glBegin(GL_TRIANGLES) try: try: glTexCoord2f(.5, 1) glVertex3f(0., 1., 0.) except Exception: traceback.print_exc() glTexCoord2f(0, 0) glVertex3fv([-1, 0, 0]) glTexCoord2f(1, 0) glVertex3dv([1, 0, 0]) try: glVertex3dv([1, 0]) except ValueError: assert OpenGL.ARRAY_SIZE_CHECKING, """Should have raised ValueError when doing array size checking""" else: assert not OpenGL.ARRAY_SIZE_CHECKING, """Should not have raised ValueError when not doing array size checking""" finally: glEnd()
def createTexture( self, image, mode=None ): """Create a new texture-holding object Uses the TextureCache to try to minimise the number of textures created """ # basically just the interpretation of an SFImage # field as a texture... if len( image ) < 4: # don't have any components... return None width, height, componentCount = [int(x) for x in image[:3]] if not componentCount: log.warn( 'bad component count in pixeltexture %s', self ) return None if (not width) or (not height): log.warn( '0-size dimension in pixeltexture %s', self ) return None if len(image) != width*height+3: log.warn( 'PixelTexture has incorrect image size, expected %s items (%s*%s)+3, got %s', width*height+3, width, height, len(image), ) return None import struct imageBody = image[3:] data = b"".join([ struct.pack( b'>L', item )[-componentCount:] for item in imageBody ]) tex = texture.Texture( ) tex.store( componentCount, [0, GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_RGB, GL_RGBA ][componentCount], width, height, data, ) return tex
def test_texture( self ): """Test texture (requires OpenGLContext and PIL)""" try: from OpenGLContext import texture import Image from OpenGL.GLUT import glutSolidTeapot except ImportError as err: pass else: glEnable( GL_TEXTURE_2D ) ourTexture = texture.Texture( Image.open( 'yingyang.png' ) ) ourTexture() glEnable( GL_LIGHTING ) glEnable( GL_LIGHT0 ) glBegin( GL_TRIANGLES ) try: try: glTexCoord2f( .5, 1 ) glVertex3f( 0.,1.,0. ) except Exception as err: traceback.print_exc() glTexCoord2f( 0, 0 ) glVertex3fv( [-1,0,0] ) glTexCoord2f( 1, 0 ) glVertex3dv( [1,0,0] ) try: glVertex3dv( [1,0] ) except ValueError as err: #Got expected value error (good) pass else: raise RuntimeError( """Should have raised a value error on passing 2-element array to 3-element function!""", ) finally: glEnd()
vert = (x, y, 0.0) gluTessVertex(tobj, vert, vert) gluTessEndContour(tobj) gluTessEndPolygon(tobj) def test_texture(self): """Test texture (requires OpenGLContext and PIL)""" try: from OpenGLContext import texture import Image from OpenGL.GLUT import glutSolidTeapot except ImportError, err: pass else: glEnable(GL_TEXTURE_2D) ourTexture = texture.Texture(Image.open('yingyang.png')) ourTexture() glEnable(GL_LIGHTING) glEnable(GL_LIGHT0) glBegin(GL_TRIANGLES) try: try: glTexCoord2f(.5, 1) glVertex3f(0., 1., 0.) except Exception, err: traceback.print_exc() glTexCoord2f(0, 0) glVertex3fv([-1, 0, 0]) glTexCoord2f(1, 0) glVertex3dv([1, 0, 0])
class TestContext(BaseContext): """Multi-texturing demo """ initialPosition = (0, 0, 0) rotation = 0 def OnInit(self): """Do all of our setup functions...""" if not glMultiTexCoord2f: print 'Multitexture not supported!' sys.exit(1) self.addEventHandler("keypress", name="r", function=self.OnReverse) self.addEventHandler("keypress", name="s", function=self.OnSlower) self.addEventHandler("keypress", name="f", function=self.OnFaster) print 'r -- reverse time\ns -- slow time\nf -- speed time' self.time = Timer(duration=8.0, repeating=1) self.time.addEventHandler("fraction", self.OnTimerFraction) self.time.register(self) self.time.start() '''Load both of our textures.''' self.Load() ### Timer callback def OnTimerFraction(self, event): self.rotation = event.fraction() * -360 '''Keyboard callbacks, to allow for manipulating timer''' def OnReverse(self, event): self.time.internal.multiplier = -self.time.internal.multiplier print "reverse", self.time.internal.multiplier def OnSlower(self, event): self.time.internal.multiplier = self.time.internal.multiplier / 2.0 print "slower", self.time.internal.multiplier def OnFaster(self, event): self.time.internal.multiplier = self.time.internal.multiplier * 2.0 print "faster", self.time.internal.multiplier def Load(self): self.image = self.loadImage("nehe_wall.bmp") self.lightmap = self.loadLightMap("lightmap1.jpg") def Render(self, mode): """Render scene geometry""" BaseContext.Render(self, mode) if mode.visible: glDisable(GL_LIGHTING) # context lights by default glTranslatef(1.5, 0.0, -6.0) glRotated(self.rotation, 1, 0, 0) glRotated(self.rotation, 0, 1, 0) glRotated(self.rotation, 0, 0, 1) '''We set up each texture in turn, the only difference between them being their application model. We want texture 0 applied as a simple decal, while we want the light-map to modulate the colour in the base texture.''' glActiveTexture(GL_TEXTURE0) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST) glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL) '''Enable the image (with the current texture unit)''' self.image() glActiveTexture(GL_TEXTURE1) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST) glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE) '''Enable the image (with the current texture unit)''' self.lightmap() self.drawCube() def loadImage(self, imageName="nehe_wall.bmp"): """Load an image from a file using PIL.""" try: from PIL.Image import open except ImportError, err: from Image import open glActiveTexture(GL_TEXTURE0_ARB) return texture.Texture(open(imageName))
try: from PIL.Image import open except ImportError, err: from Image import open glActiveTexture(GL_TEXTURE0_ARB) return texture.Texture(open(imageName)) def loadLightMap(self, imageName="lightmap1.jpg"): """Load an image from a file using PIL as a lightmap (greyscale) """ try: from PIL.Image import open except ImportError, err: from Image import open glActiveTextureARB(GL_TEXTURE1) return texture.Texture(open(imageName)) def drawCube(self): """Draw a cube with texture coordinates""" glBegin(GL_QUADS) mTexture(0.0, 0.0) glVertex3f(-1.0, -1.0, 1.0) mTexture(1.0, 0.0) glVertex3f(1.0, -1.0, 1.0) mTexture(1.0, 1.0) glVertex3f(1.0, 1.0, 1.0) mTexture(0.0, 1.0) glVertex3f(-1.0, 1.0, 1.0) mTexture(1.0, 0.0) glVertex3f(-1.0, -1.0, -1.0)
class TestContext(BaseContext): """Timer-based control of animation (OpenGLContext timers) """ initialPosition = (0, 0, 0) drawPollTimeout = 0.01 def OnInit(self): """Load the image on initial load of the application""" self.image = self.loadImage() print """You should see a slowly rotating textured cube The animation is provided by a timer, rather than the crude time-module based animation we use for the other NeHe tutorials.""" print ' <r> reverse the time-sequence' print ' <s> make time pass more slowly' print ' <f> make time pass faster' '''Here we will register key-press handlers for the various operations the user can perform.''' self.addEventHandler("keypress", name="r", function=self.OnReverse) self.addEventHandler("keypress", name="s", function=self.OnSlower) self.addEventHandler("keypress", name="f", function=self.OnFaster) '''We'll create a Timer object. The duration is the total cycle length for the timer, the repeating flag tells the timer to continue running.''' self.time = Timer(duration=8.0, repeating=1) '''The timer generates events for "fractions" as well as for cycles. We use the fraction value to generate a smooth animation.''' self.time.addEventHandler("fraction", self.OnTimerFraction) '''Registering and starting the timer are only necessary because the node is not part of a scenegraph.''' self.time.register(self) self.time.start() '''As with the time.time() mechanism, we need to track our current rotation so that the rendering pass can perform the rotation calculated by the timer callback.''' self.rotation = 0 '''Timer callback''' def OnTimerFraction(self, event): self.rotation = event.fraction() * -360 '''Keyboard callbacks. Each of these simply modifies the timer's internal-timer multiplier. Each Timer node has an internal timer which provides the low-level events that the timer interprets. By changing the multiplier on this internal timer we change the perceived passage of time for the user.''' def OnReverse(self, event): self.time.internal.multiplier = -self.time.internal.multiplier print "reverse", self.time.internal.multiplier def OnSlower(self, event): self.time.internal.multiplier = self.time.internal.multiplier / 2.0 print "slower", self.time.internal.multiplier def OnFaster(self, event): self.time.internal.multiplier = self.time.internal.multiplier * 2.0 print "faster", self.time.internal.multiplier def Render(self, mode): """Render scene geometry""" BaseContext.Render(self, mode) glDisable(GL_LIGHTING) # context lights by default glTranslatef(1.5, 0.0, -6.0) glRotated(self.rotation, 1, 0, 0) glRotated(self.rotation, 0, 1, 0) glRotated(self.rotation, 0, 0, 1) self.setupTexture() self.drawCube() def loadImage(self, imageName="nehe_wall.bmp"): """Load an image file as a 2D texture using PIL """ try: from PIL.Image import open except ImportError, err: from Image import open im = texture.Texture(open(imageName)) return im