elect
Jr. Member   Posts: 58
|
 |
«
on:
2012-02-03 09:36:11 » |
|
Hi guys, I had my program working with VBOs, but then I had to change the general structure, create additional classes and make everything cleaner, ect.. But when I finished it was not working any more... Here the basic: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
| public class Test extends javax.swing.JFrame {
private Viewer viewer=null; ArrayList<Triangle> sectionPointsArray; ArrayList<LightBulb> lightBulbs = new ArrayList<LightBulb>(); ArrayList<Plane> planes = new ArrayList<Plane>(); public Test() { initComponents(); DataModelViewer.testclass = this; this.setSize(800, 800); viewer = new Viewer(); DataModelViewer.viewer = viewer; this.getContentPane().add(viewer,BorderLayout.CENTER); } private void initComponents() {
fileChooser = new javax.swing.JFileChooser(); jMenuBar1 = new javax.swing.JMenuBar(); jMenu1 = new javax.swing.JMenu(); button_load = new javax.swing.JMenuItem(); button_calc = new javax.swing.JMenuItem(); button_exit = new javax.swing.JMenuItem();
fileChooser.setDialogTitle("Choose a stl file.."); fileChooser.setFileFilter(new StlFilter());
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
jMenu1.setText("Process");
button_load.setText("Load Model"); button_load.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { button_loadActionPerformed(evt); } }); jMenu1.add(button_load);
button_calc.setText("Calculate"); button_calc.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { button_calcActionPerformed(evt); } }); jMenu1.add(button_calc);
button_exit.setText("Exit"); button_exit.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { button_exitActionPerformed(evt); } }); jMenu1.add(button_exit);
jMenuBar1.add(jMenu1);
setJMenuBar(jMenuBar1);
pack(); }
private void button_loadActionPerformed(java.awt.event.ActionEvent evt) { int returnVal = fileChooser.showOpenDialog(this); if (returnVal == JFileChooser.APPROVE_OPTION) { File file = fileChooser.getSelectedFile(); System.out.println(file.getAbsolutePath()); System.out.println("Loading model."); LoadSTL loadSTL = new LoadSTL(file, DataModelViewer.array); System.out.println("Loading model finished."); viewer.loadModel(DataModelViewer.gl); } else { System.out.println("File access cancelled by user."); } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
| public class Viewer extends JPanel implements GLEventListener, MouseListener, MouseMotionListener, MouseWheelListener, KeyListener {
int nbVBO = 1; int[] VBO = new int[nbVBO];
public Viewer () { initDisplay(); initFlags(); } private void initDisplay() { glProfile = GLProfile.get(GLProfile.GL2); final GLCapabilities glCapabilities = new GLCapabilities(glProfile); GLCanvas glComponent = new GLCanvas(glCapabilities); this.gLCanvas = glComponent; this.setLayout(new BorderLayout()); gLCanvas.setPreferredSize(new Dimension(this.getWidth(),this.getHeight())); gLCanvas.setBackground(Color.RED); this.add(gLCanvas, BorderLayout.CENTER); gLCanvas.requestFocus(); gLCanvas.addGLEventListener(this); gLCanvas.addMouseListener(this); gLCanvas.addMouseMotionListener(this); gLCanvas.addMouseWheelListener(this); gLCanvas.addKeyListener(this); }
@Override public void init(GLAutoDrawable gLAutoDrawable) { System.out.println("Init");
currentRotation = identity();
animator = new Animator(gLCanvas); animator.start();
GL2 gl = gLAutoDrawable.getGL().getGL2(); DataModelViewer.gl = gl; loadFloorTexture(gl); gl.glClear(GL2.GL_COLOR_BUFFER_BIT); gl.glClearColor(0.17f, 0.65f, 0.92f, 0.0f); }
@Override public void display(GLAutoDrawable gLAutoDrawable) { GL2 gl = gLAutoDrawable.getGL().getGL2(); if ( switchableFlags.get("lighting").getFlag() ) gl.glEnable(GL2.GL_LIGHTING); else gl.glDisable(GL2.GL_LIGHTING); if ( switchableFlags.get("smoothing").getFlag() ) gl.glShadeModel(GL2.GL_SMOOTH); else gl.glShadeModel(GL2.GL_FLAT);
if ( switchableFlags.get("color").getFlag() ) gl.glEnable(GL2.GL_COLOR_MATERIAL); else gl.glDisable(GL2.GL_COLOR_MATERIAL); gl.glMatrixMode(GL2.GL_MODELVIEW); gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT); gl.glLoadIdentity(); gl.glMultMatrixf(currentRotation, 0); gl.glTranslatef((float)translationX/20.0f, (float)translationY/20.0f, 0); gl.glScalef(scale%10.0f, scale%10.0f, scale%10.0f); gl.glMatrixMode(GL2.GL_PROJECTION); if(isThereModel) { gl.glEnableClientState(GL2.GL_VERTEX_ARRAY); gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, VBO[0]); gl.glVertexPointer(3, GL2.GL_FLOAT, 0, 0);
gl.glColor3f(0.0f, 0.0f, 0.0f);
gl.glDrawArrays(GL2.GL_TRIANGLES, 0, triangleNumber*3);
gl.glDisableClientState(GL2.GL_VERTEX_ARRAY); } gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, 0); renderLightSource(gl); drawFloor(gl); }
private void initVertexArray(GL2 gl) { gl.glEnableClientState(GL2.GL_VERTEX_ARRAY); gl.glGenBuffers(1, VBO, 0);
gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, VBO[0]); gl.glBufferData(GL2.GL_ARRAY_BUFFER, triangleNumber*3*3, vertexData, GL2.GL_STATIC_DRAW); gl.glDisableClientState(GL2.GL_VERTEX_ARRAY); } |
And this is still the error I get: Exception in thread "AWT-EventQueue-0-AWTAnimator-1" javax.media.opengl.GLException: javax.media.opengl.GLException: array vertex_buffer_object must be enabled to call this method at jogamp.opengl.awt.AWTThreadingPlugin.invokeOnOpenGLThread(AWTThreadingPlugin.java:98) at jogamp.opengl.ThreadingImpl.invokeOnOpenGLThread(ThreadingImpl.java:197) at javax.media.opengl.Threading.invokeOnOpenGLThread(Threading.java:164) at javax.media.opengl.awt.GLCanvas.maybeDoSingleThreadedWorkaround(GLCanvas.java:830) at javax.media.opengl.awt.GLCanvas.display(GLCanvas.java:419) at com.jogamp.opengl.util.AWTAnimatorImpl.display(AWTAnimatorImpl.java:74) at com.jogamp.opengl.util.AnimatorBase.display(AnimatorBase.java:142) at com.jogamp.opengl.util.Animator$MainLoop.run(Animator.java:176) at java.lang.Thread.run(Thread.java:722) Caused by: javax.media.opengl.GLException: array vertex_buffer_object must be enabled to call this method at jogamp.opengl.gl4.GL4bcImpl.checkBufferObject(GL4bcImpl.java:32025) at jogamp.opengl.gl4.GL4bcImpl.checkArrayVBOEnabled(GL4bcImpl.java:32052) at jogamp.opengl.gl4.GL4bcImpl.glVertexPointer(GL4bcImpl.java:31004) at cuda.Viewer.display(Viewer.java:333) at jogamp.opengl.GLDrawableHelper.displayImpl(GLDrawableHelper.java:182) at jogamp.opengl.GLDrawableHelper.display(GLDrawableHelper.java:170) at javax.media.opengl.awt.GLCanvas$DisplayAction.run(GLCanvas.java:939) at jogamp.opengl.GLDrawableHelper.invokeGL(GLDrawableHelper.java:398) at javax.media.opengl.awt.GLCanvas$DisplayOnEventDispatchThreadAction.run(GLCanvas.java:956) at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:241) at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:705) at java.awt.EventQueue.access$000(EventQueue.java:101) at java.awt.EventQueue$3.run(EventQueue.java:666) at java.awt.EventQueue$3.run(EventQueue.java:664) at java.security.AccessController.doPrivileged(Native Method) at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76) at java.awt.EventQueue.dispatchEvent(EventQueue.java:675) at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:211) at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:128) at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:117) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:113) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:105) at java.awt.EventDispatchThread.run(EventDispatchThread.java:90) My specs are: Win7 64bit, 4gb, 560 Ti (285.62) The code is JOGL in Netbeans. I am using OpenGL 2.0.
|
|
|
|
|
|
|
elect
Jr. Member   Posts: 58
|
 |
