/** * Initializes a framebuffer object, using the given width and height as * a guide. See OGLSD_InitTextureObject() and OGLSD_InitFBObject() * for more information. */ JNIEXPORT jboolean JNICALL Java_sun_java2d_opengl_OGLSurfaceData_initFBObject (JNIEnv *env, jobject oglsd, jlong pData, jboolean isOpaque, jboolean texNonPow2, jboolean texRect, jint width, jint height) { OGLSDOps *oglsdo = (OGLSDOps *)jlong_to_ptr(pData); GLuint fbobjectID, depthID; J2dTraceLn2(J2D_TRACE_INFO, "OGLSurfaceData_initFBObject: w=%d h=%d", width, height); if (oglsdo == NULL) { J2dRlsTraceLn(J2D_TRACE_ERROR, "OGLSurfaceData_initFBObject: ops are null"); return JNI_FALSE; } // initialize color texture object if (!OGLSD_InitTextureObject(oglsdo, isOpaque, texNonPow2, texRect, width, height)) { J2dRlsTraceLn(J2D_TRACE_ERROR, "OGLSurfaceData_initFBObject: could not init texture object"); return JNI_FALSE; } // initialize framebuffer object using color texture created above if (!OGLSD_InitFBObject(&fbobjectID, &depthID, oglsdo->textureID, oglsdo->textureTarget, oglsdo->textureWidth, oglsdo->textureHeight)) { J2dRlsTraceLn(J2D_TRACE_ERROR, "OGLSurfaceData_initFBObject: could not init fbobject"); j2d_glDeleteTextures(1, &oglsdo->textureID); return JNI_FALSE; } oglsdo->drawableType = OGLSD_FBOBJECT; // other fields (e.g. width, height) are set in OGLSD_InitTextureObject() oglsdo->fbobjectID = fbobjectID; oglsdo->depthID = depthID; OGLSD_SetNativeDimensions(env, oglsdo, oglsdo->textureWidth, oglsdo->textureHeight); // framebuffer objects differ from other OpenGL surfaces in that the // value passed to glRead/DrawBuffer() must be GL_COLOR_ATTACHMENTn_EXT, // rather than GL_FRONT (or GL_BACK) oglsdo->activeBuffer = GL_COLOR_ATTACHMENT0_EXT; return JNI_TRUE; }
/** * Returns JNI_TRUE only if all of the following conditions are met: * - the GL_EXT_framebuffer_object extension is available * - FBO support has been enabled via the system property * - we can successfully create an FBO with depth capabilities */ static jboolean OGLContext_IsFBObjectExtensionAvailable(JNIEnv *env, const char *extString) { jboolean isFBObjectEnabled = JNI_FALSE; GLuint fbobjectID, textureID, depthID; jint width = 1, height = 1; J2dTraceLn(J2D_TRACE_INFO, "OGLContext_IsFBObjectExtensionAvailable"); // first see if the fbobject extension is available if (!OGLContext_IsExtensionAvailable(extString, "GL_EXT_framebuffer_object")) { return JNI_FALSE; } // next see if the depth texture extension is available if (!OGLContext_IsExtensionAvailable(extString, "GL_ARB_depth_texture")) { return JNI_FALSE; } // next see if the fbobject system property has been enabled isFBObjectEnabled = JNU_GetStaticFieldByName(env, NULL, "sun/java2d/opengl/OGLSurfaceData", "isFBObjectEnabled", "Z").z; if (!isFBObjectEnabled) { J2dRlsTraceLn(J2D_TRACE_INFO, "OGLContext_IsFBObjectExtensionAvailable: disabled via flag"); return JNI_FALSE; } // finally, create a dummy fbobject with depth capabilities to see // if this configuration is supported by the drivers/hardware // (first we initialize a color texture object that will be used to // construct the dummy fbobject) j2d_glGenTextures(1, &textureID); j2d_glBindTexture(GL_TEXTURE_2D, textureID); j2d_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); j2d_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); j2d_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // initialize framebuffer object using color texture created above if (!OGLSD_InitFBObject(&fbobjectID, &depthID, textureID, GL_TEXTURE_2D, width, height)) { J2dRlsTraceLn(J2D_TRACE_INFO, "OGLContext_IsFBObjectExtensionAvailable: fbobject unsupported"); j2d_glDeleteTextures(1, &textureID); return JNI_FALSE; } // delete the temporary resources j2d_glDeleteTextures(1, &textureID); j2d_glDeleteRenderbuffersEXT(1, &depthID); j2d_glDeleteFramebuffersEXT(1, &fbobjectID); J2dRlsTraceLn(J2D_TRACE_INFO, "OGLContext_IsFBObjectExtensionAvailable: fbobject supported"); return JNI_TRUE; }