Esempio n. 1
0
/**
 * Deattaches an attachment from the framebuffer
 */
void FBO::Unattach(const GLenum attachment)
{
	GLuint target;
	glGetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER_EXT, attachment,
		GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT,
		(GLint*)&target);

	if (target==GL_RENDERBUFFER_EXT) {
		//! check if the RBO was created via FBO::CreateRenderBuffer()
		GLuint id;
		glGetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER_EXT, attachment,
			GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT,
			(GLint*)&id);

		glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, attachment, GL_RENDERBUFFER_EXT, 0);

		for (std::vector<GLuint>::iterator ri=myRBOs.begin(); ri!=myRBOs.end(); ++ri) {
			if (*ri == id) {
				glDeleteRenderbuffersEXT(1, &(*ri));
				myRBOs.erase(ri);
				break;
			}
		}
	} else {
		glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, attachment, GL_TEXTURE_2D, 0, 0);
	}
}
void WebGraphicsContext3DDefaultImpl::getFramebufferAttachmentParameteriv(unsigned long target, unsigned long attachment,
                                                                          unsigned long pname, int* value)
{
    makeContextCurrent();
    if (attachment == GL_DEPTH_STENCIL_ATTACHMENT)
        attachment = GL_DEPTH_ATTACHMENT; // Or GL_STENCIL_ATTACHMENT, either works.
    glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, value);
}
 inline void VL_glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint *params)
 {
   if (glGetFramebufferAttachmentParameteriv)
     glGetFramebufferAttachmentParameteriv(target,attachment,pname,params);
   else
   if (glGetFramebufferAttachmentParameterivEXT)
     glGetFramebufferAttachmentParameterivEXT(target,attachment,pname,params);
   else
     VL_UNSUPPORTED_FUNC();
 }
Esempio n. 4
0
GLuint GlFramebufferObject::getAttachmentID(GLenum attachment) {

  FboBinder b(_handle);
  
  GLint id = 0;
  glGetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER_EXT, attachment,
                                           GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT,
                                           &id);
  return GLuint(id);
  
}
Esempio n. 5
0
GLenum GlFramebufferObject::getAttachmentType(GLenum attachment) {

  FboBinder b(_handle);

  GLint type = 0;
  glGetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER_EXT, attachment,
                                           GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT, 
                                           &type);
  return GLenum(type);

}
/**
 *  Run a check and output any errors.
 */