«
Reply #2 on:
2012-02-06 03:27:18 » |
|
Hi gouessej, Ok, I added, but I still get the error.. I also tried with glBegin/glEnd and Vertex Array and I didnt encounter any problem... Is it right to enable GL_Vertex_array only when I need (and disable just after)? or should I keep it always on?
|
|
|
|
|
Games published by our own members! Go get 'em!
|
|
elect
Jr. Member   Posts: 58
|
 |
«
Reply #3 on:
2012-02-06 04:13:28 » |
|
Can I safely declare the gl as public variable instead passing it to each function that needs it?
|
|
|
|
|
elect
Jr. Member   Posts: 58
|
 |
«
Reply #4 on:
2012-02-06 05:38:11 » |
|
It is funny, look, I modified the following: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| private void initVertexArray() { vertexData = GLBuffers.newDirectFloatBuffer(9); vertexData.put(new float[]{0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f}); vertexData.flip(); gl.glGenBuffers(1, VBO, 0); gl.glEnableClientState(GL2.GL_VERTEX_ARRAY); gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, VBO[0]); gl.glBufferData(GL2.GL_ARRAY_BUFFER, 36, vertexData, GL2.GL_STATIC_DRAW); gl.glDisableClientState(GL2.GL_VERTEX_ARRAY); gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, 0); } |
If I call the initVertexArray from the init(), no problem, the triangle get rendered. But if I call it when the user performs some action, then I get the exception... O_o
|
|
|
|
|
theagentd
JGO Wizard     Posts: 1392 Medals: 88
|
 |
