//////////////////////////////////////////////////////////////////////////////// //! Create offscreen render target //////////////////////////////////////////////////////////////////////////////// void createFBO( GLuint* fbo, GLuint* tex) { // create a new fbo glGenFramebuffersEXT( 1, fbo); glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, *fbo); CUT_CHECK_ERROR_GL(); // check if the fbo is valid if( ! glIsFramebufferEXT( *fbo)) { fprintf( stderr, "Framebuffer object creation failed.\n"); fflush( stderr); return; } // create attachment createTexture( tex, image_width, image_height); CUT_CHECK_ERROR_GL(); // attach texture to fbo glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, *tex, 0); CUT_CHECK_ERROR_GL(); // deactivate offsreen render target glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0); CUT_CHECK_ERROR_GL(); }
static void Init( void ) { if (!glutExtensionSupported("GL_EXT_framebuffer_object")) { printf("fbotest2: GL_EXT_framebuffer_object not found!\n"); exit(0); } printf("fbotest2: GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); glGenFramebuffersEXT(1, &MyFB); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, MyFB); assert(glIsFramebufferEXT(MyFB)); /* set color buffer */ glGenRenderbuffersEXT(1, &ColorRb); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, ColorRb); assert(glIsRenderbufferEXT(ColorRb)); glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, ColorRb); glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGB, Width, Height); /* setup depth buffer */ glGenRenderbuffersEXT(1, &DepthRb); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, DepthRb); assert(glIsRenderbufferEXT(DepthRb)); glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, DepthRb); glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, Width, Height); CheckError(__LINE__); /* restore to default */ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); CheckError(__LINE__); }
static void CleanUp(void) { glDeleteFramebuffersEXT(1, &MyFB); glDeleteRenderbuffersEXT(1, &MyRB); assert(!glIsFramebufferEXT(MyFB)); assert(!glIsRenderbufferEXT(MyRB)); glutDestroyWindow(Win); exit(0); }
static void Init( void ) { if (!glutExtensionSupported("GL_EXT_framebuffer_object")) { printf("fbotest3: GL_EXT_framebuffer_object not found!\n"); exit(0); } printf("fbotest3: GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); /* create initial tex obj as an RGBA texture */ glGenTextures(1, &Tex); glBindTexture(GL_TEXTURE_2D, Tex); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glEnable(GL_TEXTURE_2D); /* draw something to make sure the texture is used */ glBegin(GL_POINTS); glVertex2f(0, 0); glEnd(); /* done w/ texturing */ glDisable(GL_TEXTURE_2D); /* Create my Framebuffer Object */ glGenFramebuffersEXT(1, &MyFB); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, MyFB); assert(glIsFramebufferEXT(MyFB)); /* Setup color renderbuffer */ glGenRenderbuffersEXT(1, &ColorRb); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, ColorRb); assert(glIsRenderbufferEXT(ColorRb)); glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, ColorRb); glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGB, Width, Height); /* Setup depth renderbuffer (a texture) */ glGenRenderbuffersEXT(1, &DepthRb); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, DepthRb); assert(glIsRenderbufferEXT(DepthRb)); /* replace RGBA texture with Z texture */ glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, Width, Height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, Tex, 0); CheckError(__LINE__); /* restore to default */ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); CheckError(__LINE__); }
inline GLboolean VL_glIsFramebuffer(GLuint framebuffer) { if (glIsFramebuffer) return glIsFramebuffer(framebuffer); else if (glIsFramebufferEXT) return glIsFramebufferEXT(framebuffer); else VL_UNSUPPORTED_FUNC(); return GL_FALSE; }
static void CleanUp(void) { glDeleteFramebuffersEXT(1, &MyFB); glDeleteRenderbuffersEXT(1, &ColorRb); glDeleteRenderbuffersEXT(1, &DepthRb); glDeleteTextures(1, &Tex); assert(!glIsFramebufferEXT(MyFB)); assert(!glIsRenderbufferEXT(ColorRb)); assert(!glIsRenderbufferEXT(DepthRb)); glutDestroyWindow(Win); exit(0); }
static void Init(int argc, char *argv[]) { if (!glutExtensionSupported("GL_EXT_framebuffer_object")) { printf("GL_EXT_framebuffer_object not found!\n"); exit(0); } printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); /* Make texture object/image */ glGenTextures(1, &TexObj); glBindTexture(TexTarget, TexObj); glTexParameteri(TexTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(TexTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(TexTarget, GL_TEXTURE_BASE_LEVEL, TextureLevel); glTexParameteri(TexTarget, GL_TEXTURE_MAX_LEVEL, TextureLevel); glTexImage2D(TexTarget, 0, TexIntFormat, TexWidth, TexHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); /* gen framebuffer id, delete it, do some assertions, just for testing */ glGenFramebuffersEXT(1, &MyFB); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, MyFB); assert(glIsFramebufferEXT(MyFB)); CheckError(__LINE__); /* Render color to texture */ glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, TexTarget, TexObj, TextureLevel); CheckError(__LINE__); /* bind regular framebuffer */ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); }
void GlFramebufferObject::deleteObject() { if (_handle && glIsFramebufferEXT(_handle)) { glDeleteFramebuffersEXT(1, &_handle); } _handle = 0; }
JNIEXPORT jboolean JNICALL Java_org_lwjgl_opengl_EXTFramebufferObject_glIsFramebufferEXT(JNIEnv *__env, jclass clazz, jint framebuffer) { glIsFramebufferEXTPROC glIsFramebufferEXT = (glIsFramebufferEXTPROC)tlsGetFunction(1704); UNUSED_PARAM(clazz) return (jboolean)glIsFramebufferEXT(framebuffer); }
GLboolean is_frame_buffer(GLuint framebuffer) { GLboolean result = glIsFramebufferEXT(framebuffer); CHECK_GL_ERROR(); return result; }
PsychError SCREENBeginOpenGL(void) { static char useString[] = "Screen('BeginOpenGL', windowPtr [, sharecontext=0]);"; static char synopsisString[] = "Prepare window 'windowPtr' for OpenGL rendering by external OpenGL code. " "This allows to use OpenGL drawing routines other than the ones implemented " "in Screen() to draw to a Psychtoolbox onscreen- or offscreen window via execution of " "OpenGL commands. Typical clients of this function are mogl (Richard F. Murrays OpenGL for Matlab wrapper), " "the new Eyelink-Toolbox and third party Matlab Mex-Files which contain OpenGL rendering routines. " "You *have to* call this command once before using any of those external drawing commands for the window. " "After drawing, you *must* switch back to PTB's rendering via the Screen('EndOpenGL', windowPtr); command. " "Normally, you won't provide the optional flag 'sharecontext', so PTB will automatically isolate the OpenGL " "state of your code from its internal state. However, if you provide sharecontext=1, then PTB will allow " "your code to use and affect PTBs internal context. Only do this if you really know what you're doing! " "If you provide sharecontext=2 then PTB will give you your own private context, but it will synchronize " "the state of that context with its internal state - Seldomly needed, but here for your convenience. " "The context state isolation is as strict as possible without seriously affecting performance and functionality: " "All OpenGL context state is separated, with two exceptions: The framebuffer binding (if any) is always synchronized " "with PTB (and reset to zero when calling 'EndOpenGL' or another Screen command) to allow external code to transparently " "render into PTBs internal framebuffers - Needed for the imaging pipeline to work. Ressources like textures, display lists, " "FBOs, VBOs, PBOs and GLSL shaders are shared between PTB and your code as well for efficiency reasons. Both types of " "ressource sharing shouldn't be a problem, because either you are a beginner or advanced OpenGL programmer and won't use " "those facilities anyway, or you are an expert user - in which case you'll know how to prevent any conflicts easily."; static char seeAlsoString[] = "EndOpenGL SetOpenGLTexture GetOpenGLTexture moglcore"; PsychWindowRecordType *windowRecord; GLint fboid, coltexid, ztexid, stexid; //all sub functions should have these two lines PsychPushHelp(useString, synopsisString,seeAlsoString); if(PsychIsGiveHelp()){PsychGiveHelp();return(PsychError_none);}; //check for superfluous arguments PsychErrorExit(PsychCapNumInputArgs(2)); // The maximum number of inputs PsychErrorExit(PsychRequireNumInputArgs(1)); // Number of required inputs. PsychErrorExit(PsychCapNumOutputArgs(0)); // The maximum number of outputs //get the window record from the window record argument and get info from the window record PsychAllocInWindowRecordArg(kPsychUseDefaultArgPosition, TRUE, &windowRecord); // Already in userspace mode? if (PsychIsUserspaceRendering()) PsychErrorExitMsg(PsychError_user, "Tried to call Screen('BeginOpenGL'), but userspace rendering is already active! Missing or mismatched Screen('EndOpenGL')? Check your code."); // (Optional) context sharing flag provided? sharecontext = 0; PsychCopyInIntegerArg(2, FALSE, &sharecontext); if (sharecontext<0 || sharecontext>2) PsychErrorExitMsg(PsychError_user, "Invalid value for 'sharecontext' provided. Not in range 0 to 2."); // Master override: If context isolation is disabled then we use the PTB internal context... if (PsychPrefStateGet_ConserveVRAM() & kPsychDisableContextIsolation) sharecontext = 1; // Set it as drawing target: This will set up the proper FBO bindings as well: PsychSetDrawingTarget(windowRecord); // Store it as a reference for later 'EndOpenGL' call: preswitchWindowRecord = windowRecord; // Userspace wants its own private rendering context, optionally updated to match PTBs internal state? if (sharecontext == 0 || sharecontext == 2) { // Yes. This is the normal case for 3D rendering. MOGLs and PTBs contexts are separated to // increase robustness, only ressources like textures, display lists, PBO's, VBO's, FBO's // and GLSL shaders are shared, but not the current renderstate. // Make sure 3D rendering is globally enabled, otherwise this is considered a userspace bug: if (PsychPrefStateGet_3DGfx()==0) PsychErrorExitMsg(PsychError_user, "Tried to call 'BeginOpenGL' for external rendering, but 3D rendering not globally enabled! Call 'InitializeMatlabOpenGL' at the beginning of your script!!"); // Query current FBO binding. We need to manually transfer this to the userspace context, so // it can render into our window: if (glBindFramebufferEXT) { fboid = 0; glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &fboid); if (fboid>0) { // Query attachments of FBO: glGetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT, &coltexid); glGetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT, &ztexid); glGetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT, &stexid); } } // Flush our context before context switch: glFlush(); // Unbind possible FBOs, so system FB is active in our context: if (glBindFramebufferEXT && (fboid > 0)) { glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); glFlush(); } // Switch to userspace context for this window, optionally sync state with PTBs context: PsychOSSetUserGLContext(windowRecord, (sharecontext==2) ? TRUE : FALSE); // All following ops apply to the usercontext, not our internal context: // Manually establish proper FBO binding for userspace. This will get reset automaticaly on back-transition // inside PsychSetGLContext on its first invocation. If we are in non-imaging mode then there's nothing to do. if (glBindFramebufferEXT && (fboid > 0)) { if (!glIsFramebufferEXT(fboid)) { // Special case: Need to bind a special FBO and the underlying OpenGL driver is faulty, // i.e. it doesn't share FBO names accross our OpenGL contexts as it should according to // spec.: We manually create a clone of our internal FBO - Create an FBO in the userspace // context with the same FBO handle, then manually reattach the proper attachments... if (PsychPrefStateGet_Verbosity()>1) printf("PTB-WARNING: Faulty graphics driver - FBO sharing doesn't work properly, trying work-around. Update your drivers as soon as possible!\n"); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboid); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_EXT, coltexid, 0); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_RECTANGLE_EXT, ztexid, 0); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_TEXTURE_RECTANGLE_EXT, stexid, 0); if (GL_FRAMEBUFFER_COMPLETE_EXT != glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT)) { // Game over :( PsychErrorExitMsg(PsychError_internal, "Graphics driver malfunction: Failed to clone PTBs internal FBO for userspace GLContext inside SCREENBeginOpenGL as part of workaround code! Upgrade your gfx-drivers!!"); } // If we reach this point, then the workaround for the worst OS in existence has worked. } else { // Need to bind a special FBO and the system works correctly - no workaround needed. Just bind it in new context: glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboid); } } // Is this the first time that the userspace rendering context of this // onscreen window is selected for real userspace rendering? if (windowRecord->needsViewportSetup && PsychIsOnscreenWindow(windowRecord)) { // Yes. Need to perform one-time setup actions for this context: windowRecord->needsViewportSetup = FALSE; // Need to setup glViewPort, scissor rectangle, projection and modelview // matrices to values that match the windows client rectangle. We need to // do this here because some imaging pipeline display modes, e.g, stereomodes // for top-bottom stereo or dualview stereo may have altered the useable client // rendering area after the context was initially created. OpenGL spec states that // at least the viewport and scissor rectangles are set to the full client window // area at first bind of a context to its drawable, so we emulate this here on first // 'BeginOpenGL' to avoid unpleasant surprises for unsuspecting users: PsychSetupView(windowRecord, FALSE); } // Running without imaging pipeline and a stereo mode is active? if ((windowRecord->stereomode) > 0 && !(windowRecord->imagingMode & kPsychNeedFastBackingStore)) { // Perform setup work for stereo drawbuffers in fixed function mode: PsychSwitchFixedFunctionStereoDrawbuffer(windowRecord); } } else { // Userspace shares context with PTB. Let's disable possibly bound GLSL shaders: PsychSetShader(windowRecord, 0); } // Check for GL errors: PsychTestForGLErrors(); // Set the userspace flag: PsychSetUserspaceGLFlag(TRUE); // Ready for userspace rendering: return(PsychError_none); }
/** * Sets up and binds the FBO. * 1: Set element according to fields. * 2: Let children manipulate setup. * 3: Allocate/deallocate if need be. * 4: Set element according to finished Fbo */ void SoXipFbo::GLRender(SoGLRenderAction* action) { //SoDebugError::postInfo(__FUNCTION__, "(1) in mod out (%d %d %d)", mFboIn.isDirty, mFboMod.isDirty, mFboOut.isDirty); if (autoSize.getValue()) { const SbVec2s &viewportSize = action->getViewportRegion().getViewportSizePixels(); if (viewportSize != SbVec2s(width.getValue(), height.getValue())) { SoDebugError::postInfo("SoXipFbo", "Autosetting FBO size to (%d, %d)", viewportSize[0], viewportSize[1]); width.setValue(viewportSize[0]); height.setValue(viewportSize[1]); mNeedsUpdate = true; } } // Can't use sensors if fields are changed while traversing tree, such as by parent size changing if (width.getValue() != mFboIn.width || height.getValue() != mFboIn.height) mNeedsUpdate = true; if (mNeedsUpdate) { // Check number of buffers checkMaxNumBuffers(); // Dealloc if allocated if (mIsAllocated) deallocate(); mFboIn.clear(); mFboMod.clear(); mFboOut.clear(); int currUnit = SoXipMultiTextureElement::getCurrentUnit(action->getState()); int freeUnit = SoXipMultiTextureElement::getFreeUnit(action->getState()); SoXipMultiTextureElement::setUnit(action->getState(), freeUnit); allocateFbo(); SoXipMultiTextureElement::setUnit(action->getState(), currUnit); //SoDebugError::postInfo(__FUNCTION__, "Allocated new Fbo (dirty)"); mNeedsUpdate = false; } else mFboIn.isDirty = false; mFboMod.isDirty = false; //SoDebugError::postInfo(__FUNCTION__, "(2) in mod out (%d %d %d)", mFboIn.isDirty, mFboMod.isDirty, mFboOut.isDirty); // Send to element and render children to allow modification mFboIn.isOpen = true; SoXipFboElement::set(action->getState(), this, mFboIn); SoXipFboElement::bind(action->getState(), this); int currentFbo; glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, ¤tFbo); if (!glIsFramebufferEXT(mFboIn.fboHandle) || mFboIn.fboHandle != currentFbo) { SoDebugError::postWarning("SoXipFbo", "Error in the setup, fbo not guaranteed to be bound"); mNeedsUpdate = true; return; } ////////// /// Traverse children SoGroup::GLRender(action); /// Traverse children ////////// FboSetup * fbo = SoXipFboElement::getActive(action->getState(), this); // Detect any change in fbo handle if (mFboIn.fboHandle != fbo->fboHandle) SoDebugError::postWarning("SoXipFbo", "Keep Fbo bound during traversal (%d %d)", mFboIn.fboHandle, fbo->fboHandle); //SoDebugError::postInfo(__FUNCTION__, "(3) in mod out (%d %d %d)", mFboIn.isDirty, mFboMod.isDirty, mFboOut.isDirty); // Reflect changes if change since last run if (mFboMod != *fbo) { mFboMod = *fbo; mFboOut = *fbo; int currUnit = SoXipMultiTextureElement::getCurrentUnit(action->getState()); int freeUnit = SoXipMultiTextureElement::getFreeUnit(action->getState()); SoXipMultiTextureElement::setUnit(action->getState(), freeUnit); processColorMods(); processDepthMods(); SoXipMultiTextureElement::setUnit(action->getState(), currUnit); mErrorInSetup = false; } else mFboOut.isDirty = false; //SoDebugError::postInfo(__FUNCTION__, "(4) in mod out (%d %d %d)", mFboIn.isDirty, mFboMod.isDirty, mFboOut.isDirty); SoXipDrawBuffersElement::set(action->getState(), this, mFboOut.numColorAttachments); // Everything is now attached so test completeness if (!mErrorInSetup) mFboOut.isComplete = checkFramebufferStatus(); if (!mFboOut.isComplete) mErrorInSetup = true; // Activate FBO element (also sets draw buffer element) mFboOut.isOpen = false; SoXipFboElement::set(action->getState(), this, mFboOut); //SoDebugError::postInfo(__FUNCTION__, "(5) in mod out (%d %d %d)", mFboIn.isDirty, mFboMod.isDirty, mFboOut.isDirty); if (!mFboOut.isComplete) SoXipDrawBuffersElement::set(action->getState(), this, 0); }
void GLTexture::init() { if (m_fbType == ENone) Log(ETrace, "Uploading a texture : %s", toString().c_str()); else Log(ETrace, "Creating a framebuffer : %s", toString().c_str()); if (m_samples > 1) { int maxSamples = 1; if (GLEW_ARB_texture_multisample) glGetIntegerv(GL_MAX_SAMPLES_EXT, &maxSamples); if (m_samples > maxSamples) { Log(EWarn, "Attempted to create a multisample framebuffer " "with an unsupported number of samples (requested=%i, supported=%i)", m_samples, maxSamples); m_samples = maxSamples; } } lookupGLConstants(); /* Generate an identifier */ glGenTextures(1, &m_id); /* Bind to the texture */ glBindTexture(m_glType, m_id); /* Set the texture filtering / wrapping modes (don't do this for multisample textures)*/ if (!((m_fbType & EColorBuffer) && m_samples > 1)) configureTexture(); /* Multisample textures don't have these parameters */ if (m_fbType == ENone) { Assert(m_samples == 1); refresh(); } else { /* Create the FBO and bind it */ glGenFramebuffersEXT(1, &m_fboId); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fboId); AssertEx(glIsFramebufferEXT(m_fboId), "Creating an FBO failed"); bool depthAsTexture = m_fbType & EDepthBuffer; switch (m_fbType) { case EColorAndDepthBuffer: case EColorBuffer: { if (m_type == ETexture2D) { if (!depthAsTexture) { glGenRenderbuffersEXT(1, &m_depthId); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthId); if (m_samples == 1) glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT32, m_size.x, m_size.y); else glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, m_samples, GL_DEPTH_COMPONENT32, m_size.x, m_size.y); glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthId); } else { glGenTextures(1, &m_depthId); glBindTexture(m_glType, m_depthId); configureTexture(); glTexParameteri(m_glType, GL_TEXTURE_COMPARE_MODE, GL_NONE); glTexParameteri(m_glType, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE); if (m_samples == 1) glTexImage2D(m_glType, 0, GL_DEPTH_COMPONENT32, m_size.x, m_size.y, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL); else glTexImage2DMultisample(m_glType, m_samples, GL_DEPTH_COMPONENT32, m_size.x, m_size.y, GL_FALSE); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT, m_glType, m_depthId, 0); glBindTexture(m_glType, m_id); } if (m_samples == 1) glTexImage2D(m_glType, 0, m_internalFormat, m_size.x, m_size.y, 0, m_format, m_dataFormat, NULL); else glTexImage2DMultisample(m_glType, m_samples, m_internalFormat, m_size.x, m_size.y, GL_FALSE); if (isMipMapped()) glGenerateMipmapEXT(m_glType); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, m_glType, m_id, 0); } else if (m_type == ETextureCubeMap) { Assert(m_size.x == m_size.y && math::isPowerOfTwo(m_size.x)); Assert(m_fbType == EColorBuffer); Assert(m_samples == 1); for (int i=0; i<6; i++) glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, m_internalFormat, m_size.x, m_size.y, 0, m_format, m_dataFormat, NULL); if (isMipMapped()) glGenerateMipmapEXT(m_glType); if (depthAsTexture) { /* Generate an identifier */ glGenTextures(1, &m_depthId); glBindTexture(m_glType, m_depthId); glTexParameteri(m_glType, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(m_glType, GL_TEXTURE_MIN_FILTER, GL_LINEAR); for (int i=0; i<6; i++) glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_DEPTH_COMPONENT32, m_size.x, m_size.y, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL); if (GLEW_EXT_geometry_shader4) activateSide(-1); else activateSide(0); } else { glGenRenderbuffersEXT(1, &m_depthId); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthId); glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT32, m_size.x, m_size.y); glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthId); activateSide(0); } } else { Log(EError, "Unsupported texture type!"); } } break; case EDepthBuffer: Assert(m_samples == 1); if (m_depthMode == ECompare) { glTexParameteri(m_glType, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); glTexParameteri(m_glType, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE); } if (m_type == ETexture2D) { /* Allocate the texture memory */ glTexImage2D(m_glType, 0, m_internalFormat, m_size.x, m_size.y, 0, GL_DEPTH_COMPONENT, m_dataFormat, NULL); /* Attach the texture as a depth target */ glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, m_glType, m_id, 0); } else if (m_type == ETextureCubeMap) { Assert(m_size.x == m_size.y && math::isPowerOfTwo(m_size.x)); for (int i=0; i<6; i++) glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, m_internalFormat, m_size.x, m_size.y, 0, m_format, m_dataFormat, NULL); if (GLEW_EXT_geometry_shader4) activateSide(-1); else activateSide(0); } else { Log(EError, "Unsupported texture type!"); } glDrawBuffer(GL_NONE); glReadBuffer(GL_NONE); break; default: Log(EError, "Invalid render buffer type!"); } GLenum errorStatusID = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); std::string errorStatus; switch (errorStatusID) { case GL_FRAMEBUFFER_COMPLETE_EXT: break; case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: errorStatus = "Incomplete attachment"; break; case GL_FRAMEBUFFER_UNSUPPORTED_EXT: errorStatus = "Unsupported framebuffer format"; break; case GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT: errorStatus = "Incomplete framebuffer - duplicate attachment"; break; case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT: errorStatus = "Incomplete framebuffer - missing attachment"; break; case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: errorStatus = "Incomplete framebuffer - invalid dimensions"; break; case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT: errorStatus = "Incomplete framebuffer - no draw buffer"; break; case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT: errorStatus = "Incomplete framebuffer - invalid formats"; break; case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT: errorStatus = "Incomplete framebuffer - no readbuffer"; break; case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT: errorStatus = "Incomplete multisample framebuffer"; break; case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS: errorStatus = "Incomplete layer targets"; break; default: errorStatus = "Unknown error status"; break; } if (!errorStatus.empty()) Log(EError, "FBO Error 0x%x: %s!\nFramebuffer configuration: %s", errorStatusID, errorStatus.c_str(), toString().c_str()); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, GL_NONE); } glBindTexture(m_glType, GL_NONE); }
JNIEXPORT jboolean JNICALL Java_org_lwjgl_opengl_EXTFramebufferObject_nglIsFramebufferEXT(JNIEnv *env, jclass clazz, jint framebuffer, jlong function_pointer) { glIsFramebufferEXTPROC glIsFramebufferEXT = (glIsFramebufferEXTPROC)((intptr_t)function_pointer); GLboolean __result = glIsFramebufferEXT(framebuffer); return __result; }
static void Init(int argc, char *argv[]) { static const GLfloat mat[4] = { 1.0, 0.5, 0.5, 1.0 }; GLint i; if (!glutExtensionSupported("GL_EXT_framebuffer_object")) { printf("GL_EXT_framebuffer_object not found!\n"); exit(0); } if (argc > 1 && strcmp(argv[1], "-ds") == 0) { if (!glutExtensionSupported("GL_EXT_packed_depth_stencil")) { printf("GL_EXT_packed_depth_stencil not found!\n"); exit(0); } UsePackedDepthStencil = GL_TRUE; printf("Using GL_EXT_packed_depth_stencil\n"); } printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); /* gen framebuffer id, delete it, do some assertions, just for testing */ glGenFramebuffersEXT(1, &MyFB); assert(MyFB); assert(!glIsFramebufferEXT(MyFB)); glDeleteFramebuffersEXT(1, &MyFB); assert(!glIsFramebufferEXT(MyFB)); /* Note, continue to use MyFB below */ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, MyFB); assert(glIsFramebufferEXT(MyFB)); glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &i); assert(i == MyFB); /* Make texture object/image */ glGenTextures(1, &TexObj); glBindTexture(TexTarget, TexObj); /* make two image levels */ glTexImage2D(TexTarget, 0, TexIntFormat, TexWidth, TexHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glTexImage2D(TexTarget, 1, TexIntFormat, TexWidth/2, TexHeight/2, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); TexWidth = TexWidth >> TextureLevel; TexHeight = TexHeight >> TextureLevel; glTexParameteri(TexTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(TexTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glTexParameteri(TexTarget, GL_TEXTURE_BASE_LEVEL, TextureLevel); glTexParameteri(TexTarget, GL_TEXTURE_MAX_LEVEL, TextureLevel); CheckError(__LINE__); /* Render color to texture */ glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, TexTarget, TexObj, TextureLevel); #if DEPTH /* make depth renderbuffer */ glGenRenderbuffersEXT(1, &DepthRB); assert(DepthRB); assert(!glIsRenderbufferEXT(DepthRB)); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, DepthRB); assert(glIsRenderbufferEXT(DepthRB)); if (UsePackedDepthStencil) glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_STENCIL_EXT, TexWidth, TexHeight); else glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, TexWidth, TexHeight); CheckError(__LINE__); glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_DEPTH_SIZE_EXT, &i); CheckError(__LINE__); printf("Depth renderbuffer size = %d bits\n", i); assert(i > 0); /* attach DepthRB to MyFB */ glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, DepthRB); #endif CheckError(__LINE__); #if STENCIL if (UsePackedDepthStencil) { /* DepthRb is a combined depth/stencil renderbuffer */ glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, DepthRB); } else { /* make stencil renderbuffer */ glGenRenderbuffersEXT(1, &StencilRB); assert(StencilRB); assert(!glIsRenderbufferEXT(StencilRB)); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, StencilRB); assert(glIsRenderbufferEXT(StencilRB)); glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_STENCIL_INDEX, TexWidth, TexHeight); /* attach StencilRB to MyFB */ glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, StencilRB); } glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_STENCIL_SIZE_EXT, &i); CheckError(__LINE__); printf("Stencil renderbuffer size = %d bits\n", i); assert(i > 0); #endif CheckError(__LINE__); /* bind regular framebuffer */ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); /* lighting */ glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat); }
static void Init( void ) { GLboolean ARB_fbo = glutExtensionSupported("GL_ARB_framebuffer_object"); GLint i; if (!glutExtensionSupported("GL_EXT_framebuffer_object")) { printf("GL_EXT_framebuffer_object not found!\n"); exit(0); } printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); glGenFramebuffersEXT(1, &MyFB); assert(MyFB); assert(!glIsFramebufferEXT(MyFB)); if (!ARB_fbo) { glDeleteFramebuffersEXT(1, &MyFB); assert(!glIsFramebufferEXT(MyFB)); } /* Note, continue to use MyFB below */ glGenRenderbuffersEXT(1, &MyRB); assert(MyRB); assert(!glIsRenderbufferEXT(MyRB)); if (!ARB_fbo) { glDeleteRenderbuffersEXT(1, &MyRB); assert(!glIsRenderbufferEXT(MyRB)); MyRB = 42; /* an arbitrary ID */ } glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, MyFB); assert(glIsFramebufferEXT(MyFB)); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, MyRB); assert(glIsRenderbufferEXT(MyRB)); glGetIntegerv(GL_RENDERBUFFER_BINDING_EXT, &i); assert(i == MyRB); glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &i); assert(i == MyFB); CheckError(__LINE__); glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, MyRB); glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGB, Width, Height); CheckError(__LINE__); { GLint r, g, b, a; glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_RED_SIZE_EXT, &r); glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_GREEN_SIZE_EXT, &g); glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_BLUE_SIZE_EXT, &b); glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_ALPHA_SIZE_EXT, &a); CheckError(__LINE__); printf("renderbuffer RGBA sizes = %d %d %d %d\n", r, g, b, a); glGetIntegerv(GL_RED_BITS, &r); glGetIntegerv(GL_GREEN_BITS, &g); glGetIntegerv(GL_BLUE_BITS, &b); glGetIntegerv(GL_ALPHA_BITS, &a); printf("Visual RGBA sizes = %d %d %d %d\n", r, g, b, a); } /* restore to default */ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); CheckError(__LINE__); }