FBO and MRT round 2

Started by pobrien, April 12, 2010, 03:23:10

Previous topic - Next topic

pobrien

I've decided to try and stick with the ARB extensions way of doing fbos, since I have it working and can't for the life of me figure out OpenGL 3. I am having problems with MRTs though. I just get a black screen, and can't figure out where I'm messing up at. Below is the two important functions, does anything jump out (the read flag is used to switch between framebuffers to do a ping pong technique (the output of one pass is the input to the next pass)?
  
declared members of the class:
private static int myFBOId;
  
  private static IntBuffer fbotexID1, fbotexID2, fbotexID3, fbotexID4;
  private static int[] fboTextures1 = new int[2];
  private static int[] fboTextures2 = new int[2];
  
  private static int read;
  
  private static int winWidth = 800;
  
  private static int winHeight = 600;
 
  private static DisplayMode chosenMode = null;
  
  private static int shaderProgram;
  
  private static int[] attach1 = {EXTFramebufferObject.GL_COLOR_ATTACHMENT0_EXT, EXTFramebufferObject.GL_COLOR_ATTACHMENT1_EXT};
  private static int[] attach2 = {EXTFramebufferObject.GL_COLOR_ATTACHMENT2_EXT, EXTFramebufferObject.GL_COLOR_ATTACHMENT3_EXT};
  private static IntBuffer currentReadAttach;



private static void init(boolean fullscreen) throws Exception {
 
	read = 1;  
	  
	DisplayMode[] modes = Display.getAvailableDisplayModes();
	  
	for (int i=0;i<modes.length;i++) {
	   if ((modes[i].getWidth() == winWidth) && (modes[i].getHeight() == winHeight)) {
	               chosenMode = modes[i];
	               break;
	   }
	}
	
	
	currentReadAttach = BufferUtils.createIntBuffer(8);
	
	
	// Create a fullscreen window with 1:1 orthographic 2D projection (default)
    Display.setTitle(GAME_TITLE);
    Display.setFullscreen(false);
    Display.setDisplayMode(chosenMode);
 
    // Enable vsync if we can (due to how OpenGL works, it cannot be guarenteed to always work)
    Display.setVSyncEnabled(true);
    // Create default display of 640x480
    Display.create();
	
    float[] texColor = new float[Display.getDisplayMode().getWidth() * Display.getDisplayMode().getHeight() * 4];
    float[] texColor2 = new float[Display.getDisplayMode().getWidth() * Display.getDisplayMode().getHeight() * 4];
    
    for (int i=0; i < texColor.length; i+=4) {
    	texColor[i] = (float) 1.0;
    	texColor[i+1] = (float) 0.0;
    	texColor[i+2] = (float) 0.0;
    	texColor[i+3] = (float) 1.0;
    }
    
    FloatBuffer scratch = BufferUtils.createFloatBuffer(Display.getDisplayMode().getWidth() * Display.getDisplayMode().getHeight() * 4);
    FloatBuffer scratch2 = BufferUtils.createFloatBuffer(Display.getDisplayMode().getWidth() * Display.getDisplayMode().getHeight() * 4);
    FloatBuffer scratch3 = BufferUtils.createFloatBuffer(Display.getDisplayMode().getWidth() * Display.getDisplayMode().getHeight() * 4);
    FloatBuffer scratch4 = BufferUtils.createFloatBuffer(Display.getDisplayMode().getWidth() * Display.getDisplayMode().getHeight() * 4);
    scratch2.put(texColor);
	scratch2.rewind();
	scratch4.put(texColor);
	scratch4.rewind();
	

	fbotexID1 = GenTexture(scratch);
	fbotexID2 = GenTexture(scratch2);
	fbotexID3 = GenTexture(scratch3);
	fbotexID4 = GenTexture(scratch4);

    fboTextures1[0] = fbotexID1.get(0);
    fboTextures1[1] = fbotexID2.get(0);
    fboTextures2[0] = fbotexID3.get(0);
    fboTextures2[1] = fbotexID4.get(0);
    
  
    boolean FBOEnabled = GLContext.getCapabilities().GL_EXT_framebuffer_object;
	
	IntBuffer buffer = ByteBuffer.allocateDirect(1*4).order(ByteOrder.nativeOrder()).asIntBuffer(); // allocate a 1 int byte buffer
	EXTFramebufferObject.glGenFramebuffersEXT( buffer ); // generate 
	myFBOId = buffer.get();
	
	EXTFramebufferObject.glBindFramebufferEXT( EXTFramebufferObject.GL_FRAMEBUFFER_EXT, myFBOId );
	EXTFramebufferObject.glFramebufferTexture2DEXT( EXTFramebufferObject.GL_FRAMEBUFFER_EXT, EXTFramebufferObject.GL_COLOR_ATTACHMENT0_EXT,
	        ARBTextureRectangle.GL_TEXTURE_RECTANGLE_ARB, fbotexID1.get(0), 0);
	EXTFramebufferObject.glFramebufferTexture2DEXT( EXTFramebufferObject.GL_FRAMEBUFFER_EXT, EXTFramebufferObject.GL_COLOR_ATTACHMENT1_EXT,
            ARBTextureRectangle.GL_TEXTURE_RECTANGLE_ARB, fbotexID2.get(0), 0);
	EXTFramebufferObject.glFramebufferTexture2DEXT( EXTFramebufferObject.GL_FRAMEBUFFER_EXT, EXTFramebufferObject.GL_COLOR_ATTACHMENT3_EXT,
            ARBTextureRectangle.GL_TEXTURE_RECTANGLE_ARB, fbotexID3.get(0), 0);
	EXTFramebufferObject.glFramebufferTexture2DEXT( EXTFramebufferObject.GL_FRAMEBUFFER_EXT, EXTFramebufferObject.GL_COLOR_ATTACHMENT4_EXT,
            ARBTextureRectangle.GL_TEXTURE_RECTANGLE_ARB, fbotexID4.get(0), 0);
	
	int framebuffer = EXTFramebufferObject.glCheckFramebufferStatusEXT( EXTFramebufferObject.GL_FRAMEBUFFER_EXT ); 
	switch ( framebuffer ) {
		case EXTFramebufferObject.GL_FRAMEBUFFER_COMPLETE_EXT:
			break;
		case EXTFramebufferObject.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
			throw new RuntimeException( "FrameBuffer: " + myFBOId
					+ ", has caused a GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT exception" );
		case EXTFramebufferObject.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
			throw new RuntimeException( "FrameBuffer: " + myFBOId
					+ ", has caused a GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT exception" );
		case EXTFramebufferObject.GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
			throw new RuntimeException( "FrameBuffer: " + myFBOId
					+ ", has caused a GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT exception" );
		case EXTFramebufferObject.GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
			throw new RuntimeException( "FrameBuffer: " + myFBOId
					+ ", has caused a GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT exception" );
		case EXTFramebufferObject.GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
			throw new RuntimeException( "FrameBuffer: " + myFBOId
					+ ", has caused a GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT exception" );
		case EXTFramebufferObject.GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
			throw new RuntimeException( "FrameBuffer: " + myFBOId
					+ ", has caused a GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT exception" );
		default:
			throw new RuntimeException( "Unexpected reply from glCheckFramebufferStatusEXT: " + framebuffer );
	}
 
	
	shaderProgram = GLSL_Shader.loadShadersCode("pass1.vert","pass1.frag");

	
	
    // Put the window into orthographic projection mode with 1:1 pixel ratio.
    // We haven't used GLU here to do this to avoid an unnecessary dependency.
    GL11.glMatrixMode(GL11.GL_PROJECTION);
    GL11.glLoadIdentity();
    GL11.glOrtho(0.0, Display.getDisplayMode().getWidth(), 0.0, Display.getDisplayMode().getHeight(), -1.0, 1.0);
    GL11.glMatrixMode(GL11.GL_MODELVIEW);
    GL11.glLoadIdentity();
    GL11.glViewport(0, 0, Display.getDisplayMode().getWidth(), Display.getDisplayMode().getHeight());
  }

private static void render() {
  // clear the screen
  
  //GL11.glPushAttrib(GL11.GL_VIEWPORT_BIT);
  GL11.glViewport( 0, 0, winWidth, winHeight );
  GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
  
  EXTFramebufferObject.glBindFramebufferEXT( EXTFramebufferObject.GL_FRAMEBUFFER_EXT, myFBOId );
  currentReadAttach.put(0,attach1[1-read]);
  currentReadAttach.put(1,attach2[1-read]);
  
  GL20.glDrawBuffers(currentReadAttach);
  GL11.glEnable(ARBTextureRectangle.GL_TEXTURE_RECTANGLE_ARB);
  
  ARBShaderObjects.glUseProgramObjectARB(shaderProgram);

  GL13.glActiveTexture(GL13.GL_TEXTURE0);
  GL11.glBindTexture(ARBTextureRectangle.GL_TEXTURE_RECTANGLE_ARB, fboTextures1[read]);
  GLSL_Shader.sendUniform1f(shaderProgram, "texture1", 0);
  GL11.glBegin(GL11.GL_QUADS); 
	GL11.glTexCoord2f(0, 0);					GL11.glVertex3f(0, 0, 0);
	GL11.glTexCoord2f(0, winHeight);			GL11.glVertex3f(0, winHeight, 0);
	GL11.glTexCoord2f(winWidth, winHeight);		GL11.glVertex3f(winWidth, winHeight, 0);
	GL11.glTexCoord2f(winWidth, 0);				GL11.glVertex3f(winWidth, 0, 0);
  GL11.glEnd();
  ARBShaderObjects.glUseProgramObjectARB(0);
  EXTFramebufferObject.glBindFramebufferEXT(EXTFramebufferObject.GL_FRAMEBUFFER_EXT, 0);

  
  

  GL11.glEnable(ARBTextureRectangle.GL_TEXTURE_RECTANGLE_ARB);
  GL13.glActiveTexture(GL13.GL_TEXTURE0);
  GL11.glBindTexture(ARBTextureRectangle.GL_TEXTURE_RECTANGLE_ARB, fboTextures1[1-read]);

  GL11.glBegin(GL11.GL_QUADS); 
	GL11.glTexCoord2f(0, 0);					GL11.glVertex3d(0.0, 0.0, 0);
	GL11.glTexCoord2f(0, winHeight);			GL11.glVertex3d(0.0, winHeight, 0);
	GL11.glTexCoord2f(winWidth, winHeight);		GL11.glVertex3d(winWidth, winHeight, 0);
	GL11.glTexCoord2f(winWidth, 0);				GL11.glVertex3d(winWidth, 0.0, 0);
  GL11.glEnd();

  //GL11.glPopAttrib();
  
  //System.err.println(read);
  
  read = 1-read;
  
}


pobrien

Ok I think I may have found the issue, I'm thinking it may be the number of color attachment points.
I tried this to check the max color attachments, but it doesn't work. Whats the proper way to write this:

   IntBuffer temp = ByteBuffer.allocateDirect(4).order(ByteOrder.nativeOrder()).asIntBuffer();
   GL11.glGetInteger(GL30.GL_MAX_COLOR_ATTACHMENTS, temp);
   System.out.println(temp.get(0));

Thanks

spasi

glGetInteger requires a buffer with at least 16 elements remaining. You could also use the new glGetInteger in LWJGL 2.4 that simply returns an integer.

The only potential problem I can notice from quickly inspecting your code is this:

EXTFramebufferObject.glFramebufferTexture2DEXT( EXTFramebufferObject.GL_FRAMEBUFFER_EXT, EXTFramebufferObject.GL_COLOR_ATTACHMENT0_EXT,
	        ARBTextureRectangle.GL_TEXTURE_RECTANGLE_ARB, fbotexID1.get(0), 0);
EXTFramebufferObject.glFramebufferTexture2DEXT( EXTFramebufferObject.GL_FRAMEBUFFER_EXT, EXTFramebufferObject.GL_COLOR_ATTACHMENT1_EXT,
            ARBTextureRectangle.GL_TEXTURE_RECTANGLE_ARB, fbotexID2.get(0), 0);
EXTFramebufferObject.glFramebufferTexture2DEXT( EXTFramebufferObject.GL_FRAMEBUFFER_EXT, EXTFramebufferObject.GL_COLOR_ATTACHMENT3_EXT,
            ARBTextureRectangle.GL_TEXTURE_RECTANGLE_ARB, fbotexID3.get(0), 0);
EXTFramebufferObject.glFramebufferTexture2DEXT( EXTFramebufferObject.GL_FRAMEBUFFER_EXT, EXTFramebufferObject.GL_COLOR_ATTACHMENT4_EXT,
            ARBTextureRectangle.GL_TEXTURE_RECTANGLE_ARB, fbotexID4.get(0), 0);


The last two calls should probably use EXTFramebufferObject.GL_COLOR_ATTACHMENT2_EXT and EXTFramebufferObject.GL_COLOR_ATTACHMENT3_EXT respectively (instead of 3 and 4).

pobrien

It seems to be as simple as fixing what you pointed out, thanks!