/** * 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(); }
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); }
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; }
/////////////////////////////////////////////////////////////////////////////// // 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(); }
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); }
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); }
/** * 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; }
/** * 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; }