Loading...
Logo
Processing Forum
Calling all you openGL gurus..  I'm trying to figure out how to copy the contents of the processing window into a GLTexture.

The reason I want to do this is to work around the issues regarding GLGraphicOffScreen and partially transparent pixels, but now I'm hoping it can be a good experience to learn a little more about openGL too.  I've tried a bunch of different things but have either had no luck, or have run into strange error messages that lead me to dead-end google searching..


Here's my simple sketch which exhibits the problem, but I don't know why it's not working.

Copy code
  1. import codeanticode.glgraphics.*;
  2. import javax.media.opengl.*;
  3. import processing.opengl.*;

  4. GLTexture tex;
  5. PGraphicsOpenGL pgl;

  6. void setup() {
  7.   size(800, 600, OPENGL);

  8.   tex = new GLTexture(this, 512, 512);
  9.   tex.init(512,512);
  10.   
  11.   PGraphicsOpenGL pgl = (PGraphicsOpenGL) g;
  12. }

  13. void draw() {
  14.   background(255);
  15.   fill(0);
  16.   ellipse(mouseX, mouseY, 30, 30);

  17.   GL gl = pgl.beginGL();
  18.   
  19.   gl.glBindTexture(gl.GL_TEXTURE_2D, tex.getTextureID());
  20.   gl.glCopyTexSubImage2D(gl.GL_TEXTURE_2D, 0, 0, 0, 0, 0, 512, 512); 
  21.   
  22.   pgl.endGL();

  23.   // The image appears to be blank (transparent) instead of a copy of the main screen.
  24.   image(tex, 0, 0, 128, 128);
  25. }


So, lines 23 - 28 are the important ones.  I bind the texture, and then copy a 512x512 region into it..  Seems simple but the "tex" instance of GLTexture always seems to be blank (transparent) instead of containing a copy of what was just drawn..

Any help would be greatly appreciated, I've searched all over the forums and internet and am out of ideas..

-Ben

Replies(4)

Try this...

NOTE 1: Given Processing and OPENGL's opposite coordinate systems, I have flipped the texture on the Y.
NOTE 2: Since the texture is part of the drawing, it creates a small feedback loop (press the mouse to see it).

Code Example
Copy code
  1. import codeanticode.glgraphics.*;
  2. import javax.media.opengl.GL;
  3. import processing.opengl.*;
  4.  
  5. GLTexture tex;
  6.  
  7. void setup() {
  8.   size(800, 600, GLConstants.GLGRAPHICS);
  9.   tex = new GLTexture(this, width, height);
  10.   tex.setFlippedY(true);
  11. }
  12.  
  13. void draw() {
  14.   if (!mousePressed) background(255);
  15.   fill(0);
  16.   ellipse(mouseX, mouseY, 30, 30);
  17.  
  18.   GLGraphics renderer = (GLGraphics)g;
  19.   renderer.beginGL();
  20.   GL gl = renderer.gl;
  21.   gl.glBindTexture(gl.GL_TEXTURE_2D, tex.getTextureID());
  22.   gl.glCopyTexSubImage2D(gl.GL_TEXTURE_2D, 0, 0, 0, 0, 0, width, height);
  23.   renderer.endGL();   
  24.  
  25.   fill(255, 0, 0);
  26.   rect(10, 10, width/3+2, height/3+2);
  27.   image(tex, 11, 11, width/3, height/3);
  28. }
Thank you SO much, that's exactly what I needed.  Works perfectly.

So, is this only possible with the GLGraphics library rather than the built-in openGL renderer?  I'd like to understand why it wasn't working with my original code..

thanks again!
-Ben


The GLGraphics library facilitates the easy use of (pure) opengl calls. You could also fully do it yourself.

Your code relies on GLTexture, but you don't use the GLGRAPHICS renderer.

I had the same pb and used a GLGraphicsOffScreen to capture a OCD cam, applied some filters on it then render it using a texture...

I'm not sure this is making the best out of openGL capacities though, the display seems to be much slower than other experiments I've done with 3D and glgraphics. The whole openGL thing is still pretty obscure to me, just started few days back so any suggestions on the code are welcome!! Cheers.

Copy code
  1. import processing.opengl.*;
  2. import codeanticode.glgraphics.*;
  3. import damkjer.ocd.*;
  4. GLTexture dest, src;
  5. GLTextureFilter[] filters;
  6. GLGraphicsOffScreen offscreen;
  7. Camera cam;
  8. int selFilter = 0;
  9. float s = 0;
  10. void setup() {
  11.   size(1000, 800, GLConstants.GLGRAPHICS);
  12.  
  13.   PFont font = loadFont("Tahoma-18.vlw");
  14.   textFont(font, 18);
  15.   dest = new GLTexture(this, width, height);
  16.  
  17.   filters = new GLTextureFilter[7]; 
  18.   filters[0] = new GLTextureFilter(this, "CrossHatch.xml");
  19.   filters[1] = new GLTextureFilter(this, "Thermal.xml");
  20.   filters[2] = new GLTextureFilter(this, "Toon.xml");
  21.   filters[3] = new GLTextureFilter(this, "Dream.xml");
  22.   filters[4] = new GLTextureFilter(this, "CrossStich.xml");
  23.   filters[5] = new GLTextureFilter(this, "FreiChen.xml");
  24.   filters[6] = new GLTextureFilter(this, "Sobel.xml");
  25.  
  26.   textureMode(NORMALIZED);
  27.  
  28.   cam = new Camera(this, 0, 0, 200);
  29.  
  30.   offscreen = new GLGraphicsOffScreen(this, width, height, true, 4); 
  31.   
  32.   frameRate(30);
  33. }
  34. void draw() {
  35.   background(0);
  36.  
  37.   src = offscreen.getTexture();
  38.   offscreen.beginDraw();
  39.     offscreen.background(0);
  40.     offscreen.lights();
  41.     cam.circle(radians(noise(millis()*2)*noise(millis())*50));   
  42.     cam.feed();
  43.     // DRAW STUFF HERE
  44.    
  45.   offscreen.endDraw();
  46.    
  47.   filters[selFilter].apply(src, dest);
  48.    
  49.   beginShape(QUADS);
  50.   texture(src);
  51.   vertex(0, 0, 0, 0);
  52.   vertex(mouseX, 0, float(mouseX)/width, 0);
  53.   vertex(mouseX, height, float(mouseX)/width, 1);
  54.   vertex(0, height, 0, 1); 
  55.   endShape();
  56.  
  57.   beginShape(QUADS);
  58.   texture(dest);
  59.   vertex(mouseX, 0, float(mouseX)/width, 0);
  60.   vertex(width, 0, 1, 0);
  61.   vertex(width, height, 1, 1);
  62.   vertex(mouseX, height, float(mouseX)/width, 1); 
  63.   endShape();
  64.  
  65.   fill(255, 0, 0);  
  66.   stroke(255, 0, 0);
  67.   line(mouseX, 0, mouseX, height);
  68.   text(filters[selFilter].getName(), 0, 20);
  69.  
  70. }
  71. void keyPressed() {
  72.   selFilter = (selFilter + 1) % filters.length;
  73. }