How to change the config var model-path at runtime?

I would like to add, at runtime, a new path to the config variable model-path. What’s the best way to do it? Thanks!

Probably the easiest way is:

getModelPath().appendDirectory('/my/new/directory')

David

Or not use the model path at all. You can always build the full path at runtime from a global variable.

For instance, before I new of the configurable variable, I just got the current running directory and had a global variable that was the running directory + data/models or something like that.

Right, but that’s the hard way. :wink:

David

Which by the way won’t work if you’re running the game from any other directory. getModelPath is the way to go, it should handle paths relative to the main.py correctly, even in the plugin environment.

I can’t get this to work. I’m using a Panda 1.8.0 cvs snapshot from a month ago. Here is a complete test script:

from panda3d.core import *
import sys,os

import direct.directbase.DirectStart

shader_directory = os.path.abspath("../Shadows") # (it failed without the abspath, too)
getModelPath().appendDirectory(shader_directory) # (it also fails if I use shader_directory + '/' here)
    # (it even fails if I replace appendDirectory with prependDirectory.)

# (it also failed when I did this instead, like this or with extra '/' at end of string literal:)
## loadPrcFileData("","model-path %s" % shader_directory)

file1 = file(shader_directory + '/' + 'caster.sha', 'r')
print "file is there and has %d lines" % len(file1.readlines())

Shader.load('caster.sha') # this prints console error message:
    ## :gobj(error): Could not read shader file: caster.sha

(The file caster.sha is present in the indicated place; it’s from the shadow samples that come with Panda.)

The complete console output (except for kCGErrorIllegalArgument lines which always show up on Mac OS X Lion) is:

% ppython testload.py
DirectStart: Starting the game.
Known pipe types:
  osxGraphicsPipe
(all display modules loaded.)
file is there and has 40 lines
:gobj(error): Could not read shader file: caster.sha
% 

Is there anything I’m missing, or any easy way to debug this?

Is there anything for shaders analogous to the bam caching mechanism for egg files, which could be intervening to make an initial error persistent, or hidden on later test runs? (I ask because I once had an egg file that referred to a nonexistent texture file; the error message for this was only printed on the first run of a test program, and again after I modified the egg file. So the caching mechanism was effectively suppressing the error message on most runs of the program (at least that was my guess, I never looked into it closely).)

(Edit: I should add that I know a shader is not a model. There was a shader manual page, and also a forum post by rdb, which seemed to say I should use the model path for shaders too.)

You shouldn’t use Shader.load() to load a shader; that’s a low-level function and it doesn’t search the model-path. Instead, use ShaderPool.loadShader(); this is the function that is intended to be used to load shaders, and this function does search the model-path.

David

Thanks – that may work (at least it gave no error message).

(Someone ought to tell this to the manual page and the sample code :slight_smile: … I’ll add it to my growing list of candidates for my first fix to a manual page.)

If I needed to specify the shader language, or give multiple shader files, could I do it the same way as for Shader.load? The api reference doesn’t list any other argument signature than a single filename.

I believe ShaderPool.load() is meant for the usual case of a single combined shader file; it can infer the language from the filename extension. If you have a nonstandard extension, or you need to load multiple shader files, and you need to fall back to the lower-level Shader.load(), then you will also be responsible for looking up the shader filename on the model-path if necessary. You can do this, for instance, with code like this:

filename = getModelPath().findFile('shader.cg')

David