HI ! This is the first time I try porting my code to Linux and it is worth to say that LWJGL is a good lib. However, I'm not able to init the LWJGL screen with my AWTGLCanvas extension, which has worked on Windows and Mac.
I'm wondering if the Thread context handler is much eager on Linux. I think if my code is well designed, especially with the context switch. Could someone check upon this sample ? :
if ((mode & options.MODE_RENDER_GL.bit()) != 0) {
889 if (initGL) {/*getContext() == null) {*/
890 /** initGL context with a call to super.paint()*/
891 try {
892 SwingUtilities.invokeAndWait(new Runnable() {
893
894 public void run() {
895 try {
896 final CoalescedThreadsMonitor monitor0 = bufferSynch;
897 synchronized (monitor0.getMonitor()) {
898 if (buffering) {
899 System.err.println("RenderingScene screen task is waitin' for buffering...");
900 }
901 while (buffering) {
902 System.err.print(".");
903 monitor0.waitOnMonitor();
904 }
905 rendering = true;
906 Graphics g = getGraphics();
907 update(g);
908 g.dispose();
909 monitor0.notifyOnMonitor();
910 }
911 } catch (Exception e) {
912 e.printStackTrace(System.out);
913 } finally {
914 try {
915 releaseContext();
916 initGL = false;
917 final CoalescedThreadsMonitor monitor1 = vSynch;
918 synchronized (monitor1.getMonitor()) {
919 rendering = false;
920 monitor1.notifyAllOnMonitor();
921 }
922 System.out.println("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\screen flushed - " + System.currentTimeMillis());
923 } catch (LWJGLException ex) {
924 ex.printStackTrace();
925 }
926 }
927 }
928 });
929 } catch (Exception ex) {
930 ex.printStackTrace();
931 }
932 }
I've initialized the Canvas over Swing-EDT--initially with the AWTGLCanvas new instance creation--and yet the SwingEDT has just released the LWJGL Thread above. Now rendering is done on a dedicated Timer until the user stops it manually :
else {
933 try {
934 final CoalescedThreadsMonitor monitor0 = bufferSynch;
935 synchronized (monitor0.getMonitor()) {
936 if (buffering) {
937 System.err.println("RenderingScene screen task is waitin' for buffering...");
938 }
939 while (buffering) {
940 System.err.print(".");
941 monitor0.waitOnMonitor();
942 }
943 rendering = true;
944 paintGL();
945 swapBuffers();
946 markFPS();
947 monitor0.notifyOnMonitor();
948 }
949 } catch (Exception e) {
950 e.printStackTrace(System.out);
951 } finally {
952 try {
953 releaseContext();
954 initGL = false;
955 final CoalescedThreadsMonitor monitor1 = vSynch;
956 synchronized (monitor1.getMonitor()) {
957 rendering = false;
958 monitor1.notifyAllOnMonitor();
959 }
960 System.out.println("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\screen flushed - " + System.currentTimeMillis());
961 } catch (LWJGLException ex) {
962 ex.printStackTrace();
963 }
964 }
965 }
966 }
This is all part of one TimerTask run() method.
Issue is with Linux, where I received a XLib : async error and the jvm crashes , which turns out to be a Thread context error. Think about that the LWJGL demos run well (except for the openAL ALC sound)... ::)
full source code of these samples is here : sf.net/projects/sf3 Rendering Scene source (http://sf3jswing.cvs.sourceforge.net/viewvc/sf3jswing/JIGAXtendedAPI/src/net/library/jiga/sf3/game/RenderingScene.java?view=markup)
I found out how to correct my code. I'll post the solution further... :D thanks to you who read my posts !
SO to correct the bug above, it's quite simple : we use SwingEDT to render and a Timer to send an update event as if you were rendering softly.
/** within any external Timer/Thread loop */
try {
SwingUtilities.invokeAndWait(LWJGLrender);
} catch (Exception ex) {
ex.printStackTrace();
} finally {
System.out.println("XXXX GL CONTEXT SHOULD BE INITIED XXXX");
}
the LWJGLrender Swing Runnable looks like the Swing soft update call, adding releaseContext() in the case you want to render else where too (which is thoroughly NOT recommended) :
public void run() {
try {
final CoalescedThreadsMonitor monitor0 = bufferSynch;
synchronized (monitor0.getMonitor()) {
if (buffering) {
System.err.println("RenderingScene screen task is waitin' for buffering...");
}
while (buffering) {
System.err.print(".");
monitor0.waitOnMonitor();
}
rendering = true;
Graphics g = getGraphics();
update(g);
g.dispose();
monitor0.notifyOnMonitor();
}
} catch (Exception e) {
e.printStackTrace(System.out);
} finally {
try {
releaseContext();
final CoalescedThreadsMonitor monitor1 = vSynch;
synchronized (monitor1.getMonitor()) {
rendering = false;
monitor1.notifyAllOnMonitor();
}
System.out.println("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\screen flushed - " + System.currentTimeMillis());
} catch (LWJGLException ex) {
ex.printStackTrace();
}
}
}
the most IMPORTANT is paintGL() which HAS TO INCLUDE SWAPBUFFERS() :
protected void paintGL() {
try {
if ((mode & options.MODE_RENDER_GL.bit()) == 0) {
return;
}
makeCurrent(); // not used
super.paintGL();
/*GLContext.useContext(getContext());*/
_GL_reshape(this);
/* clear screen*/
GL11.glClear(GL11.GL_DEPTH_BUFFER_BIT | GL11.GL_COLOR_BUFFER_BIT | GL11.GL_STENCIL_BUFFER_BIT);
// RENDERING IS DONE HERE
GL11.glFlush();
swapBuffers();
markFPS();
} catch (Exception ex) {
ex.printStackTrace();
}
}
Think about that this uses the AWTGLCanvas and not Display !!! ;D
thanks for posting your solution