trying to use video texture -> no error but material turns black




    if 'Init' not in own:
        meshOb = bge.logic.getCurrentScene().objects['Plane']
        
        
        obj = meshOb




        background = Image.open(logic.expandPath("//cIRLIC2.png"))
        foreground = Image.open(logic.expandPath("//00SpriteSheet.png"))


        background.paste(foreground, (0, 0), foreground)
        
        #get the reference pointer (ID) of the internal texture
        ID = 0
        
        # create a texture object
        object_texture = texture.Texture(obj, ID)
        
        # create a new source with an external image
        url = logic.expandPath("//cIRLIC2.png")
        new_source = texture.ImageBuff(url)
        print(new_source)


        # the texture has to be stored in a permanent Python object
        logic.texture = object_texture


        #update/replace the texture
        logic.texture.source = new_source
        logic.texture.refresh(False)




        
        
        own['Init']=True
        
        mesh = meshOb.meshes[0]
        VL =[]
        PL =[]
        for m_index in range(len(mesh.materials)):
            for v_index in range(mesh.getVertexArrayLength(m_index)):
                vertex = mesh.getVertex(m_index, v_index)
                xYz = meshOb.worldPosition+(meshOb.worldOrientation.inverted()*vertex.XYZ)
                
                VL.append((xYz[0],xYz[1],xYz[2]) )
                
                
            for f_index in range(mesh.numPolygons):
                poly = mesh.getPolygon(f_index)
                L=[]
                v0 = poly.getVertexIndex(0)
                L.append(v0)
                v1 = poly.getVertexIndex(1)
                L.append(v1)
                v2 = poly.getVertexIndex(2)
                L.append(v2)
                if poly.v4:
                    v3=poly.getVertexIndex(3)
                    L.append(v3)
                PL.append(L)
                    
        #print(VL)
        #print(PL)       
        own['Mesh']=mesh        
        B =mathutils.bvhtree.BVHTree.FromPolygons(VL, PL, all_triangles=False, epsilon=0.0)
        

        own['BVH']=B

2 = how would I use the image I generated using PIL as the buffer image?

You skip important information:

A) what does the console say? (You added a print but never show the outcome)
B) what is Image? You need to provide your imports even on snippets

Create texture source
The API says:

class bge.texture.ImageBuff(width, height, color=0, scale=False)
Image source from image buffer.

Parameters:
width (int) – Width of the image.
height (int) – Height of the image.
color (int in [0, 255]) – Value to initialize RGB channels with. The initialized buffer will have all pixels set to (color, color, color, 255). (optional)
scale (bool) – Image uses scaling. (optional)

Somehow they forgot to tell that all parameters are optional and not type checked.

Therefore your code:

texture.ImageBuff(url)

is equal to

texture.ImageBuff()

And creates a black buffer with zero content.

–> results in a black texture

You can initialize the ImageBuf e.g. with a gray color:


source = texture.ImageBuff(1, 1, 150)

Now you know how you can generate a gray texture.

With the grey initial texture you know the source was successfully created and displayed.
Now the interesting part.

Create a custom buffer
You create a buffer with pixel information. You can use an array. The size equals: widthheightcolor-size (=3)
The color-size can vary dependent on the applied filter.
Example:


def generateColorRampPattern(width, height):
    buffer = array.array('B')
    for x in range(width):
        for y in range(height):
            red = int(256*x/width))
            green = int(256*y/height))
            buffer.append(red)
            buffer.append(green)
            buffer.append(0)
    return buffer

You load this buffer into the above imageBuff overriding whatever you initialized before.


def loadBuffer(source):
    width = 10
    height = 10
    buffer = generateColorRampPattern(width, height)
    source.load(buffer, width, height)

This allows you to generate your very own colorful texture.

Buffer from image file

I can’t tell much about this. I recommend to look at attribute bge.texture.ImageFFmpeg.image.

Isn’t that what you want?

You get your image as buffer -> you can manipulate the buffer -> you can apply the buffer to the texture source.

There might be another way to directly load an image file into a buffer. I can’t tell right now.

Storing textures

You followed the example provided by the API Documentation.

I do not think that module logic is a good place to store a texture.

  • You restrict yourself to a single texture
  • You save it scene independent
  • Great danger to override the texture with another one

This will not be a big deal on static texture as you do not even need to store them. Videofiles and Camera needs constant updates.

I suggest you either create a sufficient container (list, dict), or store it somewhere else. A good place is one of the game objects that use this texture.


  owner["texture"] = object_texture

This way the logic and the storage are close to each other. It enables you to use exactly the same code with different objects and different materials. A little customization (e.g. filenames) can be done via external properties while you keep the texture in an internal property.

I am creating a new texture using


background = Image.open(logic.expandPath("//cIRLIC2.png"))
foreground = Image.open(logic.expandPath("//00SpriteSheet.png"))
background.paste(foreground, (0, 0), foreground)

that I would like to pass to the texture, but I don’t really know exactly how to do this.

and your right, imageBuff was creating the black screen as I wanted -
ImageFFmpeg worked like a charm,

but now I would like to use “background” instead?

(I am making a texture painting app in preparation to make a material painting app)

edit: I think I need to use the current background each frame vs the brush, but I need to know how to pass the edit texture without exporting it to a file, (or should I just dump it as a png each frame?)

