Author Topic: Isometric 3D in JPanel  (Read 4498 times)

Offline dunkedbiscuit

  • byte
  • *
  • Posts: 20
    • View Profile
Isometric 3D in JPanel
« on: January 12, 2012, 01:03:43 am »
Hi

I've got (I think) isometric 3D working, which is pretty nice. However, when I try to put it into a JPanel I get an error like this:

Code: [Select]
Exception in thread "main" java.lang.NullPointerException
        at org.lwjgl.opengl.GL11.glMatrixMode(GL11.java:2052)
        at orthogonal_test.Main.loop(Main.java:56)
        at orthogonal_test.Main.main(Main.java:22)

And here's all the code:

Code: [Select]
package orthogonal_test;

import com.threed.jpct.*;
import org.lwjgl.opengl.GL11;

import javax.swing.*;
import java.awt.*;

/**
 * A simple HelloWorld using the OpenGL-renderer.
 * @author EgonOlsen
 *
 */
public class Main {

private World world;
private FrameBuffer buffer;
private Object3D box;
        private Camera cam;

public static void main(String[] args) throws Exception {
new Main().loop();
}

public Main() throws Exception {
world = new World();
world.setAmbientLight(0, 255, 0);

box = Primitives.getBox(1f, 1f);
box.build();
world.addObject(box);

                float dist = 30f;

                cam = world.getCamera();
                cam.setPosition( new SimpleVector( dist, dist, dist ) );
                cam.lookAt( new SimpleVector( 0, 0, 0 ) );
}

private void loop() throws Exception {
buffer = new FrameBuffer(800, 600, FrameBuffer.SAMPLINGMODE_NORMAL);
buffer.disableRenderer(IRenderer.RENDERER_SOFTWARE);
buffer.enableRenderer(IRenderer.RENDERER_OPENGL);

                JFrame frame = new JFrame();
                Canvas canvas = buffer.enableGLCanvasRenderer();
                frame.add(canvas);
                frame.setVisible(true);
                frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
               
while ( frame.isVisible() ) {

buffer.clear(java.awt.Color.BLACK);
world.renderScene(buffer);
world.drawWireframe(buffer, java.awt.Color.YELLOW);
buffer.update();

                       
                        GL11.glMatrixMode(GL11.GL_PROJECTION);
                        GL11.glLoadIdentity();
                        float scalar = 50f;
                        //GL11.glOrtho(-13, 13, -1, 10, -30, 100);
                        GL11.glMatrixMode(GL11.GL_MODELVIEW);
                        GL11.glLoadIdentity();
                        GL11.glRotatef(35.264f, 1.0f, 0.0f, 0.0f);
                        GL11.glRotatef(-45.0f, 0.0f, 1.0f, 0.0f);
                        GL11.glScalef(1.0f, 1.0f, -1.0f);
                        GL11.glTranslatef( 0, 0, 0 );
                       
                        GL11.glBegin(GL11.GL_LINES);
                        GL11.glColor3f(1.0f, 0.0f, 0.0f);
                        GL11.glVertex3d(0, 0, 0);
                        GL11.glVertex3d(10, 0, 0);
                        GL11.glEnd();

                        GL11.glBegin(GL11.GL_LINES);
                        GL11.glColor3f(0.0f, 1.0f, 0.0f);
                        GL11.glVertex3d(0, 0, 0);
                        GL11.glVertex3d(0, 10, 0);
                        GL11.glEnd();

                        GL11.glBegin(GL11.GL_LINES);
                        GL11.glColor3f(0.0f, 0.0f, 1.0f);
                        GL11.glVertex3d(0, 0, 0);
                        GL11.glVertex3d(0, 0, -10);
                        GL11.glEnd();

buffer.displayGLOnly();
Thread.sleep(10);
}
buffer.disableRenderer(IRenderer.RENDERER_OPENGL);
buffer.dispose();
System.exit(0);
}
}

Any help / code snippets would be greatly appreciated.

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 12295
    • View Profile
    • http://www.jpct.net
Re: Isometric 3D in JPanel
« Reply #1 on: January 12, 2012, 08:03:06 am »
When using the GLCanvasRenderer, the gl context might or might not have been created when entering the loop, because it all happens in another thread. Apart from that, it wouldn't work anyway this way, because the thread which does the rendering isn't the thread of your main loop. COnsider to put your code into an implementation of the IPainterListener interface instead.

