Bug 536 : Errors when using Framebuffer Objects for off screen rendering
Last modified: 2007-03-15 19:24




Status:
RESOLVED
Resolution:
INVALID -
Priority:
P2
Severity:
normal

 

Reporter:
Rod Harris
Assigned To:
fry

Attachment Type Created Size Actions

Description:   Opened: 2007-03-15 17:35
My aim is to use FBOs as a quick render-to-texture method.

How I do it is generate the FBO id and texture id in the setup method (no
errors reported and the ids are both valid). Then in the draw method I use
the opengl call glBindFramebufferEXT( GL.GL_FRAMEBUFFER_EXT, fbo_id );
Which doesn't throw any exception there, but when I actually try to draw
anything I get
GL_ERROR at render_triangles in: 0506 UNKNOWN
GL_ERROR at render_triangles out: 0506 UNKNOWN
GL_ERROR at render_lines out: 0506 UNKNOWN
printed to the console, and no rendering is done.

I know my graphics card is capable of using this extension, as are the jogl
libraries I'm using as I've tested this outside processing and it works fine.

I'm using 0116 (built from source)
My OS is Fedora Core 5
Im using a P4 with an Nvidia 6800

Thanks in advance and heres the code:

import processing.opengl.*;

import javax.media.opengl.GL;
import javax.media.opengl.glu.GLU;
import com.sun.opengl.util.GLUT;

float a;

int col;

FBOTexture2 fbo_texture;

GL gl;

GLU glu;

GLUT glut;


void setup()
{
size( 600, 600, OPENGL );

gl = ( (PGraphicsGL) g ).gl;

glu = ( (PGraphicsGL) g ).glu;

glut = new GLUT();

fbo_texture = new FBOTexture2( GL.GL_RGBA, 512, 512 );

println( "texture id = " + fbo_texture.tex_id );

println( "frame_buffer id = " + fbo_texture.fbo_id );

col = color( 255, 100, 100 );

framerate( 30 );
}


void draw()
{
update_scene();

render_to_texture();

draw_scene();

render_to_screen();

fbo_texture.apply();

draw_2d();

fbo_texture.unapply();
}


void render_to_texture()
{
fbo_texture.bind();
}


void render_to_screen()
{
fbo_texture.unbind();

gl.glViewport( 0, 0, width, height );
}


/**
this just draws the texture directly over the screen
*/
void draw_2d()
{
ortho( 0, width, 0, height, 0, 1 );

background( 0, 0, 0 );

fill(col );

beginShape( QUADS );

vertex( 0, 0 );

vertex( width, 0 );

vertex( width, height );

vertex( 0, height );

endShape();
}


void update_scene()
{
a += 0.04;

if( a >= TWO_PI * 2 )
{
a = 0.0;
}
}


void draw_scene()
{
background( 0, 0, 255 );

perspective( radians( 45 ), float(width)/float(height), 0.05f, 1000.0f );

pushMatrix();

camera( 0, 0, 5, 0, 0, 0, 0, 1, 0 );

fill( col );

rotateY( a );

rotateX( a / 2 );

box( 1 );

popMatrix();
}



class FBOTexture2
{
public final int tex_id;

public final int fbo_id;

public final int format;

public final int width;

public final int height;


public int wrap_s = GL.GL_REPEAT;

public int wrap_t = GL.GL_REPEAT;

public int mag_filter = GL.GL_NEAREST;

public int min_filter = GL.GL_NEAREST;

public int mode = GL.GL_REPLACE;


/**
creates a frame buffer object that is bound to a texture of the specified
size and format
width and height should be power of 2 for performance reasons
@param format either GL_RGB or GL_RGBA
*/
public FBOTexture2( int format, int width, int height )
{
this.format = format;

this.width = width;

this.height = height;

int[] ids = { 0 };


gl.glGenTextures( 1, ids, 0 );

tex_id = ids[ 0 ];

gl.glPixelStorei( GL.GL_UNPACK_ALIGNMENT, 1 );

gl.glBindTexture( GL.GL_TEXTURE_2D, tex_id );

gl.glTexImage2D( GL.GL_TEXTURE_2D, 0, format, width, height, 0, format,
GL.GL_UNSIGNED_BYTE, null );


gl.glGenFramebuffersEXT( 1, ids, 0 );

fbo_id = ids[ 0 ];

gl.glBindFramebufferEXT( GL.GL_FRAMEBUFFER_EXT, fbo_id );

gl.glFramebufferTexture2DEXT( GL.GL_FRAMEBUFFER_EXT,
GL.GL_COLOR_ATTACHMENT0_EXT, GL.GL_TEXTURE_2D, tex_id, 0 );

gl.glBindFramebufferEXT( GL.GL_FRAMEBUFFER_EXT, 0 );
}


/**
all rendering operations are now bound to the FrameBuffer
*/
public void bind()
{
gl.glBindFramebufferEXT( GL.GL_FRAMEBUFFER_EXT, fbo_id );

gl.glViewport( 0, 0, width, height );
}


/**
all rendering operations are now returned to the prevois buffer (probably
GL_BACK)
*/
public void unbind()
{
gl.glBindFramebufferEXT( GL.GL_FRAMEBUFFER_EXT, 0 );
}


/**
applys the texture to GL_TEXTURE_2D operations
*/
public void apply()
{
gl.glBindTexture( GL.GL_TEXTURE_2D, tex_id );

gl.glTexParameteri( GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, wrap_s );
gl.glTexParameteri( GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, wrap_t );
gl.glTexParameteri( GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, mag_filter );
gl.glTexParameteri( GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, min_filter );

gl.glTexEnvf( GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, mode );

gl.glEnable( GL.GL_TEXTURE_2D );
}


/**
disables the texture
*/
public void unapply()
{
gl.glBindTexture( GL.GL_TEXTURE_2D, 0 );
}
}
Additional Comment #1 From fry 2007-03-15 18:24
please read the "using the opengl renderer" section of the opengl reference:
http://processing.org/reference/libraries/opengl/index.html