Exception: array vertex_buffer_object must be enabled to call this method

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

Exception: array vertex_buffer_object must be enabled to call this method

gmseed
Hi

I ported the Tutorial 2 FragPosition.cpp tutorial at http://arcsynthesis.org/gltut/ to JOGL; see code below.

It works fine on my 64bit WinXP PC with an Nvidia Quadro but when I run it on my laptop with 64bit Win7 with an ATI Radeon I get the following exception trace.

Does anyone know why this is happening?

It appears to be failing in:

Exception in thread "AWT-EventQueue-0" javax.media.opengl.GLException: array vertex_buffer_object must be enabled to call this method
        at jogamp.opengl.gl4.GL4bcImpl.checkBufferObject(GL4bcImpl.java:32020)
        at jogamp.opengl.gl4.GL4bcImpl.checkArrayVBOEnabled(GL4bcImpl.java:32047)
        at jogamp.opengl.gl4.GL4bcImpl.glVertexAttribPointer(GL4bcImpl.java:30691)

and doesn't like the call to glVertexAttribPointer().

Thanks Graham

===Exception===

Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: Compile failure in vertex shader: ????????????????????????????????›?????????????????????????????›?????????????????????????????›??????????????????????????

        at modern_gl_prog.Framework.compileShader(Framework.java:113)
        at modern_gl_prog.Framework.loadShader(Framework.java:60)
        at modern_gl_prog.tut2FragPositionCanvas.initializeProgram(tut2FragPosition.java:83)
        at modern_gl_prog.tut2FragPositionCanvas.init(tut2FragPosition.java:116)
        at jogamp.opengl.GLDrawableHelper.init(GLDrawableHelper.java:132)
        at jogamp.opengl.GLDrawableHelper.init(GLDrawableHelper.java:151)
        at javax.media.opengl.awt.GLCanvas$InitAction.run(GLCanvas.java:881)
        at jogamp.opengl.GLDrawableHelper.invokeGL(GLDrawableHelper.java:336)
        at javax.media.opengl.awt.GLCanvas.maybeDoSingleThreadedWorkaround(GLCanvas.java:794)
        at javax.media.opengl.awt.GLCanvas.display(GLCanvas.java:398)
        at javax.media.opengl.awt.GLCanvas.paint(GLCanvas.java:497)
        at sun.awt.RepaintArea.paintComponent(Unknown Source)
        at sun.awt.RepaintArea.paint(Unknown Source)
        at sun.awt.windows.WComponentPeer.handleEvent(Unknown Source)
        at java.awt.Component.dispatchEventImpl(Unknown Source)
        at java.awt.Component.dispatchEvent(Unknown Source)
        at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
        at java.awt.EventQueue.access$000(Unknown Source)
        at java.awt.EventQueue$3.run(Unknown Source)
        at java.awt.EventQueue$3.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
        at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
        at java.awt.EventQueue$4.run(Unknown Source)
        at java.awt.EventQueue$4.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
        at java.awt.EventQueue.dispatchEvent(Unknown Source)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
        at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
        at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
        at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
        at java.awt.EventDispatchThread.run(Unknown Source)