Offline dunkedbiscuit

  • byte
  • *
  • Posts: 20
    • View Profile
Re: Isometric 3D in JPanel
« Reply #2 on: January 12, 2012, 09:38:20 am »
I've tried putting the opengl code in the startPainting() method, but there's no effect. I also put it in finishedPainting() but that didn't work. Am I missing something crucial?

Code: [Select]
package orthogonal_test;

import com.threed.jpct.*;
import org.lwjgl.opengl.GL11;

import javax.swing.*;
import java.awt.*;

/**
 * A simple HelloWorld using the OpenGL-renderer.
 * @author EgonOlsen
 *
 */
public class Main implements IPaintListener {

private World world;
private FrameBuffer buffer;
private Object3D box;
        private Camera cam;

public static void main(String[] args) throws Exception {
new Main().loop();
}

public Main() throws Exception {
world = new World();
world.setAmbientLight(0, 255, 0);

box = Primitives.getBox(1f, 1f);
box.build();
world.addObject(box);

                float dist = 30f;

                cam = world.getCamera();
                cam.setPosition( new SimpleVector( dist, dist, dist ) );
                cam.lookAt( box.getTransformedCenter() );
}

private void loop() throws Exception {
buffer = new FrameBuffer(800, 600, FrameBuffer.SAMPLINGMODE_NORMAL);
buffer.disableRenderer(IRenderer.RENDERER_SOFTWARE);
buffer.enableRenderer(IRenderer.RENDERER_OPENGL, IRenderer.MODE_OPENGL);
                buffer.setPaintListener(this);

                JFrame frame = new JFrame();
                frame.setSize( 800, 600 );
                frame.setResizable(false);
                Canvas canvas = buffer.enableGLCanvasRenderer();
                frame.add(canvas);
                frame.setVisible(true);
                frame.setDefaultCloseOperation( JFrame.HIDE_ON_CLOSE );
               
while ( frame.isVisible() ) {

buffer.clear(java.awt.Color.BLACK);
world.renderScene(buffer);
world.draw(buffer);
buffer.update();

buffer.displayGLOnly();
Thread.sleep(10);
}
buffer.disableRenderer(IRenderer.RENDERER_OPENGL);
buffer.dispose();
System.exit(0);
}

        public void startPainting()
        {
            GL11.glMatrixMode(GL11.GL_PROJECTION);
            GL11.glLoadIdentity();
            GL11.glOrtho(-13, 13, -1, 10, -30, 100);
            GL11.glMatrixMode(GL11.GL_MODELVIEW);
            GL11.glLoadIdentity();
            GL11.glRotatef(35.264f, 1.0f, 0.0f, 0.0f);
            GL11.glRotatef(-45.0f, 0.0f, 1.0f, 0.0f);
            GL11.glScalef(1.0f, 1.0f, -1.0f);
            GL11.glTranslatef( 0, 0, 0 );

            GL11.glBegin(GL11.GL_LINES);
            GL11.glColor3f(1.0f, 0.0f, 0.0f);
            GL11.glVertex3d(0, 0, 0);
            GL11.glVertex3d(10, 0, 0);
            GL11.glEnd();

            GL11.glBegin(GL11.GL_LINES);
            GL11.glColor3f(0.0f, 1.0f, 0.0f);
            GL11.glVertex3d(0, 0, 0);
            GL11.glVertex3d(0, 10, 0);
            GL11.glEnd();

            GL11.glBegin(GL11.GL_LINES);
            GL11.glColor3f(0.0f, 0.0f, 1.0f);
            GL11.glVertex3d(0, 0, 0);
            GL11.glVertex3d(0, 0, -10);
            GL11.glEnd();
        }

