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.javaas 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);
}