Cube mapping using JOGL's Texture and TextureIO classes

Hi everyone.

I’m trying to implement an environment mapping functionality with cube maps. (I already got sphere mapping to work, which was pretty easy.)
I would like to rely on the JOGL texture classes for that task. The JOGL javadoc at some places points out which methods are usually meant for initializing and creating cube maps.
But I’m not sure how to use them. Does someone have a simple example imlementation using the JOGL texture classes and is willing to share it? That would be really great, because I’m having a real hard time to find one on the internet, at least one that relies on the JOGL texture classes.

Thanks
Frank

Take a look at the source code for demos.vertexProgRefract.VertexProgRefract in the jogl-demos workspace.

Thanks Ken.

How stupid of me not to have a closer look on the JOGL demos data.

I will try your suggestion.

Frank

Hi

I couldn’t really solve the problem with the JOGL demo code, because I’m still getting a GL_INVALID_ENUM exception.
File pathes to texture files are correct. The texture data must have been created properly, because I can query the height and width from the TextureData objects (or can I get them even if the texture data object isn’ t set up correctly?).
I don’t know why, but the GL_INVALID_ENUM occurs right at the first updateImage() method


this.cubeMapTex.updateImage(TextureIO.newTextureData(new File(this.posX), true, null), GL.GL_TEXTURE_CUBE_MAP_POSITIVE_X);

This is how I initialize the cube map texture and I can’t find any significant deviations from the JOGL demos Cubemap.class code:


/**
	 * Initializes the cube map data.
	 * @param gl
	 */
	private void init(GL gl)
	{
		this.cubeMapTex = TextureIO.newTexture(GL.GL_TEXTURE_CUBE_MAP);

		try
		{
			this.cubeMapTex.updateImage(TextureIO.newTextureData(new File(this.posX), true, null), GL.GL_TEXTURE_CUBE_MAP_POSITIVE_X);
			this.cubeMapTex.updateImage(TextureIO.newTextureData(new File(this.negX), true, null), GL.GL_TEXTURE_CUBE_MAP_NEGATIVE_X);
			this.cubeMapTex.updateImage(TextureIO.newTextureData(new File(this.posY), true, null), GL.GL_TEXTURE_CUBE_MAP_POSITIVE_Y);
			this.cubeMapTex.updateImage(TextureIO.newTextureData(new File(this.negY), true, null), GL.GL_TEXTURE_CUBE_MAP_NEGATIVE_Y);
			this.cubeMapTex.updateImage(TextureIO.newTextureData(new File(this.posZ), true, null), GL.GL_TEXTURE_CUBE_MAP_POSITIVE_Z);
			this.cubeMapTex.updateImage(TextureIO.newTextureData(new File(this.negZ), true, null), GL.GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);
		}
		catch (GLException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		catch (IOException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

Here is the compiler’s error report:

GL vendor: ATI Technologies Inc.
GL version: 2.0.5885 WinXP Release
GL renderer: 128MB ATI Radeon X1300 x86/SSE2

javax.media.opengl.GLException: glGetError() returned the following error codes after a call to glTexParameteri(): GL_INVALID_ENUM
at javax.media.opengl.DebugGL.checkGLGetError(DebugGL.java:12715)
at javax.media.opengl.DebugGL.glTexParameteri(DebugGL.java:9113)
at com.sun.opengl.util.texture.Texture.updateImage(Texture.java:433)
at de.adventure.engine.effect.environmentmapping.CubeMap.init(CubeMap.java:82)
at de.adventure.engine.effect.environmentmapping.CubeMap.(CubeMap.java:67)
at Renderer.init(Renderer.java:283)
at com.sun.opengl.impl.GLDrawableHelper.init(GLDrawableHelper.java:72)
at javax.media.opengl.GLCanvas$InitAction.run(GLCanvas.java:271)
at com.sun.opengl.impl.GLDrawableHelper.invokeGL(GLDrawableHelper.java:189)
at javax.media.opengl.GLCanvas$DisplayOnEventDispatchThreadAction.run(GLCanvas.java:305)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:199)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:461)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:163)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:157)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:149)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:110)

What version of JOGL are you running? Could you please try the latest nightly build?

I just tried the latest nightly build, but still get the same error code. I even tried to switch from bitmaps to JPGs picture files, but no improvement :frowning:

Maybe I can show you my complete cubemap class:


public class CubeMap implements EnvironmentMappingIface
{
	private Texture cubeMapTex = null;
	private String posX = "";
	private String posY = "";
	private String posZ = "";
	private String negX = "";
	private String negY = "";
	private String negZ = "";

	/**
	 * Creates a new cube map with the specified six textures.
	 * @param posX path to posX texture
	 * @param negX path to negX texture
	 * @param posY path to posY texture
	 * @param negY path to negY texture
	 * @param posZ path to posZ texture
	 * @param negZ path to negZ texture
	 * @param width texture width in pixels
	 * @param height texture height in pixels
	 */
	public CubeMap(GL gl, String posX, String negX, String posY, String negY, String posZ, String negZ /*, int width, int height */)
	{
		this.posX = posX;
		this.negX = negX;
		this.posY = posY;
		this.negY = negY;
		this.posZ = posZ;
		this.negZ = negZ;

		this.init(gl); // init the cube map data
	}