bool SoXipFboAttachColor3D::checkFramebufferStatus()
{
    bool isOk = false;
    int db[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
    int tp[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
    GLenum status = (GLenum)glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
    switch(status) {
    case GL_FRAMEBUFFER_COMPLETE_EXT:
        isOk = true;
        break;
    case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
        SoDebugError::post("SoXipFboAttachColor3D", "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT");
        break;
    case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
        SoDebugError::post("SoXipFboAttachColor3D", "GL_FRAMEBUFFER_UNSUPPORTED_EXT");
        break;
    case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
        SoDebugError::post("SoXipFboAttachColor3D", "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT");
        break;
    case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
        SoDebugError::post("SoXipFboAttachColor3D", "GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT");
        break;
    case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
        SoDebugError::post("SoXipFboAttachColor3D", "GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT");
        break;
    case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
        // Extract buffer setup
        for (int i = 0; i < mMaxAttachments; i++)
            glGetIntegerv(GL_DRAW_BUFFER0 + i, db + i);
        // Extract type setup
        for (int i = 0; i < mMaxAttachments; i++)
            glGetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER_EXT,
                    GL_COLOR_ATTACHMENT0_EXT + i,
                    GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT,
                    tp + i);
        // Print
        SoDebugError::post("SoXipFboAttachColor3D", "Incomplete Draw Buffer: draw (%d %d %d %d) type (%d %d %d %d)",
                           db[0], db[1], db[2], db[3], tp[0], tp[1], tp[2], tp[3]);
        break;
    case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
        SoDebugError::post("SoXipFboAttachColor3D", "GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT");
        break;
    default:
        SoDebugError::post("SoXipFboAttachColor3D", "UNKNOWN frambuffer error %i", status);
    }
    return isOk;
}
Esempio n. 7
0
///////////////////////////////////////////////////////////////////////////////
// print out the FBO infos
///////////////////////////////////////////////////////////////////////////////
void PrintFramebufferInfo()
{
    cout << "\n***** FBO STATUS *****\n";

    // print max # of colorbuffers supported by FBO
    int colorBufferCount = 0;
    glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS_EXT, &colorBufferCount);
    cout << "Max Number of Color Buffer Attachment Points: " << colorBufferCount << endl;

    int objectType;
    int objectId;

    // print info of the colorbuffer attachable image
    for(int i = 0; i < colorBufferCount; ++i)
    {
        glGetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER_EXT,
                                                 GL_COLOR_ATTACHMENT0_EXT+i,
                                                 GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT,
                                                 &objectType);
        if(objectType != GL_NONE)
        {
            glGetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER_EXT,
                                                     GL_COLOR_ATTACHMENT0_EXT+i,
                                                     GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT,
                                                     &objectId);

            std::string formatName;

            cout << "Color Attachment " << i << ": ";
            if(objectType == GL_TEXTURE)
                cout << "GL_TEXTURE, " << GetTextureParameters(objectId) << endl;
            else if(objectType == GL_RENDERBUFFER_EXT)
                cout << "GL_RENDERBUFFER_EXT, " << GetRenderbufferParameters(objectId) << endl;
        }
    }

    // print info of the depthbuffer attachable image
    glGetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER_EXT,
                                             GL_DEPTH_ATTACHMENT_EXT,
                                             GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT,
                                             &objectType);
    if(objectType != GL_NONE)
    {
        glGetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER_EXT,
                                                 GL_DEPTH_ATTACHMENT_EXT,
                                                 GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT,
                                                 &objectId);

        cout << "Depth Attachment: ";
        switch(objectType)
        {
        case GL_TEXTURE:
            cout << "GL_TEXTURE, " << GetTextureParameters(objectId) << endl;
            break;
        case GL_RENDERBUFFER_EXT:
            cout << "GL_RENDERBUFFER_EXT, " << GetRenderbufferParameters(objectId) << endl;
            break;
        }
    }

    // print info of the stencilbuffer attachable image
    glGetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER_EXT,
                                             GL_STENCIL_ATTACHMENT_EXT,
                                             GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT,
                                             &objectType);
    if(objectType != GL_NONE)
    {
        glGetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER_EXT,
                                                 GL_STENCIL_ATTACHMENT_EXT,
                                                 GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT,
                                                 &objectId);

        cout << "Stencil Attachment: ";
        switch(objectType)
        {
        case GL_TEXTURE:
            cout << "GL_TEXTURE, " << GetTextureParameters(objectId) << endl;
            break;
        case GL_RENDERBUFFER_EXT:
            cout << "GL_RENDERBUFFER_EXT, " << GetRenderbufferParameters(objectId) << endl;
            break;
        }
    }

    cout << endl;
}
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_EXTFramebufferObject_nglGetFramebufferAttachmentParameterivEXT__IIIJ(JNIEnv *__env, jclass clazz, jint target, jint attachment, jint pname, jlong paramsAddress) {
    glGetFramebufferAttachmentParameterivEXTPROC glGetFramebufferAttachmentParameterivEXT = (glGetFramebufferAttachmentParameterivEXTPROC)tlsGetFunction(1713);
    intptr_t params = (intptr_t)paramsAddress;
    UNUSED_PARAM(clazz)
    glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, params);
}
				void get_frame_buffer_attachment_parameter(GLenum target, GLenum attachment, GLenum pname, GLint *params) {
					glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, params);
					CHECK_GL_ERROR();
				}
