JOGL: all gl method calls return "GL_INVALID_ENUM"

Hello All,

I am trying to port over a piece of sample code from the OpenGL SuperBible from C to JOGL and have been running into a bizarre issue. In my display(GLAutoDrawable) method, ALL calls to my GL object (e.g. gl.glMatrixMode(GL.GL_PROJECTION):wink: return a glError which resolves to:

ā€œglGetError() returned the following error codes after a call to gl________(): GL_INVALID_ENUMā€

Note that I have wrapped my GL object into a DebugGL wrapper in order for it to throw an exception.

The sample code involves shadow mapping, but I think this is more of a general JOGL issue. Here is my ported sample code for reference. The issue specifically involves gl calls in display() but do not have any issues with gl calls in init():

This issue has had me stumped since yesterday and most of today. Has anybody ever run into this issue and know how to resolve it?

Iā€™ve included my code for reference. The display() routine is bolded. Thanks for reading:

package sm;

import graphicslib3D.Matrix3D;

import javax.media.opengl.DebugGL;
import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCanvas;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.TraceGL;
import javax.media.opengl.glu.GLU;
import javax.swing.JFrame;

import sm.util.GLCheckError;

import com.sun.opengl.util.Animator;
import com.sun.opengl.util.GLUT;

public class Display extends JFrame implements GLEventListener
{
private GLCanvas glCanvas;
private GLU glu;
private GLUT glut;
private Animator animator;

private boolean ambientShadowAvailable = false;
private boolean npotTexturesAvailable = false;
private boolean controlCamera = true;		// xyz keys will control lightpos
private boolean noShadows = false;			// normal lighting
private boolean showShadowMap = false;		// show the shadowmap texture

private float factor = 4.0f;				// for polygon offset

private int windowWidth = 1024;				// window size
private int windowHeight = 512;

private int shadowWidth = 1024;
private int shadowHeight = 512;
private int shadowTextureID;

private int maxTexSize;						// maximum allowed size for 1D/2D texture

private float[] ambientLight = { 0.2f, 0.2f, 0.2f, 1.0f};
private float[] diffuseLight = { 0.7f, 0.7f, 0.7f, 1.0f};
private float[] noLight		 = { 0.0f, 0.0f, 0.0f, 0.0f};
private float[] lightPos		 = { 100.0f, 150.0f, 200.0f, 1.0f};

private float[] cameraPos	 = { 100.0f, 150.0f, 200.0f, 1.0f};
double cameraZoom = 0.3;

private Matrix3D textureMatrix = new Matrix3D();

public Display()
{
	super();
	setTitle("ShadowMap Demo");
	setSize(windowWidth, windowHeight);
	setLocation(200, 200);
	setDefaultCloseOperation(EXIT_ON_CLOSE);
	
	GLCapabilities caps = new GLCapabilities();
	caps.setDoubleBuffered(true);
	caps.setHardwareAccelerated(true);
	
	// create a canvas on which to draw
	//glCanvas = new GLCanvas(caps);
	glCanvas = new GLCanvas();
	glCanvas.addGLEventListener(this);
	
	// add the canvas to the JFrame and make it visible
	this.add(glCanvas);
	this.setVisible(true);
	
	// start animating
	animator = new Animator(glCanvas);
	animator.start();
}

// called to draw scene objects
private void drawModels(GLAutoDrawable drawable,
		boolean drawBasePlane)
{
	GL gl = drawable.getGL();
	
	if (drawBasePlane)
	{
		// Draw plane that the objects rest on
		gl.glColor3f(0.0f, 0.0f, 0.90f);	// Blue
		gl.glNormal3f(0.0f, 1.0f, 0.0f);
		gl.glBegin(GL.GL_QUADS);
			gl.glVertex3f(-100.0f, -25.0f, -100.0f);
			gl.glVertex3f(-100.0f, -25.0f, 100.0f);
			gl.glVertex3f(100.0f, -25.0f, 100.0f);
			gl.glVertex3f(100.0f, -25.0f, -100.0f);
		gl.glEnd();
	}
	
	// Draw red cube
	gl.glColor3f(1.0f, 0.0f, 0.0f);
	glut.glutSolidCube(48.0f);
	
	// Draw green sphere
	gl.glColor3f(0.0f, 1.0f, 0.0f);
	gl.glPushMatrix();
	gl.glTranslatef(-60.0f, 0.0f, 0.0f);
	glut.glutSolidSphere(25.0f, 50, 50);
	gl.glPopMatrix();
	
	// Draw yellow cone
	gl.glColor3f(1.0f, 1.0f, 1.0f);
	gl.glPushMatrix();
	gl.glRotatef(-90.0f, 1.0f, 0.0f, 0.0f);
	gl.glTranslatef(60.0f, 0.0f, -24.0f);
	glut.glutSolidCone(25.0f, 50.0f, 50, 50);
	gl.glPopMatrix();
	
	// Draw magenta torus
	gl.glColor3f(1.0f, 0.0f, 1.0f);
	gl.glPushMatrix();
	gl.glTranslatef(0.0f, 0.0f, 60.0f);
	glut.glutSolidTorus(8.0f, 16.0f, 50, 50);
	gl.glPopMatrix();
	
	// Draw cyan octaheron
	gl.glColor3f(0.0f, 1.0f, 1.0f);
	gl.glPushMatrix();
	gl.glTranslatef(0.0f, 0.0f, -60.0f);
	gl.glScalef(25.0f, 25.0f, 25.0f);
	glut.glutSolidOctahedron();
	gl.glPopMatrix();
}

public void regenerateShadowMap(GLAutoDrawable drawable)
{
	GL gl = drawable.getGL();
	
	float lightToSceneDistance, nearPlane, fieldOfView;
	Matrix3D lightProjection, lightModelView;
	float[] temp = new float[16];
	float sceneBoundingRadius = 95.0f;	// based on objects in the scene
	
	// Save the depth precision for where it's useful
	lightToSceneDistance = (float)Math.sqrt(lightPos[0] * lightPos[0] +
											lightPos[1] * lightPos[1] +
											lightPos[2] * lightPos[2]);
	nearPlane = lightToSceneDistance - sceneBoundingRadius;
	// Keep the scene filling the depth texture
	fieldOfView = (float)Math.toDegrees(2.0f * Math.atan(sceneBoundingRadius / lightToSceneDistance));
	
	gl.glMatrixMode(GL.GL_PROJECTION);
	gl.glLoadIdentity();
	glu.gluPerspective(fieldOfView, 1.0f, nearPlane, nearPlane + (2.0f * sceneBoundingRadius));
	gl.glGetFloatv(GL.GL_PROJECTION_MATRIX, temp, 0);
	lightProjection = new Matrix3D(floatArrayToDouble(temp));
	// Switch to light's point of view
	gl.glMatrixMode(GL.GL_MODELVIEW);
	gl.glLoadIdentity();
	glu.gluLookAt(lightPos[0], lightPos[1], lightPos[2],
			0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
	gl.glGetFloatv(GL.GL_MODELVIEW_MATRIX, temp, 0);
	lightModelView = new Matrix3D(floatArrayToDouble(temp));
	gl.glViewport(0, 0, shadowWidth, shadowHeight);
	
	// Clear the depth buffer only
	gl.glClear(GL.GL_DEPTH_BUFFER_BIT);
	
	// All we care about here is resulting depth values
	gl.glShadeModel(GL.GL_FLAT);
	gl.glDisable(GL.GL_LIGHTING);
	gl.glDisable(GL.GL_COLOR_MATERIAL);
	gl.glDisable(GL.GL_NORMALIZE);
	gl.glColorMask(false, false, false, false);
	
	// Overcome imprecision
	gl.glEnable(GL.GL_POLYGON_OFFSET_FILL);
	
	// Draw objects in the scene except base plane
	// which never shadows anything
	drawModels(drawable, false);
	
	// Copy depth values into depth texture
	gl.glCopyTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_DEPTH_COMPONENT,
			0, 0, shadowWidth, shadowHeight, 0);
	
	// Restore normal drawing state
	gl.glShadeModel(GL.GL_SMOOTH);
	gl.glEnable(GL.GL_LIGHTING);
	gl.glEnable(GL.GL_COLOR_MATERIAL);
	gl.glEnable(GL.GL_NORMALIZE);
	gl.glColorMask(true, true, true, true);
	gl.glDisable(GL.GL_POLYGON_OFFSET_FILL);
	
	// Set up texture matrix for shadow map projection,
	// which will be rolled into the eye linear
	// texture coordinate generation plane equations
	textureMatrix.setToIdentity();
	textureMatrix.translate(0.5, 0.5, 0.5);
	textureMatrix.scale(0.5, 0.5, 0.5);
	textureMatrix.concatenate(lightProjection);
	textureMatrix.concatenate(lightModelView);
	// transpose to get the s, t, r, and q rows for plane equations
	textureMatrix.transpose();
}

//--GLEventListener--
// initializes GL stuff
public void init(GLAutoDrawable drawable)
{
	glu = new GLU();
	glut = new GLUT();		
	GL gl = drawable.getGL();
	
	int[] temp = new int[1];
	gl.glGetIntegerv(GL.GL_MAX_TEXTURE_SIZE, temp, 0);
	maxTexSize = temp[0];
	
	ambientShadowAvailable = true;	// hard-coded
	
	// Black background		
	gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
	
	// Hidden surface removal
	gl.glEnable(GL.GL_DEPTH_TEST);
	gl.glDepthFunc(GL.GL_LEQUAL);
	gl.glPolygonOffset(factor, 0.0f);
	
	// Set up some lighting state that never changes
	gl.glShadeModel(GL.GL_SMOOTH);
	gl.glEnable(GL.GL_LIGHTING);
	gl.glEnable(GL.GL_COLOR_MATERIAL);
	gl.glEnable(GL.GL_NORMALIZE);
	gl.glEnable(GL.GL_LIGHT0);
	
	// Set up some texture state that never changes
	gl.glGenTextures(1, temp, 0);
	shadowTextureID = temp[0];
	gl.glBindTexture(GL.GL_TEXTURE_2D, shadowTextureID);
	gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP_TO_EDGE);
	gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP_TO_EDGE);
	gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);
	gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
	gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_DEPTH_TEXTURE_MODE, GL.GL_INTENSITY); //??
	if (ambientShadowAvailable)
		gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_COMPARE_FAIL_VALUE_ARB,
				0.5f);
	gl.glTexGeni(GL.GL_S, GL.GL_TEXTURE_GEN_MODE, GL.GL_EYE_LINEAR);
	gl.glTexGeni(GL.GL_T, GL.GL_TEXTURE_GEN_MODE, GL.GL_EYE_LINEAR);
	gl.glTexGeni(GL.GL_R, GL.GL_TEXTURE_GEN_MODE, GL.GL_EYE_LINEAR);
	gl.glTexGeni(GL.GL_Q, GL.GL_TEXTURE_GEN_MODE, GL.GL_EYE_LINEAR);
	
	regenerateShadowMap(drawable);
}

