Cannot use Buffers when Array Buffer Object is enabled

Started by Peter M Ashford, February 06, 2012, 07:57:27

Previous topic - Next topic

Peter M Ashford

Hi There

I'm trying to get VBOs working with shader vertex attribute arrays.  I keep getting this exception:

Exception in thread "main" org.lwjgl.opengl.OpenGLException: Cannot use Buffers when Array Buffer Object is enabled
   at org.lwjgl.opengl.GLChecks.ensureArrayVBOdisabled(GLChecks.java:87)
   at org.lwjgl.opengl.GL20.glVertexAttribPointer(GL20.java:890)
   at jthrust_phys2d.test.TestVBO_Shader.<init>(TestVBO_Shader.java:118)
   at jthrust_phys2d.test.TestVBO_Shader.main(TestVBO_Shader.java:39)

When I try to do a simple VBO by itself, it works fine but trying to introduce the shader vertex attribute arrays is proving to be a problem.  I've attached the full code of a test case below.  If someone could let me know what I'm doing wrong, I'd like to know :o)

Cheers!

package jthrust_phys2d.test;

import java.io.BufferedReader;
import java.io.FileReader;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL12.*;
import static org.lwjgl.opengl.GL13.*;
import static org.lwjgl.opengl.GL15.*;
import static org.lwjgl.opengl.GL20.*;
import static org.lwjgl.opengl.GL30.*;
import static org.lwjgl.opengl.GL31.*;
import static org.lwjgl.util.glu.GLU.*;

/**
 *
 * @author peter
 */
public class TestVBO_Shader {
    private final int screenWidth;
    private final int screenHeight;
    private final float FOV = 60f;
    private final int vertexBufferID;
    private final int colourBufferID;
    private final int indexBufferID;
    private final int basicShader;
    
    /**
     * 
     * @param args 
     */
    public static void main(String[] args){
        try {
            new TestVBO_Shader().start();
        } catch (LWJGLException ex) {
            ex.printStackTrace();
        }
    }
    
  
   
    /**
     * 
     * @throws LWJGLException 
     */
    public TestVBO_Shader() throws LWJGLException{
    
        final float sScale = 0.5f;
        screenWidth  = (int)(sScale * 1000);
        screenHeight = (int)(sScale *  800);

        Display.setDisplayMode(new DisplayMode(screenWidth,screenHeight));        
        Display.create();        
        
        glEnable(GL_DEPTH_TEST);        
        glDisable(GL_LIGHTING);
        glDisable(GL_LIGHT0);      
        glDisable(GL_TEXTURE_2D);     
        glDisable(GL_CULL_FACE);
        
        //--- shader ---
        basicShader = ARBShaderObjects.glCreateProgramObjectARB();
                    
        int basicVert = createVertShader("shaders/basic.vert");
        int basicFrag = createFragShader("shaders/basic.frag");

        ARBShaderObjects.glAttachObjectARB(basicShader, basicVert);
        ARBShaderObjects.glAttachObjectARB(basicShader, basicFrag);

        glBindAttribLocation(basicShader, 0, "VertexPosition");
        glBindAttribLocation(basicShader, 1, "VertexColor");

        ARBShaderObjects.glLinkProgramARB(basicShader);
        ARBShaderObjects.glValidateProgramARB(basicShader);
        printLogInfo(basicShader);        
        
        //--- vbo ---
        vertexBufferID = createVBOID();
        colourBufferID = createVBOID();
        indexBufferID  = createVBOID();
        
        FloatBuffer vertBuf = BufferUtils.createFloatBuffer(10);
        vertBuf.put(new float[]{ 
            -5f, -5f, 0f,
             5f, -5f, 0f,
             0f,  5f, 0f });

        FloatBuffer colBuf = BufferUtils.createFloatBuffer(12);
        colBuf.put(new float[]{ 
            1f, 0f, 0f, 1f,
            0f, 1f, 0f, 1f,
            0f, 0f, 1f, 1f});
        
        IntBuffer intBuf = BufferUtils.createIntBuffer(3);
        intBuf.put(new int[]{0,1,2});
        
        vertBuf.rewind();
        colBuf.rewind();
        intBuf.rewind();
        
        bufferData(vertexBufferID, vertBuf);
        bufferData(colourBufferID, colBuf);
        bufferElementData(indexBufferID, intBuf);
 
        vertBuf.rewind();
        colBuf.rewind();
        intBuf.rewind();
        
        glEnableVertexAttribArray(0);  // Vertex position
        glEnableVertexAttribArray(1);  // Vertex color

        glBindBuffer(GL_ARRAY_BUFFER, vertexBufferID);
        glVertexAttribPointer(0, 3, false, 0, vertBuf);  //<<< this line is where the exception is raised               

        glBindBuffer(GL_ARRAY_BUFFER, colourBufferID);
        glVertexAttribPointer(1, 3, false, 0, colBuf);

    }
    
    public static int createVBOID() {        
        IntBuffer buffer = BufferUtils.createIntBuffer(1);
        ARBVertexBufferObject.glGenBuffersARB(buffer);
        return buffer.get(0);        
    }
    
