question about the GLCanvas and GLJPanel

classic Classic list List threaded Threaded
18 messages Options
Reply | Threaded
Open this post in threaded view
|

question about the GLCanvas and GLJPanel

cznlzq
Hi,

I'm trying to use the Graphics2D to draw some 2D stuff on the 3D scene,
however, I find that only the GLJPanel works but the GLCanvas doesn't.

Does someone has the same experience on this?

And here is the example I'm using as following
( If I change the GLJPanel to the GLCanvas in the testJOGL(),
after the Graphics2D drawString in the paintComponent() I can see nothing.......)


import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.media.opengl.GL;
import javax.media.opengl.GL2;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLProfile;

import javax.media.opengl.GLEventListener;
import javax.media.opengl.awt.GLCanvas;
import javax.media.opengl.awt.GLJPanel;
import javax.media.opengl.glu.GLU;
import javax.media.opengl.glu.GLUquadric;
import javax.swing.JFrame;
import javax.swing.JPanel;

import com.jogamp.opengl.util.FPSAnimator;

   
public class testJOGL extends JPanel implements GLEventListener
{
        @Override
    protected void paintComponent(Graphics arg0)
    {                  
        // TODO Auto-generated method stub
        super.paintComponent(arg0);    
       
        Graphics2D g2 = (Graphics2D)arg0;
        Font font = new Font("Times", Font.BOLD, 32);
        g2.setColor(Color.BLUE);
        g2.setFont(font);
        g2.drawString("2DRender", 150, 50);
       
    }

    private static final int REFRESH_FPS = 60;    // Display refresh frames per second
        final FPSAnimator animator;  // Used to drive display()
        private GLU glu;             // For the GL Utility

        static float anglePyramid = 0;    // rotational angle in degree for pyramid
        static float angleCube = 0;       // rotational angle in degree for cube
        static float speedPyramid = 2.0f; // rotational speed for pyramid
        static float speedCube = -1.5f;   // rotational speed for cube

        // Constructor
        public testJOGL() {
            GLProfile profile = GLProfile.getMaxProgrammable();    
            GLCapabilities capabilities = new GLCapabilities(profile);
            capabilities.setDoubleBuffered(true);
           
            //GLCanvas canvas = new GLCanvas(capabilities);
               
            GLJPanel canvas = new GLJPanel(capabilities);
            canvas.setOpaque(false);
               
            this.setLayout(new BorderLayout());
            this.add(canvas, BorderLayout.CENTER);
            canvas.addGLEventListener(this);

            // Run the animation loop using the fixed-rate Frame-per-second animator,
           // which calls back display() at this fixed-rate (FPS).
           animator = new FPSAnimator(canvas, REFRESH_FPS, true);
        }

        // Main program
        public static void main(String[] args) {
                final int WINDOW_WIDTH = 800;  // Width of the drawable
                final int WINDOW_HEIGHT = 400; // Height of the drawable
                final String WINDOW_TITLE = "3D Shapes";

                JFrame frame = new JFrame();
                final testJOGL joglMain = new testJOGL();
                frame.setContentPane(joglMain);
                frame.addWindowListener(new WindowAdapter() {
                        @Override
                        public void windowClosing(WindowEvent e) {
                                // Use a dedicate thread to run the stop() to ensure that the
                                // animator stops before program exits.
                                new Thread() {
                                        @Override
                                        public void run() {
                                                joglMain.animator.stop(); // stop the animator loop
                                                System.exit(0);
                                        }
                                }.start();
                        }
                });
                frame.setSize(WINDOW_WIDTH, WINDOW_HEIGHT);
                frame.setTitle(WINDOW_TITLE);
                frame.setVisible(true);
                joglMain.animator.start(); // start the animation loop
        }