Esempio n. 10
0
static GLboolean
render_and_check_textures(GLenum internal_format)
{
	GLuint rgba_fb;
	GLuint other_fb;
	float rgba_image[4 * 64 * 64];
	float other_image[4 * 64 * 64];
	GLboolean has_green;
	GLuint vs;
	GLuint fs;
	GLint scale_loc;
	GLint bias_loc;
	float scale;
	float bias;

	piglit_require_extension("GL_EXT_framebuffer_object");
	piglit_require_extension("GL_ARB_texture_rg");
	piglit_require_extension("GL_ARB_texture_non_power_of_two");

	has_green = GL_FALSE;
	scale = 1.0;
	bias = 0.0;
	switch (internal_format) {
	case GL_RG:
	case GL_RG8:
	case GL_RG16:
		has_green = GL_TRUE;
		/* FALLTHROUGH */
	case GL_RED:
	case GL_R8:
	case GL_R16:
		break;

	case GL_RG16F:
		has_green = GL_TRUE;
		/* FALLTHROUGH */
	case GL_R16F:
		piglit_require_extension("GL_ARB_half_float_pixel");
		/* FALLTHROUGH */
	case GL_RG32F:
		has_green = GL_TRUE;
		/* FALLTHROUGH */
	case GL_R32F:
		scale = 511.0;
		piglit_require_extension("GL_ARB_texture_float");
		break;

	case GL_RG_INTEGER:
	case GL_RG8I:
	case GL_RG16I:
	case GL_RG32I:
		has_green = GL_TRUE;
		/* FALLTHROUGH */
	case GL_R8I:
	case GL_R16I:
	case GL_R32I:
		bias = -100.0;
		scale = 511.0;
		piglit_require_extension("GL_EXT_texture_integer");
		break;

	case GL_RG8UI:
	case GL_RG16UI:
	case GL_RG32UI:
		has_green = GL_TRUE;
		/* FALLTHROUGH */
	case GL_R16UI:
	case GL_R32UI:
		scale = 511.0;
		piglit_require_extension("GL_EXT_texture_integer");
		break;

	case GL_RG_SNORM:
	case GL_RG8_SNORM:
	case GL_RG16_SNORM:
		has_green = GL_TRUE;
		/* FALLTHROUGH */
	case GL_RED_SNORM:
	case GL_R8_SNORM:
	case GL_R16_SNORM:
		scale = 0.5;
		bias = -0.5;
		piglit_require_extension("GL_EXT_texture_snorm");
		break;
	default:
		fprintf(stderr, "invalid format 0x%04x\n", internal_format);
		piglit_report_result(PIGLIT_FAIL);
		break;
	}

	glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE,
			      2 * sizeof(GLfloat), positions);
	glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE,
			      4 * sizeof(GLfloat), colors);

	glEnableVertexAttribArray(0);
	glEnableVertexAttribArray(1);

	vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vert_code);
	fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, frag_code);
	fbo_program = piglit_link_simple_program(vs, fs);

	glBindAttribLocation(fbo_program, 0, "position");
	glBindAttribLocation(fbo_program, 1, "color");
	glLinkProgram(fbo_program);
	if (!piglit_link_check_status(fbo_program))
		piglit_report_result(PIGLIT_FAIL);

	scale_loc = glGetUniformLocation(fbo_program, "scale");
	if (scale_loc < 0) {
		fprintf(stderr,
			"couldn't get uniform location for \"scale\"\n");
		piglit_report_result(PIGLIT_FAIL);
	}

	bias_loc = glGetUniformLocation(fbo_program, "bias");
	if (bias_loc < 0) {
		fprintf(stderr,
			"couldn't get uniform location for \"bias\"\n");
		piglit_report_result(PIGLIT_FAIL);
	}

	glUseProgram(fbo_program);
	glUniform1f(scale_loc, scale);
	glUniform1f(bias_loc, bias);

	/* Draw the reference image to the RGBA texture.
	 */
	rgba_fb = create_fbo(64, 64, GL_RGBA);
	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, rgba_fb);
	glViewport(0, 0, 64, 64);
	glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

	glGetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER_EXT,
						 GL_COLOR_ATTACHMENT0_EXT,
						 GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT,
						 (GLint *) &rgba_tex);
	glBindTexture(GL_TEXTURE_2D, rgba_tex);
	glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT, rgba_image);


	/* Draw the comparison image to the other texture.
	 */
	other_fb = create_fbo(64, 64, internal_format);
	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, other_fb);
	glViewport(0, 0, 64, 64);
	glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

	glGetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER_EXT,
						 GL_COLOR_ATTACHMENT0_EXT,
						 GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT,
						 (GLint *) &other_tex);
	glBindTexture(GL_TEXTURE_2D, other_tex);
	glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT, other_image);

	glUseProgram(0);
	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, piglit_winsys_fbo);
	glViewport(0, 0, piglit_width, piglit_height);

	return compare_texture(rgba_image, other_image,
			       internal_format, GL_RGBA,
			       64 * 64, has_green);
}
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
void GL_WriteTexturesToDisk()
{
#pragma warning(push)
#pragma warning(disable : 4996)  // sprintf unsafe

	static std::vector<unsigned char> bytes;

	int activeTexture;
	glGetIntegerv(GL_ACTIVE_TEXTURE, &activeTexture);

	int originalBoundTex = 0;
	glGetIntegerv(GL_TEXTURE_BINDING_2D, &originalBoundTex);

	int maxColorAttachments;
	glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &maxColorAttachments);


	int depthAttachment = -1;
	glGetFramebufferAttachmentParameterivEXT(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &depthAttachment);

	std::map<GLuint, int> colorAttachments;
	for( int i=0; i<maxColorAttachments; i++ )
	{
		int name;
		glGetFramebufferAttachmentParameterivEXT(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+i, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &name);

		if( name != 0 ) colorAttachments[name] = i;
	}

	int maxTextureUnits;
	glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxTextureUnits);

	std::map<GLuint, int> boundTextures;
	for( int i=0; i<maxTextureUnits; i++ ) {
		int boundTexture;
		glActiveTexture(GL_TEXTURE0+i);
		glGetIntegerv(GL_TEXTURE_BINDING_2D, &boundTexture);

		if( boundTexture ) {
			boundTextures[boundTexture] = i;
		}
	}

	glActiveTexture(activeTexture);

	for( int i=1; i<200; i++ ) {  // save textures to disk

		if( glIsTexture(i) ) {
			glBindTexture(GL_TEXTURE_2D, i);

			int width, height, format, components;
			glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width);
			glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height);
			glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &format);  // Danger, GL_TEXTURE_INTERNAL_FORMAT equals GL_TEXTURE_COMPONENTS
			glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPONENTS, &components);

			if( format == 1 ) format = GL_R;
			else if( format == 2 ) format = GL_RG;
			else if( format == 3 || format == GL_RGB8 ) format = GL_RGB;
			else if( format == 4 || format == GL_RGBA8 ) format = GL_RGBA;
			else if( format==GL_DEPTH_COMPONENT24 || format==GL_DEPTH_COMPONENT32 ) format = GL_DEPTH_COMPONENT;

			bool floatFormat = false;

			if( format == GL_RGBA32F_ARB )
			{
				floatFormat = true;
			}

			if( components > 4 ) 
			{
				switch( format ) {
				case GL_RGBA:
				case GL_RGBA8:
#if GS_WIN
				case GL_RGBA16F:
				case GL_RGBA32F:
#else
				case GL_RGBA16F_ARB:
				case GL_RGBA32F_ARB:
#endif
					components = 4;
					break;
				case GL_RGB:
#if GS_WIN
				case GL_RGB16F:
				case GL_RGB32F:
#else
				case GL_RGB16F_ARB:
				case GL_RGB32F_ARB:
#endif
					components = 3;
					break;
				case GL_RG:
				case GL_RG16F:
				case GL_RG32F:
					components = 2;
					break;
				case GL_R:
				case GL_DEPTH_COMPONENT16:
				case GL_DEPTH_COMPONENT24:
				case GL_DEPTH_COMPONENT32:
				default:
					components = 1;
					break;
				}

			}

			int size = width * height * components;
			bytes.resize(size);

			if( floatFormat )
			{
				std::vector<float> floatBytes(size);				
				glGetTexImage(GL_TEXTURE_2D, 0, format, GL_FLOAT, &floatBytes[0]);

				for( size_t i=0; i<floatBytes.size(); i++ )
				{
					bytes[i] = (unsigned char)glm::min(1.0f, glm::max(0.0f, floatBytes[i]*255.0f));
				}
			}
			else
			{
				glGetTexImage(GL_TEXTURE_2D, 0, format, GL_UNSIGNED_BYTE, &bytes[0]);
			}

			int err = glGetError();
			if( err != 0 ) {
				err = 0;
			}

			char filename[256];
			int len=0;
