But it does not seem to work. I am trying to preload some of the common ships modes at the start. But i still get slowdowns when i first look at the ships in game. Is there a way to load every thing in (short of putting every ship on the screen for a moment) ?
I think you can temporarily set an omni bounding volume for render, and set it as final, then force render frame once.
The idea of pre-rendering is quite easy, load this and this before this and this. But this is Panda3D so i think this’d be the better:
from blablabla import moreblablabla #blablabla... prerenderlist =  while prerenderingisnotdone(): prerenderlist.append(allobjectsyouneed;object;object) if prerenderingisdone = true: PandaNode.append(prerenderlist)
I’ve written it in speed, so this won’t work, however take this to mind.
treeform is referring to not just loading up the models, but having Panda send the models and their associated assets (especially textures) to the graphics card for rendering.
Normally, Panda doesn’t load these assets to the graphics card immediately, because your graphics memory is limited and there may not be room for it to hold all of your models at once. Instead, if you do nothing else, Panda will upload these assets the first time the model is rendered: the first time it appears in front of your camera.
This can result in a perceptible slowdown, especially if you plunk your camera down in the middle of a scene with lots of things to see all around. The first time you pan the camera left or right, Panda has to upload all of these textures to the graphics card, which slows down the panning and makes it feel sluggish.
To avoid this sluggishness, you can tell Panda to upload specific assets immediately. This is the purpose of node.prepareScene().
It works perfectly for me, although I do believe it might preload only textures, and avoid vertex buffers and shaders for later. The vertex buffers in practice aren’t a problem (they seem to load really fast), but shaders could be. Might it be a problem with shaders in your case?
Honestly, until today, I haven’t seen any good proof of prepareScene.
Here is my tests result :
no prep : 1.64100003242 with prep : 1.70300006866 temporary OBV : 1.01600003242
Even using temporary OBV, there are still some chugs. There is no chug at all if I use finalized OBV all the time, but that’s stupid.
Here is my test scene, no lights, no shaders :
from pandac.PandaModules import * import direct.directbase.DirectStart from direct.interval.IntervalGlobal import * import os,sys import time,random os.chdir(sys.path) def printTime(startT): print 'elapsed:',time.time()-startT root='G:\PictureZ\movies' CREATE=1 useOBV=0 getModelPath().appendPath(root) if CREATE: modelroot=NodePath('models') num=0 for path in os.listdir(root): folder=os.path.join(root,path) if os.path.isdir(folder): for pic in os.listdir(folder): if pic[-3:].lower()!='jpg': continue print pic if num==130: break tex=loader.loadTexture(os.path.join(path,pic)) cube=loader.loadModel('box') cube.setTexture(tex,1) cube.reparentTo(modelroot) cube.setPos(random.uniform(-10,10),random.uniform(-10,10),random.uniform(-10,10)) num+=1 if num==130: break modelroot.writeBamFile('testmodels.bam') sys.exit() else: models=loader.loadModel('testmodels.bam') models.reparentTo(render) if useOBV: # print models.node().getBounds() models.node().setBounds(OmniBoundingVolume()) models.node().setFinal(1) # print models.node().getBounds() base.graphicsEngine.renderFrame() base.graphicsEngine.renderFrame() models.node().setFinal(0) models.node().clearBounds() # print models.node().getBounds() print '\nusing temporary OmniBoundingVolume\n' else: models.prepareScene(base.win.getGsg()) print '\nusing prepareScene\n' Sequence( models.posInterval(1,Point3(0,50,0)), Func(printTime,time.time()) ).start() # MY RECORDS (note : interval duration is 1 second) : # no prep : 1.64100003242 # with prep : 1.70300006866 # temporary OBV : 1.01600003242 run()
[+] root is the parent of directories containing JPG images
[+] set CREATE to 1 first to build the scenegraph and serialize it
[+] set CREATE to 0 to load the .bam
[+] set useOBV to 0 to use prepareScene, or 1 to use temporary OBV
no prep : 1.11458396912 with prep : 1.00821399689 temporary OBV : 1.00658011436
However, I did need to make one change to achieve this. What prepareScene() actually does is queue up all of the textures to be loaded on the next frame to be rendered. This means if you don’t want to count that time in your statistics, you need to let a frame go by after calling prepareScene():
models.prepareScene(base.win.getGsg()) print '\nusing prepareScene\n' base.graphicsEngine.renderFrame()
Now that I think about it, though, it’s possible that prepareScene() has been broken for a while, until I fixed it recently on CVS. If you still don’t see it working after applying the above fix, try it with the latest from CVS to see if that makes any difference for you.
(I’ve been doing a lot of low-level optimizations lately toward smoothing out asset load times. The CVS version, for instance, also supports texture trickling–rendering the frame without waiting for all of its textures to load.)
By letting 2 frames go by, I got 1.34.
David, is yours on AGP or PCIE ?
Hmm, I’m not actually sure anymore, without lifting the lid and checking. But it shouldn’t matter: either prepareScene() works, and succesfully preloads all of the textures, or it doesn’t work, and some or all of the textures must be loaded during the normal rendering cycle.
Have you tried it with the latest CVS version? Only reason I ask is that I’ve more-or-less completely rewritten the prepareScene() code recently, and while I harbor a few doubts about whether it worked previously, I’m quite certain that it works now.
No, I haven’t tried CVS version, but it’s good to know that it works as expected.