Clear Shader Cache

I am developing some shader code and I don’t want to close the panda window and restart again after I change the shader program.

I call clearShader and also ShaderPool.releaseAllShaders() to unload the shaders after I modify the shader code. But it does not work all the time. What is the proper way to do so ? Thank you.

Hmm, panda should automatically recompile the shader if it has changed.
How are you creating your shaders? Using Shader.load or using Shader.make(shadercontents) ?

I use loader.loadShader.

Try sh = Shader.load(Filename(blah)) then. Or Shader.make if you have the shader stored in a string. I believe this method doesn’t use caching.

I try also Shader.load. The result is the same.

If I get the reference count of the shader before I called clearShader, it is 3. After I called clearShader, it is 2. Somehow it is locked ?

Is it possible a bug on Windows XP platform ?

Advance the frame, call base.graphicsEngine.renderFrame() once or twice after release.

It does not help either.

It does work, unless there are some references of the shader somewhere in your script, eg. if you save it in some attributes.

I re-test several other sample programs and most of them work. Only one complicated one is not working. I will recheck and track it down later. Thank you.

This is my test :

from direct.showbase.DirectObject import DirectObject
from pandac.PandaModules import ShaderPool
import direct.directbase.DirectStart

def changeShader():
    global color
    # If sh is in global namespace, it will hold the shader's reference,
    # so its refcount won't reach 0, and won't be released.
    # Comment this to see the difference.
#     global sh
    color = not color
    code = '''//Cg
void vshader(float4 vtx_position : POSITION,
             uniform float4x4 mat_modelproj,
             out float4 l_position : POSITION)
  { l_position=mul(mat_modelproj, vtx_position); }

void fshader(out float4 o_color:COLOR)
  { o_color=%i; }'''%color
    print '\ncolor : %i'%color
    f=open(shaderName,'w')
    f.write(code)
    f.close()
    sphere.clearShader()
    # release all shaders
    ShaderPool.releaseAllShaders()
    # it seems the release is queued until next frame, so force render now
    base.graphicsEngine.renderFrame()
    # reload & apply
    sh=loader.loadShader(shaderName)
    sphere.setShader(sh)

sphere=loader.loadModel('misc/sphere')
sphere.reparentTo(render)
sphere.setY(5)

shaderName='shader-test.cg'
color=0

DO=DirectObject()
DO.accept('space',changeShader)

changeShader()
run()

Press SPACE to toggle the white or black color.

My problem is in the ocean2 demo inside demomaster that I just posted
discourse.panda3d.org/viewtopic.php?t=5915

If I select Ocean2, and then select IDLE (or switch to another demo), then I edit the share/shaders/ocean2.sha, and then select Ocean2 demo again. The new changes are not applied. I have to quit the whole application and start again for it to work.

This problem does not happen on other parts of the program.