Exception in thread "AWT-EventQueue-0" javax.media.opengl.GLException: array vertex_buffer_object must be enabled to call this method
        at jogamp.opengl.gl4.GL4bcImpl.checkBufferObject(GL4bcImpl.java:32020)
        at jogamp.opengl.gl4.GL4bcImpl.checkArrayVBOEnabled(GL4bcImpl.java:32047)
        at jogamp.opengl.gl4.GL4bcImpl.glVertexAttribPointer(GL4bcImpl.java:30691)
        at modern_gl_prog.tut2FragPositionCanvas.display(tut2FragPosition.java:138)
        at jogamp.opengl.GLDrawableHelper.displayImpl(GLDrawableHelper.java:171)
        at jogamp.opengl.GLDrawableHelper.display(GLDrawableHelper.java:159)
        at javax.media.opengl.awt.GLCanvas$DisplayAction.run(GLCanvas.java:898)
        at jogamp.opengl.GLDrawableHelper.invokeGL(GLDrawableHelper.java:343)
        at javax.media.opengl.awt.GLCanvas.maybeDoSingleThreadedWorkaround(GLCanvas.java:794)
        at javax.media.opengl.awt.GLCanvas.display(GLCanvas.java:398)
        at javax.media.opengl.awt.GLCanvas.paint(GLCanvas.java:497)
        at sun.awt.RepaintArea.paintComponent(Unknown Source)
        at sun.awt.RepaintArea.paint(Unknown Source)
        at sun.awt.windows.WComponentPeer.handleEvent(Unknown Source)
        at java.awt.Component.dispatchEventImpl(Unknown Source)
        at java.awt.Component.dispatchEvent(Unknown Source)
        at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
        at java.awt.EventQueue.access$000(Unknown Source)
        at java.awt.EventQueue$3.run(Unknown Source)
        at java.awt.EventQueue$3.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
        at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
        at java.awt.EventQueue$4.run(Unknown Source)
        at java.awt.EventQueue$4.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
        at java.awt.EventQueue.dispatchEvent(Unknown Source)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
        at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
        at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
        at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
        at java.awt.EventDispatchThread.run(Unknown Source)

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

===Program===

package modern_gl_prog;

//java
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import java.awt.Canvas;
import java.nio.FloatBuffer;
//gl
import javax.media.opengl.GL;
import javax.media.opengl.GL2;
import javax.media.opengl.GL4;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.awt.GLCanvas;
import com.jogamp.common.nio.Buffers;

public class tut2FragPosition extends JFrame
{
    private JPanel contentPane;
    private Canvas canvas;
   
    /**
     * Launch the application.
     */
    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                try
                {
                    tut2FragPosition frame = new tut2FragPosition();
                    frame.setVisible(true);
                }
                catch (Exception e)
                {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */
    public tut2FragPosition()
    {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 500, 500);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(contentPane);
        contentPane.setLayout(null);
       
        canvas = new tut2FragPositionCanvas();
        canvas.setBounds(0, 0, 500, 500);
        contentPane.add(canvas);        
    }

} // class tut2FragPosition

