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 } } |
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
|
Just tried. Doesn't work. The program even doesn't call the update(Graphics g) when it's rendering...... |
Administrator
|
Then call repaint() in the display() method. I hope it will work.
Julien Gouesse | Personal blog | Website
|
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? |
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.
|
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. |
in my program ,glcanvas runs faster than gljpanel
|
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
|
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 |
Administrator
|
I've just tried to provide some possible solutions.
Julien Gouesse | Personal blog | Website
|
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. |
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. |
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
|
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...... |
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 |
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:
Julien Gouesse | Personal blog | Website
|
In reply to this post by cznlzq
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 |
Free forum by Nabble | Edit this page |