Hello. I have to display large amount of quads, and for more performance I decide to use VBO for that task. But something goes wrong, and I got a batch of exceptions on
gl.glBufferData(targetsBuffer.get(0), fBuff.capacity(),fBuff,gl.GL_STATIC_DRAW); Here is class which I use for creating and using VBO public class Terrain implements IShape { private ObjectArrayList<Vector3f> vectors; private GL2 gl; private FloatBuffer fBuff; private IntBuffer targetsBuffer; public Terrain(GL2 gl) throws Exception { this.gl=gl; vectors=new ObjectArrayList<Vector3f>(); Import(".//data.exp"); } private void Import(String path) throws Exception { byte[] bytes = Files.readAllBytes(Paths.get(path)); // import files with heights int resolution = (int)Math.sqrt(bytes.length/4); // define resolution float[] floats=new float[resolution*resolution]; ByteBuffer.wrap(bytes).order(ByteOrder.nativeOrder()).asFloatBuffer().get(floats); float step = 100/(resolution-1.0f); fBuff = FloatBuffer.allocate(resolution*resolution*3*4); // create buffer with vertices for(int i =0; i<resolution-1; i++) { for(int j =0; j<resolution-1; j++) // here I create a grid, 4 vertices for each quad { float x1=i,y1=floats[i*resolution+j]*600,z1=j; vectors.add(new Vector3f(x1,y1,z1)); // physics engine needs it for create a collider float x2=i+1,y2=floats[(i+1)*resolution+j]*600,z2=j; vectors.add(new Vector3f(x2,y2,z2)); float x3=i+1,y3=floats[(i+1)*resolution+(j+1)]*600,z3=j+1; vectors.add(new Vector3f(x3,y3,z3)); float x4=i,y4=floats[i*resolution+(j+1)]*600,z4=j+1; vectors.add(new Vector3f(x4,y4,z4)); fBuff.put(x1); // add vertices to buffer fBuff.put(y1); fBuff.put(z1); fBuff.put(x2); fBuff.put(y2); fBuff.put(z2); fBuff.put(x3); fBuff.put(y3); fBuff.put(z3); fBuff.put(x4); fBuff.put(y4); fBuff.put(z4); } } float max=Float.MIN_VALUE,min=Float.MAX_VALUE; for(float f : floats) { if(f>max)max=f; if(f<min)min=f; } System.out.println(floats[0]+" : "+floats[floats.length-1]); System.out.println("Max: "+max+"\nMin: "+min); } public ObjectArrayList<Vector3f> GetVertexes() { return vectors; } public void CreateBuffer(GL2 gl) { this.gl=gl; targetsBuffer = IntBuffer.allocate(1); gl.glGenBuffers(1,targetsBuffer); gl.glBindBuffer(gl.GL_ARRAY_BUFFER,targetsBuffer.get(0)); gl.glBufferData(targetsBuffer.get(0), fBuff.capacity(),fBuff,gl.GL_STATIC_DRAW); } @Override public void Draw() { gl.glEnableClientState(gl.GL_VERTEX_ARRAY); gl.glBindVertexArray(targetsBuffer.get(0)); gl.glDrawArrays(gl.GL_QUADS,0,fBuff.capacity()); gl.glDisableClientState(gl.GL_VERTEX_ARRAY); } } In Main class I have initialize this class terrain=new Terrain(); And then call methods from init and render methods @Override public void init(GLAutoDrawable glAutoDrawable) { glu=GLU.createGLU(glAutoDrawable.getGL().getGL2()); glut=new GLUT(); gl=glAutoDrawable.getGL().getGL2(); //gl.glPolygonMode(gl.GL_FRONT_AND_BACK,gl.GL_LINE); terrain.CreateBuffer(gl); System.out.println(gl.isExtensionAvailable("GL_ARB_vertex_buffer_object")); } private void render(GLAutoDrawable drawable) { gl.glEnable(gl.GL_DEPTH_TEST); gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); gl.glClearColor(0.2f, 0.4f, 0.7f, 0); gl.glMatrixMode(gl.GL_MODELVIEW); gl.glLoadIdentity(); glu.gluLookAt(cameraPos.x, cameraPos.y, cameraPos.z, pointOfInterest.x, pointOfInterest.y, pointOfInterest.z, 0, 1, 0); gl.glPushMatrix(); int x=0; for(RigidBody ball : balls) { gl.glPushMatrix(); { float[] buff = new float[16]; ball.getWorldTransform(new Transform()).getOpenGLMatrix(buff); gl.glMultMatrixf(FloatBuffer.wrap(buff)); gl.glColor3f(0, 1, 0); glut.glutSolidSphere(1,10,10); } gl.glPopMatrix(); x++; } gl.glColor3f(0.5f,0,0); gl.glPopMatrix(); terrain.Draw(); } But I have exception which appears in this method public void CreateBuffer(GL2 gl) on call gl.glBufferData(targetsBuffer.get(0), fBuff.capacity(),fBuff,gl.GL_STATIC_DRAW); So what I did wrong? |
Administrator
|
Hi
Please read the "man" of glBufferData: https://www.opengl.org/sdk/docs/man/html/glBufferData.xhtml You should rather write: fBuff = Buffers.newDirectFloatBuffer(resolution*resolution*3*4); gl.glBufferData(targetsBuffer.get(0), Buffers.SIZEOF_FLOAT*fBuff.capacity(),fBuff,GL.GL_STATIC_DRAW); targetsBuffer = Buffers.newDirectIntBuffer(1); Call fBuff.rewind() at the end of your import method. Please post your exceptions. How can we help you if you don't show us what's wrong? (even though your code helps)
Julien Gouesse | Personal blog | Website
|
Ok, i have changed the code. But exceptions still are.
Exception in thread "AWT-EventQueue-0" javax.media.opengl.GLException: Caught GLException: GL_INVALID_ENUM​: Invalid binding target 0x1 on thread AWT-EventQueue-0 at javax.media.opengl.GLException.newGLException(GLException.java:75) at jogamp.opengl.GLDrawableHelper.invokeGLImpl(GLDrawableHelper.java:1311) at jogamp.opengl.GLDrawableHelper.invokeGL(GLDrawableHelper.java:1131) at javax.media.opengl.awt.GLCanvas$11.run(GLCanvas.java:1394) at javax.media.opengl.Threading.invoke(Threading.java:223) at javax.media.opengl.awt.GLCanvas.display(GLCanvas.java:525) at javax.media.opengl.awt.GLCanvas.paint(GLCanvas.java:579) at sun.awt.RepaintArea.paintComponent(RepaintArea.java:264) at sun.awt.RepaintArea.paint(RepaintArea.java:240) at sun.awt.windows.WComponentPeer.handleEvent(WComponentPeer.java:347) at java.awt.Component.dispatchEventImpl(Component.java:4937) at java.awt.Component.dispatchEvent(Component.java:4687) at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:735) at java.awt.EventQueue.access$200(EventQueue.java:103) at java.awt.EventQueue$3.run(EventQueue.java:694) at java.awt.EventQueue$3.run(EventQueue.java:692) at java.security.AccessController.doPrivileged(Native Method) at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76) at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87) at java.awt.EventQueue$4.run(EventQueue.java:708) at java.awt.EventQueue$4.run(EventQueue.java:706) at java.security.AccessController.doPrivileged(Native Method) at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76) at java.awt.EventQueue.dispatchEvent(EventQueue.java:705) at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242) at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161) at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138) at java.awt.EventDispatchThread.run(EventDispatchThread.java:91) Caused by: javax.media.opengl.GLException: GL_INVALID_ENUM​: Invalid binding target 0x1 at jogamp.opengl.GLBufferStateTracker.getQueryName(GLBufferStateTracker.java:151) at jogamp.opengl.GLBufferStateTracker.getBoundBufferObject(GLBufferStateTracker.java:225) at jogamp.opengl.GLBufferObjectTracker.createBufferStorage(GLBufferObjectTracker.java:156) at jogamp.opengl.gl4.GL4bcImpl.glBufferData(GL4bcImpl.java:37383) at Terrain.CreateBuffer(Terrain.java:98) at Main.init(Main.java:329) at jogamp.opengl.GLDrawableHelper.init(GLDrawableHelper.java:640) at jogamp.opengl.GLDrawableHelper.init(GLDrawableHelper.java:662) at javax.media.opengl.awt.GLCanvas$9.run(GLCanvas.java:1366) at jogamp.opengl.GLDrawableHelper.invokeGLImpl(GLDrawableHelper.java:1275) ... 28 more |
Administrator
|
Rather write:
gl.glBufferData(GL.GL_ARRAY_BUFFER, Buffers.SIZEOF_FLOAT*fBuff.capacity(),fBuff,GL.GL_STATIC_DRAW); You passed a buffer identifier instead of a buffer target. It was explained in the documentation: target Specifies the target to which the buffer object is bound for glBufferData, which must be one of the buffer binding targets in the following table: Please read the documentation carefully, it will prevent you from doing tons of mistakes.
Julien Gouesse | Personal blog | Website
|
i thought that target it is buffer id xD
Now all exceptions disappeared! But i have this thing # # A fatal error has been detected by the Java Runtime Environment: # # EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x000000000ee5fe93, pid=5408, tid=7308 # # JRE version: Java(TM) SE Runtime Environment (7.0_51-b13) (build 1.7.0_51-b13) # Java VM: Java HotSpot(TM) 64-Bit Server VM (24.51-b03 mixed mode windows-amd64 compressed oops) # Problematic frame: # C 0x000000000ee5fe93 # # Failed to write core dump. Minidumps are not enabled by default on client versions of Windows # # An error report file with more information is saved as: # D:\IdeaProjects\Java3D\hs_err_pid5408.log # # If you would like to submit a bug report, please visit: # http://bugreport.sun.com/bugreport/crash.jsp # The crash happened outside the Java Virtual Machine in native code. # See problematic frame for where to report the bug. # |
Administrator
|
Replace:
gl.glBindVertexArray(targetsBuffer.get(0)); by gl.glBindBuffer(gl.GL_ARRAY_BUFFER,targetsBuffer.get(0)); glBindVertexArray is used for VAOs, not for VBOs. Please ensure that you call fBuff.rewind() to avoid to ask OpenGL to read beyond the size of the buffer. If you really want to use VAOs, look at this example: http://jogamp.org/git/?p=jogl-demos.git;a=blob;f=src/demos/es2/RawGL2ES2demo.java;hb=HEAD Always look at the documentation when you're not sure of what to pass to an OpenGL method.
Julien Gouesse | Personal blog | Website
|
Thanks! Additional to your advice i replaced all VERTEX ARRAY to ARRAY BUFFER and now have this code
public void CreateBuffer(GL2 gl) { this.gl=gl; targetsBuffer = Buffers.newDirectIntBuffer(1); gl.glGenBuffers(1,targetsBuffer); gl.glBindBuffer(gl.GL_ARRAY_BUFFER,targetsBuffer.get(0)); gl.glBufferData(GL.GL_ARRAY_BUFFER, Buffers.SIZEOF_FLOAT*fBuff.capacity(),fBuff,GL.GL_STATIC_DRAW); } @Override public void Draw() { gl.glEnableClientState(gl.GL_ARRAY_BUFFER); gl.glBindBuffer(GL.GL_ARRAY_BUFFER,targetsBuffer.get(0)); gl.glDrawBuffer(targetsBuffer.get(0)); gl.glDisableClientState(gl.GL_ARRAY_BUFFER); } Now it compiles and runs good - but i don't see any mesh in my window =( |
Administrator
|
This post was updated on .
Sorry but your change is wrong, you broke something that was correct, rather write that:
gl.glEnableClientState(GLPointerFunc.GL_VERTEX_ARRAY); ... gl.glDisableClientState(GLPointerFunc.GL_VERTEX_ARRAY); Look at the documentation: https://www.opengl.org/sdk/docs/man2/xhtml/glEnableClientState.xml No you don't have to call glDrawBuffer, you should call glDrawArrays, it was correct: gl.glDrawArrays(GL2GL3.GL_QUADS,0,fBuff.capacity()/3); You should really spend some time in reading the example I quoted because you seem to make some changes without understanding how the API works.
Julien Gouesse | Personal blog | Website
|
Jesus Christ! Hallelujah! LOL
Actually i watched examples but all they was different. This code is works! public void CreateBuffer(GL2 gl) { this.gl=gl; BufferOffset=Buffers.newDirectIntBuffer(4); targetsBuffer = Buffers.newDirectIntBuffer(1); gl.glGenBuffers(1, targetsBuffer); gl.glBindBuffer(GL.GL_ARRAY_BUFFER, targetsBuffer.get(0)); gl.glEnableClientState(gl.GL_VERTEX_ARRAY); gl.glBufferData(GL.GL_ARRAY_BUFFER, fBuff.capacity()*4, fBuff, GL.GL_STATIC_DRAW); gl.glDisableClientState(gl.GL_VERTEX_ARRAY); } @Override public void Draw(){ gl.glBindBuffer(GL.GL_ARRAY_BUFFER,targetsBuffer.get(0)); gl.glEnableClientState(GL2.GL_VERTEX_ARRAY); gl.glVertexPointer(3, GL.GL_FLOAT, 0, 0 ); gl.glDrawArrays(GL2.GL_QUADS,0,fBuff.capacity()*4); gl.glBindBuffer(GL.GL_ARRAY_BUFFER,0); gl.glDisableClientState(GL2.GL_VERTEX_ARRAY); } |
Administrator
|
You seem not to understand the examples that you looked, you give the impression to tinker without understanding what you do. Buffers.SIZEOF_FLOAT = 4, therefore fBuff.capacity()*4 should be rewritten by using Buffers.SIZEOF_FLOAT as I suggested, it's more readable, it's better than using a magic number. BufferOffset seems to be useless. gl.glEnableClientState(gl.GL_VERTEX_ARRAY) is the equivalent of gl.glEnableClientState(GLPointerFunc.GL_VERTEX_ARRAY) but as the constant is static, there is no need of using "gl". gl.glDrawArrays(GL2.GL_QUADS,0,fBuff.capacity()*4) is still wrong because the last parameter is the count of vertices or indices to render and your vertices have 3 coordinates (x, y, z) then you should write gl.glDrawArrays(GL2GL3.GL_QUADS,0,fBuff.capacity()/3). Yes I forgot to tell you that you had forgotten glVertexPointer but your code was full of mistakes, I did my best.
Julien Gouesse | Personal blog | Website
|
Free forum by Nabble | Edit this page |