Esempio n. 1
0
////////////////////////////////////////////////////////////////////////////////
//! 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();
}
Esempio n. 2
0
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__);
}
Esempio n. 3
0
static void
CleanUp(void)
{
   glDeleteFramebuffersEXT(1, &MyFB);
   glDeleteRenderbuffersEXT(1, &MyRB);
   assert(!glIsFramebufferEXT(MyFB));
   assert(!glIsRenderbufferEXT(MyRB));
   glutDestroyWindow(Win);
   exit(0);
}
Esempio n. 4
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;
 }
Esempio n. 6
0
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);
}
Esempio n. 7
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);


}
Esempio n. 8
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);
}
Esempio n. 12
0
/**
 *  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, &currentFbo);
    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);
}
Esempio n. 13
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;
}
Esempio n. 15
0
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);
}
Esempio n. 16
0
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__);
}