class tut2FragPositionCanvas extends GLCanvas
                             implements GLEventListener
{
    protected int mTheProgram;              // handle to program object
    protected int mVertexBufferObject;      // handle to buffer object
    protected int mvao;                     // vertex array object

    protected int           mVertexCount = 3;
    protected FloatBuffer   mVertexData  = null;
   
    public tut2FragPositionCanvas()
    {
        super();
        this.addGLEventListener(this);
    }

    void initializeProgram(GL2 gl)
    {
        int   vertexShader      = Framework.loadShader(gl,GL2.GL_VERTEX_SHADER,"FragPosition.vert");
        int   fragmentShader    = Framework.loadShader(gl,GL2.GL_FRAGMENT_SHADER,"FragPosition.frag");
        int[] shaderList        = new int[2];
        shaderList[0] = vertexShader;
        shaderList[1] = fragmentShader;
       
        mTheProgram = Framework.createProgram(gl,shaderList);
    }

    void initializeVertexBuffer(GL2 gl)
    {
        int[] array = new int[1];
        gl.glGenBuffers(1, array, 0);
        mVertexBufferObject = array[0];

        // allocate vertex buffer [4 for (x,y,z,w) for each vertex]
        mVertexData = Buffers.newDirectFloatBuffer(4*mVertexCount);
        mVertexData.put(0.75f);  mVertexData.put(0.75f);  mVertexData.put(0.75f); mVertexData.put(1.0f);
        mVertexData.put(0.75f);  mVertexData.put(-0.75f); mVertexData.put(0.0f);  mVertexData.put(1.0f);
        mVertexData.put(-0.75f); mVertexData.put(-0.75f); mVertexData.put(0.0f);  mVertexData.put(1.0f);
        // invoke this method to prepare for a sequence of channel-write or relative get operations
        mVertexData.flip();
       
        gl.glBindBuffer(GL2.GL_ARRAY_BUFFER,mVertexBufferObject);
        gl.glBufferData(GL2.GL_ARRAY_BUFFER,4*mVertexCount*Buffers.SIZEOF_FLOAT,mVertexData,GL2.GL_STATIC_DRAW);
        gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, 0);
    }
   
    @Override
    public void init(GLAutoDrawable gLDrawable)
    {
        GL2 gl = gLDrawable.getGL().getGL2();
       
        initializeProgram(gl);
        initializeVertexBuffer(gl);

        // generate vertex array and bind
        int[] array = new int[1];
        gl.glGenVertexArrays(1,array,0);
        mvao = array[0];
        gl.glBindVertexArray(mvao);
    }
   
    @Override
    public void display(GLAutoDrawable gLDrawable)
    {
        final GL2 gl = gLDrawable.getGL().getGL2();
        //final GL4 gl = gLDrawable.getGL().getGL4();
        gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        gl.glClear(GL.GL_COLOR_BUFFER_BIT);

        gl.glUseProgram(mTheProgram);

        gl.glBindBuffer(GL2.GL_ARRAY_BUFFER,mVertexBufferObject);
        gl.glEnableVertexAttribArray(0);
        gl.glVertexAttribPointer(0, 4, GL.GL_FLOAT,false, 0, 0);
        gl.glDrawArrays(GL.GL_TRIANGLES, 0, 3);
       
        gl.glDisableVertexAttribArray(0);
        gl.glUseProgram(0);

        gLDrawable.swapBuffers();
    }
   
    @Override
    public void reshape(GLAutoDrawable gLDrawable, int x, int y, int width, int height)
    {      
        GL2 gl = gLDrawable.getGL().getGL2();
        if (height <= 0)
        {
            height = 1;
        }
        gl.glViewport(0,0,width,height);
    }
   
    @Override
    public void dispose(GLAutoDrawable arg0)
    {
        // do nothing
    }
} // class tut2FragPositionCanvas

===========
Reply | Threaded
Open this post in threaded view
|

Re: Exception: array vertex_buffer_object must be enabled to call this method

Pixelapp
Since you changed computers. Make sure you are compiling against the latest java sdk i.e. Java 1.7update1.

Reply | Threaded
Open this post in threaded view
|

Re: Exception: array vertex_buffer_object must be enabled to call this method

Sven Gothel
Administrator
In reply to this post by gmseed
On Thursday, November 17, 2011 11:36:10 PM gmseed [via jogamp] wrote:

>
> Hi
>
> I ported the Tutorial 2 FragPosition.cpp tutorial at
> http://arcsynthesis.org/gltut/ to JOGL; see code below.
>
> It works fine on my 64bit WinXP PC with an Nvidia Quadro but when I run it
> on my laptop with 64bit Win7 with an ATI Radeon I get the following
> exception trace.
>
> Does anyone know why this is happening?
>
> It appears to be failing in:
>
> Exception in thread "AWT-EventQueue-0" javax.media.opengl.GLException: array
> vertex_buffer_object must be enabled to call this method
> at jogamp.opengl.gl4.GL4bcImpl.checkBufferObject(GL4bcImpl.java:32020)
> at jogamp.opengl.gl4.GL4bcImpl.checkArrayVBOEnabled(GL4bcImpl.java:32047)
> at jogamp.opengl.gl4.GL4bcImpl.glVertexAttribPointer(GL4bcImpl.java:30691)
>
> and doesn't like the call to glVertexAttribPointer().


You call the VBO version w/ offset of
  'gl.glVertexAttribPointer(0, 4, GL.GL_FLOAT,false, 0, 0);'
hence the VBO must be enabled - hence the error message.

Ofc you know this.
Maybe run your code w/ debug and trace enabled to see whether
your VBO name 'mVertexBufferObject' is properly initialized
and you do have VBO support in the 1st place.
If the VBO name is '0' and/or glGetError() returns an error,
you may not have VBO support - which is odd.