// draw commands

[b] public void display(GLAutoDrawable drawable)
{
// Debugging stuff
DebugGL dbg = new DebugGL(drawable.getGL());
drawable.setGL(dbg);

	GL gl = drawable.getGL();
	// Track camera angle
	gl.glMatrixMode(GL.GL_PROJECTION);
	gl.glLoadIdentity();
	if (windowWidth > windowHeight)
	{
		double ar = (double)windowWidth / (double)windowHeight;
		gl.glFrustum(-ar * cameraZoom, ar * cameraZoom,
				-cameraZoom, cameraZoom, 1.0, 1000.0);
	}
	else
	{
		double ar = (double)windowHeight / (double)windowWidth;
		gl.glFrustum(-cameraZoom, cameraZoom,
				-ar * cameraZoom, ar * cameraZoom, 1.0, 1000.0);
	}
	
	gl.glMatrixMode(GL.GL_MODELVIEW);
	gl.glLoadIdentity();
	glu.gluLookAt(cameraPos[0], cameraPos[1], cameraPos[2],
			0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
	
	gl.glViewport(0, 0, windowWidth, windowHeight);		// necessary?
	
	// Track light position
	gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, lightPos, 0);
	
	// Clear the window with current clearing color
	gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
	
	if (showShadowMap)
	{
		// Display shadow map for educational purposes
		gl.glMatrixMode(GL.GL_PROJECTION);
		gl.glLoadIdentity();
		gl.glMatrixMode(GL.GL_MODELVIEW);
		gl.glLoadIdentity();
		gl.glMatrixMode(GL.GL_TEXTURE);
		gl.glPushMatrix();
		gl.glLoadIdentity();
		gl.glEnable(GL.GL_TEXTURE_2D);
		gl.glDisable(GL.GL_LIGHTING);
		gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_REPLACE);
		gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_COMPARE_MODE, GL.GL_NONE);
		// Show the shadowmap at its actual size relative to window
		gl.glBegin(GL.GL_QUADS);
			gl.glTexCoord2f(0.0f, 0.0f);
			gl.glVertex2f(-1.0f, -1.0f);
			gl.glTexCoord2f(1.0f, 0.0f);
			gl.glVertex2f(((float)shadowWidth / (float)windowWidth)*2.0f-1.0f,
					-1.0f);
			gl.glTexCoord2f(1.0f, 1.0f);
			gl.glVertex2f(((float)shadowWidth / (float)windowWidth)*2.0f-1.0f,
					((float)shadowHeight / (float)windowHeight)*2.0f-1.0f);
		gl.glEnd();
		gl.glDisable(GL.GL_TEXTURE_2D);
		gl.glEnable(GL.GL_LIGHTING);
		gl.glPopMatrix();
		gl.glMatrixMode(GL.GL_PROJECTION);
		glu.gluPerspective(45.0f, 1.0f, 1.0f, 1000.0f);		// why different?
		gl.glMatrixMode(GL.GL_MODELVIEW);
	}
	else if (noShadows)
	{
		// Set up some simple lighting
		gl.glLightfv(GL.GL_LIGHT0, GL.GL_AMBIENT, ambientLight, 0);
		gl.glLightfv(GL.GL_LIGHT0, GL.GL_DIFFUSE, diffuseLight, 0);
		
		// Draw objects in the scene including base plane
		drawModels(drawable, true);
	}
	else
	{
		if (!ambientShadowAvailable)
		{
			float[] lowAmbient = { 0.1f, 0.1f, 0.1f, 1.0f};
			float[] lowDiffuse = { 0.35f, 0.35f, 0.35f, 1.0f};
			
			// Because there is no support for an "ambient"
			// shadow compare fail value, we'll have to
			// draw an ambient pass first...
			gl.glLightfv(GL.GL_LIGHT0, GL.GL_AMBIENT, lowAmbient, 0);
			gl.glLightfv(GL.GL_LIGHT0, GL.GL_DIFFUSE, lowDiffuse, 0);
			
			// Draw objects in the scene, including base plane
			drawModels(drawable, true);
			
			// Enable alpha test so that shadowed fragments are discarded
			gl.glAlphaFunc(GL.GL_GREATER, 0.9f);
			gl.glEnable(GL.GL_ALPHA_TEST);
		}
		
		gl.glLightfv(GL.GL_LIGHT0, GL.GL_AMBIENT, ambientLight, 0);
		gl.glLightfv(GL.GL_LIGHT0, GL.GL_DIFFUSE, diffuseLight, 0);
		
		// Set up shadow comparison
		gl.glEnable(GL.GL_TEXTURE_2D);
		gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_MODULATE);
		gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_COMPARE_MODE,
				GL.GL_COMPARE_R_TO_TEXTURE);
		
		// Set up the eye plane for projecting the shadow map on the scene
		float[] textureMatrixValues = 
			doubleArrayToFloat(textureMatrix.getValues());
		gl.glEnable(GL.GL_TEXTURE_GEN_S);
		gl.glEnable(GL.GL_TEXTURE_GEN_T);
		gl.glEnable(GL.GL_TEXTURE_GEN_R);
		gl.glEnable(GL.GL_TEXTURE_GEN_Q);			
		gl.glTexGenfv(GL.GL_S, GL.GL_EYE_PLANE, textureMatrixValues, 0);
		gl.glTexGenfv(GL.GL_T, GL.GL_EYE_PLANE, textureMatrixValues, 4);
		gl.glTexGenfv(GL.GL_R, GL.GL_EYE_PLANE, textureMatrixValues, 8);
		gl.glTexGenfv(GL.GL_Q, GL.GL_EYE_PLANE, textureMatrixValues, 12);
		
		// Draw objects in the scene, including base plane
		drawModels(drawable, true);
		
		gl.glDisable(GL.GL_ALPHA_TEST);
		gl.glDisable(GL.GL_TEXTURE_2D);
		gl.glDisable(GL.GL_TEXTURE_GEN_S);
		gl.glDisable(GL.GL_TEXTURE_GEN_T);
		gl.glDisable(GL.GL_TEXTURE_GEN_R);
		gl.glDisable(GL.GL_TEXTURE_GEN_Q);
	}
	
	gl.glFlush();
	GLCheckError.displayErrorStatus(gl, glu, null, false);
}[/b]

public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {}
public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {}

// Converts a double array to a float array.
private float[] doubleArrayToFloat(double[] source)
{
	float[] dest = new float[source.length];
	for (int i = 0; i < source.length; i++)
		dest[i] = (float)source[i];
	
	return dest;
}

// Converts a float array to a double array.
private double[] floatArrayToDouble(float[] source)
{
	double[] dest = new double[source.length];
	for (int i = 0; i < source.length; i++)
		dest[i] = (double)source[i];
	
	return dest;
}

}

Did you try a well-known JOGL example, to rule out a problem coming from your setup or build environment ?

Thanks for the response. Yes, I have been able to run other JOGL programs on the same machine and in the same mannerā€¦which makes it even that much more perplexing as to why this program alone has this problem.