Quantcast
Channel: Processing Forum
Viewing all articles
Browse latest Browse all 1768

Re : Processing 2 and OpenGL Frame Buffer Objects (FBO)

$
0
0
Thanks for your input.  I really appreciate the detailed response.

The beginPGL makes sense now, as does popping of the viewport.  I was thinking of beginPGL as more of a constructor rather than an OpenGL call.  I've also added to my code some endPGL calls since I see beginPGL followed by endPGL in the internal code, and also logically this makes sense to me.

The best I can tell from some tests the processing internal FBO is no longer interfering with your FBO code, since I am able to get things to work without using the pushFramebuffer and popFramebuffer.  What is confusing me is that I am unable to get my own changes to affect the FBO, but calls to native processing routines such as background do affect the FBO.  When I don't use the background() routine the FBO comes out uninitialized.

The code can be found here.  Pastebin is numbered so it's just easier to talk about.

The idea is that I create an FBO in setup(), make it green, and then use it in draw() when a boolean is toggled.  A key press will toggle the boolean, and the background should alter between black (no FBO) and green (FBO).

What is killing me is that line 45 correctly changes the FBO to green, but lines 48-55 do not, even though 48-55 is a copy of the code for background()....  I even tried some Z translations to see if there was some depth test I was missing.

If anyone has any insight, I'd appreciate it.  The full code is below just so the link is never lost.

  1. import processing.core.*;
  2. import processing.opengl.*;
  3. import javax.media.opengl.GL;
  4. import javax.media.opengl.GL2;

  5. public class FBOTest extends PApplet {

  6. GL gl;

  7. int myFBO;
  8. int fboTexture;
  9. boolean drawFBO = true;

  10. public void setup() {
  11.  frameRate(30);
  12.  size(800, 600, P3D);
  13.  background(0, 0, 0);
  14.  colorMode(RGB, 100);
  15.  
  16.  // Start the opengl context so we can do some initialisation
  17.  PGL pgl = g.beginPGL();
  18.  gl = pgl.gl.getGL().getGL2();
  19.  
  20.  // Check what version of OpenGL we're using
  21.  println("This system uses OpenGL:"
  22.      + pgl.gl.getGL().glGetString(GL.GL_VERSION));
  23.  
  24.  int[] fboAndTex = new int[2];
  25.  
  26.  // create a FBO ten times smaller than the sketch
  27.  try {
  28.    fboAndTex = initializeFBO(gl, width, height);
  29.  } catch (Exception e) {
  30.    exit();
  31.  }
  32.  
  33.  myFBO = fboAndTex[0];
  34.  fboTexture = fboAndTex[1];
  35.  println("FBO created, ID: " + myFBO + ", with texture ID: " + fboTexture);

  36.  gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, myFBO); // Bind our frame buffer
  37.  
  38.  
  39.  // THIS WORKS
  40.  //background(0, 100, 0, 100);
  41.  
  42.  // THIS DOES NOT WORK
  43.  pushStyle();
  44.  pushMatrix();
  45.  resetMatrix();
  46.  //translate(0, 0, 5); // just a double check for depth test
  47.  fill(0, 100, 0, 100);
  48.  rect(0, 0, width, height);
  49.  popMatrix();
  50.  popStyle();
  51.  
  52.  /*
  53.  // TODO why won't this work??
  54.  fill(50, 50, 50);
  55.  rect(0, 0, width, height);
  56.  
  57.  fill(0, 0, 100);
  58.  textSize(32);
  59.  text("word", 50, 50, 0); 
  60.  */
  61.  gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, 0); // Bind draw buffer
  62.  
  63.  g.endPGL();
  64. }

  65. boolean checkBufferCompletness(GL gl) {
  66.  int fBStatus = gl.glCheckFramebufferStatus(GL.GL_FRAMEBUFFER);
  67.  if (fBStatus != GL.GL_FRAMEBUFFER_COMPLETE) {
  68.    switch (fBStatus) {
  69.    case GL.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
  70.      println("Not all framebuffer attachment points are framebuffer attachment complete.");
  71.      break;
  72.    case GL.GL_FRAMEBUFFER_UNSUPPORTED:
  73.      println("The combination of internal formats of the attached images violates an implementation-dependent set of restrictions.");
  74.      break;
  75.    case GL.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
  76.      println("No images are attached to the framebuffer.");
  77.      break;
  78.    default:
  79.      println("Framebuffer not ready for another reason.");
  80.    }
  81.    return false;
  82.  }
  83.  return true;
  84. }

  85. /*
  86. * Creates a Frame Buffer Object (FBO) take can be used to render color and
  87. * depth offscreen. There is a texture attached to the FBO which can be used
  88. * like a regular texture (texturing a quad for instance). gl : the OpenGL
  89. * context w : the width of the FBO h: the height Returns the ids of the FBO
  90. * and the associated texture in an array in that order. Throws an exception
  91. * if the FBO could not be created
  92. */
  93. int[] initializeFBO(GL gl, int w, int h) throws Exception {
  94.  // let's first create a texture to attach to the FBO
  95.  int[] array = new int[1];
  96.  gl.glGenTextures(1, array, 0); // ask OpenGL for a texture id
  97.  int tex = array[0];

  98.  // tell OpenGL we're going to work on this new texture
  99.  gl.glEnable(GL.GL_TEXTURE_2D);
  100.  gl.glBindTexture(GL.GL_TEXTURE_2D, tex);

  101.  // Setup some properties, mipmap etc...
  102.  
  103.  gl.glTexParameteri(GL.GL_TEXTURE_2D, 
  104.             GL.GL_TEXTURE_MIN_FILTER,
  105.             GL.GL_NEAREST);
  106.  
  107.  gl.glTexParameteri(GL.GL_TEXTURE_2D, 
  108.               GL.GL_TEXTURE_MAG_FILTER,
  109.               GL.GL_NEAREST);
  110.  
  111.  gl.glTexParameteri(GL.GL_TEXTURE_2D, 
  112.             GL.GL_TEXTURE_WRAP_S,
  113.             GL.GL_CLAMP_TO_EDGE);
  114.  
  115.  gl.glTexParameteri(GL.GL_TEXTURE_2D, 
  116.             GL.GL_TEXTURE_WRAP_T,
  117.             GL.GL_CLAMP_TO_EDGE);
  118.  
  119.  // set what the format of the pixels we're using
  120.  gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, 
  121.            GL.GL_RGBA, w, h, 0, 
  122.            GL.GL_RGBA,
  123.            GL.GL_UNSIGNED_BYTE, null);

  124.  // Done with the texture
  125.  gl.glBindTexture(GL.GL_TEXTURE_2D, 0);

  126.  // Create a Frame Buffer Object
  127.  gl.glGenFramebuffers(1, array, 0); // Ask OpenGL for a framebuffer id
  128.  int fbo = array[0];
  129.  // Tells OpenGL we're going to work on the fbo
  130.  gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, fbo);

  131.  // attach the texture to the FBO
  132.  gl.glFramebufferTexture2D(GL.GL_FRAMEBUFFER, 
  133.                GL.GL_COLOR_ATTACHMENT0,
  134.                GL.GL_TEXTURE_2D, tex, 0);
  135.  // then create a render buffer
  136.  gl.glGenRenderbuffers(1, array, 0); // Ask OpenGL for a renderbuffer id
  137.  int rb = array[0];
  138.  // attach the render buffer to the FBO
  139.  gl.glBindRenderbuffer(GL.GL_RENDERBUFFER, rb);

  140.  // this tells OpenGL that the render buffer is used for depth data and
  141.  // that we need a buffer of dimension w by h
  142.  gl.glRenderbufferStorage(GL.GL_RENDERBUFFER, 
  143.               GL2.GL_DEPTH_COMPONENT24,
  144.               w, h);
  145.  // attach it to the frame buffer
  146.  gl.glFramebufferRenderbuffer(GL2.GL_DRAW_FRAMEBUFFER,
  147.                 GL.GL_DEPTH_ATTACHMENT, 
  148.                 GL.GL_RENDERBUFFER, rb);
  149.  // done working on the render buffer
  150.  gl.glBindRenderbuffer(GL.GL_RENDERBUFFER, 0);

  151.  // At this point everything is set and all that remains to do is to
  152.  // check for completness of the FBO
  153.  if (!checkBufferCompletness(gl)) {
  154.    throw new Exception("Could not create the FBO.");
  155.  }

  156.  // done working on the frame buffer
  157.  gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, 0);

  158.  return new int[] { fbo, tex };

  159. }

  160. public void draw() {

  161.  // Start the opengl context so we can do some initialisation
  162.  PGL pgl = g.beginPGL();
  163.  gl = pgl.gl.getGL().getGL2();
  164.  
  165.  background(0);
  166.  
  167.  if(drawFBO) {
  168.    ((PGraphicsOpenGL) g).drawTexture(GL.GL_TEXTURE_2D, fboTexture,
  169.                            width, height, 0, 0, width, height);
  170.  }
  171.  
  172.  fill(100, 0, 0);
  173.  rect(0, 0, 50, 50);
  174.  
  175.  g.endPGL();
  176. }

  177. public void keyPressed() {
  178.  drawFBO = !drawFBO;
  179.  println("FBO is " + drawFBO);
  180. }

  181. }


Viewing all articles
Browse latest Browse all 1768

Trending Articles