	/**
	 * Initializes the cube map data.
	 * @param gl
	 */
	private void init(GL gl)
	{
		this.cubeMapTex = TextureIO.newTexture(GL.GL_TEXTURE_CUBE_MAP);

		try
		{
			this.cubeMapTex.updateImage(TextureIO.newTextureData(new File(this.posX), true, null), GL.GL_TEXTURE_CUBE_MAP_POSITIVE_X);
			this.cubeMapTex.updateImage(TextureIO.newTextureData(new File(this.negX), true, null), GL.GL_TEXTURE_CUBE_MAP_NEGATIVE_X);
			this.cubeMapTex.updateImage(TextureIO.newTextureData(new File(this.posY), true, null), GL.GL_TEXTURE_CUBE_MAP_POSITIVE_Y);
			this.cubeMapTex.updateImage(TextureIO.newTextureData(new File(this.negY), true, null), GL.GL_TEXTURE_CUBE_MAP_NEGATIVE_Y);
			this.cubeMapTex.updateImage(TextureIO.newTextureData(new File(this.posZ), true, null), GL.GL_TEXTURE_CUBE_MAP_POSITIVE_Z);
			this.cubeMapTex.updateImage(TextureIO.newTextureData(new File(this.negZ), true, null), GL.GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);
		}
		catch (GLException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		catch (IOException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

	/* (non-Javadoc)
	 * @see de.adventure.engine.effect.environmentmapping.EnvironmentMappingIface#bind(javax.media.opengl.GL)
	 */
	public void bind(GL gl)
	{
		gl.glPushAttrib(GL.GL_TEXTURE_BIT);
			gl.glActiveTexture(GL.GL_TEXTURE1);

			
			gl.glTexEnvf(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_MODULATE);
			gl.glEnable(GL.GL_TEXTURE_CUBE_MAP);
			gl.glEnable(GL.GL_TEXTURE_GEN_S);
			gl.glEnable(GL.GL_TEXTURE_GEN_T);
			gl.glEnable(GL.GL_TEXTURE_GEN_R);

			gl.glTexGeni(GL.GL_S, GL.GL_TEXTURE_GEN_MODE, GL.GL_REFLECTION_MAP);
			gl.glTexGeni(GL.GL_T, GL.GL_TEXTURE_GEN_MODE, GL.GL_REFLECTION_MAP);
			gl.glTexGeni(GL.GL_R, GL.GL_TEXTURE_GEN_MODE, GL.GL_REFLECTION_MAP);
			
			this.cubeMapTex.bind();
			this.cubeMapTex.enable();
	}

	/* (non-Javadoc)
	 * @see de.adventure.engine.effect.environmentmapping.EnvironmentMappingIface#release(javax.media.opengl.GL)
	 */
	public void release(GL gl)
	{
		gl.glActiveTexture(GL.GL_TEXTURE1);
		this.cubeMapTex.disable();

		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_CUBE_MAP);

		gl.glPopAttrib();
	}

Well the error already occurs in the init() method which is called in the constructor.
The bind() and release() method just run along while using an empty cube map texture object, I guess.

What’s the stack trace when you’re running with the current nightly build? I want to see which call to glTexParameteri() is failing within the TextureIO code.

Here it is:



javax.media.opengl.GLException: glGetError() returned the following error codes after a call to glTexParameteri(): GL_INVALID_ENUM 
	at javax.media.opengl.DebugGL.checkGLGetError(DebugGL.java:12715)
	at javax.media.opengl.DebugGL.glTexParameteri(DebugGL.java:9106)
	at com.sun.opengl.util.texture.Texture.updateImage(Texture.java:460)
	at de.adventure.engine.effect.environmentmapping.CubeMap.init(CubeMap.java:75)
	at de.adventure.engine.effect.environmentmapping.CubeMap.<init>(CubeMap.java:62)
	at Renderer.init(Renderer.java:306)
	at com.sun.opengl.impl.GLDrawableHelper.init(GLDrawableHelper.java:72)
	at javax.media.opengl.GLCanvas$InitAction.run(GLCanvas.java:271)
	at com.sun.opengl.impl.GLDrawableHelper.invokeGL(GLDrawableHelper.java:189)
	at javax.media.opengl.GLCanvas$DisplayOnEventDispatchThreadAction.run(GLCanvas.java:305)
	at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:199)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:461)
	at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:242)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:163)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:157)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:149)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:110)

Sorry about this. I broke TextureIO’s support for cube maps during earlier work in the JOGL 1.1.0 release to add support for updating sub-images of textures and hardware mipmap generation. I filed and fixed Issue 296 regarding this. The fix will be in the forthcoming 1.1.0 final release and in tomorrow’s nightly build.

Hi Ken

I’m glad to hear that I could help to point out a bug. I will try the nightly build as soon as possible and let you know. if it worked for me. I hope so :slight_smile:

I just tried the new release. Great job. It works fine. Nice to see that you JOGL people really take user problems seriously.

Regards
Frank