#if GS_WIN
			const char * logPath = "d:\\a\\";
#else
			const char * logPath = "/a/";
#endif
			len += sprintf(filename+len, "%stexture%d %dx%d %dBpp", logPath, i, width, height, components);
			if( boundTextures.find(i) != boundTextures.end() ) len += sprintf(filename+len, " GL_TEXTURE%d", boundTextures[i]);
			if( colorAttachments.find(i) != colorAttachments.end() ) len += sprintf(filename+len, " GL_COLOR_ATTACHMENT%d", colorAttachments[i]);
			if( i == depthAttachment ) len += sprintf(filename+len, " GL_DEPTH_ATTACHMENT");
			len += sprintf(filename+len, ".raw");

			std::ofstream out(filename, std::ios_base::binary);
			out.write((const char *)&bytes[0], size);
			out.close();
		}
	}

	glBindTexture(GL_TEXTURE_2D, originalBoundTex);

#pragma warning(pop)
}
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_EXTFramebufferObject_nglGetFramebufferAttachmentParameterivEXT(JNIEnv *env, jclass clazz, jint target, jint attachment, jint pname, jlong params, jlong function_pointer) {
	GLint *params_address = (GLint *)(intptr_t)params;
	glGetFramebufferAttachmentParameterivEXTPROC glGetFramebufferAttachmentParameterivEXT = (glGetFramebufferAttachmentParameterivEXTPROC)((intptr_t)function_pointer);
	glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, params_address);
}
Esempio n. 14
0
/**
 * Makes a copy of a texture/RBO in the system ram
 */
