/**
 * 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;
}
Example #2
0
/**
 * 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;
}