Using the information provided by Ken Russell, I came up with a hack that does not require a recompile of JOGL. It fixes the rendering problem with the TextureRender on the Mac temporarily until Apple releases their fix. If the code is run on Windows it does nothing since the problem is only on Mac.
NOTE: It is definitely a hack and allows you to access private functions within the TextRenderer. This violates encapsulation but since it is only temporary and I think a lot of people may not want to set up everything to recompile JOGL, here it is…
Create the following class in your classpath.
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import com.sun.opengl.util.j2d.TextRenderer;
import com.sun.opengl.util.j2d.TextureRenderer;
/**
* Call TextRenderHack to fix the TextRender problem on the Mac This class should only be used until
* Apple puts out their fix.
*
* @author Jeff Addison - Southgate Software Ltd. www.southgatesoftware.com
*/
public class TextRenderHack
{
/**
* Call this function in your drawing code to fix the TextRender rendering problem on the Mac
*
* @param tr Text Renderer to fix
*/
public static void fixIt(TextRenderer tr)
{
// Get the OS Name
String osName = System.getProperty("os.name");
// Only fix it if it's broke :)
if (osName != null && osName.toLowerCase().contains("mac"))
{
// Call the TextRenderer's private function getBackingStore to get the backingStore
TextureRenderer backingStore = (TextureRenderer) invokePrivateMethod(tr, "getBackingStore",
null);
// If we have a valid backing store, mark the entire thing dirty.
if (backingStore != null)
{
backingStore.markDirty(0, 0, backingStore.getWidth(), backingStore.getHeight());
}
}
}
/**
* Invokes a private method on and Object.
*
* @param o Object to call private method on
* @param methodName Name of the method to call
* @param params Array of parameters to be passed to the function
* @return Object that the method called normally returns (Cast to proper type) NOTE: This function
* was found on the Internet. Lost the link so we are unable to give the author the proper
* credit.
*/
public static Object invokePrivateMethod(Object o, String methodName, Object[] params)
{
// Go and find the private method...
final Method methods[] = o.getClass().getDeclaredMethods();
for (int i = 0; i < methods.length; ++i)
{
if (methodName.equals(methods[i].getName()))
{
try
{
methods[i].setAccessible(true);
return methods[i].invoke(o, params);
}
catch (IllegalAccessException ex)
{
System.out.println("IllegalAccessException accessing " + methodName);
}
catch (InvocationTargetException ite)
{
System.out.println("InvocationTargetException accessing " + methodName);
}
}
}
return null;
}
}
Then, use the following snippet in your drawing code wherever you use a TextRender:
TextRenderHack.fixIt( myTextRender );
I call this just before calling myTextRender.beginRendering(…); Not sure if this is the best place to call it or not, but it works.
myTextRender is the TextRender instance that you want to fix.
Hope this helps someone.
Cheers,
Jeff Addison