0

Basic usage of the image library and gltexture

Hey!

I'd like to be able to load an arbitrary image from disk and overlay it on the currently playing media using python.  I'm assuming the actual calls will use gltexture through rv.runtime.eval, but I'd like to see an example of how to get something from disk into an image object.

Thanks so much!
Scott 

4 comments

  • 0
    Avatar
    Scott Clifford

    Well.. I seemed to figure this out on my own... albeit through a truly ugly solution. I found the bug.mu plugin for rvio that used the gltexture call and ported that over into my plugin. The problem came when I tried to use the calls in the glTexture.mu via runtime.eval from python... it would always dump core when passing in ["gltexture"] for the modules. So I ended up including the actual code from gltexture.mu in the runtime.eval call of my plugin.

    So I do this one for each source to setup the textures and save the texture id:
    https://pastee.org/xx9b2

    Then this goes in the render loop to redraw the texture:
    https://pastee.org/hebuf

    Let me know if you can add any elegance to this :)

    Thanks,
    Scott

  • 0
    Avatar
    MIke Kelleher

    Bummer, looks like your files are gone on pastee. Could you re-up?

  • 0
    Avatar
    Scott Clifford

    So I do this one for each source to setup the textures and save the texture id:


    if imgPath:
    imgCode = """
    {
    global int texid;
    global int logoSize;
    global int aspect;

    let logo = image.image("%s"),
    filename = logo.name;

    aspect = float(logo.width) / float(logo.height);
    logoSize = logo.width;

    let msize = math.max(float(logoSize), float(logoSize) * aspect),
    n = int(math.log(msize)/math.log(2));

    if (logo.width != logo.height ||
    math.pow(2, n) != logo.width ||
    aspect != 1.0)
    {
    let x = math.log(float(msize)) / math.log(2),
    d = x - n,
    p = int(if d > 0.0 then math.pow(2, n+1) else math.pow(2, n));

    logo = image.resize(logo, p, p);
    }

    for (int y = 0; y < logo.height; y++)
    {
    for (int x = 0; x < logo.width; x++)
    {
    let index = y * logo.height + x,
    p = logo.data[index];
    logo.data[index] = rvtypes.Color(p.x / p.w, p.y / p.w, p.z / p.w, p.w);

    }
    }

    texid = gl.glGenTextures(1)[0];
    gl.glEnable(gl.GL_TEXTURE_2D);
    gl.glBindTexture(gl.GL_TEXTURE_2D, texid);

    gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR);
    gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR);
    gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, gl.GL_CLAMP_TO_EDGE);
    gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, gl.GL_CLAMP_TO_EDGE);

    glu.gluBuild2DMipmaps(gl.GL_TEXTURE_2D,
    gl.GL_RGBA,
    logo.width, logo.height,
    gl.GL_RGBA,
    logo.data);

    texid;
    }
    """ % imgPath

    self.shotDict[shotName]["texid"] = rv.runtime.eval(imgCode, ["gl", "glu"])

     

    Then this goes in the render loop to redraw the texture:

    if self.shotDict[shotName].get("texid"):
    imgCode = """
    {
    let texid = %s;

    let x = %f, y = %f,
    w = 100*.75, h = 100,
    flip = true, flop = false,
    opacity = 1;

    gl.glColor(0, 0, 0, .6);
    gl.glBegin(gl.GL_QUADS);
    gl.glVertex(x-5+2, y-5-4, 0);
    gl.glVertex(x-5+2, y + h+5-4, 0);
    gl.glVertex(x+5+2 + w, y+5-4 + h, 0);
    gl.glVertex(x+5+2 + w, y-5-4, 0);
    gl.glEnd();

    gl.glColor(.5, .15, 0, 1);
    gl.glBegin(gl.GL_QUADS);
    gl.glVertex(x-5, y-5, 0);
    gl.glVertex(x-5, y + h+5, 0);
    gl.glVertex(x+5 + w, y+5 + h, 0);
    gl.glVertex(x+5 + w, y-5, 0);
    gl.glEnd();

    gl.glEnable(gl.GL_TEXTURE_2D);
    gl.glBindTexture(gl.GL_TEXTURE_2D, texid);

    gl.glEnable(gl.GL_BLEND);
    gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA);

    gl.glColor(1, 1, 1, opacity);
    gl.glBegin(gl.GL_QUADS);
    gl.glTexCoord(if flop then 1.0 else 0.0, if flip then 1.0 else 0.0);
    gl.glVertex(x, y, 0);
    gl.glTexCoord(if flop then 1.0 else 0.0, if flip then 0.0 else 1.0);
    gl.glVertex(x, y + h, 0);
    gl.glTexCoord(if flop then 0.0 else 1.0, if flip then 0.0 else 1.0);
    gl.glVertex(x + w, y + h, 0);
    gl.glTexCoord(if flop then 0.0 else 1.0, if flip then 1.0 else 0.0);
    gl.glVertex(x + w, y, 0);
    gl.glEnd();


    }
    """ % (self.shotDict[shotName]["texid"], float(x+20), float(y+20))

    rv.runtime.eval(imgCode, [])

  • 0
    Avatar
    Spencer Tweed

    Hey Scott, this is a few years later. Did you ever find a more elegant solution for this? I've been in touch with SG support and they told me I need to create a GLSL node, but if you already did it then that saves me learning GLSL!

    I was hoping for a python solution and though I was able to get PySide going thanks to the PySide example in the docs. But I cannot figure out how to overlay a widget on the player, which seems to be it's own world.

    - Spencer

Please sign in to leave a comment.