Java2D dynamic Texture is upside down

Hi,

Ive been playing around with some code to create a Java2D foreground layer for my GLCanvas, and I have now successfully been able to update the Java2D texture for each frame in acceptable frame-rate (by not creating new BufferedImage, Texture or TextureData for each frame). The only problem is that the texture is upside down, and I cant figure out why this is happening. Probably some silly error, but I cant seem to find it. ???

I use the following code to create the texture:


int width = 200;
		int height = 200;
		image = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);
		
		//Paint some stuff on the texture.
		Graphics2D g2 = (Graphics2D) image.getGraphics();
		g2.setColor(new Color(0.0f, 0.0f, 0.0f, 0.5f));
		g2.fillRect(0, 0, width, height);
		g2.setColor(new Color(1.0f, 0.0f, 0.0f, 1.0f));
		g2.fillRect(10, 10, 180, 50);
		
		//Create Buffer from the BufferedImage
		imageBuffer = ByteBuffer.allocateDirect(4 * width * height);
		byte data[] = (byte[]) image.getRaster().getDataElements(0, 0, image.getWidth(), image.getHeight(), null);
		imageBuffer.clear();
		imageBuffer.put(data, 0, data.length);
		imageBuffer.rewind();
		
		//Create TextureData from the Buffer
		texdata = new TextureData(GL.GL_RGB, width, height, 0, GL.GL_BGRA, GL.GL_UNSIGNED_BYTE, false, false, false, imageBuffer, null);
		
		//Create Texture from the TextureData
		//texdata = TextureIO.newTextureData(image, false);
		texture = TextureIO.newTexture(texdata);
		texture.setTexParameteri(GL_TEXTURE_MIN_FILTER, GL_LINEAR);
		texture.setTexParameteri(GL_TEXTURE_MAG_FILTER, GL_LINEAR);

I suspect it has something to do with the following line:

texdata = new TextureData(GL.GL_RGB, width, height, 0, GL.GL_BGRA, GL.GL_UNSIGNED_BYTE, false, false, false, imageBuffer, null);

Very glad if somebody has any pointers to what might be wrong, I’ve attached a screenie, and the class where all this neat action is taking place. :slight_smile:

BTW, the code is somewhat based on the PhotoCube app created by Chris Campbell (http://weblogs.java.net/blog/campbell/archive/2006/10/easy_2d3d_mixin.html), which is a nice demo of the GLJPanel. :slight_smile:

EDIT: The screenie shows the quad with the Java2D texture, and a rotating triangle in the back, might be difficult to see…

Try using

texdata = new TextureData(GL.GL_RGB, width, height, 0, GL.GL_BGRA, GL.GL_UNSIGNED_BYTE, false, false, true, imageBuffer, null);

The difference being the boolean argument “mustFlipVertically” is true instead of false. There are a billion and a half ways of storing textures, and it seems like half of them are upside-down and half are rightside-up (depending on the file format it came from and so on)…

Hi,

Thanks for your suggestion, but setting “mustFlipVertically” to true didnt do much good, the texture is still upside down… :frowning:

Just noticed something else… The colors I use for drawing on the texture in Java2D are flipped, meaning that g2.setColor(new Color(0.0f, 0.0f, 1.0f, 0.5f)); is red, and g2.setColor(new Color(1.0f, 0.0f, 0.0f, 0.5f)); is blue… Very strange. Can it have something to do with the byte order in the ByteBuffer where the image data is stored?

Thanx

If you’re having problems with color channels or vertical flipping I’d recommend against extracting the data from the BufferedImage yourself. Just create a TextureData from the BufferedImage and use Texture.updateSubImage() to update the OpenGL texture. This may not necessarily be the most efficient option but it will work. Once you have things working you can look into the TextureIO implementation and see about potentially removing some data copies, for example.

Hi,

Thanks Ken, I will extract the data myself then, and see how that goes.

Peace

BTW, I got it working. Not sure what exactly the problem was, but after I tried to extract the pixel data myself (Which made the rendering horribly slow), I reversed it back to the original state (or so I thought) and then it worked. Find it really really smooth to have a fullscreen Java2D layer in “front” of the GLCanvas, looks amazing (and works for most platforms, as opposed to the GLJPanel).

All we need now is the Texture.updateSubImage(x,y,w,h) enhancement (https://jogl.dev.java.net/issues/show_bug.cgi?id=257) :wink:

That’s cool. Would you be willing to share some of your code? We have just recently been talking about supporting a Java2D-based overlay on top of the GLCanvas as an alternative to the GLJPanel, and accelerating this overlay with the Java2D/JOGL bridge when it’s available.

Sure, Ill share the code, although I’m not sure what use it will be, it feels quite “hacky” at the moment. The main problem I found was how to align the texture so that it is perfectly aligned with the canvas borders (Any hints on how to do this are welcome). This might not be the correct way of doing it anyways, but I think it’ll work for small and silly projects, such as I have in mind :slight_smile:

Ive put together a webstart, but the hosting company does not seem to set the correct content-type: http://www.kriik.com/webstart/JOGL2DOverlay.jnlp
And here is the Eclipse project, all included except the windows and osx natives: http://www.kriik.com/webstart/JOGL2DOverlay.zip

Looks impressive to me… are you interested in perhaps cleaning it up a little and putting it into the joglutils project?

but you might want to add the mime type application/x-java-jnlp-file jnlp to your web site, though - I had to download and run the .jnlp file.

Thanks for sharing your code. A couple of co-workers and I were talking about making a Java 2D overlay that could attach itself to any GLDrawable. Note that you can get the width and height directly from the GLDrawable, and you should be able to use glOrtho / gluOrtho2D to set up a projection matrix to draw your 2D texture directly on top of it with one quad or two triangles. Your code is probably close to supporting this.

By the way, you should really use the Texture.getImageTexCoords() or getSubImageTexCoords() methods to compute texture coordinates into the Texture object. For efficiency we’re going to flip the Y orientation of BufferedImage-based Texture objects, so if you aren’t using these methods (or aren’t looking at the result of Texture.getMustFlipVertically()) then your app will again have vertically-flipped textures.

FYI, based on your request and those from others, a couple of new classes have been added to the jogl workspace under com.sun.opengl.util which are similar in functionality to yours, though the code was rewritten. The J2DTextureRenderer makes it easier to draw using Java 2D into an OpenGL texture and to place rectangular portions of that texture on to the screen, and the J2DOverlay acts like a Java 2D-based heads-up display which overlays an arbitrary GLDrawable. There are a couple of new demos in the jogl-demos workspace under demos.j2d which exercise the new functionality. We’ll put up Java Web Start demos along with the next release build.

Thanks for raising the need for this stuff and please post with any comments on the new utility classes.

Hey,

Sorry for the delayed reply, been away for a while. First of all, I have to say that I almost started crying when I saw your work, this was exactly what I was looking for :smiley: I actually changed my code like you suggested, but I see now that your work is much better. The j2d demos run fine on my machine, and Ill try to put together some of my own tests now, for fun.

@eteq: I guess I won’t need to add the code into jogl-utils anymore :slight_smile:

Thanks alot!