Login  Register

array vertex_buffer_object must be bound to call this method

Posted by Wilds on Jan 30, 2018; 11:14am
URL: https://forum.jogamp.org/array-vertex-buffer-object-must-be-bound-to-call-this-method-tp4038581.html

*EDIT
Oke it seems my context isnt sharing resources, as my renderer init was called from the dummyDrawable I create at the beginning.

My begin and end are called from the GLJPanel context.
What is the best way to share resources(share contexts)?

public final class JoglContextManager implements IViewportFactory {

    private static final Logger LOGGER = LogManager.getLogger(JoglContextManager.class);

    private GLAutoDrawable sharedAutoDrawable;
    private JoglRenderer renderer;
    private boolean isInitialized;

    public JoglContextManager() {
        renderer = new GLES2Renderer();
    }

    @Override
    public void initialize() throws ViewportException {
        if (!GLProfile.isAvailable(GLProfile.GL2ES2)) {
            throw new ViewportException("GL2ES2 profile could not be found!");
        }

        // create viewport
        GLProfile glProfile = GLProfile.get(GLProfile.GL2ES2);
        GLCapabilities glCapabilities = new GLCapabilities(glProfile);
        glCapabilities.setDepthBits(24);
//        glCapabilities.setStencilBits(8);
//        glCapabilities.setSampleBuffers(true);
//        glCapabilities.setNumSamples(8);

        sharedAutoDrawable = GLDrawableFactory
                .getFactory(glProfile)
                .createDummyAutoDrawable(null, true, glCapabilities, null);

        sharedAutoDrawable.addGLEventListener(new JoglLifecycleHandler());
        sharedAutoDrawable.display();

        isInitialized = true;
    }

    @Override
    public JoglViewport createViewport(BaseCamera camera) throws ViewportException {
        if (!isInitialized) {
            throw new ViewportException("JoglContextManager is not initialized!");
        }

        JoglViewport viewport = new JoglViewport(sharedAutoDrawable.getChosenGLCapabilities(), renderer, camera);
        viewport.setSharedContext(sharedAutoDrawable.getContext());

        return viewport;
    }

    private class JoglLifecycleHandler implements GLEventListener {
        @Override
        public void init(GLAutoDrawable drawable) {
            GL2ES2 gl = drawable.getGL().getGL2ES2();

            System.err.println("Chosen GLCapabilities: " + drawable.getChosenGLCapabilities());
            System.err.println("INIT GL IS: " + gl.getClass().getName());

            String openGLFormat = "OpenGL Canvas initialized\n%s\nGPU: %s\nGL: %s\nGLSL: %s";
            LOGGER.info(String.format(openGLFormat,
                    gl.glGetString(gl.GL_VENDOR),
                    gl.glGetString(gl.GL_RENDERER),
                    gl.glGetString(gl.GL_VERSION),
                    gl.glGetString(gl.GL_SHADING_LANGUAGE_VERSION)));

            GLCapabilitiesImmutable cap = drawable.getChosenGLCapabilities();
            String openGLCapabilities = "OpenGL capabilities\nHardware Accelerated: %s\nDepthBits: %s\nStencilBits: %s\nRGBA %s/%s/%s/%s\nSamples: %s";
            LOGGER.debug(String.format(openGLCapabilities,
                    cap.getHardwareAccelerated(),
                    cap.getDepthBits(),
                    cap.getStencilBits(),
                    cap.getRedBits(),
                    cap.getGreenBits(),
                    cap.getBlueBits(),
                    cap.getAlphaBits(),
                    cap.getNumSamples()));

            renderer.setAutoDrawable(drawable);
            renderer.init();
        }

        @Override
        public void dispose(GLAutoDrawable drawable) {
            renderer.deinit();
        }

        @Override
        public void display(GLAutoDrawable drawable) {

        }

        @Override
        public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {

        }
    }
}

*ORIGINAL
Hello I am converting my GL2 renderer to GL2ES2 and soley using the programmable pipeline.
When I run my code I get the following exception "array vertex_buffer_object must be bound to call this method".
If I am correct GLES2 doesnt need you to set VAO's (doesnt support them)?

I also used: http://jogamp.org/jogl-demos/src/demos/es2/RawGL2ES2demo.java
as a reference.

My render code:
package com.wildrune.rune.renderer.jogl;

import com.wildrune.rune.renderer.*;
import com.wildrune.rune.renderer.data.*;
import com.wildrune.rune.renderer.gl.*;

import java.nio.*;
import java.util.*;

import com.jogamp.common.nio.*;
import com.jogamp.opengl.*;
import org.joml.*;

/**
 * @author Mark "Wilds" van der Wal
 * @since 23-1-2018
 */
public class GLES2Renderer implements JoglRenderer {

    private GL2ES2 gl;
    private ShaderProgram defaultShader;

    private String defaultVertShader = "attribute vec3 " + VertexAttribute.Position.getIdentifier() + ";" +
            "void main()" +
            "{" +
            "gl_Position = vec4(" + VertexAttribute.Position.getIdentifier() + ", 1);" +
            "}";

