aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xCNativeCode/GLDrawableFactory_Win32_SunJDK13.c-jau62
-rwxr-xr-xdemos/MiscDemos/TestListener.java748
-rw-r--r--demos/gltestperf.java871
-rw-r--r--demos/natives/x11/gltestperf.c580
-rw-r--r--demos/natives/x11/xfont.c195
-rwxr-xr-xdemos/natives/x11/xfont.sh9
-rwxr-xr-xgl4java/GLCapabilities.java313
-rw-r--r--gl4java/drawable/DummyGLDrawableFactory.java39
-rw-r--r--gl4java/drawable/GLDrawable.java73
-rw-r--r--gl4java/drawable/GLDrawableFactory.java222
-rw-r--r--gl4java/drawable/GLEventListener.java102
-rw-r--r--gl4java/drawable/MacSunJDK13GLDrawableFactory.java23
-rwxr-xr-xgl4java/drawable/SunJDK13GLDrawableFactory.java74
-rw-r--r--gl4java/drawable/Win32SunJDK13GLDrawableFactory.java327
-rw-r--r--gl4java/drawable/Win32SunJDK13GLDrawableFactory.java-jau47
-rw-r--r--gl4java/drawable/X11SunJDK13GLDrawableFactory.java45
-rw-r--r--gl4java/drawable/utils/GLEventListenerList.java89
17 files changed, 3819 insertions, 0 deletions
diff --git a/CNativeCode/GLDrawableFactory_Win32_SunJDK13.c-jau b/CNativeCode/GLDrawableFactory_Win32_SunJDK13.c-jau
new file mode 100755
index 0000000..72a12ee
--- /dev/null
+++ b/CNativeCode/GLDrawableFactory_Win32_SunJDK13.c-jau
@@ -0,0 +1,62 @@
+#include "gl4java_drawable_Win32SunJDK13GLDrawableFactory.h"
+#include "OpenGL_Win32_common.h"
+
+/* FIXME: extend to support multiple monitors on Win2K/98 */
+static HDC getScreenDC(int screen)
+{
+ return CreateDC("DISPLAY", NULL, NULL, NULL);
+}
+
+static void freeScreenDC(HDC dc)
+{
+ DeleteDC(dc);
+}
+
+
+JNIEXPORT jlong JNICALL Java_gl4java_drawable_Win32SunJDK13GLDrawableFactory_ChoosePixelFormatNum
+ (JNIEnv *env, jclass unused, jint screen, jobject capsObj, jboolean verbose)
+{
+ HDC dc;
+ PIXELFORMATDESCRIPTOR pfd;
+ jboolean ok;
+ GLCapabilities glCaps;
+ int nPixelFormat;
+
+ ok = javaGLCapabilities2NativeGLCapabilities ( env, capsObj, &glCaps );
+ if(JNI_TRUE!=ok)
+ {
+ fprintf(stderr,"GL4Java Win32DrawableFactory.ChoosePixelFormatNum ERROR: gl4java/GLCapabilities fields not accessible\n");
+ fflush(stderr);
+ return JNI_FALSE;
+ }
+
+ /* dc = getScreenDC(screen); */
+ dc = GetWindowDC(NULL);
+
+ setPixelFormatByGLCapabilities(&pfd, &glCaps, JNI_FALSE, dc);
+
+ if(JNI_TRUE==verbose)
+ {
+ fprintf(stdout, "Win32DrawableFactory.ChoosePixelFormatNum: input capabilities:\n");
+ printGLCapabilities ( &glCaps );
+ }
+
+ nPixelFormat = ChoosePixelFormat(dc, &pfd);
+
+ (void) setGLCapabilities ( dc, nPixelFormat, &glCaps );
+
+ if(JNI_TRUE==verbose)
+ {
+ fprintf(stdout,"Win32DrawableFactory.ChoosePixelFormatNum: writing capabilities to GLContext's java object\n");
+ printGLCapabilities ( &glCaps );
+ fflush(stdout);
+ }
+
+ (void) nativeGLCapabilities2JavaGLCapabilities
+ (env, capsObj, &glCaps);
+
+ /* freeScreenDC(dc); */
+ ReleaseDC(NULL, dc);
+ return (jlong)nPixelFormat;
+}
+
diff --git a/demos/MiscDemos/TestListener.java b/demos/MiscDemos/TestListener.java
new file mode 100755
index 0000000..6fbb361
--- /dev/null
+++ b/demos/MiscDemos/TestListener.java
@@ -0,0 +1,748 @@
+import java.awt.*;
+import gl4java.*;
+import gl4java.awt.*;
+import gl4java.drawable.*;
+
+/** Tests the GLComponentFactory/GLEventListener mechanism via a port
+ of the OpenGL logo applet. */
+
+public class TestListener implements GLEventListener, GLEnum {
+
+ GLFunc gl;
+ GLUFunc glu;
+
+ static final int RAND_MAX = 100;
+
+ /* some math.h's don't define M_PI */
+ static final float M_PI = 3.14159265359f;
+
+ static final int ACC = 8;
+ static final int ACC2 = 16;
+ static final int ACC3 = 48;
+ static final int ACC4 = 24;
+ static final float THLD = 0.6f;
+ static final float THLD2 = 0.8f;
+
+ int angle, rotating;
+
+ float TRANS[][];
+ float ROTAXIS[][];
+ float ROT[];
+
+ float char_El[][][];
+ float normal_El[][][];
+
+ float char_O[][][];
+ float normal_O[][][];
+
+ float char_P[][][];
+ float normal_P[][][];
+
+ float char_G[][][];
+ float normal_G[][][];
+
+ float accSIN[], accCOS[];
+
+ float difmat4[] = { 0.425f, 0.570f, 0.664f, 1.0f };
+ float difamb4[] = { 0.425f, 0.570f, 0.664f, 1.0f };
+ float matspec4[] = { 0.174f, 0.174f, 0.174f, 1.0f };
+
+ float lightpos[] = { 1.0f, 1.0f, 1.0f, 0.0f };
+ float lightamb[] = { 0.3f, 0.3f, 0.3f, 1.0f };
+ float lightdif[] = { 0.8f, 0.8f, 0.8f, 1.0f };
+ float speed=0f, progress = 1f;
+
+ public void init(GLDrawable drawable) {
+ gl = drawable.getGL();
+ glu = drawable.getGLU();
+
+ /* here we should add and initialize our JAVA components */
+ TRANS = new float[7][3];
+ ROTAXIS = new float[7][3];
+ ROT = new float[7];
+
+ char_El=new float[ACC3+1][ACC+1][3];
+ normal_El=new float[ACC3+1][ACC+1][3];
+
+ char_O=new float[ACC4][ACC+1][3];
+ normal_O=new float[ACC4][ACC+1][3];
+
+ char_P=new float[ACC2][ACC+1][3];
+ normal_P=new float[ACC2][ACC+1][3];
+
+ char_G=new float[ACC4][ACC+1][3];
+ normal_G=new float[ACC4][ACC+1][3];
+
+ accSIN=new float[ACC+1];
+ accCOS=new float[ACC+1];
+
+ randomize();
+
+ gl.glShadeModel (GL_SMOOTH);
+ gl.glEnable(GL_DEPTH_TEST);
+ gl.glLightfv(GL_LIGHT0, GL_POSITION, lightpos);
+ gl.glLightfv(GL_LIGHT0, GL_AMBIENT, lightamb);
+ gl.glLightfv(GL_LIGHT0, GL_DIFFUSE, lightdif);
+ gl.glEnable(GL_LIGHTING);
+ gl.glEnable(GL_LIGHT0);
+ gl.glColor3f(1.0f, 1.0f, 1.0f);
+ gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
+ gl.glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ gl.glEnable(GL_NORMALIZE);
+ def_logo();
+ gl.glCullFace(GL_BACK);
+ gl.glEnable(GL_CULL_FACE);
+ }
+
+ public void preDisplay(GLDrawable drawable)
+ { }
+
+ public void display(GLDrawable drawable) {
+ int i;
+
+ // just render it
+ gl.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ setCamera();
+ draw_logo();
+ }
+
+ public void postDisplay(GLDrawable drawable)
+ {
+ //
+ // computation for an animation sequence ...
+ //
+ speed = -0.95f*speed + progress*0.05f;
+ if (progress > 0.0f && speed < 0.0003f)
+ speed = 0.0003f;
+ if (speed > 0.01f)
+ speed = 0.01f;
+ progress = progress - speed;
+ }
+
+ public void reshape(GLDrawable drawable, int width, int height) {
+ gl.glMatrixMode (GL_MODELVIEW);
+ gl.glViewport (0, 0, width, height);
+ gl.glLoadIdentity();
+ setCamera();
+ }
+
+ public void cleanup(GLDrawable drawable)
+ { }
+
+ void setCamera() {
+ gl.glMatrixMode (GL_PROJECTION);
+ gl.glLoadIdentity ();
+ gl.glFrustum (-0.1333f, 0.1333f, -0.1f, 0.1f, 0.2f, 150.0f);
+ gl.glMatrixMode(GL_MODELVIEW);
+ gl.glLoadIdentity();
+ glu.gluLookAt(0,1.5f,2, 0,1.5f,0, 0,1,0);
+ gl.glTranslatef(0.0f, -8.0f, -45.0f);
+ gl.glRotatef(-progress*720f, 0.0f, 1.0f, 0.0f);
+ }
+
+ int rnd(int i) {
+ return ( (int)((float)Math.random()*RAND_MAX) )%i;
+ }
+
+ void groen_texture() {
+ gl.glMaterialfv(GL_FRONT, GL_DIFFUSE, difmat4);
+ gl.glMaterialfv(GL_FRONT, GL_AMBIENT, difamb4);
+ gl.glMaterialfv(GL_FRONT, GL_SPECULAR, matspec4);
+ gl.glMaterialf(GL_FRONT, GL_SHININESS, 35.0f);
+ }
+
+ void def_O() {
+ float a, s, c, ln;
+ int i,j,k,l,m,n;
+ float dx, dy;
+ float dx1, dx2, dy1, dy2, dz1, dz2;
+ float center_O[][];
+ float width_O[];
+
+ center_O=new float[ACC4+4][3];
+ width_O=new float[ACC4+4];
+
+ for (i=0;i<ACC4;i++)
+ {
+ a = 2.0f*((float) i)*M_PI/ACC4;
+ s = 1+(float)Math.sin(a);
+ c = (float)Math.cos(a);
+ center_O[i][0] = c*3.8f;
+ center_O[i][1] = s*3.8f+(s<-1.01f?-0.8f:(s>1.01f?0.8f:0)) + 0.8f;
+ center_O[i][2] = 0.0f;
+ width_O[i] = 0.6f;
+ }
+
+ /* I should be able to generalise this. oh well */
+ for (i=0;i<ACC4;i++)
+ {
+ j = (i+1)%ACC4;
+ k = (i+ACC4-1)%ACC4;
+ for (a=0;a<ACC;a++)
+ {
+ c = (float)Math.cos(a*M_PI*2.0f/ACC);
+ s = (float)Math.sin(a*M_PI*2.0f/ACC);
+ dx = center_O[j][0] - center_O[k][0];
+ dy = center_O[j][1] - center_O[k][1];
+ ln = (float)Math.sqrt(dx*dx+dy*dy);
+ dx = dx/ln;
+ dy = dy/ln;
+ char_O[i][(int) a][0] = center_O[i][0] + width_O[i] * dy * c;
+ char_O[i][(int) a][1] = center_O[i][1] - width_O[i] * dx * c;
+ char_O[i][(int) a][2] = (s<-THLD?-THLD:(s>THLD?THLD:s));
+ }
+ }
+ for (i=0;i<ACC;i++)
+ {
+ j = (i+1)%ACC;
+ k = (i-1+ACC)%ACC;
+ for (l=0;l<ACC4;l++)
+ {
+ m = (l+1)%ACC4;
+ n = (l+ACC4-1)%ACC4;
+ dx1 = char_O[m][i][0] - char_O[n][i][0];
+ dy1 = char_O[m][i][1] - char_O[n][i][1];
+ dz1 = char_O[m][i][2] - char_O[n][i][2];
+ dx2 = char_O[l][k][0] - char_O[l][j][0];
+ dy2 = char_O[l][k][1] - char_O[l][j][1];
+ dz2 = char_O[l][k][2] - char_O[l][j][2];
+ normal_O[l][i][0] = dy2*dz1 - dy1*dz2;
+ normal_O[l][i][1] = dz2*dx1 - dz1*dx2;
+ normal_O[l][i][2] = dx2*dy1 - dx1*dy2;
+ }
+ }
+ }
+
+ void def_P() {
+ float a, s, c, ln;
+ int i,j,k,l,m,n;
+ float dx, dy;
+ float dx1, dx2, dy1, dy2, dz1, dz2;
+ float center_P[][];
+ float width_P[];
+
+ center_P=new float[ACC2][3];
+ width_P=new float[ACC2];
+
+
+ for (i=0;i<ACC2;i++)
+ {
+ a = 2.0f*((float) i)*M_PI/ACC2;
+ s = 1+(float)Math.sin(a);
+ c = (float)Math.cos(a);
+ center_P[i][0] = c*2.15f;
+ center_P[i][1] = s*2.1f + (s<-1.01f?-0.7f:(s>1.01f?0.7f:0)) + 0.7f;
+ center_P[i][2] = 0.0f;
+ width_P[i] = 0.5f;
+ }
+
+ for (i=0;i<ACC2;i++)
+ {
+ j = (i+1)%ACC2;
+ k = (i+ACC2-1)%ACC2;
+ for (a=0;a<ACC;a++)
+ {
+ accCOS[(int) a] = c = (float)Math.cos(a*M_PI*2.0f/ACC);
+ accSIN[(int) a] = s = (float)Math.sin(a*M_PI*2.0f/ACC);
+ dx = center_P[j][0] - center_P[k][0];
+ dy = center_P[j][1] - center_P[k][1];
+ ln = (float)Math.sqrt(dx*dx+dy*dy);
+ dx = dx/ln;
+ dy = dy/ln;
+ char_P[i][(int) a][0] = center_P[i][0] + width_P[i] * dy * c;
+ char_P[i][(int) a][1] = center_P[i][1] - width_P[i] * dx * c;
+ char_P[i][(int) a][2] = (s<-THLD?-THLD:(s>THLD?THLD:s));
+ }
+ }
+ for (i=0;i<ACC;i++)
+ {
+ j = (i+1)%ACC;
+ k = (i-1+ACC)%ACC;
+ for (l=0;l<ACC2;l++)
+ {
+ m = (l+1)%ACC2;
+ n = (l+ACC2-1)%ACC2;
+ dx1 = char_P[m][i][0] - char_P[n][i][0];
+ dy1 = char_P[m][i][1] - char_P[n][i][1];
+ dz1 = char_P[m][i][2] - char_P[n][i][2];
+ dx2 = char_P[l][k][0] - char_P[l][j][0];
+ dy2 = char_P[l][k][1] - char_P[l][j][1];
+ dz2 = char_P[l][k][2] - char_P[l][j][2];
+ normal_P[l][i][0] = dy2*dz1 - dy1*dz2;
+ normal_P[l][i][1] = dz2*dx1 - dz1*dx2;
+ normal_P[l][i][2] = dx2*dy1 - dx1*dy2;
+ }
+ }
+ }
+
+ void def_El() {
+ float a, s, c, ln;
+ int i,j,k,l,m,n;
+ float dx, dy;
+ float dx1, dx2, dy1, dy2, dz1, dz2;
+ float center_El[][];
+ float width_El[];
+
+ center_El=new float[ACC3+3][3];
+ width_El=new float[ACC3+3];
+
+ for (i=0;i<ACC3+1;i++)
+ {
+ /* a = (ACC3/24 + i*11/12)*M_PI*2.0f/ACC3; */
+ a = (ACC3/8 + ((float) i)*3/4)*M_PI*2.0f/ACC3;
+ s = 1+(float)Math.sin(a);
+ c = (float)Math.cos(a);
+ center_El[i][0] = c*18.0f;
+ center_El[i][1] = s*9.3f;
+ center_El[i][2] = 0.0f;
+ width_El[i] = (float)Math.pow(3.5, Math.sin(i*M_PI/ACC3))-0.6f;
+ }
+
+ for (i=0;i<ACC3+1;i++)
+ {
+ j = (i+1)%ACC3;
+ k = (i+ACC3-1)%ACC3;
+ for (a=0;a<ACC;a++)
+ {
+ c = (float)Math.cos(a*M_PI*2.0f/ACC);
+ s = (float)Math.sin(a*M_PI*2.0f/ACC);
+ dx = center_El[j][0] - center_El[k][0];
+ dy = center_El[j][1] - center_El[k][1];
+ ln = (float)Math.sqrt(dx*dx+dy*dy);
+ dx = dx/ln;
+ dy = dy/ln;
+ char_El[i][(int) a][0] = center_El[i][0] + width_El[i] * dy * c;
+ char_El[i][(int) a][1] = center_El[i][1] - width_El[i] * dx * c;
+ char_El[i][(int) a][2] = (s<-THLD2?-THLD2:(s>THLD2?THLD2:s));
+ }
+ }
+ for (i=0;i<ACC+1;i++)
+ {
+ j = (i+1)%ACC;
+ k = (i-1+ACC)%ACC;
+ for (l=0;l<ACC3;l++)
+ {
+ m = (l+1)%ACC3;
+ n = (l+ACC3-1)%ACC3;
+ dx1 = char_El[m][i][0] - char_El[n][i][0];
+ dy1 = char_El[m][i][1] - char_El[n][i][1];
+ dz1 = char_El[m][i][2] - char_El[n][i][2];
+ dx2 = char_El[l][k][0] - char_El[l][j][0];
+ dy2 = char_El[l][k][1] - char_El[l][j][1];
+ dz2 = char_El[l][k][2] - char_El[l][j][2];
+ normal_El[l][i][0] = dy2*dz1 - dy1*dz2;
+ normal_El[l][i][1] = dz2*dx1 - dz1*dx2;
+ normal_El[l][i][2] = dx2*dy1 - dx1*dy2;
+ }
+ }
+ }
+
+ void def_G() {
+ float a, s, c, ln;
+ int i,j,k,l,m,n;
+ float dx, dy;
+ float dx1, dx2, dy1, dy2, dz1, dz2;
+ float center_G[][];
+ float width_G[];
+
+ center_G=new float[ACC4][3];
+ width_G=new float[ACC4];
+
+ for (i=0;i<ACC4;i++)
+ {
+ a = 2.0f*((float) i)*M_PI/ACC4;
+ s = 1+(float)Math.sin(a);
+ c = (float)Math.cos(a);
+ center_G[i][0] = c*3.8f;
+ center_G[i][1] = s*3.8f+(s<-1.01f?-0.8f:(s>1.01f?0.8f:0)) + 0.8f;
+ center_G[i][2] = 0.0f;
+ width_G[i] = 0.9f;
+ if (i>ACC4*3/4)
+ width_G[i] = 0.9f - ((i-ACC4*3/4)*0.9f)/ACC;
+ }
+ for (i=0;i<ACC4;i++)
+ {
+ j = (i+1)%ACC4;
+ k = (i+ACC4-1)%ACC4;
+ for (a=0;a<ACC;a++)
+ {
+ c = (float)Math.cos(a*M_PI*2.0f/ACC);
+ s = (float)Math.sin(a*M_PI*2.0f/ACC);
+ dx = center_G[j][0] - center_G[k][0];
+ dy = center_G[j][1] - center_G[k][1];
+ ln = (float)Math.sqrt(dx*dx+dy*dy);
+ dx = dx/ln;
+ dy = dy/ln;
+ char_G[i][(int) a][0] = center_G[i][0] + width_G[i] * dy * c;
+ char_G[i][(int) a][1] = center_G[i][1] - width_G[i] * dx * c;
+ char_G[i][(int) a][2] = (s<-THLD?-THLD:(s>THLD?THLD:s));
+ }
+ }
+ for (i=0;i<ACC;i++)
+ {
+ j = (i+1)%ACC;
+ k = (i-1+ACC)%ACC;
+ for (l=0;l<ACC4;l++)
+ {
+ m = (l+1)%ACC4;
+ n = (l+ACC4-1)%ACC4;
+ dx1 = char_G[m][i][0] - char_G[n][i][0];
+ dy1 = char_G[m][i][1] - char_G[n][i][1];
+ dz1 = char_G[m][i][2] - char_G[n][i][2];
+ dx2 = char_G[l][k][0] - char_G[l][j][0];
+ dy2 = char_G[l][k][1] - char_G[l][j][1];
+ dz2 = char_G[l][k][2] - char_G[l][j][2];
+ normal_G[l][i][0] = dy2*dz1 - dy1*dz2;
+ normal_G[l][i][1] = dz2*dx1 - dz1*dx2;
+ normal_G[l][i][2] = dx2*dy1 - dx1*dy2;
+ }
+ }
+ }
+
+ void randomize() {
+ int i;
+ for (i=0;i<7;i++)
+ {
+ TRANS[i][0] = rnd(100)-rnd(100);
+ TRANS[i][1] = rnd(100)-rnd(100);
+ TRANS[i][1] = rnd(100)-rnd(100);
+ ROTAXIS[i][0] = rnd(100)-rnd(100);
+ ROTAXIS[i][1] = rnd(100)-rnd(100);
+ ROTAXIS[i][1] = rnd(100)-rnd(100);
+ ROT[i]=rnd(3600)-rnd(3600);
+ }
+ }
+
+ void def_logo() {
+ def_O();
+ def_P();
+ def_El();
+ def_G();
+ }
+
+ void draw_O() {
+ int i,j,k;
+ for (i=0;i<ACC;i++)
+ {
+ k = i+1;
+ if (k>=ACC)
+ k = 0;
+ gl.glBegin(GL_QUAD_STRIP);
+ for (j=0;j<ACC4;j++)
+ {
+ gl.glNormal3f(normal_O[j][k][0], normal_O[j][k][1], normal_O[j][k][2]);
+ gl.glVertex3f(char_O[j][k][0], char_O[j][k][1], char_O[j][k][2]);
+ gl.glNormal3f(normal_O[j][i][0], normal_O[j][i][1], normal_O[j][i][2]);
+ gl.glVertex3f(char_O[j][i][0], char_O[j][i][1], char_O[j][i][2]);
+ }
+ gl.glNormal3f(normal_O[0][k][0], normal_O[0][k][1], normal_O[0][k][2]);
+ gl.glVertex3f(char_O[0][k][0], char_O[0][k][1], char_O[0][k][2]);
+ gl.glNormal3f(normal_O[0][i][0], normal_O[0][i][1], normal_O[0][i][2]);
+ gl.glVertex3f(char_O[0][i][0], char_O[0][i][1], char_O[0][i][2]);
+ gl.glEnd();
+ }
+ }
+
+ void draw_P() {
+ int i,j,k;
+ for (i=0;i<ACC;i++)
+ {
+ k = i+1;
+ if (k>=ACC)
+ k = 0;
+ gl.glBegin(GL_QUAD_STRIP);
+ for (j=0;j<ACC2;j++)
+ {
+ gl.glNormal3f(normal_P[j][k][0], normal_P[j][k][1], normal_P[j][k][2]);
+ gl.glVertex3f(char_P[j][k][0], char_P[j][k][1], char_P[j][k][2]);
+ gl.glNormal3f(normal_P[j][i][0], normal_P[j][i][1], normal_P[j][i][2]);
+ gl.glVertex3f(char_P[j][i][0], char_P[j][i][1], char_P[j][i][2]);
+ }
+ gl.glNormal3f(normal_P[0][k][0], normal_P[0][k][1], normal_P[0][k][2]);
+ gl.glVertex3f(char_P[0][k][0], char_P[0][k][1], char_P[0][k][2]);
+ gl.glNormal3f(normal_P[0][i][0], normal_P[0][i][1], normal_P[0][i][2]);
+ gl.glVertex3f(char_P[0][i][0], char_P[0][i][1], char_P[0][i][2]);
+ gl.glEnd();
+ }
+ j = 0;
+ gl.glBegin(GL_QUAD_STRIP);
+ for (i=0;i<ACC;i++)
+ {
+ gl.glNormal3f(normal_P[0][i][0], normal_P[0][i][1], normal_P[0][i][2]);
+ gl.glVertex3f(char_P[0][i][0]-4.3f, -1.6f, 1.0f*char_P[0][i][2]);
+ gl.glVertex3f(char_P[0][i][0]-4.3f, 6.0f, 1.0f*char_P[0][i][2]);
+ }
+ gl.glNormal3f(normal_P[0][0][0], normal_P[0][0][1], normal_P[0][0][2]);
+ gl.glVertex3f(char_P[0][0][0]-4.3f, -1.6f, 1.0f*char_P[0][0][2]);
+ gl.glVertex3f(char_P[0][0][0]-4.3f, 6.0f, 1.0f*char_P[0][0][2]);
+ gl.glEnd();
+ }
+
+ void draw_E() {
+ int i,j,k;
+ for (i=0;i<ACC;i++)
+ {
+ k = i+1;
+ if (k>=ACC)
+ k = 0;
+ gl.glBegin(GL_QUAD_STRIP);
+ gl.glNormal3f(normal_P[0][k][0], normal_P[0][k][1], normal_P[0][k][2]);
+ gl.glVertex3f(char_P[0][k][0], char_P[0][k][1]+0.0f, char_P[0][k][2]);
+ gl.glNormal3f(normal_P[0][i][0], normal_P[0][i][1], normal_P[0][i][2]);
+ gl.glVertex3f(char_P[0][i][0], char_P[0][i][1]+0.0f, char_P[0][i][2]);
+ for (j=1;j<ACC2;j++)
+ {
+ gl.glNormal3f(normal_P[j][k][0], normal_P[j][k][1], normal_P[j][k][2]);
+ gl.glVertex3f(char_P[j][k][0], char_P[j][k][1], char_P[j][k][2]);
+ gl.glNormal3f(normal_P[j][i][0], normal_P[j][i][1], normal_P[j][i][2]);
+ gl.glVertex3f(char_P[j][i][0], char_P[j][i][1], char_P[j][i][2]);
+ }
+ gl.glNormal3f(normal_P[0][k][0], normal_P[0][k][1], normal_P[0][k][2]);
+ gl.glVertex3f(char_P[0][k][0], char_P[0][k][1]-0.4f, char_P[0][k][2]);
+ gl.glNormal3f(normal_P[0][i][0], normal_P[0][i][1], normal_P[0][i][2]);
+ gl.glVertex3f(char_P[0][i][0], char_P[0][i][1]-0.4f, char_P[0][i][2]);
+ gl.glEnd();
+ }
+
+ gl.glBegin(GL_QUAD_STRIP);
+ j = ACC2*3/4;
+ for (i=0;i<ACC;i++)
+ {
+ gl.glNormal3f(normal_P[j][i][0], normal_P[j][i][1], normal_P[j][i][2]);
+ gl.glVertex3f(-2.0f, char_P[j][i][1]+2.55f, 1.0f*char_P[j][i][2]);
+ gl.glVertex3f(2.0f, char_P[j][i][1]+2.55f, 1.0f*char_P[j][i][2]);
+ }
+ gl.glNormal3f(normal_P[j][0][0], normal_P[j][0][1], normal_P[j][0][2]);
+ gl.glVertex3f(-2.0f, char_P[j][0][1]+2.55f, 1.0f*char_P[j][0][2]);
+ gl.glVertex3f(2.0f, char_P[j][0][1]+2.55f, 1.0f*char_P[j][0][2]);
+ gl.glEnd();
+ }
+
+ void draw_El() {
+ int i,j,k;
+ for (i=0;i<ACC;i++)
+ {
+ k = i+1;
+ if (k>=ACC)
+ k = 0;
+ gl.glBegin(GL_QUAD_STRIP);
+ for (j=0;j<=ACC3;j++)
+ {
+ gl.glNormal3f(normal_El[j][k][0], normal_El[j][k][1], normal_El[j][k][2]);
+ gl.glVertex3f(char_El[j][k][0], char_El[j][k][1], char_El[j][k][2]);
+ gl.glNormal3f(normal_El[j][i][0], normal_El[j][i][1], normal_El[j][i][2]);
+ gl.glVertex3f(char_El[j][i][0], char_El[j][i][1], char_El[j][i][2]);
+ }
+ gl.glEnd();
+ }
+ }
+
+ void draw_N() {
+ int i,j,k;
+ for (i=0;i<ACC;i++)
+ {
+ k = i+1;
+ if (k>=ACC)
+ k = 0;
+ gl.glBegin(GL_QUAD_STRIP);
+ for (j=0;j<=ACC2/2;j++)
+ {
+ gl.glNormal3f(normal_P[j][k][0], normal_P[j][k][1], normal_P[j][k][2]);
+ gl.glVertex3f(char_P[j][k][0], char_P[j][k][1], char_P[j][k][2]);
+ gl.glNormal3f(normal_P[j][i][0], normal_P[j][i][1], normal_P[j][i][2]);
+ gl.glVertex3f(char_P[j][i][0], char_P[j][i][1], char_P[j][i][2]);
+ }
+ gl.glEnd();
+ }
+
+ j = 0;
+ gl.glBegin(GL_QUAD_STRIP);
+ for (i=0;i<ACC;i++)
+ {
+ gl.glNormal3f(normal_P[0][i][0], normal_P[0][i][1], normal_P[0][i][2]);
+ gl.glVertex3f(char_P[0][i][0]-4.3f, 0.2f, 1.0f*char_P[0][i][2]);
+ gl.glVertex3f(char_P[0][i][0]-4.3f, 6.0f, 1.0f*char_P[0][i][2]);
+ }
+ gl.glNormal3f(normal_P[0][0][0], normal_P[0][0][1], normal_P[0][0][2]);
+ gl.glVertex3f(char_P[0][0][0]-4.3f, 0.2f, 1.0f*char_P[0][0][2]);
+ gl.glVertex3f(char_P[0][0][0]-4.3f, 6.0f, 1.0f*char_P[0][0][2]);
+ gl.glEnd();
+ j = 0;
+
+ gl.glBegin(GL_QUAD_STRIP);
+ for (i=0;i<ACC;i++)
+ {
+ gl.glNormal3f(normal_P[0][i][0], normal_P[0][i][1], normal_P[0][i][2]);
+ gl.glVertex3f(char_P[0][i][0], 0.2f, 1.0f*char_P[0][i][2]);
+ gl.glVertex3f(char_P[0][i][0], 3.4f, 1.0f*char_P[0][i][2]);
+ }
+ gl.glNormal3f(normal_P[0][0][0], normal_P[0][0][1], normal_P[0][0][2]);
+ gl.glVertex3f(char_P[0][0][0], 0.2f, 1.0f*char_P[0][0][2]);
+ gl.glVertex3f(char_P[0][0][0], 3.4f, 1.0f*char_P[0][0][2]);
+ gl.glEnd();
+ }
+
+ void draw_G() {
+ int i,j,k;
+ for (i=0;i<ACC;i++)
+ {
+ k = i+1;
+ if (k>=ACC)
+ k = 0;
+ gl.glBegin(GL_QUAD_STRIP);
+ gl.glNormal3f(normal_G[0][k][0], normal_G[0][k][1], normal_G[0][k][2]);
+ gl.glVertex3f(char_G[0][k][0], char_G[0][k][1]+1.2f, char_G[0][k][2]);
+ gl.glNormal3f(normal_G[0][i][0], normal_G[0][i][1], normal_G[0][i][2]);
+ gl.glVertex3f(char_G[0][i][0], char_G[0][i][1]+1.2f, char_G[0][i][2]);
+ for (j=1;j<ACC4;j++)
+ {
+ gl.glNormal3f(normal_G[j][k][0], normal_G[j][k][1], normal_G[j][k][2]);
+ gl.glVertex3f(char_G[j][k][0], char_G[j][k][1], char_G[j][k][2]);
+ gl.glNormal3f(normal_G[j][i][0], normal_G[j][i][1], normal_G[j][i][2]);
+ gl.glVertex3f(char_G[j][i][0], char_G[j][i][1], char_G[j][i][2]);
+ }
+ gl.glEnd();
+ }
+
+ gl.glBegin(GL_QUAD_STRIP);
+ j = ACC4*3/4;
+ for (i=0;i<ACC;i++)
+ {
+ gl.glNormal3f(accSIN[i], 0.0f, accCOS[i] );
+ gl.glVertex3f(4.0f+0.9f*accSIN[i], 4.0f+0.9f*accSIN[i], 0.9f*accCOS[i] );
+ gl.glVertex3f(4.0f+0.9f*accSIN[i], 0.0f, 0.9f*accCOS[i]);
+ }
+ gl.glNormal3f(accSIN[0], 0.0f, accCOS[0] );
+ gl.glVertex3f(4.0f+0.9f*accSIN[0], 4.0f+0.9f*accSIN[0], 0.9f*accCOS[0] );
+ gl.glVertex3f(4.0f+0.9f*accSIN[0], 0.0f, 0.9f*accCOS[0]);
+ gl.glEnd();
+
+ gl.glBegin(GL_QUAD_STRIP);
+ j = ACC4*3/4;
+ for (i=0;i<ACC;i++)
+ {
+ gl.glNormal3f(0.0f, accSIN[i], accCOS[i] );
+ gl.glVertex3f(4.0f-0.9f*accSIN[i], 4.0f-0.9f*accSIN[i], 0.9f*accCOS[i] );
+ gl.glVertex3f(0.0f, 4.0f-0.9f*accSIN[i], 0.9f*accCOS[i]);
+ }
+ gl.glNormal3f(0.0f, accSIN[0], accCOS[0] );
+ gl.glVertex3f(4.0f-0.9f*accSIN[0], 4.0f-0.9f*accSIN[0], 0.9f*accCOS[0] );
+ gl.glVertex3f(0.0f, 4.0f-0.9f*accSIN[0], 0.9f*accCOS[0]);
+ gl.glEnd();
+
+ j = ACC4*3/4;
+ gl.glBegin(GL_TRIANGLE_FAN);
+ gl.glNormal3f(-1.0f, 0.0f, 0.0f);
+ gl.glVertex3f(0.0f, 4.0f, 0.0f);
+ for (i=0;i<ACC;i++)
+ gl.glVertex3f(0.0f, 4.0f+0.9f*accSIN[i], 0.9f*accCOS[i]);
+ gl.glVertex3f(0.0f, 4.0f+0.9f*accSIN[0], 0.9f*accCOS[0]);
+ gl.glEnd();
+ }
+
+ void draw_L() {
+ int i;
+
+ gl.glBegin(GL_QUAD_STRIP);
+ for (i=0;i<ACC;i++)
+ {
+ gl.glNormal3f(accSIN[i], 0.0f, accCOS[i] );
+ gl.glVertex3f(0.9f*accSIN[i], 9.6f, 0.9f*accCOS[i]);
+ gl.glVertex3f(0.9f*accSIN[i], 0.9f+0.9f*accSIN[i], 0.9f*accCOS[i] );
+ }
+ gl.glNormal3f(accSIN[0], 0.0f, accCOS[0] );
+ gl.glVertex3f(0.9f*accSIN[0], 9.6f, 0.9f*accCOS[0]);
+ gl.glVertex3f(0.9f*accSIN[0], 0.9f+0.9f*accSIN[0], 0.9f*accCOS[0] );
+ gl.glEnd();
+
+ gl.glBegin(GL_QUAD_STRIP);
+ for (i=0;i<ACC;i++)
+ {
+ gl.glNormal3f(0.0f, accSIN[i], accCOS[i] );
+ gl.glVertex3f(0.9f*accSIN[i], 0.9f+0.9f*accSIN[i], 0.9f*accCOS[i] );
+ gl.glVertex3f(5.6f, 0.9f+0.9f*accSIN[i], 0.9f*accCOS[i]);
+ }
+ gl.glNormal3f(0.0f, accSIN[0], accCOS[0] );
+ gl.glVertex3f(0.9f*accSIN[0], 0.9f+0.9f*accSIN[0], 0.9f*accCOS[0] );
+ gl.glVertex3f(5.6f, 0.9f+0.9f*accSIN[0], 0.9f*accCOS[0]);
+ gl.glEnd();
+
+ gl.glBegin(GL_TRIANGLE_FAN);
+ gl.glNormal3f(1.0f, 0.0f, 0.0f);
+ gl.glVertex3f(5.6f, 0.9f, 0.0f);
+ for (i=ACC-1;i>=0;i--)
+ gl.glVertex3f(5.6f, 0.9f+0.9f*accSIN[i], 0.9f*accCOS[i]);
+ gl.glVertex3f(5.6f, 0.9f+0.9f*accSIN[ACC-1], 0.9f*accCOS[ACC-1]);
+ gl.glEnd();
+ }
+
+ void draw_part(int i) {
+ gl.glPushMatrix();
+ gl.glTranslatef(TRANS[i][0]*progress, TRANS[i][1]*progress, TRANS[i][2]*progress);
+ gl.glRotatef(ROT[i]*progress, ROTAXIS[i][0], ROTAXIS[i][1], ROTAXIS[i][2]);
+ switch(i)
+ {
+ case 0: draw_El(); break;
+ case 1: draw_O(); break;
+ case 2: draw_P(); break;
+ case 3: draw_E(); break;
+ case 4: draw_N(); break;
+ case 5: draw_G(); break;
+ case 6: draw_L(); break;
+ }
+ gl.glPopMatrix();
+ }
+
+ void draw_logo() {
+ groen_texture();
+ gl.glEnable(GL_CULL_FACE);
+ gl.glTranslatef(-2.8f, 0.0f, 0.0f);
+
+ draw_part(0);
+ gl.glTranslatef(-12.0f, 4.3f, 0.0f);
+ draw_part(1);
+ gl.glTranslatef(7.3f, 0.0f, 0.0f);
+ draw_part(2);
+ gl.glTranslatef(5.4f, 0.0f, 0.0f);
+ draw_part(3);
+ gl.glTranslatef(5.4f, 0.0f, 0.0f);
+ draw_part(4);
+ gl.glTranslatef(7.4f, 0.0f, 0.0f);
+ draw_part(5);
+ gl.glTranslatef(6.8f, 0.0f, 0.0f);
+ draw_part(6);
+ }
+
+ void go() {
+ GLCapabilities caps = new GLCapabilities();
+ /*
+ caps.setDoubleBuffered(true);
+ caps.setTrueColor(true);
+ caps.setStereo(false);
+ caps.setDepthBits(32);
+ caps.setRedBits(5);
+ caps.setGreenBits(5);
+ caps.setBlueBits(5);
+ */
+ GLAnimCanvas canvas =
+ GLDrawableFactory.getFactory().createGLAnimCanvas(caps, 400, 400);
+ if (canvas == null) {
+ throw new RuntimeException("Unable to match required GLCapabilities");
+ }
+ canvas.addGLEventListener(this);
+ canvas.start();
+ Frame frame = new Frame();
+ frame.add(canvas);
+ frame.setSize(400, 400);
+ frame.pack();
+ frame.show();
+ }
+
+ public static void main(String[] args) {
+ GLContext.gljNativeDebug = true;
+ GLContext.gljThreadDebug = false;
+ GLContext.gljClassDebug = true;
+
+ new TestListener().go();
+ }
+}
diff --git a/demos/gltestperf.java b/demos/gltestperf.java
new file mode 100644
index 0000000..a97445e
--- /dev/null
+++ b/demos/gltestperf.java
@@ -0,0 +1,871 @@
+/**
+ * @(#) gltestperf.java
+ * @(#) author: David Bucciarelli ([email protected]), Humanware s.r.l.
+ *
+ * This program is under the GNU GPL.
+ * Use at your own risk.
+ *
+ * Transformed to java, using OpenGL[tm] for Java[tm] (gl4java),
+ * by Sven Goethel [email protected], http://www.jausoft.com/gl4java
+ *
+ */
+
+import java.applet.*;
+import java.awt.*;
+import java.awt.event.*;
+import java.lang.*;
+import java.util.*;
+import java.io.*;
+import java.util.*;
+
+import gl4java.*;
+import gl4java.drawable.*;
+import gl4java.awt.*;
+
+public class gltestperf extends GLCanvas
+{
+
+ static boolean frontbuffer = true;
+
+ static final float BMARKS_TIME = 5.0f;
+
+ static final int NUM_BMARKS = 6;
+
+ static int firstBenchMark = 0;
+ static int lastBenchMark = NUM_BMARKS-1;
+
+ /* 554 ~= (float)Math.sqrt(640*480) */
+
+ protected benchmark[/*NUM_BMARKS*/] bmarks = null;
+
+ protected abstract class benchmark
+ {
+ public String name;
+ public String unit;
+ public int type;
+ public int numsize;
+ public int[/*10*/] size;
+
+ public abstract void init ();
+ public abstract int run ( int size, int num ) ;
+
+ public String toString()
+ {
+ return "benchmark \""+name+"\"\n [ unit="+unit+
+ ", type="+type+
+ ", numsize="+numsize+"]";
+ }
+ }
+
+ public benchmark[] getAllBenchmarks()
+ {
+ benchmark[] _bmarks = new benchmark[NUM_BMARKS];
+ _bmarks[0] = new Pnts();
+ _bmarks[1] = new Lins();
+ _bmarks[2] = new Tris1();
+ _bmarks[3] = new Tris2();
+ _bmarks[4] = new Tris3();
+ _bmarks[5] = new Clrs();
+
+ return _bmarks;
+ }
+
+ public static void main( String args[] )
+ {
+ int i;
+
+ gltestperf canvas = null;
+ Dimension d = new Dimension(640, 480);
+ GLCapabilities glCaps = new GLCapabilities();
+
+ gl4java.drawable.GLDrawableFactory df =
+ gl4java.drawable.GLDrawableFactory.getFactory();
+
+ //Create our canvas and add it to the center of the applet
+ if(df instanceof gl4java.drawable.SunJDK13GLDrawableFactory)
+ {
+ gl4java.drawable.SunJDK13GLDrawableFactory sdf =
+ (gl4java.drawable.SunJDK13GLDrawableFactory)df;
+ canvas = new gltestperf
+ (sdf.getGraphicsConfiguration(glCaps), glCaps, d.width, d.height);
+ } else {
+ canvas = new gltestperf(glCaps, d.width, d.height);
+ }
+
+ for(i=0; i<args.length; i++)
+ {
+ if(args[i].equals("--help"))
+ {
+ System.out.println("usage:");
+ System.out.println(" --bm <int> : run only this BenchMark");
+ System.out.println(" --first <int> : firstBenchMark to run");
+ System.out.println(" --last <int> : lastBenchMark to run");
+ System.out.println(" --help : this message");
+ benchmark[] _bmarks = canvas.getAllBenchmarks();
+
+ System.out.println("Avaiable Benchmarks: ");
+ for(int j=0; j<NUM_BMARKS; j++)
+ {
+ System.out.println("Benchmarks Number: "+j);
+ System.out.println(_bmarks[j]);
+ System.out.println();
+ }
+
+ System.exit(0);
+ }
+ if(args[i].equals("--first"))
+ {
+ i++;
+ try {
+ gltestperf.firstBenchMark=
+ Integer.valueOf(args[i]).intValue();
+ } catch (Exception ex) {}
+
+ if(gltestperf.firstBenchMark<0)
+ gltestperf.firstBenchMark=0;
+ if(gltestperf.firstBenchMark>=NUM_BMARKS)
+ gltestperf.firstBenchMark=NUM_BMARKS-1;
+ } else if(args[i].equals("--last")) {
+ i++;
+ try {
+ gltestperf.lastBenchMark=
+ Integer.valueOf(args[i]).intValue();
+ } catch (Exception ex) {}
+
+ if(gltestperf.lastBenchMark<0)
+ gltestperf.lastBenchMark=0;
+ if(gltestperf.lastBenchMark>=NUM_BMARKS)
+ gltestperf.lastBenchMark=NUM_BMARKS-1;
+ } else if(args[i].equals("--bm")) {
+ i++;
+ try {
+ gltestperf.lastBenchMark=
+ Integer.valueOf(args[i]).intValue();
+ } catch (Exception ex) {}
+ if(gltestperf.lastBenchMark<0)
+ gltestperf.lastBenchMark=0;
+ if(gltestperf.lastBenchMark>=NUM_BMARKS)
+ gltestperf.lastBenchMark=NUM_BMARKS-1;
+ gltestperf.firstBenchMark=
+ gltestperf.lastBenchMark;
+ } else {
+ System.out.println("ERROR Unknown Argument !");
+ System.out.println("arg "+i+": "+args[i]);
+ System.exit(1);
+ }
+ }
+
+ if(gltestperf.firstBenchMark>gltestperf.lastBenchMark)
+ gltestperf.firstBenchMark=
+ gltestperf.lastBenchMark;
+
+ Frame f = new Frame("gltestperf");
+
+ GLContext.gljNativeDebug = false;
+ GLContext.gljThreadDebug = false;
+ GLContext.gljClassDebug = false;
+
+ f.addWindowListener( new WindowAdapter()
+ {
+ public void windowClosed(WindowEvent e)
+ {
+ System.exit(0);
+ }
+ public void windowClosing(WindowEvent e)
+ {
+ windowClosed(e);
+ }
+ }
+ );
+
+ f.setLayout(new BorderLayout());
+ canvas.requestFocus();
+ f.add("Center", canvas);
+ Dimension ps = canvas.getPreferredSize();
+ f.setBounds(-100,-100,99,99);
+ f.setVisible(true);
+ //f.setVisible(false);
+ //f.setVisible(true);
+ Insets is = f.getInsets();
+ f.setBounds(0,0,
+ ps.width+is.left+is.right,
+ ps.height+is.top+is.bottom);
+ f.setVisible(true);
+ }
+
+ public gltestperf(GraphicsConfiguration g, GLCapabilities glCaps,
+ int w, int h)
+ {
+ super(g, glCaps, w, h);
+ }
+
+ public gltestperf(GLCapabilities glCaps, int w, int h)
+ {
+ super(glCaps, w, h);
+ }
+
+ public void init()
+ {
+ System.out.println("**** Window Size: "+getSize());
+ System.out.println("**** Running Benchmarks ["+
+ firstBenchMark+".."+lastBenchMark+"]");
+ bmarks = getAllBenchmarks();
+ }
+
+ public void display()
+ {
+ int i;
+
+ if (glj.gljMakeCurrent() == false) return;
+
+ if (frontbuffer)
+ gl.glDrawBuffer(GL_FRONT);
+ else
+ gl.glDrawBuffer(GL_BACK);
+
+ for (i = firstBenchMark; i <= lastBenchMark; i++) {
+ System.out.println("**** Benchmark: "+i);
+
+ switch (bmarks[i].type) {
+ case 0:
+ case 3:
+ dotest0param(bmarks[i]);
+ break;
+ case 1:
+ case 2:
+ dotest1param(bmarks[i]);
+ break;
+ }
+ }
+
+ glj.gljSwap();
+ glj.gljCheckGL();
+ glj.gljFree();
+
+ }
+
+/***************************************************************************/
+
+protected void dotest0param(benchmark bmark)
+{
+ long stime, etime, tottime, maxtime, mintime;
+ double dtime;
+ int num=0, numelem=0, calibnum=0, j=0;
+
+ gl.glPushAttrib(GL_ALL_ATTRIB_BITS);
+ bmark.init();
+
+ stime=System.currentTimeMillis();
+
+ dtime = 0.0D;
+ calibnum = 0;
+ while (dtime < 2.0D) {
+ bmark.run(0, 1);
+ gl.glFinish();
+ etime = System.currentTimeMillis();
+ dtime = (etime - stime) / 1000.0D;
+ calibnum++;
+ }
+ gl.glPopAttrib();
+
+ System.out.println("***** Elapsed time for the calibration test ("+
+ calibnum+"): "+dtime);
+
+ num = (int) ((BMARKS_TIME / dtime) * calibnum);
+
+ if (num < 1)
+ num = 1;
+
+ System.out.println("***** Selected number of benchmark iterations: "+
+ num);
+
+
+ mintime = Long.MAX_VALUE;
+ maxtime = Long.MIN_VALUE;
+
+ for (tottime = 0, j = 0; j < 5; j++) {
+ gl.glPushAttrib(GL_ALL_ATTRIB_BITS);
+ bmark.init();
+
+ stime = System.currentTimeMillis();
+ numelem = bmark.run(0, num);
+ gl.glFinish();
+ etime = System.currentTimeMillis();
+
+ gl.glPopAttrib();
+
+ dtime = (etime - stime) / 1000.0D;
+ tottime += dtime;
+
+ System.out.println("****** Elapsed time for run "+
+ j+": "+dtime);
+
+
+ if (dtime < mintime)
+ mintime = (long)dtime;
+ if (dtime > maxtime)
+ maxtime = (long)dtime;
+ }
+
+ tottime -= mintime + maxtime;
+
+ System.out.println("***** "+bmark.name+"\n***** "+
+ (numelem / (tottime / 3.0D))+" "+bmark.unit+"/sec");
+
+ if (bmark.type == 3)
+ System.out.println(", MPixel Fill/sec: "+
+ ( (numelem * bmark.size[0] * (float) bmark.size[0]) /
+ (1000000.0D * tottime / 3.0D)
+ ) +"\n\n");
+
+ else
+ System.out.println("\n");
+}
+
+/***************************************************************************/
+
+protected void dotest1param(benchmark bmark)
+{
+ double stime, etime, dtime, tottime, maxtime, mintime;
+ int num, numelem, calibnum, j, k;
+
+ System.out.println("***** "+bmark.name);
+
+ for (j = 0; j < bmark.numsize; j++) {
+ System.out.println("****** "+ "Current size: "+ bmark.size[j]);
+
+ gl.glPushAttrib(GL_ALL_ATTRIB_BITS);
+ bmark.init();
+
+ stime = System.currentTimeMillis();
+
+ dtime = 0.0D;
+ calibnum = 0;
+ while (dtime < 2.0D) {
+ bmark.run(bmark.size[j], 1);
+ gl.glFinish();
+ etime = System.currentTimeMillis();
+ dtime = (etime - stime) / 1000.0D;
+ calibnum++;
+ }
+ gl.glPopAttrib();
+
+ System.out.println("****** Elapsed time for the calibration test ("+
+ calibnum+"): "+dtime);
+
+ num = (int) ((BMARKS_TIME / dtime) * calibnum);
+
+ if (num < 1)
+ num = 1;
+
+ System.out.println("****** Selected number of benchmark iterations: "+
+ num);
+
+ mintime = Long.MAX_VALUE;
+ maxtime = Long.MIN_VALUE;
+
+ for (numelem = 1, tottime = 0.0D, k = 0; k < 5; k++) {
+ gl.glPushAttrib(GL_ALL_ATTRIB_BITS);
+ bmark.init();
+
+ stime = System.currentTimeMillis();
+ numelem = bmark.run(bmark.size[j], num);
+ gl.glFinish();
+ etime = System.currentTimeMillis();
+
+ gl.glPopAttrib();
+
+ dtime = (etime - stime) / 1000.0D;
+ tottime += dtime;
+
+ System.out.println("******* Elapsed time for run "+
+ k+": "+dtime);
+
+ if (dtime < mintime)
+ mintime = dtime;
+ if (dtime > maxtime)
+ maxtime = dtime;
+ }
+
+ tottime -= mintime + maxtime;
+
+ System.out.print("****** "+ "SIZE="+bmark.size[j]+" => "+
+ (numelem / (tottime / 3.0D)) + " "+bmark.unit+"/sec");
+
+ if (bmark.type == 2)
+ System.out.println(", MPixel Fill/sec: "+
+ (
+ (numelem * bmark.size[j] * bmark.size[j] / 2) /
+ (1000000.0D * tottime / 3.0D)
+ ) );
+ else
+ System.out.println();
+ }
+
+ System.out.println("\n");
+}
+
+/***************************************************************************/
+
+protected class Clrs
+ extends benchmark
+{
+ public Clrs()
+ {
+ name="Color/Depth Buffer Clears";
+ unit="Clrs";
+ type=3;
+ numsize=0;
+ size=new int[10];
+ size[0]=554;
+ size[1]=0;
+ size[2]=0;
+ size[3]=0;
+ size[4]=0;
+ size[5]=0;
+ size[6]=0;
+ size[7]=0;
+ size[8]=0;
+ size[9]=0;
+ }
+
+ public void init()
+ {
+ gl.glMatrixMode(GL_PROJECTION);
+ gl.glLoadIdentity();
+ glu.gluOrtho2D(-0.5f, 639.5f, -0.5f, 479.5f);
+ gl.glMatrixMode(GL_MODELVIEW);
+
+ gl.glShadeModel(GL_SMOOTH);
+ gl.glEnable(GL_DEPTH_TEST);
+
+ gl.glClearColor(0.0f, 0.1f, 1.0f, 0.0f);
+ gl.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ }
+
+ public int run(int size, int num)
+ {
+ int y;
+
+ for (y = 0; y < num; y++) {
+ gl.glClearColor(y / (float) num, 0.1f, 1.0f, 0.0f);
+ gl.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ }
+
+ return num;
+ }
+
+}
+
+protected class Tris3
+ extends benchmark
+{
+ public Tris3()
+ {
+ name="ZSmooth Tex Blend TMesh Triangles";
+ unit="Tris";
+ type=2;
+ numsize=8;
+ size=new int[10];
+ size[0]=400;
+ size[1]=250;
+ size[2]=100;
+ size[3]=50;
+ size[4]=25;
+ size[5]=10;
+ size[6]=5;
+ size[7]=2;
+ size[8]=0;
+ size[9]=0;
+ }
+
+ public void init()
+ {
+ int x, y;
+ byte[] tex = new byte[128 * 128 * 3];
+ int gluerr;
+
+ gl.glMatrixMode(GL_PROJECTION);
+ gl.glLoadIdentity();
+ gl.glOrtho(-0.5f, 639.5f, -0.5f, 479.5f, -1.0f, 1.0f);
+
+ gl.glMatrixMode(GL_MODELVIEW);
+
+ gl.glShadeModel(GL_SMOOTH);
+ gl.glEnable(GL_DEPTH_TEST);
+
+ gl.glEnable(GL_BLEND);
+ gl.glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ for (y = 0; y < 128; y++)
+ for (x = 0; x < 128; x++) {
+ tex[((x + (y * 128)) * 3) + 0] = (byte) ( ((x % (128 / 4)) < (128 / 8)) ? 255 : 0 );
+ tex[((x + (y * 128)) * 3) + 1] = (byte) ( ((y % (128 / 4)) < (128 / 8)) ? 255 : 0 );
+ tex[((x + (y * 128)) * 3) + 2] = (byte) x;
+ }
+
+ gl.glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ if (0<(gluerr = glu.gluBuild2DMipmaps(GL_TEXTURE_2D, 3, 128, 128,
+ GL_RGB, GL_UNSIGNED_BYTE, tex)))
+ {
+ System.out.println("!!!! GLULib"+ glu.gluErrorString(gluerr));
+ System.exit(1);
+ }
+
+ gl.glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ gl.glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+
+ gl.glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
+ GL_LINEAR_MIPMAP_NEAREST);
+ gl.glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+ gl.glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ gl.glEnable(GL_TEXTURE_2D);
+
+ gl.glDepthFunc(GL_ALWAYS);
+
+ gl.glClearColor(0.0f, 0.1f, 1.0f, 0.0f);
+ gl.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ }
+
+ public int run(int size, int num)
+ {
+ int y;
+ float[] v0=new float[3], v1=new float[3],
+ v2=new float[3], v3=new float[3];
+ float[] cv0=new float[3], cv1=new float[3],
+ cv2=new float[3], cv3=new float[3];
+ float[] tv0=new float[3], tv1=new float[3],
+ tv2=new float[3], tv3=new float[3];
+
+ v0[0] = 320 - size / 2;
+ v0[1] = 240 - size / 2;
+ v0[2] = 0.0f;
+ v1[0] = 320 + size / 2;
+ v1[1] = 240 - size / 2;
+ v1[2] = 0.0f;
+ v2[0] = 320 - size / 2;
+ v2[1] = 240 + size / 2;
+ v2[2] = 0.0f;
+ v3[0] = 320 + size / 2;
+ v3[1] = 240 + size / 2;
+ v3[2] = 0.0f;
+ cv0[0] = 1.0f;
+ cv0[1] = 0.0f;
+ cv0[2] = 0.0f;
+ cv1[0] = 1.0f;
+ cv1[1] = 1.0f;
+ cv1[2] = 0.0f;
+ cv2[0] = 1.0f;
+ cv2[1] = 0.0f;
+ cv2[2] = 1.0f;
+ cv3[0] = 1.0f;
+ cv3[1] = 1.0f;
+ cv3[2] = 1.0f;
+ tv0[0] = 0.0f;
+ tv0[1] = 0.0f;
+ tv0[2] = 0.0f;
+ tv1[0] = 1.0f;
+ tv1[1] = 0.0f;
+ tv1[2] = 0.0f;
+ tv2[0] = 0.0f;
+ tv2[1] = 1.0f;
+ tv2[2] = 0.0f;
+ tv3[0] = 1.0f;
+ tv3[1] = 1.0f;
+ tv3[2] = 0.0f;
+
+ gl.glBegin(GL_TRIANGLE_STRIP);
+ for (y = 0; y < num; y++) {
+ gl.glColor3fv(cv0);
+ gl.glTexCoord2fv(tv0);
+ gl.glVertex3fv(v0);
+
+ gl.glColor3fv(cv1);
+ gl.glTexCoord2fv(tv1);
+ gl.glVertex3fv(v1);
+
+ gl.glColor3fv(cv2);
+ gl.glTexCoord2fv(tv2);
+ gl.glVertex3fv(v2);
+
+ gl.glColor3fv(cv3);
+ gl.glTexCoord2fv(tv3);
+ gl.glVertex3fv(v3);
+ }
+ gl.glEnd();
+
+ return 4 * num - 2;
+ }
+
+}
+
+protected class Tris2
+ extends benchmark
+{
+ public Tris2()
+ {
+ name="ZSmooth Tex Blend Triangles";
+ unit="Tris";
+ type=1;
+ numsize=5;
+ size=new int[10];
+ size[0]=480;
+ size[1]=250;
+ size[2]=100;
+ size[3]=50;
+ size[4]=25;
+ size[5]=0;
+ size[6]=0;
+ size[7]=0;
+ size[8]=0;
+ size[9]=0;
+ }
+
+ public void init()
+ {
+ int x, y;
+ byte[] tex= new byte[128 * 128 * 3];
+ int gluerr;
+
+ gl.glMatrixMode(GL_PROJECTION);
+ gl.glLoadIdentity();
+ gl.glOrtho(-0.5f, 639.5f, -0.5f, 479.5f, 1.0f, -1000.0f * 480.0f);
+
+ gl.glMatrixMode(GL_MODELVIEW);
+
+ gl.glShadeModel(GL_SMOOTH);
+ gl.glEnable(GL_DEPTH_TEST);
+
+ gl.glEnable(GL_BLEND);
+ gl.glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ for (y = 0; y < 128; y++)
+ for (x = 0; x < 128; x++) {
+ tex[((x + (y * 128)) * 3) + 0] = (byte) ( ((x % (128 / 4)) < (128 / 8)) ? 255 : 0 );
+ tex[((x + (y * 128)) * 3) + 1] = (byte) ( ((y % (128 / 4)) < (128 / 8)) ? 255 : 0 );
+ tex[((x + (y * 128)) * 3) + 2] = (byte) x;
+ }
+
+ gl.glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ if (0<(gluerr = glu.gluBuild2DMipmaps(GL_TEXTURE_2D, 3, 128, 128,
+ GL_RGB, GL_UNSIGNED_BYTE, tex)))
+ {
+ System.out.println("!!!! GLULib"+ glu.gluErrorString(gluerr));
+ System.exit(1);
+ }
+
+ gl.glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ gl.glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+
+ gl.glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
+ GL_LINEAR_MIPMAP_NEAREST);
+ gl.glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+ gl.glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ gl.glEnable(GL_TEXTURE_2D);
+
+ gl.glClearColor(0.0f, 0.1f, 1.0f, 0.0f);
+ gl.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ }
+
+ public int run(int size, int num)
+ {
+ int x, y, z;
+
+ gl.glBegin(GL_TRIANGLES);
+ for (y = 0; y < num; y++)
+ for (x = 0; x < size; x += 5) {
+ z = num * size - (y * size + x);
+ gl.glTexCoord2f(1.0f, 1.0f);
+ gl.glColor3f(1.0f, 0.0f, 0.0f);
+ gl.glVertex3i(0, x, z);
+
+ gl.glTexCoord2f(0.0f, 1.0f);
+ gl.glColor3f(0.0f, 1.0f, 0.0f);
+ gl.glVertex3i(size - 1 - x, 0, z);
+
+ gl.glTexCoord2f(1.0f, 0.0f);
+ gl.glColor3f(0.0f, 0.0f, 1.0f);
+ gl.glVertex3i(x, size - 1 - x, z);
+ }
+ gl.glEnd();
+
+ return num * size / 5;
+ }
+
+}
+
+protected class Tris1
+ extends benchmark
+{
+ public Tris1()
+ {
+ name="ZSmooth Triangles";
+ unit="Tris";
+ type=1;
+ numsize=5;
+ size=new int[10];
+ size[0]=480;
+ size[1]=250;
+ size[2]=100;
+ size[3]=50;
+ size[4]=25;
+ size[5]=0;
+ size[6]=0;
+ size[7]=0;
+ size[8]=0;
+ size[9]=0;
+ }
+
+ public void init()
+ {
+ gl.glMatrixMode(GL_PROJECTION);
+ gl.glLoadIdentity();
+ gl.glOrtho(-0.5f, 639.5f, -0.5f, 479.5f, 1.0f, -1000.0f * 480.0f);
+ gl.glMatrixMode(GL_MODELVIEW);
+
+ gl.glShadeModel(GL_SMOOTH);
+ gl.glEnable(GL_DEPTH_TEST);
+
+ gl.glClearColor(0.0f, 0.1f, 1.0f, 0.0f);
+ gl.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ }
+
+ public int run(int size, int num)
+ {
+ int x, y, z;
+
+ gl.glBegin(GL_TRIANGLES);
+ for (y = 0; y < num; y++)
+ for (x = 0; x < size; x += 5) {
+ z = num * size - (y * size + x);
+ gl.glColor3f(0.0f, 1.0f, 0.0f);
+ gl.glVertex3i(0, x, z);
+
+ gl.glColor3f(1.0f, 0.0f, x / (float) size);
+ gl.glVertex3i(size - 1 - x, 0, z);
+
+ gl.glColor3f(1.0f, x / (float) size, 0.0f);
+ gl.glVertex3i(x, size - 1 - x, z);
+ }
+ gl.glEnd();
+
+ return size * num / 5;
+ }
+
+}
+
+protected class Lins
+ extends benchmark
+{
+ public Lins()
+ {
+ name="Smooth Lines";
+ unit="Lins";
+ type=1;
+ numsize=5;
+ size=new int[10];
+ size[0]=480;
+ size[1]=250;
+ size[2]=100;
+ size[3]=50;
+ size[4]=25;
+ size[5]=0;
+ size[6]=0;
+ size[7]=0;
+ size[8]=0;
+ size[9]=0;
+ }
+
+ public void init()
+ {
+ gl.glMatrixMode(GL_PROJECTION);
+ gl.glLoadIdentity();
+ glu.gluOrtho2D(-0.5f, 639.5f, -0.5f, 479.5f);
+ gl.glMatrixMode(GL_MODELVIEW);
+
+ gl.glShadeModel(GL_SMOOTH);
+ gl.glDisable(GL_DEPTH_TEST);
+
+ gl.glClearColor(0.0f, 0.1f, 1.0f, 0.0f);
+ gl.glClear(GL_COLOR_BUFFER_BIT);
+ }
+
+ public int run(int size, int num)
+ {
+ int x, y;
+
+ gl.glBegin(GL_LINES);
+ for (y = 0; y < num; y++)
+ for (x = 0; x < size; x++) {
+ gl.glColor3f(0.0f, 1.0f, y / (float) num);
+ gl.glVertex2i(0, size - 1);
+ gl.glColor3f(1.0f, 0.0f, x / (float) size);
+ gl.glVertex2i(x, x);
+ }
+ gl.glEnd();
+
+ return num * size;
+ }
+
+}
+
+
+protected class Pnts
+ extends benchmark
+{
+ public Pnts()
+ {
+ name="Simple Points";
+ unit="Pnts";
+ type=0;
+ numsize=0;
+ size=new int[10];
+ size[0]=0;
+ size[1]=0;
+ size[2]=0;
+ size[3]=0;
+ size[4]=0;
+ size[5]=0;
+ size[6]=0;
+ size[7]=0;
+ size[8]=0;
+ size[9]=0;
+ }
+
+ public void init()
+ {
+ gl.glMatrixMode(GL_PROJECTION);
+ gl.glLoadIdentity();
+ glu.gluOrtho2D(-0.5f, 639.5f, -0.5f, 479.5f);
+ gl.glMatrixMode(GL_MODELVIEW);
+
+ gl.glShadeModel(GL_FLAT);
+ gl.glDisable(GL_DEPTH_TEST);
+
+ gl.glClearColor(0.0f, 0.1f, 1.0f, 0.0f);
+ gl.glClear(GL_COLOR_BUFFER_BIT);
+ gl.glColor3f(1.0f, 0.0f, 0.0f);
+ }
+
+ public int run(int size, int num)
+ {
+ int x, y;
+
+ gl.glBegin(GL_POINTS);
+ for (y = 0; y < num; y++)
+ for (x = 0; x < 480; x++)
+ gl.glVertex2i(x, x);
+ gl.glEnd();
+
+ return 480 * num;
+ }
+
+}
+
+
+
+}
diff --git a/demos/natives/x11/gltestperf.c b/demos/natives/x11/gltestperf.c
new file mode 100644
index 0000000..2df168b
--- /dev/null
+++ b/demos/natives/x11/gltestperf.c
@@ -0,0 +1,580 @@
+/*
+ * This program is under the GNU GPL.
+ * Use at your own risk.
+ *
+ * written by David Bucciarelli ([email protected])
+ * Humanware s.r.l.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <GL/glut.h>
+
+typedef struct
+{
+ char *name;
+ char *unit;
+ void (*init) (void);
+ int (*run) (int, int);
+ int type;
+ int numsize;
+ int size[10];
+}
+benchmark;
+
+static int frontbuffer = 1;
+
+/***************************************************************************/
+
+static void
+init_test01(void)
+{
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ gluOrtho2D(-0.5, 639.5, -0.5, 479.5);
+ glMatrixMode(GL_MODELVIEW);
+
+ glShadeModel(GL_FLAT);
+ glDisable(GL_DEPTH_TEST);
+
+ glClearColor(0.0, 0.1, 1.0, 0.0);
+ glClear(GL_COLOR_BUFFER_BIT);
+ glColor3f(1.0, 0.0, 0.0);
+}
+
+static int
+test01(int size, int num)
+{
+ int x, y;
+
+ glBegin(GL_POINTS);
+ for (y = 0; y < num; y++)
+ for (x = 0; x < 480; x++)
+ glVertex2i(x, x);
+ glEnd();
+
+ return 480 * num;
+}
+
+/***************************************************************************/
+
+static void
+init_test02(void)
+{
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ gluOrtho2D(-0.5, 639.5, -0.5, 479.5);
+ glMatrixMode(GL_MODELVIEW);
+
+ glShadeModel(GL_SMOOTH);
+ glDisable(GL_DEPTH_TEST);
+
+ glClearColor(0.0, 0.1, 1.0, 0.0);
+ glClear(GL_COLOR_BUFFER_BIT);
+}
+
+static int
+test02(int size, int num)
+{
+ int x, y;
+
+ glBegin(GL_LINES);
+ for (y = 0; y < num; y++)
+ for (x = 0; x < size; x++) {
+ glColor3f(0.0, 1.0, y / (float) num);
+ glVertex2i(0, size - 1);
+ glColor3f(1.0, 0.0, x / (float) size);
+ glVertex2i(x, x);
+ }
+ glEnd();
+
+ return num * size;
+}
+
+/***************************************************************************/
+
+static void
+init_test03(void)
+{
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(-0.5, 639.5, -0.5, 479.5, 1.0, -1000.0 * 480.0);
+ glMatrixMode(GL_MODELVIEW);
+
+ glShadeModel(GL_SMOOTH);
+ glEnable(GL_DEPTH_TEST);
+
+ glClearColor(0.0, 0.1, 1.0, 0.0);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+}
+
+static int
+test03(int size, int num)
+{
+ int x, y, z;
+
+ glBegin(GL_TRIANGLES);
+ for (y = 0; y < num; y++)
+ for (x = 0; x < size; x += 5) {
+ z = num * size - (y * size + x);
+ glColor3f(0.0, 1.0, 0.0);
+ glVertex3i(0, x, z);
+
+ glColor3f(1.0, 0.0, x / (float) size);
+ glVertex3i(size - 1 - x, 0, z);
+
+ glColor3f(1.0, x / (float) size, 0.0);
+ glVertex3i(x, size - 1 - x, z);
+ }
+ glEnd();
+
+ return size * num / 5;
+}
+
+/***************************************************************************/
+
+static void
+init_test04(void)
+{
+ int x, y;
+ GLubyte tex[128 * 128 * 3];
+ GLenum gluerr;
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(-0.5, 639.5, -0.5, 479.5, 1.0, -1000.0 * 480.0);
+
+ glMatrixMode(GL_MODELVIEW);
+
+ glShadeModel(GL_SMOOTH);
+ glEnable(GL_DEPTH_TEST);
+
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ for (y = 0; y < 128; y++)
+ for (x = 0; x < 128; x++) {
+ tex[(x + y * 128) * 3 + 0] = ((x % (128 / 4)) < (128 / 8)) ? 255 : 0;
+ tex[(x + y * 128) * 3 + 1] = ((y % (128 / 4)) < (128 / 8)) ? 255 : 0;
+ tex[(x + y * 128) * 3 + 2] = x;
+ }
+
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ if ((gluerr = gluBuild2DMipmaps(GL_TEXTURE_2D, 3, 128, 128, GL_RGB,
+ GL_UNSIGNED_BYTE, (GLvoid *) (&tex[0])))) {
+ fprintf(stderr, "GLULib%s\n", gluErrorString(gluerr));
+ exit(-1);
+ }
+
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
+ GL_LINEAR_MIPMAP_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ glEnable(GL_TEXTURE_2D);
+
+ glClearColor(0.0, 0.1, 1.0, 0.0);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+}
+
+static int
+test04(int size, int num)
+{
+ int x, y, z;
+
+ glBegin(GL_TRIANGLES);
+ for (y = 0; y < num; y++)
+ for (x = 0; x < size; x += 5) {
+ z = num * size - (y * size + x);
+ glTexCoord2f(1.0, 1.0);
+ glColor3f(1.0, 0.0, 0.0);
+ glVertex3i(0, x, z);
+
+ glTexCoord2f(0.0, 1.0);
+ glColor3f(0.0, 1.0, 0.0);
+ glVertex3i(size - 1 - x, 0, z);
+
+ glTexCoord2f(1.0, 0.0);
+ glColor3f(0.0, 0.0, 1.0);
+ glVertex3i(x, size - 1 - x, z);
+ }
+ glEnd();
+
+ return num * size / 5;
+}
+
+/***************************************************************************/
+
+static void
+init_test05(void)
+{
+ int x, y;
+ GLubyte tex[128 * 128 * 3];
+ GLenum gluerr;
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(-0.5, 639.5, -0.5, 479.5, -1.0, 1.0);
+
+ glMatrixMode(GL_MODELVIEW);
+
+ glShadeModel(GL_SMOOTH);
+ glEnable(GL_DEPTH_TEST);
+
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ for (y = 0; y < 128; y++)
+ for (x = 0; x < 128; x++) {
+ tex[(x + y * 128) * 3 + 0] = ((x % (128 / 4)) < (128 / 8)) ? 255 : 0;
+ tex[(x + y * 128) * 3 + 1] = ((y % (128 / 4)) < (128 / 8)) ? 255 : 0;
+ tex[(x + y * 128) * 3 + 2] = x;
+ }
+
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ if ((gluerr = gluBuild2DMipmaps(GL_TEXTURE_2D, 3, 128, 128, GL_RGB,
+ GL_UNSIGNED_BYTE, (GLvoid *) (&tex[0])))) {
+ fprintf(stderr, "GLULib%s\n", gluErrorString(gluerr));
+ exit(-1);
+ }
+
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
+ GL_LINEAR_MIPMAP_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ glEnable(GL_TEXTURE_2D);
+
+ glDepthFunc(GL_ALWAYS);
+
+ glClearColor(0.0, 0.1, 1.0, 0.0);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+}
+
+static int
+test05(int size, int num)
+{
+ int y;
+ float v0[3], v1[3], v2[3], v3[3];
+ float cv0[3], cv1[3], cv2[3], cv3[3];
+ float tv0[3], tv1[3], tv2[3], tv3[3];
+
+ v0[0] = 320 - size / 2;
+ v0[1] = 240 - size / 2;
+ v0[2] = 0.0;
+ v1[0] = 320 + size / 2;
+ v1[1] = 240 - size / 2;
+ v1[2] = 0.0;
+ v2[0] = 320 - size / 2;
+ v2[1] = 240 + size / 2;
+ v2[2] = 0.0;
+ v3[0] = 320 + size / 2;
+ v3[1] = 240 + size / 2;
+ v3[2] = 0.0;
+ cv0[0] = 1.0;
+ cv0[1] = 0.0;
+ cv0[2] = 0.0;
+ cv1[0] = 1.0;
+ cv1[1] = 1.0;
+ cv1[2] = 0.0;
+ cv2[0] = 1.0;
+ cv2[1] = 0.0;
+ cv2[2] = 1.0;
+ cv3[0] = 1.0;
+ cv3[1] = 1.0;
+ cv3[2] = 1.0;
+ tv0[0] = 0.0;
+ tv0[1] = 0.0;
+ tv0[2] = 0.0;
+ tv1[0] = 1.0;
+ tv1[1] = 0.0;
+ tv1[2] = 0.0;
+ tv2[0] = 0.0;
+ tv2[1] = 1.0;
+ tv2[2] = 0.0;
+ tv3[0] = 1.0;
+ tv3[1] = 1.0;
+ tv3[2] = 0.0;
+
+ glBegin(GL_TRIANGLE_STRIP);
+ for (y = 0; y < num; y++) {
+ glColor3fv(cv0);
+ glTexCoord2fv(tv0);
+ glVertex3fv(v0);
+
+ glColor3fv(cv1);
+ glTexCoord2fv(tv1);
+ glVertex3fv(v1);
+
+ glColor3fv(cv2);
+ glTexCoord2fv(tv2);
+ glVertex3fv(v2);
+
+ glColor3fv(cv3);
+ glTexCoord2fv(tv3);
+ glVertex3fv(v3);
+ }
+ glEnd();
+
+ return 4 * num - 2;
+}
+
+/***************************************************************************/
+
+static void
+init_test06(void)
+{
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ gluOrtho2D(-0.5, 639.5, -0.5, 479.5);
+ glMatrixMode(GL_MODELVIEW);
+
+ glShadeModel(GL_SMOOTH);
+ glEnable(GL_DEPTH_TEST);
+
+ glClearColor(0.0, 0.1, 1.0, 0.0);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+}
+
+static int
+test06(int size, int num)
+{
+ int y;
+
+ for (y = 0; y < num; y++) {
+ glClearColor(y / (float) num, 0.1, 1.0, 0.0);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ }
+
+ return num;
+}
+
+/***************************************************************************/
+
+#define BMARKS_TIME 5.0
+
+#define NUM_BMARKS 6
+
+/* 554 ~= sqrt(640*480) */
+
+static benchmark bmarks[NUM_BMARKS] = {
+ {"Simple Points", "Pnts", init_test01, test01, 0, 0,
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
+ {"Smooth Lines", "Lins", init_test02, test02, 1, 5,
+ {480, 250, 100, 50, 25, 0, 0, 0, 0, 0}},
+ {"ZSmooth Triangles", "Tris", init_test03, test03, 1, 5,
+ {480, 250, 100, 50, 25, 0, 0, 0, 0, 0}},
+ {"ZSmooth Tex Blend Triangles", "Tris", init_test04, test04, 1, 5,
+ {480, 250, 100, 50, 25, 0, 0, 0, 0, 0}},
+ {"ZSmooth Tex Blend TMesh Triangles", "Tris", init_test05, test05, 2, 8,
+ {400, 250, 100, 50, 25, 10, 5, 2, 0, 0}},
+ {"Color/Depth Buffer Clears", "Clrs", init_test06, test06, 3, 0,
+ {554, 0, 0, 0, 0, 0, 0, 0, 0, 0}}
+};
+
+/***************************************************************************/
+
+static void
+dotest0param(benchmark * bmark)
+{
+ float stime, etime, dtime, tottime, maxtime, mintime;
+ int num, numelem, calibnum, j;
+
+ glPushAttrib(GL_ALL_ATTRIB_BITS);
+ bmark->init();
+
+ stime = glutGet(GLUT_ELAPSED_TIME);
+
+ dtime = 0.0;
+ calibnum = 0;
+ while (dtime < 2.0) {
+ bmark->run(0, 1);
+ glFinish();
+ etime = glutGet(GLUT_ELAPSED_TIME);
+ dtime = (etime - stime) / 1000.0;
+ calibnum++;
+ }
+ glPopAttrib();
+
+ fprintf(stderr, "Elapsed time for the calibration test (%d): %f\n",
+ calibnum, dtime);
+
+ num = (int) ((BMARKS_TIME / dtime) * calibnum);
+
+ if (num < 1)
+ num = 1;
+
+ fprintf(stderr, "Selected number of benchmark iterations: %d\n", num);
+
+ mintime = HUGE_VAL;
+ maxtime = -HUGE_VAL;
+
+ for (tottime = 0.0, j = 0; j < 5; j++) {
+ glPushAttrib(GL_ALL_ATTRIB_BITS);
+ bmark->init();
+
+ stime = glutGet(GLUT_ELAPSED_TIME);
+ numelem = bmark->run(0, num);
+ glFinish();
+ etime = glutGet(GLUT_ELAPSED_TIME);
+
+ glPopAttrib();
+
+ dtime = (etime - stime) / 1000.0;
+ tottime += dtime;
+
+ fprintf(stderr, "Elapsed time for run %d: %f\n", j, dtime);
+
+ if (dtime < mintime)
+ mintime = dtime;
+ if (dtime > maxtime)
+ maxtime = dtime;
+ }
+
+ tottime -= mintime + maxtime;
+
+ fprintf(stdout, "%s\n%f %s/sec", bmark->name, numelem / (tottime / 3.0),
+ bmark->unit);
+
+ if (bmark->type == 3)
+ fprintf(stdout, ", MPixel Fill/sec: %f\n\n",
+ (numelem * bmark->size[0] * (float) bmark->size[0]) /
+ (1000000.0 * tottime / 3.0));
+ else
+ fprintf(stdout, "\n\n");
+}
+
+/***************************************************************************/
+
+static void
+dotest1param(benchmark * bmark)
+{
+ float stime, etime, dtime, tottime, maxtime, mintime;
+ int num, numelem, calibnum, j, k;
+
+ fprintf(stdout, "%s\n", bmark->name);
+
+ for (j = 0; j < bmark->numsize; j++) {
+ fprintf(stderr, "Current size: %d\n", bmark->size[j]);
+
+ glPushAttrib(GL_ALL_ATTRIB_BITS);
+ bmark->init();
+
+ stime = glutGet(GLUT_ELAPSED_TIME);
+
+ dtime = 0.0;
+ calibnum = 0;
+ while (dtime < 2.0) {
+ bmark->run(bmark->size[j], 1);
+ glFinish();
+ etime = glutGet(GLUT_ELAPSED_TIME);
+ dtime = (etime - stime) / 1000.0;
+ calibnum++;
+ }
+ glPopAttrib();
+
+ fprintf(stderr, "Elapsed time for the calibration test (%d): %f\n",
+ calibnum, dtime);
+
+ num = (int) ((BMARKS_TIME / dtime) * calibnum);
+
+ if (num < 1)
+ num = 1;
+
+ fprintf(stderr, "Selected number of benchmark iterations: %d\n", num);
+
+ mintime = HUGE_VAL;
+ maxtime = -HUGE_VAL;
+
+ for (numelem = 1, tottime = 0.0, k = 0; k < 5; k++) {
+ glPushAttrib(GL_ALL_ATTRIB_BITS);
+ bmark->init();
+
+ stime = glutGet(GLUT_ELAPSED_TIME);
+ numelem = bmark->run(bmark->size[j], num);
+ glFinish();
+ etime = glutGet(GLUT_ELAPSED_TIME);
+
+ glPopAttrib();
+
+ dtime = (etime - stime) / 1000.0;
+ tottime += dtime;
+
+ fprintf(stderr, "Elapsed time for run %d: %f\n", k, dtime);
+
+ if (dtime < mintime)
+ mintime = dtime;
+ if (dtime > maxtime)
+ maxtime = dtime;
+ }
+
+ tottime -= mintime + maxtime;
+
+ fprintf(stdout, "SIZE=%03d => %f %s/sec", bmark->size[j],
+ numelem / (tottime / 3.0), bmark->unit);
+ if (bmark->type == 2)
+ fprintf(stdout, ", MPixel Fill/sec: %f\n",
+ (numelem * bmark->size[j] * bmark->size[j] / 2) /
+ (1000000.0 * tottime / 3.0));
+ else
+ fprintf(stdout, "\n");
+ }
+
+ fprintf(stdout, "\n\n");
+}
+
+/***************************************************************************/
+
+static void
+display(void)
+{
+ int i;
+
+ if (frontbuffer)
+ glDrawBuffer(GL_FRONT);
+ else
+ glDrawBuffer(GL_BACK);
+
+ for (i = 0; i < NUM_BMARKS; i++) {
+ fprintf(stderr, "Benchmark: %d\n", i);
+
+ switch (bmarks[i].type) {
+ case 0:
+ case 3:
+ dotest0param(&bmarks[i]);
+ break;
+ case 1:
+ case 2:
+ dotest1param(&bmarks[i]);
+ break;
+ }
+ }
+
+ exit(0);
+}
+
+int
+main(int ac, char **av)
+{
+ fprintf(stderr, "GLTest v1.0\nWritten by David Bucciarelli\n");
+
+ if (ac == 2)
+ frontbuffer = 0;
+
+ glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
+ glutInitWindowPosition(0, 0);
+ glutInitWindowSize(640, 480);
+ glutCreateWindow("OpenGL/Mesa Performances");
+ glutDisplayFunc(display);
+ glutMainLoop();
+
+ return 0;
+}
diff --git a/demos/natives/x11/xfont.c b/demos/natives/x11/xfont.c
new file mode 100644
index 0000000..a63257c
--- /dev/null
+++ b/demos/natives/x11/xfont.c
@@ -0,0 +1,195 @@
+/* $Id$ */
+
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 1999 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/*
+ * Example of using glXUseXFont().
+ * 5 November 1999
+ * Brian Paul
+ */
+
+
+#include <GL/gl.h>
+#include <GL/glx.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+static const char *ProgramName = "xfont";
+
+static const char *FontName = "fixed";
+
+static GLuint FontBase = 0;
+
+ GLXContext ctx;
+ Window win;
+
+
+static void redraw(Display *dpy )
+{
+ static const char *text = "This is glXUseXFont()";
+
+ glXMakeCurrent( dpy, win, ctx );
+ glClear( GL_COLOR_BUFFER_BIT );
+
+ /* triangle */
+ glColor3f( 0.2, 0.2, 1.0 );
+ glBegin(GL_TRIANGLES);
+ glVertex2f( 0, 0.8 );
+ glVertex2f( -0.8, -0.7 );
+ glVertex2f( 0.8, -0.7 );
+ glEnd();
+
+ /* text */
+ glColor3f( 1, 1, 1 );
+ glRasterPos2f(-0.8, 0);
+ glListBase(FontBase);
+ glCallLists(strlen(text), GL_UNSIGNED_BYTE, (GLubyte *) text);
+
+ glXSwapBuffers( dpy, win );
+
+ /**
+ * NOTE:
+ * this is the "bad" call,
+ * which produces so many "(II) [GLX]:" messages in .X.err
+ * by the NVidia 0.96 linux driver !
+ *
+ * but it is a MUST, if we assume,
+ * that this ctx should be called many threads
+ * -> only one thread can hold the ctx at a time !
+ */
+ glXMakeCurrent( dpy, None, NULL);
+}
+
+
+
+static void setup_font( Display *dpy )
+{
+ XFontStruct *fontInfo;
+ Font id;
+ unsigned int first, last;
+
+ fontInfo = XLoadQueryFont(dpy, FontName);
+ if (!fontInfo) {
+ printf("Error: font %s not found\n", FontName);
+ exit(0);
+ }
+
+ id = fontInfo->fid;
+ first = fontInfo->min_char_or_byte2;
+ last = fontInfo->max_char_or_byte2;
+
+ FontBase = glGenLists((GLuint) last + 1);
+ if (!FontBase) {
+ printf("Error: unable to allocate display lists\n");
+ exit(0);
+ }
+ glXUseXFont(id, first, last - first + 1, FontBase + first);
+}
+
+static Window make_rgb_db_window( Display *dpy, int xpos, int ypos,
+ unsigned int width, unsigned int height )
+{
+ int attrib[] = { GLX_RGBA,
+ GLX_RED_SIZE, 1,
+ GLX_GREEN_SIZE, 1,
+ GLX_BLUE_SIZE, 1,
+ GLX_DOUBLEBUFFER,
+ None };
+ int scrnum;
+ XSetWindowAttributes attr;
+ unsigned long mask;
+ Window root;
+ XVisualInfo *visinfo;
+
+ scrnum = DefaultScreen( dpy );
+ root = RootWindow( dpy, scrnum );
+
+ visinfo = glXChooseVisual( dpy, scrnum, attrib );
+ if (!visinfo) {
+ printf("Error: couldn't get an RGB, Double-buffered visual\n");
+ exit(1);
+ }
+
+ /* window attributes */
+ attr.background_pixel = 0;
+ attr.border_pixel = 0;
+ attr.colormap = XCreateColormap( dpy, root, visinfo->visual, AllocNone);
+ attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
+ mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
+
+ win = XCreateWindow( dpy, root, 0, 0, width, height,
+ 0, visinfo->depth, InputOutput,
+ visinfo->visual, mask, &attr );
+
+ {
+ XSizeHints sizehints;
+ sizehints.x = xpos;
+ sizehints.y = ypos;
+ sizehints.width = width;
+ sizehints.height = height;
+ sizehints.flags = USSize | USPosition;
+ XSetNormalHints(dpy, win, &sizehints);
+ XSetStandardProperties(dpy, win, ProgramName, ProgramName,
+ None, (char **)NULL, 0, &sizehints);
+ }
+
+
+ ctx = glXCreateContext( dpy, visinfo, NULL, True );
+
+ glXMakeCurrent( dpy, win, ctx );
+
+ return win;
+}
+
+
+static void event_loop( Display *dpy )
+{
+ while (1) {
+ redraw(dpy );
+ }
+}
+
+
+
+int main( int argc, char *argv[] )
+{
+ Display *dpy;
+ Window win;
+
+ dpy = XOpenDisplay(NULL);
+
+ win = make_rgb_db_window( dpy, 0, 0, 300, 300 );
+ setup_font( dpy );
+
+ glShadeModel( GL_FLAT );
+ glClearColor( 0.5, 0.5, 1.0, 1.0 );
+
+ XMapWindow( dpy, win );
+
+ event_loop( dpy );
+ return 0;
+}
diff --git a/demos/natives/x11/xfont.sh b/demos/natives/x11/xfont.sh
new file mode 100755
index 0000000..a311161
--- /dev/null
+++ b/demos/natives/x11/xfont.sh
@@ -0,0 +1,9 @@
+#! /bin/sh
+
+rm -f xfont
+
+gcc -I/usr/X11R6/include -g -O2 -Wall -o xfont xfont.c \
+ -L/usr/X11R6/lib -lGLU -lGL
+
+./xfont
+
diff --git a/gl4java/GLCapabilities.java b/gl4java/GLCapabilities.java
new file mode 100755
index 0000000..f3beb79
--- /dev/null
+++ b/gl4java/GLCapabilities.java
@@ -0,0 +1,313 @@
+package gl4java;
+
+/** Specifies a set of OpenGL capabilities that a rendering context
+ must support, such as color depth and whether stereo is
+ enabled. It currently contains the minimal number of routines
+ which allow configuration on all supported window systems. */
+
+public class GLCapabilities
+ implements Cloneable
+{
+
+ private static final int BUFFER_SINGLE = 0;
+ private static final int BUFFER_DOUBLE = 1;
+
+ private static final int COLOR_INDEX = 0;
+ private static final int COLOR_RGBA = 1;
+
+ private static final int STEREO_OFF = 0;
+ private static final int STEREO_ON = 1;
+
+ // Boolean attributes
+ // NOTE that we do not specify on- or off-screen visuals here --
+ // that will be taken care of by the factory.
+
+ /* x11: exact value
+ w32: exact value
+ */
+ private int buffer = BUFFER_DOUBLE;
+
+ /* x11: exact value
+ w32: exact value
+ */
+ private int color = COLOR_RGBA;
+
+ /* x11: exact value
+ w32: exact value
+ */
+ private int stereo = STEREO_OFF;
+
+ /* x11: getting the largest regardless the value if >0, set to max
+ w32: getting the best from it's max
+ */
+ private int depthBits = 24;
+
+ /* x11: getting the best from it's max
+ w32: getting the best from it's max
+ */
+ private int stencilBits = 0;
+
+ /* x11: getting the largest regardless the value if >0, set to max
+
+ w32: getting the best from it's max
+ cColorBits := redBits + greenBits + blueBits
+ */
+ private int redBits = 8;
+ private int greenBits = 8;
+ private int blueBits = 8;
+ private int alphaBits = 0;
+
+ /* x11: getting the largest regardless the value if >0, set to max
+
+ w32: getting the best from it's max
+ cAccumBits := accumRedBits + accumGreenBits + accumBlueBits +
+ accumAlphaBits
+ */
+ private int accumRedBits = 0;
+ private int accumGreenBits = 0;
+ private int accumBlueBits = 0;
+ private int accumAlphaBits = 0;
+
+ /**
+ * this is the holder for the native visualID,
+ * e.g. Win32's number of the PIXELFORMATDESC,
+ * or X11's VisualID
+ */
+ private long nativeVisualID = -1;
+
+ // Shift bits from PIXELFORMATDESCRIPTOR not present because they
+ // are unlikely to be supported on Windows anyway
+
+ /** Creates a GLCapabilities object. All attributes are in
+ a default state, they can be configured by the client.
+ The arguments are the usual user defined capabilities,
+ which can be set here for construction.
+ */
+ public GLCapabilities(boolean doubleBuffer, boolean stereoView,
+ boolean rgba,
+ int stencilBits,
+ int accumRedSize, int accumGreenSize,
+ int accumBlueSize, int accumAlphaSize)
+ {
+ setDoubleBuffered(doubleBuffer);
+ setStereo(stereoView);
+ setTrueColor(rgba);
+ setStencilBits(stencilBits);
+ setAccumRedBits(accumRedSize);
+ setAccumGreenBits(accumGreenSize);
+ setAccumBlueBits(accumBlueSize);
+ setAccumAlphaBits(accumAlphaSize);
+ }
+
+ /** Creates a GLCapabilities object. All attributes are in
+ a default state, they can be configured by the client.
+ */
+ public GLCapabilities() {}
+
+ public Object clone()
+ throws CloneNotSupportedException
+ {
+ GLCapabilities nobj = new GLCapabilities();
+ nobj.buffer=buffer;
+ nobj.color=color;
+ nobj.stereo=stereo;
+ nobj.depthBits=depthBits;
+ nobj.stencilBits=stencilBits;
+ nobj.redBits=redBits;
+ nobj.greenBits=greenBits;
+ nobj.blueBits=blueBits;
+ nobj.alphaBits=alphaBits;
+ nobj.accumRedBits=accumRedBits;
+ nobj.accumGreenBits=accumGreenBits;
+ nobj.accumBlueBits=accumBlueBits;
+ nobj.accumAlphaBits=accumAlphaBits;
+ nobj.nativeVisualID=nativeVisualID;
+ return nobj;
+ }
+
+ /** Indicates whether double-buffering is enabled. */
+ public boolean getDoubleBuffered() { return buffer == BUFFER_DOUBLE; }
+
+ /** Indicates whether true color (as opposed to indexed color) is
+ enabled. */
+ public boolean getTrueColor() { return color == COLOR_RGBA; }
+
+ /** Indicates whether stereo is enabled. */
+ public boolean getStereo() { return stereo == STEREO_ON; }
+
+ /** Enables or disables double buffering. */
+ public void setDoubleBuffered(boolean onOrOff) {
+ buffer = (onOrOff ? BUFFER_DOUBLE : BUFFER_SINGLE);
+ }
+
+ /** Enables or disables true color (RGBA mode). */
+ public void setTrueColor(boolean onOrOff) {
+ color = (onOrOff ? COLOR_RGBA : COLOR_INDEX);
+ }
+
+ /** Enables or disables stereo viewing. */
+ public void setStereo(boolean onOrOff) {
+ stereo = (onOrOff ? STEREO_ON : STEREO_OFF);
+ }
+
+ /** Returns number of bits requested for depth buffer */
+ public int getDepthBits() { return depthBits; }
+
+ /** Sets number of bits requested for depth buffer */
+ public void setDepthBits(int depthBits) { this.depthBits = depthBits; }
+
+ /** Returns number of bits requested for stencil buffer */
+ public int getStencilBits() { return stencilBits; }
+
+ /** Sets number of bits requested for stencil buffer */
+ public void setStencilBits(int stencilBits) { this.stencilBits = stencilBits; }
+
+ /** Returns number of bits requested for color buffer's red
+ component. On some systems and in color index mode only the
+ color depth, which is the sum of the red, green, and blue bits,
+ is considered. */
+ public int getRedBits() { return redBits; }
+
+ /** Sets number of bits requested for color buffer's red
+ component. On some systems and in color index mode only the
+ color depth, which is the sum of the red, green, and blue bits,
+ is considered. */
+ public void setRedBits(int redBits) { this.redBits = redBits; }
+
+ /** Returns number of bits requested for color buffer's green
+ component. On some systems and in color index mode only the
+ color depth, which is the sum of the red, green, and blue bits,
+ is considered. */
+ public int getGreenBits() { return greenBits; }
+
+ /** Sets number of bits requested for color buffer's green
+ component. On some systems and in color index mode only the
+ color depth, which is the sum of the red, green, and blue bits,
+ is considered. */
+ public void setGreenBits(int greenBits) { this.greenBits = greenBits; }
+
+ /** Returns number of bits requested for color buffer's blue
+ component. On some systems and in color index mode only the
+ color depth, which is the sum of the red, green, and blue bits,
+ is considered. */
+ public int getBlueBits() { return blueBits; }
+
+ /** Sets number of bits requested for color buffer's blue
+ component. On some systems and in color index mode only the
+ color depth, which is the sum of the red, green, and blue bits,
+ is considered. */
+ public void setBlueBits(int blueBits) { this.blueBits = blueBits; }
+
+ /** Returns number of bits requested for color buffer's alpha
+ component. On some systems and in color index mode only the
+ color depth, which is the sum of the red, green, and blue bits,
+ is considered. */
+ public int getAlphaBits() { return alphaBits; }
+
+ /** Sets number of bits requested for color buffer's alpha
+ component. On some systems and in color index mode only the
+ color depth, which is the sum of the red, green, and blue bits,
+ is considered. */
+ public void setAlphaBits(int alphaBits) { this.alphaBits = alphaBits; }
+
+ /** Returns number of bits requested for accumulation buffer's red
+ component. On some systems only the accumulation buffer depth,
+ which is the sum of the red, green, and blue bits, is
+ considered. */
+ public int getAccumRedBits() { return accumRedBits; }
+
+ /** Sets number of bits requested for accumulation buffer's red
+ component. On some systems only the accumulation buffer depth,
+ which is the sum of the red, green, and blue bits, is
+ considered. */
+ public void setAccumRedBits(int accumRedBits) { this.accumRedBits = accumRedBits; }
+
+ /** Returns number of bits requested for accumulation buffer's green
+ component. On some systems only the accumulation buffer depth,
+ which is the sum of the red, green, and blue bits, is
+ considered. */
+ public int getAccumGreenBits() { return accumGreenBits; }
+
+ /** Sets number of bits requested for accumulation buffer's green
+ component. On some systems only the accumulation buffer depth,
+ which is the sum of the red, green, and blue bits, is
+ considered. */
+ public void setAccumGreenBits(int accumGreenBits) { this.accumGreenBits = accumGreenBits; }
+
+ /** Returns number of bits requested for accumulation buffer's blue
+ component. On some systems only the accumulation buffer depth,
+ which is the sum of the red, green, and blue bits, is
+ considered. */
+ public int getAccumBlueBits() { return accumBlueBits; }
+
+ /** Sets number of bits requested for accumulation buffer's blue
+ component. On some systems only the accumulation buffer depth,
+ which is the sum of the red, green, and blue bits, is
+ considered. */
+ public void setAccumBlueBits(int accumBlueBits) { this.accumBlueBits = accumBlueBits; }
+
+ /** Returns number of bits requested for accumulation buffer's alpha
+ component. On some systems only the accumulation buffer depth,
+ which is the sum of the red, green, and blue bits, is
+ considered. */
+ public int getAccumAlphaBits() { return accumAlphaBits; }
+
+ /** Sets number of bits requested for accumulation buffer's alpha
+ component. On some systems only the accumulation buffer depth,
+ which is the sum of the red, green, and blue bits, is
+ considered. */
+ public void setAccumAlphaBits(int accumAlphaBits) { this.accumAlphaBits = accumAlphaBits; }
+
+ /**
+ * Set the fetched native VisualID.
+ * This is an interface for the Factory and GLContext.
+ *
+ * Because the GLCapabilities are copied through
+ * the handling between the Factory and GLContext,
+ * you cannot missuse it ..
+ *
+ * this is the holder for the native visualID,
+ * e.g. Win32's number of the PIXELFORMATDESC,
+ * or X11's VisualID
+ */
+ public void setNativeVisualID(long id)
+ { nativeVisualID = id; }
+
+ /**
+ * Get the fetched native VisualID.
+ * This is an interface for the Factory and GLContext.
+ *
+ * this is the holder for the native visualID,
+ * e.g. Win32's number of the PIXELFORMATDESC,
+ * or X11's VisualID
+ */
+ public long getNativeVisualID()
+ { return nativeVisualID ; }
+
+
+ public String toString()
+ {
+ return "GLCapabilities ["+
+ "DoubleBuffer: "+buffer+", "+
+ "RGBA: "+ color+", "+
+ "Stereo: "+ stereo+",\n\t"+
+ "DepthSize: "+ depthBits+", "+
+ "StencilSize: "+ stencilBits+",\n\t"+
+ "Red: "+ redBits+", "+
+ "Green: "+ greenBits+", "+
+ "Blue: "+ blueBits+", "+
+ "Alpha: "+ alphaBits+",\n\t"+
+ "Red Accum: "+ accumRedBits+", "+
+ "Green Accum: "+ accumGreenBits+", "+
+ "Blue Accum: "+ accumBlueBits+", "+
+ "Alpha Accum: "+ accumAlphaBits+",\n\t"+
+ "NativeVisualID: "+nativeVisualID+
+ "] ";
+ }
+
+ public static void main( String args[] )
+ {
+ GLCapabilities glCaps = new GLCapabilities();
+ System.out.println("Default GLCapabilities:\n"+glCaps);
+ }
+}
diff --git a/gl4java/drawable/DummyGLDrawableFactory.java b/gl4java/drawable/DummyGLDrawableFactory.java
new file mode 100644
index 0000000..0ba0429
--- /dev/null
+++ b/gl4java/drawable/DummyGLDrawableFactory.java
@@ -0,0 +1,39 @@
+package gl4java.drawable;
+
+import gl4java.*;
+import gl4java.awt.*;
+
+public class DummyGLDrawableFactory extends GLDrawableFactory {
+
+ DummyGLDrawableFactory() {
+ }
+
+ public GLAnimCanvas createGLAnimCanvas(GLCapabilities capabilities,
+ int width,
+ int height,
+ String glName,
+ String gluName)
+ {
+ GLCapabilities own = null;
+ try {
+ own = (GLCapabilities) capabilities.clone();
+ } catch (Exception ex) { System.out.println(ex); own=capabilities; }
+
+ return new GLAnimCanvas(own, width, height, glName, gluName);
+ }
+
+ public GLCanvas createGLCanvas(GLCapabilities capabilities,
+ int width,
+ int height,
+ String glName,
+ String gluName)
+ {
+ GLCapabilities own = null;
+ try {
+ own = (GLCapabilities) capabilities.clone();
+ } catch (Exception ex) { System.out.println(ex); own=capabilities; }
+
+ return new GLCanvas(own, width, height, glName, gluName);
+ }
+
+}
diff --git a/gl4java/drawable/GLDrawable.java b/gl4java/drawable/GLDrawable.java
new file mode 100644
index 0000000..a0818c0
--- /dev/null
+++ b/gl4java/drawable/GLDrawable.java
@@ -0,0 +1,73 @@
+package gl4java.drawable;
+
+import java.awt.event.*;
+import java.util.EventListener;
+
+import gl4java.*;
+
+/** Abstracts common functionality among the OpenGL components such as
+ GLCanvas and GLJPanel. The GLDrawable/GLEventListener interfaces
+ allow client code to draw using OpenGL without subclassing. */
+
+public interface GLDrawable
+{
+ /** Add a GLEventListener to this drawable. If multiple listeners
+ are added to a given drawable, they are notified of events in an
+ arbitrary order. */
+ public void addGLEventListener(GLEventListener listener);
+
+ /** Remove a GLEventListener from this drawable. */
+ public void removeGLEventListener(GLEventListener listener);
+
+ /** Gets the GL functions used by this drawable. */
+ public GLFunc getGL();
+
+ /** Gets the GLU functions used by this drawable. */
+ public GLUFunc getGLU();
+
+ /**
+ * Used to return the created GLContext
+ */
+ public GLContext getGLContext();
+
+ /**
+ * the components listener's should be implemented also !
+ * since JDK 1.1
+ */
+ public void addComponentListener(ComponentListener l);
+ public void removeComponentListener(ComponentListener l);
+ public void addFocusListener(FocusListener l);
+ public void addKeyListener(KeyListener l);
+ public void removeFocusListener(FocusListener l);
+ public void addMouseListener(MouseListener l);
+ public void removeMouseListener(MouseListener l);
+ public void addMouseMotionListener(MouseMotionListener l);
+ public void removeMouseMotionListener(MouseMotionListener l);
+
+ /**
+ * JDK 1.2 the components listener's are left,
+ * because of JDK 1.1 compatibility
+ *
+ public void addInputMethodListener(InputMethodListener l);
+ public void removeInputMethodListener(InputMethodListener l);
+ */
+
+ /**
+ * JDK 1.3 the components listener's are left,
+ * because of JDK 1.1 compatibility
+ *
+ public void addHierarchyListener(HierarchyListener l);
+ public void removeHierarchyListener(HierarchyListener l);
+ public void addHierarchyBoundsListener(HierarchyBoundsListener l);
+ public void removeHierarchyBoundsListener(HierarchyBoundsListener l);
+ */
+
+
+ /**
+ * JDK 1.3 the listener's methods are left,
+ * because of JDK 1.1 compatibility
+ * since JDK 1.3, e.g. implemented within GLCanvas
+ *
+ public EventListener[] getListeners(Class listenerType);
+ */
+}
diff --git a/gl4java/drawable/GLDrawableFactory.java b/gl4java/drawable/GLDrawableFactory.java
new file mode 100644
index 0000000..603cf37
--- /dev/null
+++ b/gl4java/drawable/GLDrawableFactory.java
@@ -0,0 +1,222 @@
+package gl4java.drawable;
+
+import java.awt.*;
+import gl4java.*;
+import gl4java.awt.*;
+import gl4java.swing.*;
+
+/** <P> Provides a VM- and OS-independent mechanism for creating
+ {@link gl4java.awt.GLAnimCanvas},
+ {@link gl4java.awt.GLCanvas},
+ {@link gl4java.swing.GLAnimJPanel}
+ and {@link gl4java.swing.GLJPanel}
+ objects. Most useful when used in conjunction with the {@link
+ gl4java.drawable.GLEventListener} model, where subclassing is not
+ required. </P>
+
+ <P> The {@link gl4java.GLCapabilities} objects passed in to the
+ various factory methods are used as a minimum specification for
+ the properties of the returned GLCanvas. The canvas will either
+ meet or exceed all of the integer properties such as color and
+ accumulation buffer depth and will match all of the boolean
+ properties such as enabling or disabling of stereo. The selection
+ algorithm in general attempts to select the most minimal window
+ type to meet the criteria, but is otherwise left loosely
+ specified.
+ </P>
+
+ <P> The implementing class of this abstract factory methods
+ does clone your given GLCapabilities. So your version is unchanged.
+ The GLContext's GLCapabilites instance is changed to
+ the used capabilities, so you can query GLContext's GLCapabilites!
+ </P>
+
+ <P> It is currently not possible to specify GLCapabilities for
+ lightweight components. </P>
+*/
+
+public abstract class GLDrawableFactory {
+
+ static {
+ GLContext.loadNativeLibraries(null, null, null);
+ }
+
+ private static GLDrawableFactory soleInstance;
+
+ /** Returns the sole instance of the GLCanvasFactory (singleton
+ pattern). */
+ public static GLDrawableFactory getFactory() {
+
+ GLContext.loadNativeLibraries(null, null, null);
+
+ String jvmVendor = GLContext.getJVMVendor();
+ boolean isIBMJvm = jvmVendor!=null && jvmVendor.indexOf("IBM")>=0 ;
+ boolean isMicrosoftJvm =
+ jvmVendor!=null && jvmVendor.indexOf("Microsoft")>=0 ;
+
+ if (soleInstance == null) {
+ if( GLContext.getJVMVersionMajor()>=2 ||
+ ( GLContext.getJVMVersionMajor()==1 &&
+ GLContext.getJVMVersionMinor()>=4
+ ) ||
+ ( GLContext.getJVMVersionMajor()==1 &&
+ GLContext.getJVMVersionMinor()>=3 &&
+ !isIBMJvm && !isMicrosoftJvm
+ )
+ )
+ {
+ String clazzName = null;
+
+ switch(GLContext.getNativeOSType())
+ {
+ case GLContext.OsWindoof:
+ clazzName =
+ "gl4java.drawable.Win32SunJDK13GLDrawableFactory";
+ break;
+ case GLContext.OsMac:
+ clazzName =
+ "gl4java.drawable.MacSunJDK13GLDrawableFactory";
+ break;
+ case GLContext.OsX11:
+ clazzName =
+ "gl4java.drawable.X11SunJDK13GLDrawableFactory";
+ break;
+ default:
+ System.out.println("GLDrawableFactory: Unsupported OS: "+
+ GLContext.getNativeOSName() + ", using DummyGLDrawableFactory");
+ }
+
+ if(clazzName!=null)
+ {
+ try {
+ soleInstance = (GLDrawableFactory)
+ Class.forName(clazzName).newInstance();
+ } catch (Exception ex) {
+ System.out.println("GLDrawableFactory: could not create instance of: "+ clazzName + ", using DummyGLDrawableFactory");
+ }
+ }
+ }
+
+ if( soleInstance == null )
+ {
+ soleInstance = new DummyGLDrawableFactory();
+ }
+ }
+ return soleInstance;
+ }
+
+ /** Create a new GLAnimCanvas given the specified GLCapabilities.
+
+ @param capabilities the requested set of OpenGL capabilities of
+ the canvas
+ @param width the canvas's initial width
+ @param height the canvas's initial height
+
+ @return a GLAnimCanvas supporting the set of specified capabilities,
+ or null if there was no matching visual */
+ public GLAnimCanvas createGLAnimCanvas(GLCapabilities capabilities,
+ int width,
+ int height)
+ {
+ return createGLAnimCanvas(capabilities, width, height, null, null);
+ }
+
+ /** Create a new GLAnimCanvas given the specified GLCapabilities.
+
+ @param capabilities the requested set of OpenGL capabilities of
+ the canvas
+ @param width the canvas's initial width
+ @param height the canvas's initial height
+ @param glName the name of the GLFunc implementation.
+ If null, the default class will be used
+ @param gluName the name of the GLUFunc implementation.
+ If null, the default class will be used
+
+ @return a GLAnimCanvas supporting the set of specified capabilities,
+ or null if there was no matching visual */
+ public abstract GLAnimCanvas createGLAnimCanvas(GLCapabilities capabilities,
+ int width,
+ int height,
+ String glName,
+ String gluName);
+
+ /** Create a new GLCanvas given the specified GLCapabilities.
+
+ @param capabilities the requested set of OpenGL capabilities of
+ the canvas
+ @param width the canvas's initial width
+ @param height the canvas's initial height
+
+ @return a GLCanvas supporting the set of specified capabilities,
+ or null if there was no matching visual */
+ public GLCanvas createGLCanvas(GLCapabilities capabilities,
+ int width,
+ int height)
+ {
+ return createGLCanvas(capabilities, width, height, null, null);
+ }
+
+ /** Create a new GLCanvas given the specified GLCapabilities.
+
+ @param capabilities the requested set of OpenGL capabilities of
+ the canvas
+ @param width the canvas's initial width
+ @param height the canvas's initial height
+ @param glName the name of the GLFunc implementation.
+ If null, the default class will be used
+ @param gluName the name of the GLUFunc implementation.
+ If null, the default class will be used
+
+ @return a GLCanvas supporting the set of specified capabilities,
+ or null if there was no matching visual */
+ public abstract GLCanvas createGLCanvas(GLCapabilities capabilities,
+ int width,
+ int height,
+ String glName,
+ String gluName);
+
+ /** Create a new GLAnimJPanel. */
+ public GLAnimJPanel createGLAnimJPanel() {
+ return new GLAnimJPanel();
+ }
+
+ /** Create a new GLAnimJPanel with the specified GL/GLU library names,
+ LayoutManager, and double buffering specification.
+
+ @param glName the name of the GLFunc implementation.
+ If null, the default class will be used
+ @param gluName the name of the GLUFunc implementation.
+ If null, the default class will be used
+ @param layout the layout manager
+ @param isDoubleBuffered indicates if double buffering should be used
+ */
+ public GLAnimJPanel createGLAnimJPanel(String glName,
+ String gluName,
+ LayoutManager layout,
+ boolean isDoubleBuffered) {
+ return new GLAnimJPanel(glName, gluName, layout, isDoubleBuffered);
+ }
+
+ /** Create a new GLJPanel. */
+ public GLJPanel createGLJPanel() {
+ return new GLJPanel();
+ }
+
+ /** Create a new GLJPanel with the specified GL/GLU library names,
+ LayoutManager, and double buffering specification.
+
+ @param glName the name of the GLFunc implementation.
+ If null, the default class will be used
+ @param gluName the name of the GLUFunc implementation.
+ If null, the default class will be used
+ @param layout the layout manager
+ @param isDoubleBuffered indicates if double buffering should be used
+ */
+ public GLJPanel createGLJPanel(String glName,
+ String gluName,
+ LayoutManager layout,
+ boolean isDoubleBuffered) {
+ return new GLJPanel(glName, gluName, layout, isDoubleBuffered);
+ }
+
+}
diff --git a/gl4java/drawable/GLEventListener.java b/gl4java/drawable/GLEventListener.java
new file mode 100644
index 0000000..feb388d
--- /dev/null
+++ b/gl4java/drawable/GLEventListener.java
@@ -0,0 +1,102 @@
+package gl4java.drawable;
+
+import gl4java.GLEnum;
+import gl4java.GLUEnum;
+
+/** Declares events which client code can handle to perform OpenGL
+ rendering into a GLDrawable without subclassing. */
+
+public interface GLEventListener
+ extends java.util.EventListener, GLEnum, GLUEnum
+{
+ /** Called by the drawable immediately after the OpenGL context is
+ initialized; the GLContext has already been made current when
+ this method is called. Can be used to perform one-time OpenGL
+ initialization such as setup of lights and display lists.
+
+ @see gl4java.awt.GLCanvas#init
+ @see gl4java.swing.GLJPanel#init
+ */
+ public void init(GLDrawable drawable);
+
+ /** Called by the drawable before initiate rendering by the client. At
+ the time this method is called, the duration for this frames
+ time consume is started.
+ After all GLEventListeners have been notified of a preDisplay event,
+ the drawable will continues with the
+ {@link gl4java.drawable.GLEventListener#display} event.
+
+ @see gl4java.awt.GLAnimCanvas#display
+ @see gl4java.awt.GLCanvas#display
+ @see gl4java.swing.GLJPanel#display
+ @see gl4java.drawable.GLEventListener#display
+ @see gl4java.drawable.GLEventListener#postDisplay
+ */
+ public void preDisplay(GLDrawable drawable);
+
+ /** Called by the drawable to initiate rendering by the client. At
+ the time this method is called, the drawable has already called
+ {@link gl4java.drawable.GLEventListener#preDisplay} and made
+ its associated GLContext current by a call to {@link
+ gl4java.GLContext#gljMakeCurrent}. After all GLEventListeners
+ have been notified of a display event, the drawable will swap
+ its buffers if necessary and then free its GLContext with a call
+ to {@link gl4java.GLContext#gljFree} and
+ and continues with the
+ {@link gl4java.drawable.GLEventListener#postDisplay} event.
+ So the GLContext is locked while the GLEventListeners
+ receives this display event.
+
+ @see gl4java.awt.GLAnimCanvas#display
+ @see gl4java.awt.GLCanvas#display
+ @see gl4java.swing.GLJPanel#display
+ @see gl4java.drawable.GLEventListener#preDisplay
+ @see gl4java.drawable.GLEventListener#postDisplay
+ */
+ public void display(GLDrawable drawable);
+
+ /** Called by the drawable after initiate rendering by the client. At
+ the time this method is called, the drawable has already called
+ {@link gl4java.drawable.GLEventListener#display}.
+ After all GLEventListeners
+ have been notified of a postDisplay event, the
+ duration for the consumed time is stopped.
+
+ @see gl4java.awt.GLAnimCanvas#display
+ @see gl4java.awt.GLCanvas#display
+ @see gl4java.swing.GLJPanel#display
+ @see gl4java.drawable.GLEventListener#preDisplay
+ @see gl4java.drawable.GLEventListener#display
+ @see gl4java.drawable.GLEventListener#postDisplay
+ */
+ public void postDisplay(GLDrawable drawable);
+
+ /** Called by the drawable if it wants to destroy itself.
+ Here you can clean up any OpenGL stuff (delete textures
+ or whatever) prior to actually deleting the OpenGL context.
+
+ @see gl4java.awt.GLCanvas#doCleanup
+ @see gl4java.swing.GLJPanel#doCleanup
+ */
+ public void cleanup(GLDrawable drawable);
+
+ /** Called by the drawable during the first repaint after the
+ component has been resized. The client can update the viewport
+ and view volume of the window appropriately, for example by a
+ call to {@link gl4java.GLFunc#glViewport}; note that for
+ convenience the component has already called {@link
+ gl4java.GLContext#gljResize}(width, height) and {@link
+ gl4java.GLFunc.glViewport}(0, 0, width, height) when this method
+ is called, so the client may not have to do anything in this
+ method. At the time this method is called, the drawable has
+ already made its associated GLContext current by a call to
+ {@link gl4java.GLContext#gljMakeCurrent}. After all
+ GLEventListeners have been notified of a reshape event, the
+ drawable will free its GLContext with a call to {@link
+ gl4java.GLContext#gljFree}.
+
+ @see gl4java.awt.GLCanvas#reshape
+ @see gl4java.swing.GLJPanel#reshape
+ */
+ public void reshape(GLDrawable drawable, int width, int height);
+}
diff --git a/gl4java/drawable/MacSunJDK13GLDrawableFactory.java b/gl4java/drawable/MacSunJDK13GLDrawableFactory.java
new file mode 100644
index 0000000..7cf368d
--- /dev/null
+++ b/gl4java/drawable/MacSunJDK13GLDrawableFactory.java
@@ -0,0 +1,23 @@
+package gl4java.drawable;
+
+import sun.awt.*;
+import gl4java.*;
+
+public class MacSunJDK13GLDrawableFactory
+ extends SunJDK13GLDrawableFactory
+{
+
+ public MacSunJDK13GLDrawableFactory() { }
+
+ public GraphicsConfiguration
+ getGraphicsConfiguration(GLCapabilities capabilities,
+ GraphicsDevice device)
+ {
+ return null;
+ }
+
+ // Needs to return an XVisualID which can be wrapped in an
+ // X11GraphicsConfig object
+ //public static native long glXChooseVisual(int screen,
+ // GLCapabilities capabilities);
+}
diff --git a/gl4java/drawable/SunJDK13GLDrawableFactory.java b/gl4java/drawable/SunJDK13GLDrawableFactory.java
new file mode 100755
index 0000000..bc707d8
--- /dev/null
+++ b/gl4java/drawable/SunJDK13GLDrawableFactory.java
@@ -0,0 +1,74 @@
+package gl4java.drawable;
+
+import java.awt.*;
+import gl4java.*;
+import gl4java.awt.*;
+
+/** A GLDrawableFactory which works with Sun's JDK 1.3 or greater. */
+
+public abstract class SunJDK13GLDrawableFactory extends GLDrawableFactory {
+
+ public GLAnimCanvas createGLAnimCanvas(GLCapabilities capabilities,
+ int width,
+ int height,
+ String glName,
+ String gluName)
+ {
+ GLCapabilities own = null;
+ try {
+ own = (GLCapabilities) capabilities.clone();
+ } catch (Exception ex) { System.out.println(ex); own=capabilities; }
+
+ GraphicsConfiguration config = getGraphicsConfiguration(own);
+ if (config == null) {
+ return null;
+ }
+ return new GLAnimCanvas(config, own,
+ width, height, glName, gluName);
+ }
+
+ public GLCanvas createGLCanvas(GLCapabilities capabilities,
+ int width,
+ int height,
+ String glName,
+ String gluName)
+ {
+ GLCapabilities own = null;
+ try {
+ own = (GLCapabilities) capabilities.clone();
+ } catch (Exception ex) { System.out.println(ex); own=capabilities; }
+
+ GraphicsConfiguration config = getGraphicsConfiguration(own);
+ if (config == null) {
+ return null;
+ }
+ return new GLCanvas(config, own,
+ width, height, glName, gluName);
+ }
+
+ /** Returns the GraphicsConfiguration most closely matching the
+ specified set of GLCapabilities, or null if there was no
+ matching visual.
+
+ @param capabilities the requested set of OpenGL capabilities of
+ the canvas
+ @return a GraphicsConfiguration supporting the set of specified capabilities,
+ or null if there was no matching visual
+ */
+ public GraphicsConfiguration getGraphicsConfiguration
+ (GLCapabilities capabilities)
+ {
+ return getGraphicsConfiguration(capabilities,
+ GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice());
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only below this point
+ //
+
+ /** The choice of the GraphicsDevice is not yet exported to
+ clients. */
+ abstract GraphicsConfiguration
+ getGraphicsConfiguration(GLCapabilities capabilities,
+ GraphicsDevice device);
+}
diff --git a/gl4java/drawable/Win32SunJDK13GLDrawableFactory.java b/gl4java/drawable/Win32SunJDK13GLDrawableFactory.java
new file mode 100644
index 0000000..da8fd93
--- /dev/null
+++ b/gl4java/drawable/Win32SunJDK13GLDrawableFactory.java
@@ -0,0 +1,327 @@
+package gl4java.drawable;
+
+import java.awt.*;
+import java.lang.reflect.*;
+import java.util.*;
+import sun.awt.*;
+import gl4java.*;
+
+public class Win32SunJDK13GLDrawableFactory
+ extends SunJDK13GLDrawableFactory
+{
+ // Use reflection to get access to internal methods in sun.awt.*
+ private static Method getMaxConfigsMethod;
+ private static Method getDefaultPixIDMethod;
+
+ static {
+ try {
+ getMaxConfigsMethod =
+ sun.awt.Win32GraphicsDevice.class.
+ getDeclaredMethod("getMaxConfigs",
+ new Class[] { Integer.TYPE });
+ getMaxConfigsMethod.setAccessible(true);
+
+ getDefaultPixIDMethod =
+ sun.awt.Win32GraphicsDevice.class.
+ getDeclaredMethod("getDefaultPixID",
+ new Class[] { Integer.TYPE });
+ getDefaultPixIDMethod.setAccessible(true);
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw new InternalError(e.toString());
+ }
+ }
+
+ public Win32SunJDK13GLDrawableFactory() {
+ // describeAllGraphicsConfigurations();
+ }
+
+ public GraphicsConfiguration
+ getGraphicsConfiguration(GLCapabilities capabilities,
+ GraphicsDevice device) {
+ // On Windows, ChoosePixelFormat does not work as desired; it
+ // shoehorns the given pixel format descriptor into what a
+ // particular window can render. Instead we enumerate all possible
+ // pixel formats for a given GraphicsDevice and try to find one
+ // matching the given capabilities. To do this we provide
+ // accessors which query the OpenGL-related properties of a
+ // GraphicsConfiguration. FIXME: should implement better selection
+ // algorithm; this one does not choose the most minimal.
+
+ Win32GraphicsConfig[] configs =
+ getAllGraphicsConfigurations((Win32GraphicsDevice) device);
+
+ int maxDepth = 0;
+ int maxColor = 0;
+ int maxStencil = 0;
+ int maxAccum = 0;
+
+ for (int i = 0; i < configs.length; i++) {
+ Win32GraphicsConfig config = configs[i];
+
+ if( ! getConfigSupportsOpenGL(config) )
+ continue;
+
+ if(getConfigDepthBits(config)>maxDepth) maxDepth=getConfigDepthBits(config);
+ if(getConfigColorBits(config)>maxColor) maxColor=getConfigColorBits(config);
+ if(getConfigStencilBits(config)>maxStencil) maxStencil=getConfigStencilBits(config);
+ if(getConfigAccumBits(config)>maxAccum) maxAccum=getConfigAccumBits(config);
+ }
+
+ if(maxDepth>24) maxDepth=24;
+
+ /** fall down to overall's maximum **/
+ if(capabilities.getDepthBits()>maxDepth) capabilities.setDepthBits(maxDepth);
+ if(capabilities.getStencilBits()>maxStencil) capabilities.setStencilBits(maxStencil);
+
+ if(getCapsColorBits(capabilities)>maxColor)
+ { capabilities.setRedBits(maxColor/3);
+ capabilities.setGreenBits(maxColor/3+maxColor%3);
+ capabilities.setBlueBits(maxColor/3);
+ }
+
+ if(getCapsAccumBits(capabilities)>maxAccum)
+ { capabilities.setAccumRedBits(maxAccum/3);
+ capabilities.setAccumGreenBits(maxAccum/3+maxAccum%3);
+ capabilities.setAccumBlueBits(maxAccum/3);
+ }
+
+ Win32GraphicsConfig config = configsSupportsCapabilities(configs, capabilities, maxDepth);
+ if(config!=null) return config;
+
+ /* lets .. fall down .. individual .. */
+
+ /* general normals .. */
+ boolean tryit = false;
+ if(capabilities.getDepthBits()>24) { capabilities.setDepthBits(24); tryit=true; }
+ else if(capabilities.getDepthBits()>16) { capabilities.setDepthBits(16); tryit=true; }
+ if(getCapsColorBits(capabilities)>24)
+ { capabilities.setRedBits(8); capabilities.setGreenBits(8); capabilities.setBlueBits(8); tryit=true; }
+ if(capabilities.getAlphaBits()>8) { capabilities.setAlphaBits(8); tryit=true; }
+ if(tryit) config = configsSupportsCapabilities(configs, capabilities, maxDepth);
+ if(config!=null) return config; tryit=false;
+
+ /* no stereo .. */
+ if(capabilities.getStereo()) { capabilities.setStereo(false); tryit=true; }
+ if(tryit) config = configsSupportsCapabilities(configs, capabilities, maxDepth);
+ if(config!=null) return config; tryit=false;
+
+ /* stencil<=16 .. */
+ if(capabilities.getStencilBits()>16) { capabilities.setStencilBits(16); tryit=true; }
+ if(tryit) config = configsSupportsCapabilities(configs, capabilities, maxDepth);
+ if(config!=null) return config; tryit=false;
+
+ /* accum rgb each <=16.. */
+ if(getCapsAccumBits(capabilities)>48)
+ { capabilities.setAccumRedBits(16); capabilities.setAccumGreenBits(16); capabilities.setAccumBlueBits(16);
+ tryit=true; }
+ if(tryit) config = configsSupportsCapabilities(configs, capabilities, maxDepth);
+ if(config!=null) return config; tryit=false;
+
+ /* stencil<=8 .. */
+ if(capabilities.getStencilBits()>8) { capabilities.setStencilBits(8); tryit=true; }
+ if(tryit) config = configsSupportsCapabilities(configs, capabilities, maxDepth);
+ if(config!=null) return config; tryit=false;
+
+ /* accum rgb each <=8.. */
+ if(getCapsAccumBits(capabilities)>24)
+ { capabilities.setAccumRedBits(8); capabilities.setAccumGreenBits(8); capabilities.setAccumBlueBits(8);
+ tryit=true; }
+ if(tryit) config = configsSupportsCapabilities(configs, capabilities, maxDepth);
+ if(config!=null) return config; tryit=false;
+
+ /* stencil=0 .. */
+ if(capabilities.getStencilBits()>0) { capabilities.setStencilBits(0); tryit=true; }
+ if(tryit) config = configsSupportsCapabilities(configs, capabilities, maxDepth);
+ if(config!=null) return config; tryit=false;
+
+ /* alpha=0 */
+ if(capabilities.getAlphaBits()>0) { capabilities.setAlphaBits(0); tryit=true; }
+ if(tryit) config = configsSupportsCapabilities(configs, capabilities, maxDepth);
+ if(config!=null) return config; tryit=false;
+
+ return null;
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only below this point
+ //
+
+ private Win32GraphicsConfig configsSupportsCapabilities(Win32GraphicsConfig[] configs,
+ GLCapabilities glCaps,
+ int maxDepth)
+ {
+ if(GLContext.gljNativeDebug)
+ {
+ System.out.println("---------------");
+ System.out.println("---------------");
+ System.out.println("---------------");
+ System.out.println("->check caps: "+glCaps);
+ System.out.println("---------------");
+ }
+ for (int i = 0; i < configs.length; i++) {
+ if (configSupportsCapabilities(configs[i], glCaps, maxDepth)) {
+ glCaps.setNativeVisualID( (long) configs[i].getVisual() );
+ return configs[i];
+ }
+ }
+ return null;
+ }
+
+ private Win32GraphicsConfig[]
+ getAllGraphicsConfigurations(Win32GraphicsDevice device)
+ {
+ try {
+ int max =
+ ((Integer) getMaxConfigsMethod.invoke(device,
+ new Object[] {
+ new Integer(device.getScreen())
+ })).intValue();
+ int defaultPixID =
+ ((Integer) getDefaultPixIDMethod.invoke(device,
+ new Object[] {
+ new Integer(device.getScreen())
+ })).intValue();
+ java.util.List l = new ArrayList(max);
+ if (defaultPixID == 0) {
+ // From Win32GraphicsDevice: workaround for failing GDI calls
+ l.add(Win32GraphicsConfig.getConfig(device, defaultPixID));
+ } else {
+ for (int i = 1; i <= max; i++) {
+ l.add(Win32GraphicsConfig.getConfig(device, i));
+ }
+ }
+ Win32GraphicsConfig[] configs = new Win32GraphicsConfig[l.size()];
+ l.toArray(configs);
+ return configs;
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw new InternalError(e.toString());
+ }
+ }
+
+ private boolean configSupportsCapabilities(Win32GraphicsConfig config,
+ GLCapabilities caps, int maxDepth)
+ {
+ boolean res = ( getConfigSupportsOpenGL(config)
+ && getConfigDoubleBuffered(config) == caps.getDoubleBuffered()
+ && caps.getTrueColor() == getConfigTrueColor(config)
+ && caps.getDepthBits() <= getConfigDepthBits(config)
+ && maxDepth >= getConfigDepthBits(config)
+ && caps.getStencilBits() <= getConfigStencilBits(config)
+ && (caps.getStereo() ? getConfigStereo(config):true)
+ && getCapsColorBits(caps) <= getConfigColorBits(config)
+ /* && caps.getAlphaBits() <= getConfigAlphaBits(config) N.A. */
+ && getCapsAccumBits(caps) <= getConfigAccumBits(config));
+
+ if(GLContext.gljNativeDebug)
+ {
+ System.out.println("->against config: ");
+ describeGraphicsConfiguration(config);
+ System.out.println("---------------");
+ System.out.println("result: "+res);
+ System.out.println("---------------");
+ }
+ return res;
+ }
+
+ private static int getCapsColorBits(GLCapabilities caps) {
+ return caps.getRedBits() + caps.getGreenBits() + caps.getBlueBits();
+ }
+
+ private static int getCapsAccumBits(GLCapabilities caps) {
+ return caps.getAccumRedBits() + caps.getAccumGreenBits() + caps.getAccumBlueBits();
+ }
+
+ private static boolean getConfigSupportsOpenGL(Win32GraphicsConfig config) {
+ return getVisualSupportsOpenGL(getScreen(config), config.getVisual());
+ }
+
+ private static boolean getConfigDoubleBuffered(Win32GraphicsConfig config) {
+ return getVisualDoubleBuffered(getScreen(config), config.getVisual());
+ }
+
+ private static boolean getConfigTrueColor(Win32GraphicsConfig config) {
+ return getVisualTrueColor(getScreen(config), config.getVisual());
+ }
+
+ private static boolean getConfigStereo(Win32GraphicsConfig config) {
+ return getVisualStereo(getScreen(config), config.getVisual());
+ }
+
+ private static int getConfigDepthBits(Win32GraphicsConfig config) {
+ return getVisualDepthBits(getScreen(config), config.getVisual());
+ }
+
+ private static int getConfigStencilBits(Win32GraphicsConfig config) {
+ return getVisualStencilBits(getScreen(config), config.getVisual());
+ }
+
+ private static int getConfigColorShiftBits(Win32GraphicsConfig config) {
+ return getVisualColorShiftBits(getScreen(config), config.getVisual());
+ }
+
+ private static int getConfigColorBits(Win32GraphicsConfig config) {
+ return getVisualColorBits(getScreen(config), config.getVisual());
+ }
+
+ private static int getConfigAlphaBits(Win32GraphicsConfig config) {
+ return getVisualAlphaBits(getScreen(config), config.getVisual());
+ }
+
+ private static int getConfigAccumBits(Win32GraphicsConfig config) {
+ return getVisualAccumBits(getScreen(config), config.getVisual());
+ }
+
+ private static int getScreen(Win32GraphicsConfig config) {
+ return ((Win32GraphicsDevice) config.getDevice()).getScreen();
+ }
+
+ // Native support routines that are not in GraphicsConfiguration or
+ // Win32GraphicsConfig. These are only necessary on Windows because
+ // X11's glXChooseVisual can implement getGraphicsConfiguration
+ // directly.
+ private static native boolean getVisualSupportsOpenGL (int screen, int pixelFormatIdx);
+ private static native boolean getVisualDoubleBuffered (int screen, int pixelFormatIdx);
+ private static native boolean getVisualTrueColor (int screen, int pixelFormatIdx);
+ private static native boolean getVisualStereo (int screen, int pixelFormatIdx);
+ private static native int getVisualDepthBits (int screen, int pixelFormatIdx);
+ private static native int getVisualStencilBits (int screen, int pixelFormatIdx);
+ private static native int getVisualColorShiftBits (int screen, int pixelFormatIdx);
+ private static native int getVisualColorBits (int screen, int pixelFormatIdx);
+ private static native int getVisualAlphaBits (int screen, int pixelFormatIdx);
+ private static native int getVisualAccumBits (int screen, int pixelFormatIdx);
+
+ // Debugging only
+ private void describeAllGraphicsConfigurations() {
+ Win32GraphicsConfig[] configs =
+ getAllGraphicsConfigurations(
+ (Win32GraphicsDevice)
+ GraphicsEnvironment.getLocalGraphicsEnvironment().
+ getDefaultScreenDevice()
+ );
+ System.err.println(configs.length + " graphics configurations found");
+ for (int i = 0; i < configs.length; i++) {
+ System.err.println(i + ".");
+ Win32GraphicsConfig config = configs[i];
+ describeGraphicsConfiguration(config);
+ System.err.println();
+ }
+ }
+
+ private void describeGraphicsConfiguration(Win32GraphicsConfig config)
+ {
+ boolean supportsOpenGL = getConfigSupportsOpenGL(config);
+ System.err.println(" SupportsOpenGL: " + supportsOpenGL);
+ if (supportsOpenGL) {
+ System.err.print(" DoubleBuffered: " + getConfigDoubleBuffered(config));
+ System.err.print(" TrueColor: " + getConfigTrueColor(config));
+ System.err.println(" Stereo: " + getConfigStereo(config));
+ System.err.print(" DepthBits: " + getConfigDepthBits(config));
+ System.err.println(" StencilBits: " + getConfigStencilBits(config));
+ System.err.print(" ColorBits: " + getConfigColorBits(config));
+ System.err.print(" AlphaBits: " + getConfigAlphaBits(config));
+ System.err.println(" AccumBits: " + getConfigAccumBits(config));
+ }
+ }
+}
diff --git a/gl4java/drawable/Win32SunJDK13GLDrawableFactory.java-jau b/gl4java/drawable/Win32SunJDK13GLDrawableFactory.java-jau
new file mode 100644
index 0000000..c10572e
--- /dev/null
+++ b/gl4java/drawable/Win32SunJDK13GLDrawableFactory.java-jau
@@ -0,0 +1,47 @@
+package gl4java.drawable;
+
+import java.awt.*;
+import java.lang.reflect.*;
+import java.util.*;
+import sun.awt.*;
+import gl4java.*;
+
+public class Win32SunJDK13GLDrawableFactory
+ extends SunJDK13GLDrawableFactory
+{
+ public Win32SunJDK13GLDrawableFactory() {
+ // describeAllGraphicsConfigurations();
+ }
+
+ public GraphicsConfiguration
+ getGraphicsConfiguration(GLCapabilities capabilities,
+ GraphicsDevice device) {
+ // On Windows, ChoosePixelFormat does not work as desired; it
+ // shoehorns the given pixel format descriptor into what a
+ // particular window can render. Instead we enumerate all possible
+ // pixel formats for a given GraphicsDevice and try to find one
+ // matching the given capabilities. To do this we provide
+ // accessors which query the OpenGL-related properties of a
+ // GraphicsConfiguration. FIXME: should implement better selection
+ // algorithm; this one does not choose the most minimal.
+
+ Win32GraphicsDevice w32Device = (Win32GraphicsDevice) device;
+ int screen = w32Device.getScreen();
+
+ int nPixelFormat = (int) ChoosePixelFormatNum (screen,
+ capabilities,
+ GLContext.gljNativeDebug);
+
+ return Win32GraphicsConfig.getConfig(w32Device, nPixelFormat);
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only below this point
+ //
+
+ // Needs to return an PixelFormatNumber can be wrapped in an
+ // X11GraphicsConfig object
+ static native long ChoosePixelFormatNum (int screen,
+ GLCapabilities capabilities,
+ boolean verbose);
+}
diff --git a/gl4java/drawable/X11SunJDK13GLDrawableFactory.java b/gl4java/drawable/X11SunJDK13GLDrawableFactory.java
new file mode 100644
index 0000000..0cdf40c
--- /dev/null
+++ b/gl4java/drawable/X11SunJDK13GLDrawableFactory.java
@@ -0,0 +1,45 @@
+package gl4java.drawable;
+
+import java.awt.*;
+import sun.awt.*;
+import gl4java.*;
+
+public class X11SunJDK13GLDrawableFactory
+ extends SunJDK13GLDrawableFactory
+{
+
+ public X11SunJDK13GLDrawableFactory() { }
+
+ GraphicsConfiguration
+ getGraphicsConfiguration(GLCapabilities capabilities,
+ GraphicsDevice device)
+ {
+ // glXChooseVisual behaves as we want. We just need to fetch
+ // the screen and visual ID and call into native code, passing
+ // in all of the parameters from the GLCapabilities,
+ X11GraphicsDevice x11Dev = (X11GraphicsDevice) device;
+
+ // From the code, this is ":0.<screen>".
+ // It looks like the X Display this is associated with is
+ // acquired via XOpenDisplay(NULL). It doesn't look like it's
+ // necessary to call X11GraphicsDevice.getDisplay(), though if
+ // it is, that int return value can be cast to a Display*.
+ int screen = x11Dev.getScreen();
+ long display = x11Dev.getDisplay();
+ int visualID = (int) glXChooseVisualID (screen, display,
+ capabilities,
+ GLContext.gljNativeDebug);
+
+ capabilities.setNativeVisualID( (long)visualID );
+
+ // Check for invalid return value (what will it be?)
+ // if (visualID invalid) return null;
+ return X11GraphicsConfig.getConfig(x11Dev, visualID);
+ }
+
+ // Needs to return an XVisualID which can be wrapped in an
+ // X11GraphicsConfig object
+ static native long glXChooseVisualID (int screen, long display,
+ GLCapabilities capabilities,
+ boolean verbose);
+}
diff --git a/gl4java/drawable/utils/GLEventListenerList.java b/gl4java/drawable/utils/GLEventListenerList.java
new file mode 100644
index 0000000..e63b6e7
--- /dev/null
+++ b/gl4java/drawable/utils/GLEventListenerList.java
@@ -0,0 +1,89 @@
+package gl4java.drawable.utils;
+
+import gl4java.drawable.GLDrawable;
+import gl4java.drawable.GLEventListener;
+import java.util.EventListener;
+
+/** Helper class for implementing a list of GLEventListeners. This is
+ only needed because we can not use the JDK 1.2 collection classes
+ since we have to be backward compatible with JDK 1.1. */
+
+public class GLEventListenerList {
+ private GLEventListener[] data = new GLEventListener[2];
+ private int nextFreeIdx = 0;
+
+ public GLEventListenerList() {
+ }
+
+ public void add(GLEventListener listener) {
+ if (nextFreeIdx == data.length) {
+ grow();
+ }
+ data[nextFreeIdx++] = listener;
+ }
+
+ public void remove(GLEventListener listener) {
+ for (int i = 0; i < nextFreeIdx; i++) {
+ if (data[i] == listener) {
+ for (int j = i; j < nextFreeIdx - 1; j++) {
+ data[j] = data[j+1];
+ }
+ data[nextFreeIdx - 1] = null;
+ --nextFreeIdx;
+ return;
+ }
+ }
+ }
+
+ public void sendInitEvent(GLDrawable from) {
+ for (int i = 0; i < nextFreeIdx; i++) {
+ data[i].init(from);
+ }
+ }
+
+ public void sendPreDisplayEvent(GLDrawable from) {
+ for (int i = 0; i < nextFreeIdx; i++) {
+ data[i].preDisplay(from);
+ }
+ }
+
+ public void sendDisplayEvent(GLDrawable from) {
+ for (int i = 0; i < nextFreeIdx; i++) {
+ data[i].display(from);
+ }
+ }
+
+ public void sendPostDisplayEvent(GLDrawable from) {
+ for (int i = 0; i < nextFreeIdx; i++) {
+ data[i].postDisplay(from);
+ }
+ }
+
+ public void sendCleanupEvent(GLDrawable from) {
+ for (int i = 0; i < nextFreeIdx; i++) {
+ data[i].cleanup(from);
+ }
+ }
+
+ public void sendReshapeEvent(GLDrawable from, int width, int height) {
+ for (int i = 0; i < nextFreeIdx; i++) {
+ data[i].reshape(from, width, height);
+ }
+ }
+
+ public EventListener[] getListeners()
+ {
+ GLEventListener[] _new = new GLEventListener[nextFreeIdx];
+ System.arraycopy(data, 0, _new, 0, nextFreeIdx);
+ return _new;
+ }
+
+ public int size()
+ { return nextFreeIdx; }
+
+ private void grow() {
+ GLEventListener[] newData = new GLEventListener[2 * data.length];
+ System.arraycopy(data, 0, newData, 0, data.length);
+ data = newData;
+ }
+}