Re: [pygame] Lousy FPS

2006-09-14 Thread Greg Ewing

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

2006-09-13 Thread Sami Hangaslammi

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

2006-09-13 Thread Kris Schnee

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

2006-09-13 Thread Jan Pobrislo
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

2006-09-13 Thread Brian Fisher

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

2006-09-12 Thread Kris Schnee

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

2006-09-12 Thread James Hofmann


--- 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

2006-09-12 Thread Brian Fisher

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)