Nehe 19: 2500 Particles (Xcode) vs 150 (BlitzMax)
BlitzMax Forums/OpenGL Module/Nehe 19: 2500 Particles (Xcode) vs 150 (BlitzMax)
| ||
Hi All, I've been going through the excellent NeHe tutorials (thanks very much to Extron for converting them to Blitzmax) - noticing that tutorial #19 seems very slow on my Powerbook G4. To get a decent framerate above 30fps I reduced the maximum number of particles to 150 (the default is 1000). I thought this to be an extremely low count so I went back to the NeHe site & downloaded an XCode (Cocoa) version, it will perform smoothly at over 2500 particles. You can find the OSX code at the bottom of this page: http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=19 In case you don't know, the blitzmax code can be found on this thread: http://www.blitzbasic.com/Community/posts.php?topic=41689 Can anyone shed some light on this matter of differing performance between the Blitzmax & XCode versions? |
| ||
I have no problems runnig either of them. You will get the same result if you set the swapinterval to zero in the max example, I think. Sveinung |
| ||
Thanks for the reply - I tried setting the swapinterval to zero and this had no effect. Just in case anyone else asks I'm not running in debug mode either. |
| ||
No problems on the PC version of Max. Whether the settings are MAX_PARTICLES=150 or MAX_PARTICLES=2500 the frame rates remain at a constant 61fps |
| ||
1000 ran just fine.. so did 2500.. I even got 25000 running at 56 fps.. :p |
| ||
I've just tested the same code under an iMac G5; the issues with performance are the same under this platform. If anyone could test these examples under the OSX platform I would appreciate it. Thanks. |
| ||
Just tried both on Dual G5 Powermac - same results. Cocoa version very fast, BMax version dog slow (6 to 7 fps). Commenting out the actual for loop that draws the particles brings it up to 60, so we're looking at something in there. So, I poked around commenting things out - and the thing that's slowing stuff down are the "If (KeyDown..." statements, surprisingly enough - commenting them out brings the framerate back up to 60. Even leaving the single "If KeyDown(KEY_TAB)" brought the fps down to 30. And this is without touching the keys during the run, so it's not the content of the if statements - it's the actual checks. ... time passes... Ah. They're inside the "For loop=0 to MAX_PARTICLES-1" loop - that explains it. Rather than check those keys once per frame, we're checking once per particle - presumably as a cheap way to adjust all of the particles. Dandy, but slow. Moving those If statements to outside that loop, and changing them to the form: If (KeyDown(KEY_NUM8)) And (particle[loop].yg<1.5) For n = 0 To MAX_PARTICLES-1 particle[n].yg:+0.01 Next EndIf Gives us a nice 60 fps. (Edited for code clarity) |
| ||
As a followup now that I think of it - it then makes no sense that the PC version would work without slowdown, as it's doing the same work - unless the implementation of KeyDown is signficantly cheaper on the PC. And in fact, on my older PC (Intel P4 2.4 Ghz, 3/4 gig of ram, ATI video card) I get 35 fps with the unmodified version. My guess is the other PC testers had better hardware than I do :-) And - the KeyDown code on the mac appears to be significantly slower than on the PC. I am sad. UPDATE: I filed a bug report on the slow KeyDown issue in the bugs forum... |
| ||
Bortels, Thanks very much for solving this problem, the last thing I expected it to be is KeyDown checking! On the iMac G5 the demo in mention now moves around 20,000 particles at full-frame. I'm very impressed. Another point of interest is it takes about 1 minute to create 20,000 instances of the particle type in the array. I've tried putting a flushmem in the loop however it makes very little diffference. Interesting? Thanks again Bortels - you're a champion!! |
| ||
The init stuff is likely to be much faster in the next blitzmax update. |
| ||
There is a simple reason initialisation takes that long: One of the worst possible implementations for the particle array's init ... (might be nice for C++ but deadly for BM with its memory management where resizing an array means much more of work than just resizing a memory block) Change the following code: Function InitGl() LoadGlTextures() glEnable(GL_TEXTURE_2D) ' Enable Texture Mapping glShadeModel(GL_SMOOTH) ' Enable Smooth Shading glClearColor(0.0, 0.0, 0.0, 0.0) ' Black Background glClearDepth(1.0) ' Depth Buffer Setup glDisable(GL_DEPTH_TEST) ' Disable Depth Testing glEnable(GL_BLEND) ' Enable Blending glBlendFunc(GL_SRC_ALPHA,GL_ONE) ' Type Of Blending To Perform glDepthFunc(GL_LEQUAL) ' The Type Of Depth Testing To Do glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST) ' Really Nice Perspective Calculations glHint(GL_POINT_SMOOTH_HINT,GL_NICEST) ' Really Nice Point Smoothing glBindTexture(GL_TEXTURE_2D,Texname) ' Select Our Texture For loop=0 To MAX_PARTICLES-1 ' Initials All The Textures particle=particle:particles[..loop+1] particle[loop]=New particles to Function InitGl() LoadGlTextures() glEnable(GL_TEXTURE_2D) ' Enable Texture Mapping glShadeModel(GL_SMOOTH) ' Enable Smooth Shading glClearColor(0.0, 0.0, 0.0, 0.0) ' Black Background glClearDepth(1.0) ' Depth Buffer Setup glDisable(GL_DEPTH_TEST) ' Disable Depth Testing glEnable(GL_BLEND) ' Enable Blending glBlendFunc(GL_SRC_ALPHA,GL_ONE) ' Type Of Blending To Perform glDepthFunc(GL_LEQUAL) ' The Type Of Depth Testing To Do glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST) ' Really Nice Perspective Calculations glHint(GL_POINT_SMOOTH_HINT,GL_NICEST) ' Really Nice Point Smoothing glBindTexture(GL_TEXTURE_2D,Texname) ' Select Our Texture particle= new particles[MAX_PARTICLES] For loop=0 To MAX_PARTICLES-1 This should speed the whole thing quite a little up |
| ||
Dreamora, this is really excellent! The improvement in speed is amazing! Thank you! |