ok so now It’s saying my image is not the size of the buffer, but it’s not loading the image in the first place correctly

here are the files I load, and the code, be aware this will only work in 2.77 as bvhtree cause a crash in 2.76b - (I guess you could comment those parts out if you don’t have 2.77?)

import bgeimport mathutils 
#from PIL import Image
from bge import texture
from bge import logic




def main():


    cont = bge.logic.getCurrentController()
    own = cont.owner


    MOA = cont.sensors['MouseOverAny']
    Left = cont.sensors['Mouse']
    MOA2 = cont.sensors['MouseOverColor']
    MOA3 = cont.sensors['MOA3']
    
    
    
    
    
    
    if 'Init' not in own:
        meshOb = bge.logic.getCurrentScene().objects['Plane']
        
        
        obj = meshOb




        #background = Image.open(logic.expandPath("//cIRLIC2.png"))
        #foreground = Image.open(logic.expandPath("//00SpriteSheet.png"))


        #background.paste(foreground, (0, 0), foreground)
        
        #get the reference pointer (ID) of the internal texture
        ID = 0
        
        # create a texture object
        object_texture = texture.Texture(obj, ID)
        
        # create a new source with an external image
       
#####################################################
        url = logic.expandPath("//cIRLIC2.png")
        url2 = logic.expandPath("//SpriteSheet.png")
        print(url)
        img = bge.texture.ImageFFmpeg(url)
        print(img.valid)
        print(img.size)
        img2 = bge.texture.ImageFFmpeg(url2)
        
        tex = bge.texture.ImageBuff(512,512,1,False).load(img.image, 512, 512)
        
        print(new_source)


        # the texture has to be stored in a permanent Python object
        logic.texture = object_texture


        #update/replace the texture
        logic.texture.source = new_source
        logic.texture.refresh(False)




#######################################################        
        
        own['Init']=True
        
        mesh = meshOb.meshes[0]
        VL =[]
        PL =[]
        for m_index in range(len(mesh.materials)):
            for v_index in range(mesh.getVertexArrayLength(m_index)):
                vertex = mesh.getVertex(m_index, v_index)
                xYz = meshOb.worldPosition+(meshOb.worldOrientation.inverted()*vertex.XYZ)
                
                VL.append((xYz[0],xYz[1],xYz[2]) )
                
                
            for f_index in range(mesh.numPolygons):
                poly = mesh.getPolygon(f_index)
                L=[]
                v0 = poly.getVertexIndex(0)
                L.append(v0)
                v1 = poly.getVertexIndex(1)
                L.append(v1)
                v2 = poly.getVertexIndex(2)
                L.append(v2)
                if poly.v4:
                    v3=poly.getVertexIndex(3)
                    L.append(v3)
                PL.append(L)
                    
        #print(VL)
        #print(PL)       
        own['Mesh']=mesh        
        B =mathutils.bvhtree.BVHTree.FromPolygons(VL, PL, all_triangles=False, epsilon=0.0)
        
        own['BVH']=B
    if MOA3.positive and Left.positive:
        
        v2 = MOA3.hitPosition-own.worldPosition
        #d = own.getDistanceTo(MOA3.hitPosition)
       # v2 = own.worldPosition+(v2*(d+1))
       
        ray =  own['BVH'].ray_cast(own.worldPosition, v2,100)
        #bge.render.drawLine(own.worldPosition+((v2)*10),own.worldPosition,(1,0,0))
       
        if ray[0]:
            poly = own['Mesh'].getPolygon(ray[2])
            
            VXZ1 =  own['Mesh'].getVertex(0,poly.getVertexIndex(0))
            
            
            VXZ1.r = own['R']
            VXZ1.g = own['G']
            VXZ1.b = own['B']
            VXZ1.a = own['A']
            
            VXZ2 =  own['Mesh'].getVertex(0,poly.getVertexIndex(1))
            VXZ2.r = own['R']
            VXZ2.g = own['G']
            VXZ2.b = own['B']
            VXZ2.a = own['A']
            
            
            VXZ3 = own['Mesh'].getVertex(0,poly.getVertexIndex(2))
            VXZ3.r = own['R']
            VXZ3.g = own['G']
            VXZ3.b = own['B']
            VXZ3.a = own['A']
            
            VXZ4 =  own['Mesh'].getVertex(0,poly.getVertexIndex(3))
            VXZ4.r = own['R']
            VXZ4.g = own['G']
            VXZ4.b = own['B']
            VXZ4.a = own['A']
            #@print(ray[2])
            
            
    if MOA.positive:
        added=bge.logic.getCurrentScene().addObject('HL',own,1)
        added.worldPosition=MOA.hitObject.worldPosition
        added.worldPosition.z+=.01    
    if MOA.positive and Left.positive:
        MOA.hitObject.color = [ own['R'], own['G'], own['B'],own['A']]
                
        
    if MOA2.positive and Left.positive:
        own['R']=MOA2.hitObject.color[0]
        own['G']=MOA2.hitObject.color[1]
        own['B']=MOA2.hitObject.color[2]
        own['A']=MOA2.hitObject.color[3]
         
                


main()



the relevant code is surrounded by #######

Attachments

BPRBrushZero.blend (2.2 MB)