Author Topic: 2 cameras with opengl  (Read 8319 times)

Offline Marlon

  • int
  • **
  • Posts: 74
    • View Profile
    • Forgotten Elements Action MMORPG
2 cameras with opengl
« on: January 25, 2011, 11:12:11 am »
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
www.forgottenelements.com
Free Action JAVA MMORPG

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 12295
    • View Profile
    • http://www.jpct.net
Re: 2 cameras with opengl
« Reply #1 on: January 25, 2011, 01:16:41 pm »
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.

Offline Marlon

  • int
  • **
  • Posts: 74
    • View Profile
    • Forgotten Elements Action MMORPG
Re: 2 cameras with opengl
« Reply #2 on: January 25, 2011, 02:30:53 pm »
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:
Code: [Select]
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:
Code: [Select]
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();
www.forgottenelements.com
Free Action JAVA MMORPG

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 12295
    • View Profile
    • http://www.jpct.net
Re: 2 cameras with opengl
« Reply #3 on: January 25, 2011, 11:25:41 pm »
I'm not sure...maybe the gl canvas doesn't like this setup. Can you assemble a little test case for me to try?

Offline Marlon

  • int
  • **
  • Posts: 74
    • View Profile
    • Forgotten Elements Action MMORPG
Re: 2 cameras with opengl
« Reply #4 on: January 26, 2011, 10:30:09 am »
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
www.forgottenelements.com
Free Action JAVA MMORPG

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 12295
    • View Profile
    • http://www.jpct.net
Re: 2 cameras with opengl
« Reply #5 on: January 26, 2011, 10:51:22 am »
A test case...the simplest possible, compilable class(es) that show the problem.

Offline Marlon

  • int
  • **
  • Posts: 74
    • View Profile
    • Forgotten Elements Action MMORPG
Re: 2 cameras with opengl
« Reply #6 on: January 26, 2011, 11:02:31 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:

Code: [Select]
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();
}

Code: [Select]
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);
}
www.forgottenelements.com
Free Action JAVA MMORPG

Offline Marlon

  • int
  • **
  • Posts: 74
    • View Profile
    • Forgotten Elements Action MMORPG
Re: 2 cameras with opengl
« Reply #7 on: January 26, 2011, 03:38:32 pm »
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)

Code: [Select]
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
www.forgottenelements.com
Free Action JAVA MMORPG

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 12295
    • View Profile
    • http://www.jpct.net
Re: 2 cameras with opengl
« Reply #8 on: January 26, 2011, 08:33:23 pm »
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.
« Last Edit: January 26, 2011, 08:42:39 pm by EgonOlsen »

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 12295
    • View Profile
    • http://www.jpct.net
Re: 2 cameras with opengl
« Reply #9 on: January 26, 2011, 08:48:01 pm »
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.

Offline Marlon

  • int
  • **
  • Posts: 74
    • View Profile
    • Forgotten Elements Action MMORPG
Re: 2 cameras with opengl
« Reply #10 on: January 27, 2011, 11:48:06 am »
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
www.forgottenelements.com
Free Action JAVA MMORPG