    private String defaultFragShader = "precision mediump float;" +
            "void main()" +
            "{" +
            "gl_FragColor = vec4(1,1,1,1);" +
            "}";

    private FloatBuffer meshBuffer = ByteBuffer.allocateDirect(4096)
            .order(ByteOrder.nativeOrder())
            .asFloatBuffer();

    private int bufferHandle;

    @Override
    public void init() {
        // enable opengl features
        gl.glEnable(gl.GL_DEPTH_TEST);
        gl.glDepthFunc(gl.GL_LESS);

//        gl.glEnable(gl.GL_CULL_FACE);
//        gl.glCullFace(gl.GL_BACK);
//        gl.glFrontFace(gl.GL_CW);

//        gl.glEnable(gl.GL_MULTISAMPLE);

        // set default state
        defaultShader = ShaderProgram.createShaderProgram(gl, defaultVertShader, defaultFragShader);

        int[] intPtr = new int[1];
        gl.glGenBuffers(1, intPtr, 0);
        bufferHandle = intPtr[0];

        gl.glBindBuffer(gl.GL_ARRAY_BUFFER, bufferHandle);
        gl.glBufferData(gl.GL_ARRAY_BUFFER, 4096, null, gl.GL_DYNAMIC_DRAW);
        gl.glBindBuffer(gl.GL_ARRAY_BUFFER, 0);
    }

    @Override
    public void deinit() {
        int[] intPtr = new int[1];
        intPtr[0] = bufferHandle;

        gl.glDeleteBuffers(1, intPtr, 0);
        defaultShader.dispose();
    }

    @Override
    public void setAutoDrawable(GLAutoDrawable autoDrawable) {
        gl = autoDrawable.getGL().getGL2ES2();
    }

    @Override
    public void setViewport(int x, int y, int width, int height) {
        gl.glViewport(x, y, width, height);
    }

    @Override
    public void setClearColor(Color color) {
        gl.glClearColor(color.r, color.g, color.b, color.a);
    }

    @Override
    public void clearBackbuffers() {
        gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT);
    }

    @Override
    public void begin(Matrix4f modelView, Matrix4f projection) {
        meshBuffer.clear();

        // test triangle in ndc space
        meshBuffer.put(-0.8f);
        meshBuffer.put(-0.8f);
        meshBuffer.put(0);

        meshBuffer.put(0f);
        meshBuffer.put(0.8f);
        meshBuffer.put(0);

        meshBuffer.put(0.8f);
        meshBuffer.put(-0.8f);
        meshBuffer.put(0);
    }

    @Override
    public void end() {
        gl.glBindBuffer(gl.GL_ARRAY_BUFFER, bufferHandle);
        defaultShader.bind();
//        defaultShader.setUniformf(ShaderUniform.ProjecionMatrix, projection);

        meshBuffer.flip();
        if (meshBuffer.hasRemaining()) {
//            gl.glBufferData(gl.GL_ARRAY_BUFFER, meshBuffer.limit() * BYTES_PER_DATA, meshBuffer, gl.GL_DYNAMIC_DRAW);
            gl.glBufferSubData(gl.GL_ARRAY_BUFFER, 0,meshBuffer.limit() * Buffers.SIZEOF_FLOAT, meshBuffer);

            defaultShader.setVertexAttribute(VertexAttribute.Position, 3, gl.GL_FLOAT,
                    false, 0, 0);
            defaultShader.enableVertexAttribute(VertexAttribute.Position);

            gl.glDrawArrays(gl.GL_TRIANGLES, 0, meshBuffer.limit() / 3);
        }

        gl.glBindBuffer(gl.GL_ARRAY_BUFFER, 0);
        defaultShader.disableVertexAttribute(VertexAttribute.Position);
        defaultShader.unbind();
    }

    @Override
    public void drawFilledPolygon(List<Vector3f> points, Color color) {
//        points.forEach(point -> {
//            meshBuffer.put(point.x);
//            meshBuffer.put(point.y);
//            meshBuffer.put(point.z);
//        });
    }

    @Override
    public void drawWiredPolygon(List<Vector3f> points, Color color, RenderLineData.LINE_TYPE lineType) {

    }

    @Override
    public void drawLine(Vector3f from, Vector3f to, Color color, RenderLineData.LINE_TYPE lineType) {

    }
}

My shaderprogram code:
    /**
     * The VBO must be bound before calling this method
     */
    public void setVertexAttribute(VertexAttribute attribute, int componentSize, int bytesPerComponent,
                                   boolean normalized, int stride, int offset) {
        int location = getAttributeLocation(attribute);
        if (location == -1) {
            LOGGER.debug("Attribute location not found!");
            return;
        }

        gl.glVertexAttribPointer(location, componentSize, bytesPerComponent, normalized,
                stride, offset);
    }

    public void enableVertexAttribute(VertexAttribute attribute) {
        int location = getAttributeLocation(attribute);
        gl.glEnableVertexAttribArray(location);
    }

    public void disableVertexAttribute(VertexAttribute attribute) {
        int location = getAttributeLocation(attribute);
        gl.glDisableVertexAttribArray(location);
    }