Drawing primitives to offscreen surfaces

I have been looking for ways to draw primitives (pixels, lines, circles etc) onto offscreen surfaces and then using those images as textures on some generic spatial.

I found [this forum article] which picks up on the general concept of rendering to offscreen surfaces but I can not seem to find any good information on drawing primitives and/or how this links with jME3’s texture format.

Any hints or suggestions would be great. Thank you! :slight_smile:

Like, the kind of primitives Java2D provides? ie: not 3D primitives but a 2D drawing operation?



How often do you need to do this? Is it a one time thing or something you do once per frame?



For 2D drawing, JME gives you very little but you can use Java2D to draw on a BufferedImage which you can then concert to a texture.

1 Like

for offscreen rendering look at TestRenderToTexture.



jME3 support any very basic primitives, like lines, curves, and everything in the com.jme3.scene.shape package. You cannot draw pixels directly, maybe you should consider making you texture with Photoshop or Gimp…



To achieve a circle you can use the Curve primitive with a Spline in CatmullRom mode, with 4 control points and a tension of 0.83.



[java]

Spline spline =new Spline();

spline.addControlpoint(new Vector3f(20, 3, 0));

spline.addControlpoint(new Vector3f(0, 3, 20));

spline.addControlpoint(new Vector3f(-20, 3, 0));

spline.addControlpoint(new Vector3f(0, 3, -20));

spline.setCycle(true);

spline.setCurveTension(0.83f);

Curve curve=new Curve(spline,10); //10 is the number of sub-segments between control points

Geometry circle= new Geometry(curve);

rootNode.attachChild(circle);

[/java]



of course you’ll have to tweak the control points to fit your needs.

@pspeed: Yes. Java2D primitives. This settles it. I was not sure if the foundation classes would operate on jME3 data structures (or vice versa). I will read up on this. Thank you very much.



@nehon: The post I referenced in TS was a discussion on TestRenderToTexture. It was not what I was looking for. However, your reference to primitives in 3D is insightful to a jME3 newbie like me. Thank you.

@pspeed:

Forgot to ask: I need to update this texture more or less every frame. How does the inner workings of jME3 corelate with OpenGL when it comes to transfering updated texture data to the GPU?

maybe these will help : http://hub.jmonkeyengine.org/groups/contribution-depot-jme3/snippets/single/15/

http://hub.jmonkeyengine.org/groups/contribution-depot-jme3/snippets/single/14/

@tralala: snip#14 looks interesting! Question now is… how’s the performance?

Thank you!

You probably want to look in the code for the AWTLoader as it takes a BufferedImage and converts it to a texture:

http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/desktop/com/jme3/texture/plugins/AWTLoader.java



I use something similar in Mythruna to draw the world map for the player… it’s best if you can reuse the buffers, etc. as much as possible. And it performs ok for my purposes.



Shuffling a whole image’s worth of data around like that is never going to be fast but if you stick to compatible formats it could be fast enough depending on how many of these you are trying to change per frame. On the one hand, it saves you from having to implement your own 2D primitive operations and the Java2D API is pretty well understood. On the other hand, it is an extra byte[] shuffle as compared to snip 14.

@pspeed: I intend to perform drawing operations on a predefined bitmap which, after processing, will be rendered onto the jME3 HUD with opacity set around 75%.



Your explanation is inspirational. I think I will do some benchmarking. Once again, thank you for helping me.

@pspeed: Ok… So I did a small test with trying to convert a regular Graphics2D object into a com.jme3.texture.Image. However… I keep running into a nullpointer exception. I am guessing that this is either due to my lack of knowledge on how to implement the com.jme3.texture.Texture class or that I am missing something of importance during the use of AWTLoader. I have tried to watch my awtLoader instance to see if there is something fishy going on. But I can’t seem to find anything of value. It feels as if this error is more simple.

Here is some code:

[java]

import com.jme3.app.SimpleApplication;

import com.jme3.material.Material;

import com.jme3.math.ColorRGBA;

import com.jme3.renderer.RenderManager;

import com.jme3.scene.Geometry;

import com.jme3.scene.shape.Quad;

import com.jme3.system.AppSettings;

import com.jme3.texture.Image;

import com.jme3.texture.Texture;

import com.jme3.texture.plugins.AWTLoader;

import java.awt.Color;

import java.awt.Graphics;

import java.awt.image.BufferedImage;



public void simpleInitApp (){

BufferedImage img = new BufferedImage(512, 512, BufferedImage.TYPE_INT_ARGB);

Graphics g = img.getGraphics();

g.setColor(Color.RED);

g.fillRect(100, 100, 100, 100);

qd_background = new Quad(11.2f, 8.6f);

geo_background = new Geometry(“Background”, qd_background);

geo_background.setLocalTranslation(-5.6f, -4.2f, 0.0f);

mat_background = new Material(assetManager, “Common/MatDefs/Misc/Unshaded.j3md”);

Texture myTex = null;

AWTLoader awtLoader = new AWTLoader();

myTex.setImage(awtLoader.load(img, false));

mat_background.setTexture(“ColorMap”, myTex); // NULLPOINTER EXCEPTION

geo_background.setMaterial(mat_background);

rootNode.attachChild(geo_background);

}

[/java]



I’m almost certain this has to be because of AWTLoader not returning a useful object which would make the data in myTex still null. However… watching myTex in the debugger shows that some of the information from img has been inserted correctly.



Any suggestions?

@gasher: solved it

[java]Texture2D myTex = new Texture2D();[/java]

not

[java]Texture myTex = null;[/java]

You cannot setImage() on a null object.

1 Like

@TimePath: Ugh… See this is what I knew all along… I just don’t have the knowledge of the jME3 API yet… ( >.< )/



Thanks man! Guesse I’ll have to do more reading on not trying to force the implementation of abstract base classes. :slight_smile: Cheers ^^b

A NullPointerException is almost always very easy to find. One of your variables is null, simply check all variables used in the line that throws the exception, then trace back why its null.

@normen: Yeah… I know… I just lack the proficiency in the jME3 API to know exactly what classes to use and when/how to use them. Ti’s all good now.



Time to move on to doing some actual testing…

@gasher: I’ve found checking out from the SVN to be a very useful tool at times :slight_smile:

You can view the source of all jme3 classes in jMP without doing that, just right-click the name of a class in the code editor and select “View Source”.