Here’s a blend showing off the module mode as I described above:
test.blend (453 KB)
Arrgh! Why are there single-space indents. That changes things completely. It is python convention to use four spaces per indent - as this makes it actually readable where things are at a glance - that said, copy-pasting into firefox is doing the same for me! So I’m hoping that’s the issue. (I use spaces rather than tabs, so don’t normally have this issue)
Can we please invest in some functions? Things like this are a good start:
import bge
def generate_render_to_texture(obj, camera, material_name):
matID = bge.texture.materialID(obj, "MA" + material_name)
renderToTexture = bge.texture.Texture(obj, matID)
renderToTexture.source = bge.texture.ImageRender(scene, cam)
return renderToTexture
Yes, VideoTexture is also bge.texture
So I just import bge, and then use bge.texture, bge.render, etc. This is both simpler and shorter than GameLogic and VideoTexture
No matter how I see it, the script is running:
shader.setSource(VertexSaber, FragmentSaber % object["saberColor"], 1)
Every frame. Which is probably not a good thing. You do delete the source at the end of each frame, but as I’ve said, recompiling shaders every frame has caused issues for me in the past. It is better to have two objects, one which displays in one mode, one which displays in the other. In my current system. Objects do not have any rendering cost if they’re invisible, so having duplicate objects has (almost) no performance loss if one of them is always invisible.
This also simplifies things: once you’ve set up the system at the game start, all you ever do is toggle visibility - presumably based on a game property.
Some other issues:
for object in [o for o in obj.scene.objects if o.visible]:
‘object’ is a python keyboard already. This is a bit like typing:
print = "Oh no"
And then (possibly) wondering why your code is failing to print, except that ‘object’ is used far less commonly used.
Perhaps a good case study for this is my ObjectsInMirror blend:
https://blenderartists.org/forum/showthread.php?400715-Mirror-help
Pretty much all that needs changing is from ImageMirror to ImageRender and you have a basic renderpass system.
The code for the mirror with some extra comments is (there is also an attached blend in the above link)
import bge
def init(cont):
# Runs on first frame
make_mirror_texture(cont)
# Set the controller to run the update method after it is initilized
cont.script = __name__+'.update'
def update(cont):
# Runs every frame except for the first frame
make_mirror_obj_visible(cont)
update_mirror_texture(cont)
make_mirror_obj_invisible(cont)
def make_mirror_obj_visible(cont):
# Any objects that should be visible in the mirror are made visible here, all other objects are made invisible
for obj in cont.owner.scene.objects:
if 'MirrorOnly' in obj or 'Mirror' in obj:
obj.visible = True
else:
obj.visible = False
def make_mirror_obj_invisible(cont):
# Objects that are only visible in the mirror are made invisible here, and other objects are made visible
# A possible change to make to this is to make it only make visible ones that it made invisible earlier
for obj in cont.owner.scene.objects:
if 'MirrorOnly' in obj:
obj.visible = False
else:
obj.visible = True
def make_mirror_texture(cont):
'''Allocates a texture for the mirror'''
obj = cont.owner
mat_id = bge.texture.materialID(obj, "MA" + cont.owner['material'])
tex = bge.texture.Texture(obj, mat_id, 0) # 0 is the first texture slot
# Set it up as a mirror, assigning the textures source as an ImageMirror
tex.source = bge.texture.ImageMirror(obj.scene, obj.scene.active_camera, obj, mat_id)
# Can restrict mirror resolution with the following line:
# tex.source.capsize = [REFLECTION_MAX_SIZE, REFLECTION_MAX_SIZE]
obj['reflection_tex'] = tex
def update_mirror_texture(cont):
# Refresh the mirror texture
obj = cont.owner
obj['reflection_tex'].refresh(False)
On a possible relevant side-note: what blender version are you using? Some of the 2.7x series have issues with ImageRender and ImageMirror.