        public void finishedPainting()
        {
           GL11.glMatrixMode(GL11.GL_PROJECTION);
            GL11.glLoadIdentity();
            float scalar = 50f;
            //GL11.glOrtho(-13, 13, -1, 10, -30, 100);
            GL11.glMatrixMode(GL11.GL_MODELVIEW);
            GL11.glLoadIdentity();
            GL11.glRotatef(35.264f, 1.0f, 0.0f, 0.0f);
            GL11.glRotatef(-45.0f, 0.0f, 1.0f, 0.0f);
            GL11.glScalef(1.0f, 1.0f, -1.0f);
            GL11.glTranslatef( 0, 0, 0 );

            GL11.glBegin(GL11.GL_LINES);
            GL11.glColor3f(1.0f, 0.0f, 0.0f);
            GL11.glVertex3d(0, 0, 0);
            GL11.glVertex3d(10, 0, 0);
            GL11.glEnd();

            GL11.glBegin(GL11.GL_LINES);
            GL11.glColor3f(0.0f, 1.0f, 0.0f);
            GL11.glVertex3d(0, 0, 0);
            GL11.glVertex3d(0, 10, 0);
            GL11.glEnd();

            GL11.glBegin(GL11.GL_LINES);
            GL11.glColor3f(0.0f, 0.0f, 1.0f);
            GL11.glVertex3d(0, 0, 0);
            GL11.glVertex3d(0, 0, -10);
            GL11.glEnd();
        }
}
« Last Edit: January 12, 2012, 09:41:46 am by dunkedbiscuit »

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 12295
    • View Profile
    • http://www.jpct.net
Re: Isometric 3D in JPanel
« Reply #3 on: January 12, 2012, 09:40:10 am »
Am I missing something crucial?
Yes. You aren't adding your IPaintListener to the FrameBuffer...

Offline dunkedbiscuit

  • byte
  • *
  • Posts: 20
    • View Profile
Re: Isometric 3D in JPanel
« Reply #4 on: January 12, 2012, 09:44:22 am »
Added the IPaintListener. Now the canvas is simply black. I think that the code in the startPainting method isn't called at all since i placed some text to be printed to the console there, and nothing is being printed.

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 12295
    • View Profile
    • http://www.jpct.net
Re: Isometric 3D in JPanel
« Reply #5 on: January 12, 2012, 09:55:07 am »
Try to add a repaint()-call just like the HelloWorld example for AWT does.

Offline dunkedbiscuit

  • byte
  • *
  • Posts: 20
    • View Profile
Re: Isometric 3D in JPanel
« Reply #6 on: January 12, 2012, 09:59:21 am »
I've added one, and now I can see the cube. However, the code in startPainting and finishedPainting isn't being called.

Code: [Select]
package orthogonal_test;

import com.threed.jpct.*;
import org.lwjgl.opengl.GL11;

import javax.swing.*;
import java.awt.*;

/**
 * A simple HelloWorld using the OpenGL-renderer.
 * @author EgonOlsen
 *
 */
public class Main implements IPaintListener {

private World world;
private FrameBuffer buffer;
private Object3D box;
        private Camera cam;

public static void main(String[] args) throws Exception {
new Main().loop();
}

public Main() throws Exception {
world = new World();
world.setAmbientLight(0, 255, 0);

box = Primitives.getBox(1f, 1f);
box.build();
world.addObject(box);

                float dist = 30f;

                cam = world.getCamera();
                cam.setPosition( new SimpleVector( dist, dist, dist ) );
                cam.lookAt( box.getTransformedCenter() );
}

private void loop() throws Exception {
buffer = new FrameBuffer(800, 600, FrameBuffer.SAMPLINGMODE_NORMAL);
buffer.disableRenderer(IRenderer.RENDERER_SOFTWARE);
buffer.enableRenderer(IRenderer.RENDERER_OPENGL, IRenderer.MODE_OPENGL);
                buffer.setPaintListener(this);

                JFrame frame = new JFrame();
                frame.setSize( 800, 600 );
                frame.setResizable(false);
                Canvas canvas = buffer.enableGLCanvasRenderer();
                frame.add(canvas);
                frame.setVisible(true);
                frame.setDefaultCloseOperation( JFrame.HIDE_ON_CLOSE );
               
while ( frame.isVisible() ) {

buffer.clear(java.awt.Color.BLACK);
world.renderScene(buffer);
world.draw(buffer);
buffer.update();

buffer.displayGLOnly();
                        canvas.repaint();
Thread.sleep(10);
}
buffer.disableRenderer(IRenderer.RENDERER_OPENGL);
buffer.dispose();
System.exit(0);
}

