jPCT - a 3d engine for Java > Bugs
jPCT dose not support jogl 2.1.5
EgonOlsen:
The HelloWorldOGL isn't supposed to work with Jogl. It renders to a native window and not into a canvas. Jogl doesn't support this. The only way to use it is to use the AWTGLRenderer.
iamfoolberg:
Thanks EgonOlsen, but i get another question to draw models in WorldWind with jPCT.
Accroding to WW's docs, i should implement the integration by implementing an interface(i.e. gov.nasa.worldwind.layers.Layer). So i extends an AbstractLayer who implemented the Layer.
And i should draw the models in jPCT to the provided GL2/3/4 object.
The code seems as follows:
--- Code: ---package org.aoe.det.ww.d3man.ww;
import java.lang.reflect.Field;
import javax.media.opengl.GL;
import javax.media.opengl.GL2;
import org.gbzh.util.resource.Resource;
import com.threed.jpct.FrameBuffer;
import com.threed.jpct.IRenderer;
import com.threed.jpct.Logger;
import com.threed.jpct.Object3D;
import com.threed.jpct.Primitives;
import com.threed.jpct.SimpleVector;
import com.threed.jpct.Texture;
import com.threed.jpct.TextureManager;
import com.threed.jpct.World;
import gov.nasa.worldwind.layers.AbstractLayer;
import gov.nasa.worldwind.render.DrawContext;
public class Jpct3DLayer extends AbstractLayer {
/** The world of jPCT. */
private World world;
/***/
private FrameBuffer buffer;
private GL2 lastGL;
public Jpct3DLayer() {
this.world = new World();
this.world.setAmbientLight(0, 255, 0);
TextureManager.getInstance().addTexture("box", new
Texture(Resource.getResource("data/POLYSHIP.jpg")));
Object3D box = Primitives.getBox(13f, 2f);
box.setTexture("box");
box.setEnvmapped(Object3D.ENVMAP_ENABLED);
box.build();
world.addObject(box);
this.world.getCamera().setPosition(50, -50, -5);
SimpleVector point = new SimpleVector(0.0, 0.0, 0.0);
this.world.getCamera().lookAt(point);// box.getTransformedCenter()
this.buffer = new FrameBuffer(800, 600,
FrameBuffer.SAMPLINGMODE_NORMAL);
this.buffer.disableRenderer(IRenderer.RENDERER_SOFTWARE);
this.buffer.enableRenderer(IRenderer.RENDERER_OPENGL,
IRenderer.MODE_OPENGL);
}
private void injectGL(GL gl) {
String[] classes = new String[] {
"org.lwjgl.opengl.GL11",
"org.lwjgl.opengl.GL15",
"org.lwjgl.opengl.GL20",
"org.lwjgl.opengl.Util",
"org.lwjgl.opengl.ARBMultitexture",
"org.lwjgl.opengl.EXTFramebufferObject",
"org.lwjgl.opengl.ARBShaderObjects",
"org.lwjgl.opengl.GLContext" };
Class<?> clazz;
for (int i = 0; i < classes.length; i++) {
try {
clazz = Class.forName(classes[i]);
Field glf = clazz.getDeclaredField("gl");
glf.set(clazz, gl);
} catch (Exception e) {
Logger.log("Unable to inject GL context into the facade!",
Logger.ERROR);
}
}
}
@Override
protected void doRender(DrawContext dc) {
GL2 gl = (GL2) dc.getGL();
if (this.lastGL != gl) {
this.injectGL(gl);
this.lastGL = gl;
}
// jPCT should draw its world with the given gl
this.repaint();
}
/**
* force this layer to redraw components inside it.
*/
public void repaint() {
world.renderScene(buffer);
world.draw(buffer);
buffer.update();
buffer.displayGLOnly();
}
}
--- End code ---
I excluded the lwjgl.jars, but get the following error(the same as that in my last reply) when adding this layer to WW.
[ Sun Aug 30 21:01:13 CST 2015 ] - WARNING: Unsupported Texture width (260)...resizing to a width of 256 pixels!
Java version is: 1.8.0_45
-> support for BufferedImage
Version helper for 1.5+ initialized!
-> using BufferedImage
Software renderer (OpenGL mode) initialized
Software renderer disposed
Exception in thread "main" java.lang.NoClassDefFoundError: org/lwjgl/opengl/Display
at com.threed.jpct.GLHelper.findMode(GLHelper.java:67)
at com.threed.jpct.GLHelper.findMode(GLHelper.java:62)
at com.threed.jpct.GLHelper.init(GLHelper.java:160)
at com.threed.jpct.GLRenderer.init(GLRenderer.java:24)
at com.threed.jpct.FrameBuffer.enableRenderer(FrameBuffer.java:1134)
at com.threed.jpct.FrameBuffer.enableRenderer(FrameBuffer.java:753)
at org.aoe.det.ww.d3man.ww.Jpct3DLayer.<init>(Jpct3DLayer.java:51)
at org.aoe.det.ww.d3man.D3ManDemoApp$DemoAppFrame.<init>(D3ManDemoApp.java:68)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
at java.lang.Class.newInstance(Class.java:442)
at gov.nasa.worldwindx.examples.ApplicationTemplate.start(ApplicationTemplate.java:294)
at org.aoe.det.ww.d3man.D3ManDemoApp.main(D3ManDemoApp.java:79)
Caused by: java.lang.ClassNotFoundException: org.lwjgl.opengl.Display
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
That is to say, jPCT uses the class org.lwjgl.opengl.Display in somewhere.
How can i remove the dependency and use the pure jogl class?
EgonOlsen:
That's because you are using the wrong enable-method. To use Jogl or lwjgl's canvas, you have to use enableGLCanvasRenderer instead. Just like the awtgl-example should do it.
iamfoolberg:
Thanks EgonOlsen again.
I change my program and it runs without the "NoClassDefFoundError".
But my next question is, where is my 3d box:)
As in the following code, i set the box on the surface of the earth, and the camera alittle higher than it.
But i can not find the box in WorldWind.
--- Code: ---package org.aoe.det.ww.d3man.ww;
import java.awt.Canvas;
import java.lang.reflect.Field;
import javax.media.opengl.GL;
import javax.media.opengl.GL2;
import javax.swing.JFrame;
import org.aoe.det.ww.d3man.D3Man;
import org.gbzh.util.log.Log;
import org.gbzh.util.resource.Resource;
import com.threed.jpct.FrameBuffer;
import com.threed.jpct.IRenderer;
import com.threed.jpct.Logger;
import com.threed.jpct.Object3D;
import com.threed.jpct.Primitives;
import com.threed.jpct.SimpleVector;
import com.threed.jpct.Texture;
import com.threed.jpct.TextureManager;
import com.threed.jpct.World;
import gov.nasa.worldwind.geom.Position;
import gov.nasa.worldwind.geom.Vec4;
import gov.nasa.worldwind.layers.AbstractLayer;
import gov.nasa.worldwind.render.DrawContext;
/**
* A jPCT based three model layer.
* In jPCT, positive x goes to the right,
* positive z goes INTO the screen
* and positive y goes DOWN.
* @author berg
*
*/
public class Jpct3DLayer extends AbstractLayer {
/** The world of jPCT. */
private World world;
/***/
private FrameBuffer buffer;
private GL2 lastGL;
private Canvas canvas;
private Object3D box;
private float move = 0.0f;
private float surfaceElevation = 6378137.0f;
private SimpleVector boxLoc = new SimpleVector(0, 0, -(surfaceElevation+50000));
private SimpleVector cameraLoc = new SimpleVector(0, 0, -(surfaceElevation+50000+100));
public Jpct3DLayer() {
this.world = new World();
this.world.setAmbientLight(0, 255, 0);
TextureManager.getInstance().addTexture("box",
new Texture(Resource.getResource("data/POLYSHIP.jpg")));
box = Primitives.getBox(13f, 2f);
box.setTexture("box");
box.setEnvmapped(Object3D.ENVMAP_ENABLED);
box.build();
world.addObject(box);
box.translate(boxLoc);
this.world.getCamera().setPosition(cameraLoc);
SimpleVector point = new SimpleVector(0.0, 0.0, 0.0);
this.world.getCamera().lookAt(point);
this.world.getCamera().setFOV(this.world.getCamera().getMaxFOV());
this.buffer = new FrameBuffer(800, 600,
FrameBuffer.SAMPLINGMODE_NORMAL);
canvas = buffer.enableGLCanvasRenderer();
buffer.disableRenderer(IRenderer.RENDERER_SOFTWARE);
}
// puts opengl in the correct state for this layer
protected void beginDraw(DrawContext dc) {
GL2 gl = (GL2) dc.getGL();
gl.glPushAttrib(GL2.GL_TEXTURE_BIT | GL2.GL_ENABLE_BIT
| GL2.GL_CURRENT_BIT | GL2.GL_TRANSFORM_BIT);
if (!dc.isPickingMode()) {
gl.glEnable(GL.GL_BLEND);
gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);
}
gl.glMatrixMode(javax.media.opengl.GL2.GL_MODELVIEW);
gl.glPushMatrix();
//inject gl if neccessary
if (this.lastGL != gl) {
this.injectGL(gl);
this.lastGL = gl;
}
}
// resets opengl state
protected void endDraw(DrawContext dc) {
GL2 gl = (GL2) dc.getGL();
gl.glMatrixMode(javax.media.opengl.GL2.GL_MODELVIEW);
gl.glPopMatrix();
gl.glPopAttrib();
}
private void injectGL(GL gl) {
String[] classes = new String[] {
"org.lwjgl.opengl.GL11",
"org.lwjgl.opengl.GL15",
"org.lwjgl.opengl.GL20",
"org.lwjgl.opengl.Util",
"org.lwjgl.opengl.ARBMultitexture",
"org.lwjgl.opengl.EXTFramebufferObject",
"org.lwjgl.opengl.ARBShaderObjects",
"org.lwjgl.opengl.GLContext" };
Class<?> clazz;
try {
for (int i = 0; i < classes.length; i++) {
clazz = Class.forName(classes[i]);
Field glf = clazz.getDeclaredField("gl");
glf.set(clazz, gl);
}
Log.d("gl injected.");
} catch (Exception e) {
Logger.log("Unable to inject GL context into the facade!",
Logger.ERROR);
}
}
/**
* Called by WorldWind to refresh this layer.
*/
@Override
protected void doRender(DrawContext dc) {
System.out.println("move="+move);
this.beginDraw(dc);
GL2 gl = (GL2) dc.getGL();
//get the WW position of the box.
Position position = D3Man.getInstance().translatePosition(
boxLoc.x, boxLoc.y, -boxLoc.z);
Vec4 loc = dc.getGlobe().computePointFromPosition(position);
double size = this.computeSize(dc, loc);
//move the box a little
move = move - 1;
box.translate(0, 0, move);
//save current gl settings before change it
dc.getView().pushReferenceCenter(dc, loc);
//adjust current gl settings for jPCT's world
gl.glRotated(position.getLongitude().degrees, 0, 1, 0);
gl.glRotated(-position.getLatitude().degrees, 1, 0, 0);
gl.glScaled(size, size, size);
// jPCT draw its world with the given gl
this.repaint();
//restore last gl settings
dc.getView().popReferenceCenter(dc);
this.endDraw(dc);
}
private double computeSize(DrawContext dc, Vec4 loc) {
if (loc == null) {
System.err.println("Null location when computing size of mode");
return 1;
}
double d = loc.distanceTo3(dc.getView().getEyePoint());
double size = 60 * dc.getView().computePixelSizeAtDistance(d);
if (size < 2)
size = 2;
return size;
}
/**
* force this layer to redraw components inside it.
*/
public void repaint() {
buffer.clear(java.awt.Color.GREEN);
world.renderScene(buffer);
world.draw(buffer);
buffer.update();
buffer.displayGLOnly();
canvas.repaint();
}
public static void main(String[] args) {
JFrame frame=new JFrame("Hello world");
frame.setSize(800, 600);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
Jpct3DLayer layer = new Jpct3DLayer();
frame.add(layer.canvas);
float x = 0f;
float y = 0f;
float z = 0f;
while (frame.isShowing()) {
layer.box.rotateY(0.1f);
y += 0.2f;
SimpleVector sv = new SimpleVector(x, y, z);
layer.box.translate(sv);
layer.buffer.clear(java.awt.Color.BLUE);
System.out.println(layer.box.getTranslation());
layer.world.renderScene(layer.buffer);
layer.world.draw(layer.buffer);
layer.buffer.update();
layer.buffer.displayGLOnly();
layer.canvas.repaint();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
--- End code ---
In the posted code, WW calls the doRender method and gives us a DrawContext where we can find the GL2 object.
I inject the GL2 object to jPCT classes.
I think it is a question about coordination transforming, but how can i get the right transformation to let jPCT
draw the box with WW's GL2?
BTW, the code can be run as a simple java app, with its main() method.
PS: Should i open another post to ask this question?
EgonOlsen:
Not sure...the mix between direct GL calls and jPCT scares me, because it's really hard to see if they don't interfere in some way. Anyway, if your WW coordinates are actual OpenGL coordinates, the jPCT equivalent would be (x, -y, -z): http://www.jpct.net/wiki/index.php?title=Coordinate_system.
I'm not sure if that's your actual issue though...
Navigation
[0] Message Index
[#] Next page
[*] Previous page
Go to full version