void FBO::DownloadAttachment(const GLenum attachment)
{
	GLuint target;
	glGetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER_EXT, attachment,
		GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT,
		(GLint*)&target);
	GLuint id;
	glGetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER_EXT, attachment,
		GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT,
		(GLint*)&id);

	if (target==GL_NONE || id==0)
		return;

	if (texBuf.find(id)!=texBuf.end())
		return;

	if (target==GL_TEXTURE) {
		target = GetTextureTargetByID(id);

		if (target<0)
			return;
	}

	struct FBO::TexData* tex = new FBO::TexData;
	tex->id = id;
	tex->target = target;

	int bits = 0;

	if (target==GL_RENDERBUFFER_EXT) {
		glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, id);
		glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_WIDTH_EXT,  &tex->xsize);
		glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_HEIGHT_EXT, &tex->ysize);
		glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_INTERNAL_FORMAT_EXT, (GLint*)&tex->format);

		GLint _cbits;
		glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_RED_SIZE_EXT, &_cbits); bits += _cbits;
		glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_GREEN_SIZE_EXT, &_cbits); bits += _cbits;
		glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_BLUE_SIZE_EXT, &_cbits); bits += _cbits;
		glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_ALPHA_SIZE_EXT, &_cbits); bits += _cbits;
		glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_DEPTH_SIZE_EXT, &_cbits); bits += _cbits;
		glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_STENCIL_SIZE_EXT, &_cbits); bits += _cbits;
	} else {
		glBindTexture(target,id);

		glGetTexLevelParameteriv(target, 0, GL_TEXTURE_WIDTH, &tex->xsize);
		glGetTexLevelParameteriv(target, 0, GL_TEXTURE_HEIGHT, &tex->ysize);
		glGetTexLevelParameteriv(target, 0, GL_TEXTURE_DEPTH, &tex->zsize);
		glGetTexLevelParameteriv(target, 0, GL_TEXTURE_INTERNAL_FORMAT, (GLint*)&tex->format);

		GLint _cbits;
		glGetTexLevelParameteriv(target, 0, GL_TEXTURE_RED_SIZE, &_cbits); bits += _cbits;
		glGetTexLevelParameteriv(target, 0, GL_TEXTURE_GREEN_SIZE, &_cbits); bits += _cbits;
		glGetTexLevelParameteriv(target, 0, GL_TEXTURE_BLUE_SIZE, &_cbits); bits += _cbits;
		glGetTexLevelParameteriv(target, 0, GL_TEXTURE_ALPHA_SIZE, &_cbits); bits += _cbits;
		glGetTexLevelParameteriv(target, 0, GL_TEXTURE_DEPTH_SIZE, &_cbits); bits += _cbits;
	}

	if (configHandler->Get("AtiSwapRBFix",false)) {
		if (tex->format == GL_RGBA) {
			tex->format = GL_BGRA;
		} else if (tex->format == GL_RGB) {
			tex->format = GL_BGR;
		}
	}

	if(bits < 32) /*FIXME*/
		bits = 32;

	switch (target) {
		case GL_TEXTURE_3D:
			tex->pixels = new unsigned char[tex->xsize*tex->ysize*tex->zsize*(bits/8)];
			glGetTexImage(tex->target,0,/*FIXME*/GL_RGBA,/*FIXME*/GL_UNSIGNED_BYTE, tex->pixels);
			break;
		case GL_TEXTURE_1D:
			tex->pixels = new unsigned char[tex->xsize*(bits/8)];
			glGetTexImage(tex->target,0,/*FIXME*/GL_RGBA,/*FIXME*/GL_UNSIGNED_BYTE, tex->pixels);
			break;
		case GL_RENDERBUFFER_EXT:
			tex->pixels = new unsigned char[tex->xsize*tex->ysize*(bits/8)];
			glReadBuffer(attachment);
			glReadPixels(0, 0, tex->xsize, tex->ysize, /*FIXME*/GL_RGBA, /*FIXME*/GL_UNSIGNED_BYTE, tex->pixels);
			break;
		default: //GL_TEXTURE_2D & GL_TEXTURE_RECTANGLE
			tex->pixels = new unsigned char[tex->xsize*tex->ysize*(bits/8)];
			glGetTexImage(tex->target,0,/*FIXME*/GL_RGBA,/*FIXME*/GL_UNSIGNED_BYTE, tex->pixels);
	}
	texBuf[id] = tex;
}
Esempio n. 15
0
/**
 * Makes a copy of a texture/RBO in the system ram
 */