        // Implement methods defined in GLEventListener
        @Override
        public void init(GLAutoDrawable drawable) {
                // Get the OpenGL graphics context
                GL2 gl = (GL2) drawable.getGL();
                // GL Utilities
                glu = new GLU();
                // Enable smooth shading, which blends colors nicely, and smoothes out lighting.
                gl.glShadeModel(GL2.GL_SMOOTH);
                // Set background color in RGBA. Alpha: 0 (transparent) 1 (opaque)
                gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
                // Setup the depth buffer and enable the depth testing
                gl.glClearDepth(1.0f);          // clear z-buffer to the farthest
                gl.glEnable(GL.GL_DEPTH_TEST);  // enables depth testing
                gl.glDepthFunc(GL.GL_LEQUAL);   // the type of depth test to do
                // Do the best perspective correction
                gl.glHint(GL2.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST);
        }

        @Override
        public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
                // Get the OpenGL graphics context
                GL2 gl = (GL2) drawable.getGL();

                height = (height == 0) ? 1 : height; // prevent divide by zero
                float aspect = (float)width / height;

                // Set the current view port to cover full screen
                gl.glViewport(0, 0, width, height);

                // Set up the projection matrix - choose perspective view
                gl.glMatrixMode(GL2.GL_PROJECTION);  
                gl.glLoadIdentity(); // reset
                // Angle of view (fovy) is 45 degrees (in the up y-direction). Based on this
                // canvas's aspect ratio. Clipping z-near is 0.1f and z-near is 100.0f.
                glu.gluPerspective(45.0f, aspect, 0.1f, 100.0f); // fovy, aspect, zNear, zFar