«
Reply #5 on:
2012-02-06 06:51:42 » |
|
gl.glEnableClientState(...) is used to tell gl.glDrawArrays(...) or glDrawElements(...) which values it should read from gl****Pointer(...) or from VBOs. It has nothing to do with creating or uploading data to a VBO. Instead you need to use gl.glEnableClientState(...) before your draw command. You can then use gl.glDisableClientState(...) to avoid leaking OpenGL state if you draw other stuff later.
|
There is no god.
|
|
|
elect
Jr. Member   Posts: 58
|
 |
«
Reply #6 on:
2012-02-06 07:17:20 » |
|
gl.glEnableClientState(...) is used to tell gl.glDrawArrays(...) or glDrawElements(...) which values it should read from gl****Pointer(...) or from VBOs. It has nothing to do with creating or uploading data to a VBO. Instead you need to use gl.glEnableClientState(...) before your draw command. You can then use gl.glDisableClientState(...) to avoid leaking OpenGL state if you draw other stuff later.
Ah ok, so I can eliminate the 2 calls to enable and disable the GL_Vertex_Array in the creation and data upload.. But for the draw command everything then looks right.. However, how could you explain the fact that calling if I call the initVertexArray from the init() everything works like a charm, but if I do from a triggered event I get an exception? I dont know, but I would say that the code lines about the VBO withing the initVertexArray() have no effect when I dont call it from the init()..
|
|
|
|
|
theagentd
JGO Wizard     Posts: 1392 Medals: 88
|
 |
«
Reply #7 on:
2012-02-06 07:20:46 » |
|
I haven't looked at your code, but OpenGL commands can only be called from a single thread, the thread owning the context. If your event is being processed on a different thread it would be an illegal command to call any OpenGL functions.
|
There is no god.
|
|
|
elect
Jr. Member   Posts: 58
|
 |
«
Reply #8 on:
2012-02-06 08:21:06 » |
|
I haven't looked at your code, but OpenGL commands can only be called from a single thread, the thread owning the context. If your event is being processed on a different thread it would be an illegal command to call any OpenGL functions.
I managed to make it work, I moved the initVertexArray() call in the display(): 1 2 3 4
| if(initialize) { initVertexArray(); initialize = false; } |
In this way the call takes place within the same class I ended up that the error was because I was calling 1 2 3 4 5 6 7 8 9
| public void loadModel() { System.out.println("BLA1"); initVertexArray(); System.out.println("BLA2"); isThereModel = true; } |
from another class (but I am pretty sure always within the same thread
|
|
|
|
|
gouessej
JGO Kernel      Posts: 3558 Medals: 30
TUER
|
 |
«
Reply #9 on:
2012-02-06 13:55:57 » |
|
Can I safely declare the gl as public variable instead passing it to each function that needs it?
No, please never do that. As someone else said, use GL only on the rendering thread and when the context is current, your OpenGL calls have to be done from a JOGL callback, for example in the display() method of your GLEventListener. You should look at the Red Book and the "man" when you don't know how to use some OpenGL calls. Good luck.
|
Julien Gouesse
|
|
|
Games published by our own members! Go get 'em!
|
|
elect
Jr. Member   Posts: 58
|
 |
«
Reply #10 on:
2012-02-07 02:55:06 » |
|
Can I safely declare the gl as public variable instead passing it to each function that needs it?
No, please never do that. As someone else said, use GL only on the rendering thread and when the context is current, your OpenGL calls have to be done from a JOGL callback, for example in the display() method of your GLEventListener. You should look at the Red Book and the "man" when you don't know how to use some OpenGL calls. Good luck. Ok, thanks gouessej (and also theagentd) 
|
|
|
|
|
gouessej
JGO Kernel      Posts: 3558 Medals: 30
TUER
|
 |
«
Reply #11 on:
2012-02-08 15:27:28 » |
|
I forgot to explain to you something. The GL instance might become invalid between several passes, that is why storing such an instance is a bad idea. Best regards.
|
Julien Gouesse
|
|
|
elect
Jr. Member   Posts: 58
|
 |
«
Reply #12 on:
2012-02-09 09:03:02 » |
|
I forgot to explain to you something. The GL instance might become invalid between several passes, that is why storing such an instance is a bad idea. Best regards.
Yep, you are right, indeed I just saw with the gDebugger that during my application up to 8 context are created/destroyed
|
|
|
|
|
gouessej
JGO Kernel      Posts: 3558 Medals: 30
TUER
|
 |
«
Reply #13 on:
2012-02-09 18:29:45 » |
|
I forgot to explain to you something. The GL instance might become invalid between several passes, that is why storing such an instance is a bad idea. Best regards.
Yep, you are right, indeed I just saw with the gDebugger that during my application up to 8 context are created/destroyed Actually, GL is not an OpenGL context, several GL instances might be used at runtime with a single real OpenGL context.
|
Julien Gouesse
|
|
|
|