Hello to all out there!
I am working with JPCT since 1 week now and I am really enjoying it!
It's a great engine, which is easy to use and there is much potential and many possibilities!
And here I start my first thread to raise my hope in solving a difficult problem:
I have written a program, which shows 1 object rendered by 2 cameras.
The reason why I use 2 cameras is to view this object in stereoscopic 3D.
In software mode the program runs great and it works, but I want the movement more smooth and so I
decided to use opengl.
Further I took a closer look at the AdvancedExample.
The problem here is that no AWT frame was used and so I don't see any possibilities to display 2 cameras (splitscreen)
in one AWT frame in opengl mode.
If somebody know how to solve the problem I would be very glad.
Thank you!
Marlon
Have a look at the AWTGLRenderer. With that, you can make the hardware renderer render into (different) canvas'. Have a look at HelloWorldAWTGL.java on how to enable it.
Thanks for your help!
I took a look at the suggested HelloWorldAWTGL.java Example and changed my code.
Unfortunately only the left (camera 1) side of the AWT frame is displayed.
I don't know, maybe I am missing something...
Here is my code, does anybody know what is wrong?
Thanks in advance!
Marlon
Init buffer and canvas of each camera:
buffer = new FrameBuffer(width / div, height, FrameBuffer.SAMPLINGMODE_NORMAL);
canvas=buffer.enableGLCanvasRenderer();
buffer.disableRenderer(IRenderer.RENDERER_SOFTWARE);
frame.add(canvas);
buffer2 = new FrameBuffer(width / 2, height, FrameBuffer.SAMPLINGMODE_NORMAL);
canvas2=buffer2.enableGLCanvasRenderer();
buffer2.disableRenderer(IRenderer.RENDERER_SOFTWARE);
frame.add(canvas2);
Render scene within loop method:
buffer.clear(java.awt.Color.BLACK);
world.renderScene(buffer);
world.draw(buffer);
buffer.update();
buffer.displayGLOnly();
canvas.repaint();
buffer2.clear(java.awt.Color.BLACK);
world2.renderScene(buffer2);
world2.draw(buffer2);
buffer2.update();
buffer2.displayGLOnly();
canvas2.repaint();
I'm not sure...maybe the gl canvas doesn't like this setup. Can you assemble a little test case for me to try?
Quote from: EgonOlsen on January 25, 2011, 11:25:41 PM
Can you assemble a little test case for me to try?
Erm.. you mean you want to test it out for yourself?
I could send you the project files (211kb), but how should I upload the data?
Thanks for your help,
Marlon
A test case...the simplest possible, compilable class(es) that show the problem.
Quote from: EgonOlsen on January 26, 2011, 10:51:22 AM
A test case...the simplest possible, compilable class(es) that show the problem.
Code has 20 kb of size :(
There are 8 classes.
Here are the most important fragments:
private void initFrame() {
frame = new JFrame("3D Car");
frame.pack();
Insets insets = frame.getInsets();
titleBarHeight = insets.top;
leftBorderWidth = insets.left;
frame.setSize(width + leftBorderWidth + insets.right, height + titleBarHeight + insets.bottom);
frame.setResizable(false);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.addKeyListener(new MyKeyListener(this));
gFrame = frame.getGraphics();
}
private void loop() {
World.setDefaultThread(Thread.currentThread());
//layout
FlowLayout flLayout = new FlowLayout();
frame.setLayout(flLayout);
frame.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
buffer = new FrameBuffer(width / 2, height, FrameBuffer.SAMPLINGMODE_NORMAL);
canvas=buffer.enableGLCanvasRenderer();
buffer.disableRenderer(IRenderer.RENDERER_SOFTWARE);
frame.add(canvas);
buffer2 = new FrameBuffer(width / 2, height, FrameBuffer.SAMPLINGMODE_NORMAL);
canvas2=buffer2.enableGLCanvasRenderer();
buffer2.disableRenderer(IRenderer.RENDERER_SOFTWARE);
frame.add(canvas2);
Timer timer = new Timer(25);
timer.start();
Timer fpsTimer = new Timer(1000);
fpsTimer.start();
while (!exit) {
if (!isIdle) {
long ticks = timer.getElapsedTicks();
for (int i = 0; i < ticks; i++) {
moveCar();
if(i==0) {
moveCamera();
}
}
buffer.clear(java.awt.Color.BLACK);
world.renderScene(buffer);
world.draw(buffer);
buffer.update();
buffer.displayGLOnly();
canvas.repaint();
buffer2.clear(java.awt.Color.BLACK);
world2.renderScene(buffer2);
world2.draw(buffer2);
buffer2.update();
buffer2.displayGLOnly();
canvas2.repaint();
fps++;
pps += world.getVisibilityList().getSize();
if (fpsTimer.getElapsedTicks() > 0) {
totalFps = (fps - lastFps);
lastFps = fps;
lastPps = pps;
pps = 0;
}
Thread.yield();
} else {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
}
}
}
buffer.disableRenderer(IRenderer.RENDERER_OPENGL);
buffer.dispose();
buffer2.disableRenderer(IRenderer.RENDERER_OPENGL);
buffer2.dispose();
frame.dispose();
System.exit(0);
}
Now I have written a small program which shows the problem.
2 worlds, 2 objects, 2 cameras but only left camera renders the scene.
(at software mode it runs great)
import java.awt.Canvas;
import java.awt.ComponentOrientation;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Insets;
import javax.swing.JFrame;
import com.threed.jpct.Config;
import com.threed.jpct.FrameBuffer;
import com.threed.jpct.IRenderer;
import com.threed.jpct.Lights;
import com.threed.jpct.Object3D;
import com.threed.jpct.Primitives;
import com.threed.jpct.SimpleVector;
import com.threed.jpct.World;
public class MainProgram implements Runnable {
private final int WIDTH=800, HEIGHT=600;
private World worldLeft, worldRight;
private Object3D objLeft, objRight;
private FrameBuffer bufferLeft, bufferRight;
private Canvas canvasLeft=null, canvasRight=null;
private float camStartX=0, camStartY=-30, camStartZ=-90;
private JFrame frame;
private int titleBarHeight, leftBorderWidth;
private boolean running=true;
public static void main(String[] args) throws Exception {
Config.glVerbose = true;
new MainProgram();
}
public MainProgram() throws Exception {
Config.maxPolysVisible=20000;
//frame
initFrame();
//world
worldLeft = createWorld();
worldRight = createWorld();
//object
objLeft = add3DObject(worldLeft);
objRight = add3DObject(worldRight);
//camera
adjustCamera(worldLeft, objLeft, true);
adjustCamera(worldRight, objRight, false);
initWorld();
new Thread(this).start();
}
private void initFrame() {
frame = new JFrame("OpenGL Stereoscopic Test");
frame.pack();
Insets insets = frame.getInsets();
titleBarHeight = insets.top;
leftBorderWidth = insets.left;
frame.setSize(WIDTH + leftBorderWidth + insets.right, HEIGHT + titleBarHeight + insets.bottom);
frame.setResizable(false);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
private World createWorld() {
// world
World world = new World();
// light
Config.fadeoutLight = false;
world.getLights().setOverbrightLighting(Lights.OVERBRIGHT_LIGHTING_DISABLED);
world.getLights().setRGBScale(Lights.RGB_SCALE_2X);
world.setAmbientLight(25, 30, 30);
world.addLight(new SimpleVector(-1000, -150, 1000), 8, 3, 2);
return world;
}
private Object3D add3DObject(World world) {
Object3D box = Primitives.getBox(13f, 2f);
box.setEnvmapped(Object3D.ENVMAP_ENABLED);
box.build();
world.addObject(box);
return box;
}
private void adjustCamera(World world, Object3D obj, boolean left) {
float add = camStartX;
if (left) {
add = 14;
}
world.getCamera().setPosition(add, camStartY, camStartZ);
world.getCamera().lookAt(obj.getTransformedCenter());
}
private void initWorld() {
//layout
FlowLayout flLayout = new FlowLayout();
frame.setLayout(flLayout);
frame.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
//left side
bufferLeft = new FrameBuffer(WIDTH/2, HEIGHT, FrameBuffer.SAMPLINGMODE_NORMAL);
canvasLeft=bufferLeft.enableGLCanvasRenderer();
bufferLeft.disableRenderer(IRenderer.RENDERER_SOFTWARE);
canvasLeft.setSize(new Dimension(WIDTH/2, HEIGHT));
frame.add(canvasLeft);
//right side
bufferRight = new FrameBuffer(WIDTH/2, HEIGHT, FrameBuffer.SAMPLINGMODE_NORMAL);
canvasRight=bufferRight.enableGLCanvasRenderer();
bufferRight.disableRenderer(IRenderer.RENDERER_SOFTWARE);
canvasRight.setSize(new Dimension(WIDTH/2, HEIGHT));
frame.add(canvasRight);
}
private void loop() {
bufferLeft.clear(java.awt.Color.BLACK);
worldLeft.renderScene(bufferLeft);
worldLeft.draw(bufferLeft);
bufferLeft.update();
bufferLeft.displayGLOnly();
canvasLeft.repaint();
bufferRight.clear(java.awt.Color.BLACK);
worldRight.renderScene(bufferRight);
worldRight.draw(bufferRight);
bufferRight.update();
bufferRight.displayGLOnly();
canvasRight.repaint();
try {
Thread.sleep(40);
} catch (InterruptedException e) {
e.printStackTrace();
}
Thread.yield();
}
@Override
public void run() {
while(running) {
loop();
}
bufferLeft.disableRenderer(IRenderer.RENDERER_OPENGL);
bufferLeft.dispose();
bufferRight.disableRenderer(IRenderer.RENDERER_OPENGL);
bufferRight.dispose();
frame.dispose();
System.exit(0);
}
}
If you are able to find a solution, please let me know.
Many many thanks!!!
Marlon
The canvas' are painted over each other. If you make the left one half the size, you'll see that the right one is below. I'm not a Swing guy, so i'm not sure how to get rid of this. I tried some things but to no avail. Swing always does these wtf-things...which is why i hate it. The same happens if you use jPCT's jogl support btw, so it's not a LWJGL issue but rather some AWT/Swing-mixing issue or whatever.
Blargh...it's actually really simple. Move the frame.pack(); to the end of initWorld() and it works fine. At least it does for me.
Ha, yeah!
Sometimes its that simple!
(Although I thought a "FlowLayoutManager" would do the whole position stuff)
Yeah, I'm not a big fan of Swing either, i use to write my own GUI frameworks.
But now it works, many many thanks!!!
Marlon