                // Enable the model-view transform
                gl.glMatrixMode(GL2.GL_MODELVIEW);
                gl.glLoadIdentity(); // reset
        }
       
        @Override
        public void display(GLAutoDrawable drawable) {
                // Get the OpenGL graphics context
                GL2 gl = (GL2) drawable.getGL();
                // Clear the color and the depth buffers
                gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
               
                drawScene(gl);

                // Update the rotational angle after each refresh.
                anglePyramid += speedPyramid;
                angleCube += speedCube;

        }
       
        public void drawScene(GL2 gl)
        {
               // ----- Render the Pyramid -----
        gl.glLoadIdentity();                 // reset the model-view matrix
        gl.glTranslatef(-2.6f, 0.0f, -6.0f); // translate left and into the screen
        gl.glRotatef(anglePyramid, -0.2f, 1.0f, 0.0f); // rotate about the y-axis

        gl.glBegin(GL.GL_TRIANGLES); // of the pyramid

        // Font-face triangle
        gl.glColor3f(1.0f, 0.0f, 0.0f); // Red
        gl.glVertex3f(0.0f, 1.0f, 0.0f);
        gl.glColor3f(0.0f, 1.0f, 0.0f); // Green
        gl.glVertex3f(-1.0f, -1.0f, 1.0f);
        gl.glColor3f(0.0f, 0.0f, 1.0f); // Blue
        gl.glVertex3f(1.0f, -1.0f, 1.0f);

        // Right-face triangle
        gl.glColor3f(1.0f, 0.0f, 0.0f); // Red
        gl.glVertex3f(0.0f, 1.0f, 0.0f);
        gl.glColor3f(0.0f, 0.0f, 1.0f); // Blue
        gl.glVertex3f(1.0f, -1.0f, 1.0f);
        gl.glColor3f(0.0f, 1.0f, 0.0f); // Green
        gl.glVertex3f(1.0f, -1.0f, -1.0f);

        // Back-face triangle
        gl.glColor3f(1.0f, 0.0f, 0.0f); // Red
        gl.glVertex3f(0.0f, 1.0f, 0.0f);
        gl.glColor3f(0.0f, 1.0f, 0.0f); // Green
        gl.glVertex3f(1.0f, -1.0f, -1.0f);
        gl.glColor3f(0.0f, 0.0f, 1.0f); // Blue
        gl.glVertex3f(-1.0f, -1.0f, -1.0f);

        // Left-face triangle
        gl.glColor3f(1.0f, 0.0f, 0.0f); // Red
        gl.glVertex3f(0.0f, 1.0f, 0.0f);
        gl.glColor3f(0.0f, 0.0f, 1.0f); // Blue
        gl.glVertex3f(-1.0f, -1.0f, -1.0f);
        gl.glColor3f(0.0f, 1.0f, 0.0f); // Green
        gl.glVertex3f(-1.0f, -1.0f, 1.0f);

        gl.glEnd(); // of the pyramid

        // ----- Render the Color Cube -----
        gl.glLoadIdentity();                // reset the current model-view matrix
        gl.glTranslatef(2.3f, 0.0f, -7.0f); // translate right and into the screen
        gl.glRotatef(angleCube, 1.0f, 1.0f, 1.0f); // rotate about the x, y and z-axes

        gl.glBegin(GL2.GL_QUADS); // of the color cube

        // Top-face
        gl.glColor3f(0.0f, 1.0f, 0.0f); // green
        gl.glVertex3f(1.0f, 1.0f, -1.0f);
        gl.glVertex3f(-1.0f, 1.0f, -1.0f);
        gl.glVertex3f(-1.0f, 1.0f, 1.0f);
        gl.glVertex3f(1.0f, 1.0f, 1.0f);

        // Bottom-face
        gl.glColor3f(1.0f, 0.5f, 0.0f); // orange
        gl.glVertex3f(1.0f, -1.0f, 1.0f);
        gl.glVertex3f(-1.0f, -1.0f, 1.0f);
        gl.glVertex3f(-1.0f, -1.0f, -1.0f);
        gl.glVertex3f(1.0f, -1.0f, -1.0f);

        // Front-face
        gl.glColor3f(1.0f, 0.0f, 0.0f); // red
        gl.glVertex3f(1.0f, 1.0f, 1.0f);
        gl.glVertex3f(-1.0f, 1.0f, 1.0f);
        gl.glVertex3f(-1.0f, -1.0f, 1.0f);
        gl.glVertex3f(1.0f, -1.0f, 1.0f);

        // Back-face
        gl.glColor3f(1.0f, 1.0f, 0.0f); // yellow
        gl.glVertex3f(1.0f, -1.0f, -1.0f);
        gl.glVertex3f(-1.0f, -1.0f, -1.0f);
        gl.glVertex3f(-1.0f, 1.0f, -1.0f);
        gl.glVertex3f(1.0f, 1.0f, -1.0f);

        // Left-face
        gl.glColor3f(0.0f, 0.0f, 1.0f); // blue
        gl.glVertex3f(-1.0f, 1.0f, 1.0f);
        gl.glVertex3f(-1.0f, 1.0f, -1.0f);
        gl.glVertex3f(-1.0f, -1.0f, -1.0f);
        gl.glVertex3f(-1.0f, -1.0f, 1.0f);

        // Right-face
        gl.glColor3f(1.0f, 0.0f, 1.0f); // magenta
        gl.glVertex3f(1.0f, 1.0f, -1.0f);
        gl.glVertex3f(1.0f, 1.0f, 1.0f);
        gl.glVertex3f(1.0f, -1.0f, 1.0f);
        gl.glVertex3f(1.0f, -1.0f, -1.0f);

        gl.glEnd(); // of the color cube
        }

        @Override
        public void dispose(GLAutoDrawable arg0) {
                // TODO Auto-generated method stub
               
        }
         
}

Reply | Threaded
Open this post in threaded view
|

Re: question about the GLCanvas and GLJPanel

gouessej
Administrator
GLJPanel is a Swing panel whereas GLCanvas is an AWT canvas, not a panel. You put your JOGL canvas into a JPanel. Maybe you should override the method update(Graphics g) of your test panel in order to force it to call paint(Graphics g).
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: question about the GLCanvas and GLJPanel

cznlzq

Just tried. Doesn't work.

The program even doesn't call the update(Graphics g) when it's rendering......



Reply | Threaded
Open this post in threaded view
|

Re: question about the GLCanvas and GLJPanel

gouessej
Administrator
Then call repaint() in the display() method. I hope it will work.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: question about the GLCanvas and GLJPanel

cznlzq
Thank you for the suggestion.

It is very interesting. Indeed we have to call the repaint in the display for the GLCanvas.

However, I found that for the GLJPanel we don't have to call any function.
Just override the paintComponent in GLJPanel then it will take care of everything.