    public static void bufferData(int id, FloatBuffer buffer) {
        ARBVertexBufferObject.glBindBufferARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, id);
        ARBVertexBufferObject.glBufferDataARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, buffer, 
                ARBVertexBufferObject.GL_STATIC_DRAW_ARB); 
    }
    
    public static void bufferElementData(int id, IntBuffer buffer) {
        ARBVertexBufferObject.glBindBufferARB(ARBVertexBufferObject.GL_ELEMENT_ARRAY_BUFFER_ARB, id);
        ARBVertexBufferObject.glBufferDataARB(ARBVertexBufferObject.GL_ELEMENT_ARRAY_BUFFER_ARB, buffer, 
                ARBVertexBufferObject.GL_STATIC_DRAW_ARB);
 
    }
    
    /**
     * 
     */
    public void start(){
        while(true){
            
            render();
            
            Display.update();
            
            try {
                Thread.sleep(100);
            } catch (InterruptedException ex) {
                //ignore
            }
            
            if(Display.isCloseRequested()){
                break;
            }
        }
    }
    
    
     /*
     * With the exception of syntax, setting up vertex and fragment shaders is the same. @param the name and
     * path to the vertex shader
     */
    private int createVertShader(String filename) {
        //vertShader will be non zero if succefully created

        int vShdr = ARBShaderObjects.glCreateShaderObjectARB(ARBVertexShader.GL_VERTEX_SHADER_ARB);
        //if created, convert the vertex shader code to a String
        if (vShdr == 0) {
            return 0;
        }
        String vertexCode = "";
        String line;
        try {
            BufferedReader reader = new BufferedReader(new FileReader(filename));
            while ((line = reader.readLine()) != null) {
                vertexCode += line + "\n";
            }
        } catch (Exception e) {
            System.out.println("Fail reading vertex shading code");
            return 0;
        }
        /*
         * associate the vertex code String with the created vertex shader and compile
         */
        ARBShaderObjects.glShaderSourceARB(vShdr, vertexCode);
        ARBShaderObjects.glCompileShaderARB(vShdr);
        //if there was a problem compiling, reset vertShader to zero
        if (!printLogInfo(vShdr)) {
            vShdr = 0;
        }
        //if zero we won't be using the shader
        return vShdr;
    }

    
    /**
     * same as per the vertex shader except for method syntax
     */
    private int createFragShader(String filename) {

        int fShdr = ARBShaderObjects.glCreateShaderObjectARB(ARBFragmentShader.GL_FRAGMENT_SHADER_ARB);
        if (fShdr == 0) {
            return 0;
        }
        String fragCode = "";
        String line;
        try {
            BufferedReader reader = new BufferedReader(new FileReader(filename));
            while ((line = reader.readLine()) != null) {
                fragCode += line + "\n";
            }
        } catch (Exception e) {
            System.out.println("Fail reading fragment shading code");
            return 0;
        }
        ARBShaderObjects.glShaderSourceARB(fShdr, fragCode);
        ARBShaderObjects.glCompileShaderARB(fShdr);
        if (!printLogInfo(fShdr)) {
            fShdr = 0;
        }

        return fShdr;
    }

    /**
     * 
     * @param obj
     * @return 
     */
    private static boolean printLogInfo(int obj) {
        IntBuffer iVal = BufferUtils.createIntBuffer(1);
        ARBShaderObjects.glGetObjectParameterARB(obj,
                ARBShaderObjects.GL_OBJECT_INFO_LOG_LENGTH_ARB, iVal);

        int length = iVal.get();
        if (length > 1) {
        // We have some info we need to output.
            ByteBuffer infoLog = BufferUtils.createByteBuffer(length);
            iVal.flip();
            ARBShaderObjects.glGetInfoLogARB(obj, iVal, infoLog);
            byte[] infoBytes = new byte[length];
            infoLog.get(infoBytes);
            String out = new String(infoBytes);
            System.out.println("Info log:\n" + out);
        } else {
            return true;
        }
        return false;
    }
    
    
    /**
     * 
     */
    void render(){
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        // --- set lighting and projection matrix -----------
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();

        //camera.applyPerspective(gl, glu);
        float aspect = (float) screenWidth / (float) screenHeight;
        
        gluPerspective(FOV, aspect, 1, 1000);

        // --- set model view matrix ----------------
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();

        final float scale = 1f;

        gluLookAt(0, 0, 10f,
                  0, 0,  0,
                  0, 1,  0);
            
        // store the view transform
        glPushMatrix();

        glEnableClientState(GL_VERTEX_ARRAY);
        ARBVertexBufferObject.glBindBufferARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, vertexBufferID);
        glVertexPointer(3, GL_FLOAT, 0, 0);

        glEnableClientState(GL_COLOR_ARRAY);
        ARBVertexBufferObject.glBindBufferARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, colourBufferID);
        glColorPointer(4, GL_FLOAT, 0, 0);

        ARBVertexBufferObject.glBindBufferARB(ARBVertexBufferObject.GL_ELEMENT_ARRAY_BUFFER_ARB, indexBufferID);
        glDrawRangeElements(GL_TRIANGLES, 0, 3, 3, GL_UNSIGNED_INT, 0);
       
        // --- debug axis at world origin ---
        final float axis = 500.0f;

        glBegin(GL_LINES);
            glColor3f(1,0,0);
            glVertex3f(0,0,0); glVertex3f(axis,0,0);
            
            glColor3f(0,1,0);
            glVertex3f(0,0,0); glVertex3f(0,axis,0);
            
            glColor3f(0,0,1);
            glVertex3f(0,0,0); glVertex3f(0,0,axis);
        glEnd();   
        
        glPopMatrix();                       
    }
}