Re: [pygame] Lousy FPS
Kris Schnee wrote: Aesthetically, I like the look of the isometric tiles more than anything I've done with OpenGL tiles. You should be able to get the same result from OpenGL by treating it as a fancy 2D drawing engine. Set up an orthographic projection that maps x,y coordinates to pixels, load all your tile images up as textures, and draw them as textured rectangles, using the z coordinate to control layering. You can use the same calculations you're doing already to work out the x,y coordinates to draw the tiles at, but won't have to worry about what order to draw things in, as the depth buffer will take care of it. And you can build a display list for all of the static tiles. The result should look pretty much identical to the pygame rendered version, and be extremely fast. -- Greg
Re: [pygame] Lousy FPS
On 9/13/06, Kris Schnee <[EMAIL PROTECTED]> wrote: hopefully something to boost the framerate above 12! As others have already mentioned, display lists are the key. For a Disgaea type map, you could compile the entire landscape into a single display list. This should speed up the rendering considerably. I.e. something like: listid = glGenLists(1) glNewList(listid, GL_COMPILE) glEndList() Then on your main loop you just call: glCallList(listid) -- Sami Hangaslammi
Re: [pygame] Lousy FPS
Jan Pobrislo wrote: Actually, if you want OpenGL version to do isometric rendering, you'll need to tweak the transformation matrix a bit. I didn't do it for a while, but you need something like this: in GL_PROJECTION matrix setup glOrtho view in GL_MODELVIEW glLoad something like this: | 1 0 0 0 | | 0 1 0 0 | | 0 x 1 0 | | 0 0 0 1 | where x is ratio by which Z axis distances (height in world) are translated to Y axis (up/down on screen), you'll probably use 0.5 you might also be able to use glMultMatrix on GL_PROJECTION instead of glLoad on GL_MODELVIEW, to have bigger freedom manipulating with modelview matrix Thanks for the info. I think I may not have explained quite what I meant, though. What I'm concerned with is the ability to get a cube-based landscape (as in "Disgaea") to display at a reasonable speed with decent lighting and the ability to do "picking" (telling which tile was mouse-clicked). Whether that's technically "isometric" in terms of the display angle and the manner of perspective distortion doesn't matter to me; I say "isometric" because I know of the word as "that thing that some games do with the diagonal camera view." I like that perspective with tiles and cubes because it allows for terrain with height, yet is much simpler than true 3D where you have to get 3D polygon models just to put a bagel onscreen. I've already got the ability to display a cube-based landscape using textures and terrain data loaded from a file -- in OpenGL/Pygame or pure Pygame, using two different homemade engines -- and to tilt and rotate the OpenGL version. If I'm to use the OpenGL version, I need to figure out picking, the math involved in making the camera follow the hero's sprite, something (lighting?) to make the landscape not hideous, and hopefully something to boost the framerate above 12! Kris Kris
Re: [pygame] Lousy FPS
Dne Tuesday 12 September 2006 21:23 Kris Schnee napsal(a): > I was messing with a Pygame/OpenGL version of my tile graphics engine, > and am alarmed by a framerate issue. > This is the OpenGL version, which looks this bad because of hastily > drawn textures, full lighting, etc.: > http://kschnee.xepher.net/pics/3dthing.jpg > This is the older version using isometric tiles: > http://kschnee.xepher.net/pics/shiningsea060630-0.jpg > > In each case the underlying world data is the same. My thinking in doing > the GL version was that I wouldn't have to draw those awkward diagonal > tiles, and that I'd be able to rotate to any angle. I tested it just now > and got 12 FPS (using a time.sleep(.05) call so the max would be 20). > OK, I said, the tradeoff is that the Pygame isometric version would be > faster than the OpenGL. > > So I tested the isometric version. 6 FPS, even with the logo and > interface turned off. Not good. How can my pasting tiles on a 2D surface > be slower than calling an OpenGL list of lists of 3D cube-drawing > instructions? > > I'll post the complete "Pearl3D" code if you want to see it. > > Kris Actually, if you want OpenGL version to do isometric rendering, you'll need to tweak the transformation matrix a bit. I didn't do it for a while, but you need something like this: in GL_PROJECTION matrix setup glOrtho view in GL_MODELVIEW glLoad something like this: | 1 0 0 0 | | 0 1 0 0 | | 0 x 1 0 | | 0 0 0 1 | where x is ratio by which Z axis distances (height in world) are translated to Y axis (up/down on screen), you'll probably use 0.5 you might also be able to use glMultMatrix on GL_PROJECTION instead of glLoad on GL_MODELVIEW, to have bigger freedom manipulating with modelview matrix
Re: [pygame] Lousy FPS
On 9/12/06, Kris Schnee <[EMAIL PROTECTED]> wrote: [SW approach drawing tiles every frame to get object occlusion right] well if you are going to get a nice speed with SW rendering, the trick is to do as little as possible. I think drawing from pre-composited backgrounds would be the least you can do when scrolling. I think the object occlusion thing can be handled with a dirty rect system, where you first draw from your pre-composed surface(s) (without alpha blending or color-keying for speed), and then draw the whole thing back to front interleaving objects and tiles properly sorted, where the objects cause screen areas to be dirty and tiles only draw to the dirty rects. The only ugly part is you'd get aliased edges on your tiles to double draw if you have them. Or if you want pygame/SDL rendering but are cool with HW acceleration, you could try going with that... ...but I'd probably go with OpenGL myself [Isometric opengl stuff] I think what you are looking for is an "Orthographic" projection (that's ortho as in orthogonal, meaning perpendicular, indicating that your z axis is drawn straight back, and doesn't go to a vanshing point like perspective) there's a gl function called glOrtho that you can use to set up your projection matrix, combined with a model matrix for a rotation (so you look at the world at an angle) you should be able to get your isometric look
Re: [pygame] Lousy FPS
Brian Fisher wrote: On 9/12/06, Kris Schnee <[EMAIL PROTECTED]> wrote: So I tested the isometric version. 6 FPS, even with the logo and interface turned off. Not good. How can my pasting tiles on a 2D surface be slower than calling an OpenGL list of lists of 3D cube-drawing instructions? How can OpenGL textured poly rendering be faster than software? well... [Long, erudite explanation omitted.] ... so lots of reasons... honestly, I'm really just suprised you are only getting 12 fps for what's drawn on the opengl screenshot, especially if you are using display lists and already have all your textures loaded... (mobo with integrated gfx in the chipset?) Laptop with an ATI Radeon 320M IGP, which runs Unreal Tournament 2004 pretty well. Much better than it runs my awesome graphics demo! > So what's the details on the SW guy? OK. I've put together a stand-alone demo of Pearl, the isometric Pygame-only engine. It's about 58KB with the included graphics. http://kschnee.xepher.net/code/Pearl060913.zip For what it's worth, you can use the code if you want. I'm drawing tiles every frame to the screen, which is inefficient. (And Psyco doesn't seem to help.) I've got a few lines of code meant to skip drawing a tile if it's obviously going to be offscreen, but that's probably not very useful. When I was using my purely 2D tile engine, I drew everything to a big offscreen buffer and then blitted a piece of that to the screen each frame rather than recalculating the tiles, but I don't think I can safely do that in isometric mode because sprites might go "behind" a tall tile; the landscape can't be drawn all at once. And it's likely I'm doing something massively stupid with the settings for the surface itself. (PS. Aesthetically, I like the isometric i.e. no perspective transform look a lot better... you can tell openGL to do that, if you want) Aesthetically, I like the look of the isometric tiles more than anything I've done with OpenGL tiles. Maybe it's just my lack of skill with OpenGL, eg. the lack of fancy lighting, but the GL stuff looks washed-out and fake while the pure Pygame stuff is more vibrant, like a cartoon. Drawing these diagonal tiles is awkward, though, and I can't rotate the landscape except (if I work at it) in 90-degree increments. What I'd really like to have is an isometric-or-3D tiled engine resembling the Nippon Ichi tactical RPGs, such as "Disgaea: Hour of Darkness." Screenshots and descriptions of these great games are at: http://hg101.classicgaming.gamespy.com/nipponichi/nipponichi.htm I know "GalaxyMage" is out there for Python, but it seems to have a license such that if I use its engine at all, I have to release all of my source code for everything else, which I'd rather not do. Uh, in looking for info about OpenGL's isometric capabilities, I immediately saw this: http://nehe.gamedev.net/data/downloads/download.asp?letter=I This site, I already knew, has many OpenGL tutorials, including some that've been translated to Python. On that link is a set of code for doing an isometric landscape, which seems to defeat the purpose of everything I've done on this part of the project... except that it's presumably in C only, so that I can't use it. Advice? Kris
Re: [pygame] Lousy FPS
--- Kris Schnee <[EMAIL PROTECTED]> wrote: > In each case the underlying world data is the same. My thinking in doing > the GL version was that I wouldn't have to draw those awkward diagonal > tiles, and that I'd be able to rotate to any angle. I tested it just now > and got 12 FPS (using a time.sleep(.05) call so the max would be 20). > OK, I said, the tradeoff is that the Pygame isometric version would be > faster than the OpenGL. > > So I tested the isometric version. 6 FPS, even with the logo and > interface turned off. Not good. How can my pasting tiles on a 2D surface > be slower than calling an OpenGL list of lists of 3D cube-drawing > instructions? Your server appears to be down right now, but I'm familiar with the old Pygame engine screenshots already. My main question would be "how many tiles are you trying to draw, and how are you trying to draw them?" Python's performance plummets when it's calling hundreds of tile-drawing functions through a for-loop, and I assume that that's what you're doing in both versions. My rough rule of thumb would be to stay under 1000 tiles per frame, and preferably under 500 if you want to have lots of cpu headroom. Performance is particularly bad if you're using a nested sequence type with a corresponding for-loop for each dimension, like this: for x in tilemap: for y in x: for x in z: drawtile(z) (Presumably, since this is an isometric engine, you'd have a z loop.) Running the draw routine with only one loop nets a surprisingly large gain in performance. I do this by setting up a "drawing cache" that is a list of tuples, with each entry pointing to the original data structure and adding positioning info: cache = [(foo[0][0][0],0,0,0),(foo[0][0][1],0,0,1),] [drawtile(c[0],c[1],c[2],c[3]) for c in cache] Pygame alone is always going to have trouble drawing a full-screen game. The only things you can really do to solve the problem are limit resolution or carefully minimize the amount drawn(eg. no smooth scrolling). A render loop in C could help, but blits take the majority of the cpu time in Pygame and it would be no different with C. Under OpenGL, if you run the cache into a display list outside of your main loop, you can call the display list once per frame and it will draw all the tiles very quickly, quickly enough so that performance is a non-issue. Pygame can get some of the same benefit by rendering the entire map to a "background" surface and drawing that every frame. The only problem is that you have to recreate the display list each time your tiles change. For scrolling, you can simply overdraw(draw everything, even offscreen stuff) without major penalties both in Pygame and OpenGL, if the map isn't too big. If you want the tiles to change dynamically, then you have to redraw at some point, and to optimize performance implies the use of some kind of culling mechanism. It could easily get VERY complicated to do that for an isometric engine. Hopefully that's enough to get you started with some optimization. I'm sure it's possible to get decent performance; but depending on what you've done it might take some major reworking of the renderer design. __ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com
Re: [pygame] Lousy FPS
On 9/12/06, Kris Schnee <[EMAIL PROTECTED]> wrote: So I tested the isometric version. 6 FPS, even with the logo and interface turned off. Not good. How can my pasting tiles on a 2D surface be slower than calling an OpenGL list of lists of 3D cube-drawing instructions? How can OpenGL textured poly rendering be faster than software? well... Parallelism between CPU and GPU (they can execute things at the same time), parallelism between the cpu memory bus and the video card memory bus (the video card adds a bunch of extra memory that can read and write while your cpu is calculating things), saving the time of copying the software surface to the video card and locks both buses (the video card can shove memory from it's texture buffers to back buffers straight to the display buffer all using it's caches and high speed buses, while the mem copy would have to use the much slower AGP or (god forbid) PCI buses) and the many many benefits of a dedicated HW design vs. a general purpose one (most of which are a form of parallelism on the video card itself, like having dedicated z-buffer mem channels to get z-buffer at no additional cost, being able to do multiple texture lookups at once over a range of pixels, being able to do complex texture interpolation in a single op, being able to interleave the screen buffer memory into multiple channels so that it can render multiple zones all at once) ... so lots of reasons... honestly, I'm really just suprised you are only getting 12 fps for what's drawn on the opengl screenshot, especially if you are using display lists and already have all your textures loaded... (mobo with integrated gfx in the chipset?) -- For that that whole SDL version screenshot, if you are redrawing every frame as a bunch of overlapping rectangular tiles with alpha blending and no RLE... well than 6 fps seems about right for an older comp I think You may have dramatically different results based on RLE and HW_ACCEL flags for your surfaces and bit depth conversion issues, but In my experience you usually can't get an app that is redrawing a full 800x600 screen with significant overdraw to ever go fast with SW rendering... ...now if your software thing were blitting those tiles to a flattened scrolling buffer (saving you a lot of alpha blending of rects with a larger area than the tile and eliminating most of the overdraw) I would expect you could get more like 12fps or so (i.e. you could do a scrolling game at a decent rate) So what's the details on the SW guy? --- (PS. Aesthetically, I like the isometric i.e. no perspective transform look a lot better... you can tell openGL to do that, if you want)