And I recode the test codes to test these two

=========================================================


import java.awt.Color;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;


import javax.media.opengl.*;
import javax.media.opengl.awt.GLCanvas;
import javax.media.opengl.awt.GLJPanel;

import com.jogamp.opengl.util.FPSAnimator;

public class SimpleScene implements GLEventListener {

    private double theta = 0;
    private double s = 0;
    private double c = 0;

    private static GLCanvas canvas = null;
    private static GLJPanel panel = null;
   
    private static int step = 1;
   
    public static void main(String[] args) {
        GLProfile glp = GLProfile.getDefault();
        GLCapabilities caps = new GLCapabilities(glp);
        caps.setDoubleBuffered(true);
       
        canvas = new GLCanvas(caps){
       
                        @Override
                        public void paint(Graphics arg0) {
                               
                        //System.out.println("paint");

                        // TODO Auto-generated method stub
                        super.paint(arg0);

                        Graphics2D g2 = (Graphics2D)arg0;
                        Font font = new Font("Times", Font.BOLD, 32);
                        g2.setColor(Color.BLUE);
                        g2.setFont(font);
                        g2.drawString("2DRender", 250, 50);
                        }
       
        };

       
        panel =  new GLJPanel(){

                        @Override
                        protected void paintComponent(Graphics arg0) {
                        //System.out.println("paintComponent");
                       
                        // TODO Auto-generated method stub
                        super.paintComponent(arg0);

                        Graphics2D g2 = (Graphics2D)arg0;
                        Font font = new Font("Times", Font.BOLD, 32);
                        g2.setColor(Color.GREEN);
                        g2.setFont(font);
                        g2.drawString("2DRender", 250, 50);
                        }
       
        };
       
        Frame frame = new Frame("AWT Window Test");
        frame.setSize(600, 600);
        frame.add(canvas);
        //frame.add(panel);
        frame.setVisible(true);

        frame.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
       
        canvas.setAutoSwapBufferMode(true);        
        canvas.addGLEventListener(new SimpleScene());
        FPSAnimator animator = new FPSAnimator(canvas, 60);
        animator.add(canvas);    
       
//        panel.setAutoSwapBufferMode(true);        
//        panel.addGLEventListener(new SimpleScene());
//        FPSAnimator animator = new FPSAnimator(panel, 60);
//        animator.add(panel);  
       
        animator.start();
    }

    @Override
    public void display(GLAutoDrawable drawable) {
        update();
        render(drawable);
       
        canvas.repaint();
    }

    @Override
    public void dispose(GLAutoDrawable drawable) {
    }

    @Override
    public void init(GLAutoDrawable drawable) {
    }

    @Override
    public void reshape(GLAutoDrawable drawable, int x, int y, int w, int h) {
    }

    private void update() {
        theta += 0.01;
        s = Math.sin(theta);
        c = Math.cos(theta);
    }

    private void render(GLAutoDrawable drawable) {
        GL2 gl = drawable.getGL().getGL2();

        gl.glClear(GL.GL_COLOR_BUFFER_BIT);

        // draw a triangle filling the window
        gl.glBegin(GL.GL_TRIANGLES);
        gl.glColor3f(1, 0, 0);
        gl.glVertex2d(-c, -c);
        gl.glColor3f(0, 1, 0);
        gl.glVertex2d(0, c);
        gl.glColor3f(0, 0, 1);
        gl.glVertex2d(s, -s);
        gl.glEnd();
    }
}



I can see the drawString things, however, its background doesn't look good and it's flashing.

Did I make something wrong?

Reply | Threaded
Open this post in threaded view
|

Re: question about the GLCanvas and GLJPanel

kitfox
In this code, you're creating and adding both a GLCanvas and a GLJPanel, and then adding the GLCanvas.  Only create the GLJPanel if you want to use Java2D.
Reply | Threaded
Open this post in threaded view
|

Re: question about the GLCanvas and GLJPanel

cznlzq


I just want to test the capability of these two.

For now, from my experience,
it looks like the GLJPanel is much more better than the GLCanvas if we want to support the Java 2D drawing stuff.


