Question

I am attempting to create an FBO to render to a texture in lwjgl. The code works fine on Linux and Windows, but falls flat on my iMac.

The relevant line is the following

 System.out.println(GLContext.getCapabilities().GL_EXT_framebuffer_object); 
    framebuffers[0] = glGenFramebuffersEXT();    

With the capability returning false, and the call to generate the framebuffer throwing

 Exception: java.lang.IllegalStateException: Function is not supported    

Which is what you would expect from trying to call an unsuported function. The graphics card in the mac is an NVIDIA GeForce GTX 675MX 1024 MB, and seeing as the computer is only a year old, I'm a bit flummoxed as to why FBO's are not supported.

The apple documentation here https://developer.apple.com/library/mac/documentation/graphicsimaging/conceptual/opengl-macprogguide/OpenGLProg_MacOSX.pdf states that where FBO's are not available, I should use PBO's. Ok, I can do that, however on the relevant section for PBO's it states

"Important: Pixel buffers are deprecated starting with OS X v10.7 and are 
 not supported by the OpenGL 3.2 Core profile; use framebuffer objects instead."

And so i seem to be chasing my tail here. I have OSX > 10.7 but no FBO :S
My question is, is this a known issue with either opengl on a mac, fbo's on a mac, or lwjgl on a mac, and what should I do to remedy this issue.

btw, I have the following information if it is helpful.

 LWJGL Version: 2.9.0
OpenGL Verison: 3.2 NVIDIA-8.16.74 310.40.00.10f02
OpenGL Shader Version: 1.50    
Was it helpful?

Solution

Don't use the EXT extension for creating FrameBuffers, they was added to the core in version 3.x

The reason why you should use core functions over the extensions is because.

You never know for sure if an extension is available, it depends on various things such as.

  • The version of OpenGL you're using
  • Your Graphics Card
  • Your Graphics Card version and model (GeForce, Cuda, Radeon, etc)
  • Your Graphics Card vendor (Nvidia, AMD, etc)

By using core functions the chances are that the majority of people will be able to run the program, as long as their graphics card can run the particular GL version.

  • EXT extensions usually only are supported by a few vendors.
  • ARB extensions are often supported by the majority but not necessarily all vendors.
  • Core functions are supported by every card which supports the particular GL version, which the program is using.

System.out.println(GLContext.getCapabilities().GL_EXT_framebuffer_object);

With the capability returning false, and the call to generate the framebuffer throwing

Well that pretty much proves my point about extensions and core functions. As said with core functions you simply need a graphics card which support the required OpenGL version or above.

I've made a more in-depth answer about OpenGL Extension vs OpenGL Core, you can by clicking the link.

So as for LWJGL to use the core Framebuffer functions you need to import the following

import static org.lwjgl.opengl.GL30.*;

Variables

The following couple of variables are used in the following code.

int fbo_handle = -1;
int texture_handle = -1;
int rbo_depth_buffer_handle = -1;

Creating the FBO

fbo_handle = glGenFramebuffers();
this.texture_handle = glGenTextures();
rbo_depth_buffer_handle = glGenRenderbuffers();

glBindFramebuffer(GL_FRAMEBUFFER, fbo_handle);

glBindTexture(GL_TEXTURE_2D, texture_handle);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_INT, (ByteBuffer) null);

glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_handle, 0);

glBindRenderbuffer(GL_RENDERBUFFER, rbo_depth_buffer_handle);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbo_depth_buffer_handle);

if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
{
    System.err.println("Framebuffer configuration error");
}

glBindTexture(GL_TEXTURE_2D, 0);
    
glBindFramebuffer(GL_FRAMEBUFFER, 0);

Binding the FBO

glBindFramebuffer(GL_FRAMEBUFFER, fbo_handle);

Binding the FBO Texture

glActiveTexture(GL_TEXTURE0); // This is for Shader usage
glBindTexture(GL_TEXTURE_2D, texture_handle);

Disposing the FBO

glDeleteFramebuffers(fbo_handle);
glDeleteRenderbuffers(rbo_depth_buffer_handle);
glDeleteTextures(texture_handle);

All Needed Imports

import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL12.*;
import static org.lwjgl.opengl.GL13.*;
import static org.lwjgl.opengl.GL14.*;
import static org.lwjgl.opengl.GL30.*;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top