Please post the appropriate debug information
  http://forum.jogamp.org/Problem-with-GLProfile-and-jogl2-rc2-td3447491.html#a3447546

Maybe run 'TestGearsES2NEWT' w/ debug flags, it usees a similar code path w/o AWT though,
but this should not matter.

+++

Some general review remarks unrelated to the above issue:

- You derive from GLCanvas, which is not recommended nor required.

- You use the VA before proper initialization:

>         gl.glUseProgram(mTheProgram);
>
>         gl.glBindBuffer(GL2.GL_ARRAY_BUFFER,mVertexBufferObject);
>         gl.glEnableVertexAttribArray(0);
>         gl.glVertexAttribPointer(0, 4, GL.GL_FLOAT,false, 0, 0);
>         gl.glDrawArrays(GL.GL_TRIANGLES, 0, 3);
>        
>         gl.glDisableVertexAttribArray(0);
>         gl.glUseProgram(0);

Proper order is:

- in
  - setup VA data
  - enable-VA
  - use-it
  - disable-VA
- out

  // in
  gl.glUseProgram(mTheProgram);

  // sync data
  if(!dataWritten) {
    gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, mVertexBufferObject);
    gl.glBufferData(..)
  } else if(vboHasChanged) {
    gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, mVertexBufferObject);
    gl.glVertexAttribPointer(0, 4, GL.GL_FLOAT,false, 0, 0);
  }
  vboHasChanged=false;
  dataWritten=true;

  // enable
  gl.glEnableVertexAttribArray(0);

  // use it
  gl.glDrawArrays(GL.GL_TRIANGLES, 0, 3);        

  // disable
  gl.glDisableVertexAttribArray(0);

  // out
  gl.glUseProgram(0);

You may assume vboHasChanged==true all the time, since it's a minor
opimization step used eg. in JOGL's GLSLArrayHandler::syncData().

>
> Thanks Graham
Reply | Threaded
Open this post in threaded view
|

Re: Exception: array vertex_buffer_object must be enabled to call this method

gmseed
Hi

Thanks for your comments.

Maybe I've missed something but I can't find a list of the appropriate debug information to post at:

http://forum.jogamp.org/Problem-with-GLProfile-and-jogl2-rc2-td3447491.html#a3447546

You say that the vertex buffer is not properly initialised. If I add the order comments to my display() we'll see that it already adheres to the order you suggest. The data initialisation is performed in init() via initializeVertexBuffer() and since no change occurs to the data then I think the display() call sequence appears fine; below with your order comments added:

    public void display(GLAutoDrawable gLDrawable)
    {
        final GL2 gl = gLDrawable.getGL().getGL2();
        gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        gl.glClear(GL.GL_COLOR_BUFFER_BIT);

        // in
        gl.glUseProgram(mTheProgram);
        // enable
        gl.glBindBuffer(GL2.GL_ARRAY_BUFFER,mVertexBufferObject);
        gl.glEnableVertexAttribArray(0);
        gl.glVertexAttribPointer(0, 4, GL.GL_FLOAT,false, 0, 0);
        // use
        gl.glDrawArrays(GL.GL_TRIANGLES, 0, 3);
        // disable
        gl.glDisableVertexAttribArray(0);
        // out
        gl.glUseProgram(0);
       
        gLDrawable.swapBuffers();
    }

Since I'm using Buffers.newDirectFloatBuffer() then there is no garbage collection calls between initialisation and the glDrawArrays() call. Thus, I don't fully see why the initialisation is incorrect.

Also, I don't understand your if-elseif block:

if(!dataWritten) {
    gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, mVertexBufferObject);
    gl.glBufferData(..)
  } else if(vboHasChanged) {
    gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, mVertexBufferObject);
    gl.glVertexAttribPointer(0, 4, GL.GL_FLOAT,false, 0, 0);
  }

It doesn't appear to have correct closure. If dataWritten is true then the "else if(vboHasChanged)" is not called.

I still don't understand the difference between working fine on WinXP/Nvidia and not working on Win7/ATI.

Thanks

Graham