Reply | Threaded
Open this post in threaded view
|

Re: question about the GLCanvas and GLJPanel

robbiezl
in my program ,glcanvas runs faster than gljpanel
Reply | Threaded
Open this post in threaded view
|

Re: question about the GLCanvas and GLJPanel

gouessej
Administrator
In reply to this post by cznlzq
Anyway, if you want to test the capability of these both canvas, only create one of it. GLCanvas is fine for Java 2D rendering if you're accustomed to mix AWT and Swing and someone else reminded us that GLCanvas is faster. GLCanvas has a lower memory footprint and is more reliable. You should use GLJPanel only in special cases, for example when you need to use internal frames with JOGL.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: question about the GLCanvas and GLJPanel

robbiezl
gouessej

Can u help to fix this problem.My code have the same problem,and there is a small example in it.Thank u very much.

http://forum.jogamp.org/Fullscreen-issue-on-KeyListener-event-td3855615.html
Reply | Threaded
Open this post in threaded view
|

Re: question about the GLCanvas and GLJPanel

gouessej
Administrator
robbiezl wrote
gouessej

Can u help to fix this problem.My code have the same problem,and there is a small example in it.Thank u very much.

http://forum.jogamp.org/Fullscreen-issue-on-KeyListener-event-td3855615.html
I've just tried to provide some possible solutions.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: question about the GLCanvas and GLJPanel

cznlzq
In reply to this post by gouessej

Actually, the second example I provided is to create just of them in the JFrame.

it is not convinced that GLCanvas is faster than GLJPanel from my experience.

Because I can see flashing in the GLCanvas when I draw some java2d things in my second example codes.

If it's fast enough, like as fast as GLJPanel, it should not be flashing.






Reply | Threaded
Open this post in threaded view
|

Re: question about the GLCanvas and GLJPanel

cznlzq
In reply to this post by robbiezl

Could you please let me know how you test the speed?

I want to test it in my own example to see the difference.

Thanks.
Reply | Threaded
Open this post in threaded view
|

Re: question about the GLCanvas and GLJPanel

gouessej
Administrator
In reply to this post by cznlzq
GLJPanel uses some kind of FBO under the hood. Of course it is slower. The flashes have nothing to do with the speed but rather with a misuse of Swing & AWT.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: question about the GLCanvas and GLJPanel

cznlzq
You post raises my guess.

At the beginning, people only have GLCanvas which can deal with the pure 3D things smoothly.

However, people find it incapable of the java2d drawing or like what you talked about the misuse of Swing & AWT, whatever.

Then people invent the GLJPanel to compromise with those situations.

GLJPanel has to do more things to be capable of something the GLCanvas can't do, so it's slower......

Reply | Threaded
Open this post in threaded view
|

Re: question about the GLCanvas and GLJPanel

robbiezl
In reply to this post by cznlzq
in my programe,with GLCanvas ths FPS is abort 60
but with GLJpanel the FPS is only 30
Reply | Threaded
Open this post in threaded view
|

Re: question about the GLCanvas and GLJPanel

gouessej
Administrator
In reply to this post by cznlzq
GLJPanel is almost only required when you use JInternalFrame, for example when you want to display some 3D meshes with a small internal window over it and even in this case, maybe it is possible to put a GLCanvas into a Panel if and only if mixing AWT & Swing is correctly supported by the JVM.

This is mentioned in the documentation:
GLJPanel is provided for compatibility with Swing user interfaces when adding a heavyweight doesn't work either because of Z-ordering or LayoutManager problems.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: question about the GLCanvas and GLJPanel

elect
In reply to this post by cznlzq
cznlzq wrote
Thank you for the suggestion.

It is very interesting. Indeed we have to call the repaint in the display
for the GLCanvas.

However, I found that for the GLJPanel we don't have to call any function.
Just override the paintComponent in GLJPanel then it will take care of
everything.

And I recode the test codes to test these two

=========================================================
For me, this last example of yours doesnt even show the "2DRender" written....

I have success only with GLJPanel so far

Ps: sorry for the email cznlzq, but I misunderstood the button to reply :p