void FBO::DownloadAttachment(const GLenum attachment)
{
	GLuint target;
	GLenum format = GL_RGBA;
	glGetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER_EXT, attachment,
		GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT,
		(GLint*)&target);
	GLuint id;
	glGetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER_EXT, attachment,
		GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT,
		(GLint*)&id);

	if (target==GL_NONE || id==0)
		return;

	if (texBuf.find(id)!=texBuf.end())
		return;

	if (target==GL_TEXTURE) {
		target = GetTextureTargetByID(id);

		if (target<0)
			return;
	}

	struct FBO::TexData* tex = new FBO::TexData;
	tex->id = id;
	tex->target = target;

	int bits = 0;

	if (target==GL_RENDERBUFFER_EXT) {
		glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, id);
		glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_WIDTH_EXT,  &tex->xsize);
		glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_HEIGHT_EXT, &tex->ysize);
		glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_INTERNAL_FORMAT_EXT, (GLint*)&tex->format);

		GLint _cbits;
		glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_RED_SIZE_EXT, &_cbits); bits += _cbits;
		glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_GREEN_SIZE_EXT, &_cbits); bits += _cbits;
		glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_BLUE_SIZE_EXT, &_cbits); bits += _cbits;
		glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_ALPHA_SIZE_EXT, &_cbits); bits += _cbits;
		glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_DEPTH_SIZE_EXT, &_cbits); bits += _cbits;
		glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_STENCIL_SIZE_EXT, &_cbits); bits += _cbits;
	} else {
		glBindTexture(target,id);

		glGetTexLevelParameteriv(target, 0, GL_TEXTURE_WIDTH, &tex->xsize);
		glGetTexLevelParameteriv(target, 0, GL_TEXTURE_HEIGHT, &tex->ysize);
		glGetTexLevelParameteriv(target, 0, GL_TEXTURE_DEPTH, &tex->zsize);
		glGetTexLevelParameteriv(target, 0, GL_TEXTURE_INTERNAL_FORMAT, (GLint*)&tex->format);

		GLint _cbits;
		glGetTexLevelParameteriv(target, 0, GL_TEXTURE_RED_SIZE, &_cbits); bits += _cbits;
		glGetTexLevelParameteriv(target, 0, GL_TEXTURE_GREEN_SIZE, &_cbits); bits += _cbits;
		glGetTexLevelParameteriv(target, 0, GL_TEXTURE_BLUE_SIZE, &_cbits); bits += _cbits;
		glGetTexLevelParameteriv(target, 0, GL_TEXTURE_ALPHA_SIZE, &_cbits); bits += _cbits;
		glGetTexLevelParameteriv(target, 0, GL_TEXTURE_DEPTH_SIZE, &_cbits); bits += _cbits;
	}

	if (gu->atiHacks) { //FIXME use a seperate configvar? duno if linux's opensource drivers still have this bug
		format = GL_BGRA; //ATI bug: it swizzles the channels in glReadPixels & glGetTexImage
	}

	switch (target) {
		case GL_TEXTURE_3D:
			tex->pixels = new unsigned char[tex->xsize*tex->ysize*tex->zsize*(bits/8)];
			glGetTexImage(tex->target,0,format,/*FIXME*/GL_UNSIGNED_BYTE, tex->pixels);
			break;
		case GL_TEXTURE_1D:
			tex->pixels = new unsigned char[tex->xsize*(bits/8)];
			glGetTexImage(tex->target,0,format,/*FIXME*/GL_UNSIGNED_BYTE, tex->pixels);
			break;
		case GL_RENDERBUFFER_EXT:
			tex->pixels = new unsigned char[tex->xsize*tex->ysize*(bits/8)];
			glReadBuffer(attachment);
			glReadPixels(0, 0, tex->xsize, tex->ysize, format, /*FIXME*/GL_UNSIGNED_BYTE, tex->pixels);
			break;
		default: //GL_TEXTURE_2D & GL_TEXTURE_RECTANGLE
			tex->pixels = new unsigned char[tex->xsize*tex->ysize*(bits/8)];
			glGetTexImage(tex->target,0,format,/*FIXME*/GL_UNSIGNED_BYTE, tex->pixels);
	}
	texBuf[id] = tex;
}