That's called a texture atlas, but be careful with the mipmaps. They usually have to be generated specially I think.
http://http.download.nvidia.com/developer/NVTextureSuite/Atlas_Tools/Texture_Atlas_Whitepaper.pdf On Mon, Mar 16, 2009 at 1:49 PM, Zack Schilling <zack.schill...@gmail.com> wrote: > If someone did this and I could drop it in to my code, that would be very > nice. But for right now, PyOpenGL is serving my needs just fine. I can use > about 600 independently textured and animated sprites onscreen, scaled and > rotated, without stressing a low-end system more than 40%. > > 40% is a significant amount of overhead, but Peter is wrong of a few points. > You certainly can animate a sprite in OpenGL using texture coords. Just load > all your animation frames, convert to strings, stick them all together, and > pass to OpenGL as one very tall texture. This works perfectly fine. That > means VBOs are definitely suitable. You can also push a VBO up piecemeal, > changing the active texture between parts (and achieving the expected > effect). > > Everything you see here is done with pygame and PyOpenGL: > http://www.youtube.com/watch?v=cBFoXqKrBa8 > > Positioning the quads directly doesn't seem to be too much of an issue, > since in my game, they move each frame anyway. The cost of adding > coordinates in Python and pushing them into a numpy array is much less than > an OpenGL push, translate/rotate, pop call for each and every sprite. It > makes a lot of sense to me that this would be the case in other languages as > well. > > -Zack > > On Mar 16, 2009, at 1:00 PM, Forrest Voight wrote: > >> Would writing a replacement for PyOpenGL in C instead of in Python >> with ctypes help? I think it really would ... PyOpenGL is internally >> pretty complex, sometimes when I get tracebacks the error is 5 or 6 >> levels into PyOpenGL. Even a C library that only implemented the >> common functions and relied on PyOpenGL for the constants and >> functions that do complex things like handling strings would probably >> help a lot. >> >> On Fri, Feb 27, 2009 at 11:19 AM, Peter Gebauer >> <peter.geba...@stockholm.bostream.se> wrote: >>> >>> Hi! >>> >>> I've done a few sprite thingies in OpenGL here are some pointers: >>> >>> Afaik display lists and VBO's can't bind different textures (?) >>> per list/array. You can't animate lists by changing texcoords >>> independently per element, so no go. VBO's have texture coords, >>> but only one texture. Again, I'm no expert, might be wrong. >>> >>> With the quad aproach you should try >>> to make the number of calls as few as possible. If you get >>> rid of the push and translate for each sprite you'll get some >>> extra speed. Try positioning each quads directly. The downside >>> with sharing matrix over all sprites is the obvious lack of >>> using OpenGL transformations, but some vector math aplied to >>> the quads has been faster for me than having one transformed >>> matrix per quad. >>> >>> Since I haven't been able to animate a list/vbo with independent >>> textures and texture coords for each element/buffer object I've only >>> used it for backdrops. The speed increase is tremendous. >>> I also partition the elements so only one list/vbo is displayed per >>> visible section, if you're screen display is smaller than the >>> entire scene, this helps even more. >>> >>> If you put all your sprites and their animation frames into one >>> big texture you could use VBO's, but I've never had the tenacity >>> to try that aproach. >>> >>> Another way to increase speed is to write an opengl rendering engine >>> in C and call and make it available as a Python extension. This is >>> a major speed boost, in particular for a large number of iterations. >>> Iirc PyOpenGL bindings are generated, many times this is suboptimal >>> code for what you're trying to do, writing the Python extension in C >>> manually have been faster for me many times. This is indeed true >>> if you put your iterations inside a C loop instead of calling the >>> C function from Python many times. >>> >>> In any case, still waiting for that OO 2D game engine with tons of >>> OpenGL features and effects, including simple things like frame >>> animation, >>> LERP-like features and a simple 2D scenegraph. No luck yet, all attempts >>> I've tried so far lack at least one "must have" feature. :) >>> >>> /Peter >>> >>> On 2009-02-26 (Thu) 11:29, Casey Duncan wrote: >>>> >>>> Immediate mode calls (glVertex et al) are the very slowest way to use >>>> OpenGL. In fact they are deprecated in OpenGL 3.0 and will eventually be >>>> removed. >>>> >>>> The display list is better as you discovered, but you still are making a >>>> few OpenGL state changes per sprite, which is likely slowing you down. >>>> Also there is some overhead for the display list call, which makes them >>>> sub-optimal for just drawing a single quad. >>>> >>>>> glPushMatrix() >>>>> glTranslate(self.positionx,self.positiony,0) >>>>> glCallList(self.displist) >>>>> glPopMatrix() >>>> >>>> You really need to batch the quads up into a few vertex arrays or vbos >>>> to stream them to the card in one go. pyglet has a high-level python >>>> sprite api that automates this for you fwiw. >>>> >>>> -Casey >>>> >>>> On Feb 26, 2009, at 11:04 AM, Zack Schilling wrote: >>>> >>>>> I know the PyOpenGL mailing list might be a better place to ask this >>>>> question, but I've had a lot of luck talking to the experienced people >>>>> here so I figured I'd try it first. >>>>> >>>>> I'm trying to migrate a game I created from using the Pygame / SDL >>>>> software rendering to OpenGL. Before attempting the massive and >>>>> complex conversion involved with moving the whole game, I decided to >>>>> make a little test program while I learned OpenGL. >>>>> >>>>> In this test, I set up OpenGL to work in 2D and began loading images >>>>> into texture objects and drawing textured quads as sprites. I created a >>>>> little glSprite class to handle the drawing and translation. At first >>>>> its draw routine looked like this: >>>>> >>>>> glPushMatrix() >>>>> glTranslate(self.positionx,self.positiony,0) >>>>> glBindTexture(GL_TEXTURE_2D, self.texture) >>>>> glBegin(GL_QUADS) >>>>> glTexCoord2f(0, 1) >>>>> glVertex2f(0, 0) >>>>> glTexCoord2f(1, 1) >>>>> glVertex2f(w, 0) >>>>> glTexCoord2f(1, 0) >>>>> glVertex2f(w, h) >>>>> glTexCoord2f(0, 0) >>>>> glVertex2f(0, h) >>>>> glEnd() >>>>> glPopMatrix() >>>>> >>>>> Note: self.texture is a texture ID of a loaded OpenGL texture object. >>>>> My sprite class keeps a dictionary cache and only loads the sprite's >>>>> image into a texture if it needs to. >>>>> >>>>> I'd get maybe 200 identical sprites (same texture) onscreen and my CPU >>>>> would hit 100% load from Python execution. I looked into what could be >>>>> causing this and found out that it's probably function call overhead. >>>>> That's 14 external library function calls per sprite draw. >>>>> >>>>> The next thing I tried was to create a display list at each sprite's >>>>> initialization. Then my code looked like this: >>>>> glPushMatrix() >>>>> glTranslate(self.positionx,self.positiony,0) >>>>> glCallList(self.displist) >>>>> glPopMatrix() >>>>> >>>>> Well, that's nice, down to 4 calls per draw. I was able to push ~500 >>>>> sprites per frame using this method before the CPU tapped out. I need >>>>> more speed than this. My game logic uses 30-40% of the CPU alone and >>>>> I'd like to push at least 1000 sprites. What can I do? I've looked into >>>>> passing sprites as a matrix with vertex arrays, but forming a proper >>>>> vertex array with numpy can sometimes be more trouble than it's worth. >>>>> Plus, I can't swap out textures easily mid-draw, so it makes things >>>>> much more complex than the simple way I'm doing things now. >>>>> >>>>> Is there any design pattern I could follow that will get me more speed >>>>> without sending me off the deep end with complexity. >>>>> >>>>> Thanks, >>>>> >>>>> Zack >>> > >