        public void startPainting()
        {
            System.out.println("here");
            GL11.glMatrixMode(GL11.GL_PROJECTION);
            GL11.glLoadIdentity();
            GL11.glOrtho(-13, 13, -1, 10, -30, 100);
            GL11.glMatrixMode(GL11.GL_MODELVIEW);
            GL11.glLoadIdentity();
            GL11.glRotatef(35.264f, 1.0f, 0.0f, 0.0f);
            GL11.glRotatef(-45.0f, 0.0f, 1.0f, 0.0f);
            GL11.glScalef(1.0f, 1.0f, -1.0f);
            GL11.glTranslatef( 0, 0, 0 );

            GL11.glBegin(GL11.GL_LINES);
            GL11.glColor3f(1.0f, 0.0f, 0.0f);
            GL11.glVertex3d(0, 0, 0);
            GL11.glVertex3d(10, 0, 0);
            GL11.glEnd();

            GL11.glBegin(GL11.GL_LINES);
            GL11.glColor3f(0.0f, 1.0f, 0.0f);
            GL11.glVertex3d(0, 0, 0);
            GL11.glVertex3d(0, 10, 0);
            GL11.glEnd();

            GL11.glBegin(GL11.GL_LINES);
            GL11.glColor3f(0.0f, 0.0f, 1.0f);
            GL11.glVertex3d(0, 0, 0);
            GL11.glVertex3d(0, 0, -10);
            GL11.glEnd();
        }

        public void finishedPainting()
        {
            System.out.println("here");
            GL11.glMatrixMode(GL11.GL_PROJECTION);
            GL11.glLoadIdentity();
            GL11.glOrtho(-13, 13, -1, 10, -30, 100);
            GL11.glMatrixMode(GL11.GL_MODELVIEW);
            GL11.glLoadIdentity();
            GL11.glRotatef(35.264f, 1.0f, 0.0f, 0.0f);
            GL11.glRotatef(-45.0f, 0.0f, 1.0f, 0.0f);
            GL11.glScalef(1.0f, 1.0f, -1.0f);
            GL11.glTranslatef( 0, 0, 0 );

            GL11.glBegin(GL11.GL_LINES);
            GL11.glColor3f(1.0f, 0.0f, 0.0f);
            GL11.glVertex3d(0, 0, 0);
            GL11.glVertex3d(10, 0, 0);
            GL11.glEnd();

            GL11.glBegin(GL11.GL_LINES);
            GL11.glColor3f(0.0f, 1.0f, 0.0f);
            GL11.glVertex3d(0, 0, 0);
            GL11.glVertex3d(0, 10, 0);
            GL11.glEnd();

            GL11.glBegin(GL11.GL_LINES);
            GL11.glColor3f(0.0f, 0.0f, 1.0f);
            GL11.glVertex3d(0, 0, 0);
            GL11.glVertex3d(0, 0, -10);
            GL11.glEnd();
        }
}

Offline dunkedbiscuit

  • byte
  • *
  • Posts: 20
    • View Profile
Re: Isometric 3D in JPanel
« Reply #7 on: January 12, 2012, 10:53:03 am »
Got it to work! It seems I forgot to use the framebuffer's setPaintListenerState() method to activate the IPaintListener. Thanks for your help. Do you know how to add a box where the axis lines are being drawn, i.e. in the centre of them, so that I can see if the view is truly isometric? Further, will object selection through Interact2D continue to work with the isometric view, and if so, how could I implement it to select objects in isometric view?

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 12295
    • View Profile
    • http://www.jpct.net
Re: Isometric 3D in JPanel
« Reply #8 on: January 12, 2012, 11:27:58 am »
No. A lot of things won't work as expected if you start to fiddle around with gl settings and projections behind the engine's back and i don't recommend to do this. I'm sorry, but i'm not able to support this kind of adventure much further than what i already did. You have the option to hook into the pipeline and do these things, but if you do, you are on your own, i'm afraid. Just expect the unexpected... ;)

Offline dunkedbiscuit

  • byte
  • *
  • Posts: 20
    • View Profile
Re: Isometric 3D in JPanel
« Reply #9 on: January 12, 2012, 12:55:41 pm »
Lol. I guess you're right. I'll have to look at the source for the Interact2D methods. Perhaps a orthogonal mode would be something for a new release?

Offline AGP

  • quad
  • ******
  • Posts: 1726
    • View Profile
Re: Isometric 3D in JPanel
« Reply #10 on: January 12, 2012, 05:12:35 pm »
So by your count, Egon, this makes how many orthogonal requests? : -)

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 12295
    • View Profile
    • http://www.jpct.net
Re: Isometric 3D in JPanel
« Reply #11 on: January 12, 2012, 08:26:53 pm »
Three, four, hundreds...i don't know exactly, but it's not going to happen.

Offline AGP

  • quad
  • ******
  • Posts: 1726
    • View Profile
Re: Isometric 3D in JPanel
« Reply #12 on: January 12, 2012, 10:33:31 pm »
OK, then.