private int initVAO(GL3 gl) { int[] buff = new int[1]; gl.glGenVertexArrays(1, buff, 0); int vao = buff[0]; Assert.assertTrue("Invalid VAO: " + vao, vao > 0); gl.glUseProgram(progID); final int posLoc = gl.glGetAttribLocation(progID, "vPosition"); final int colorLoc = gl.glGetAttribLocation(progID, "vColor"); gl.glUseProgram(0); gl.glBindVertexArray(vao); gl.glBindBuffer(GL3.GL_ARRAY_BUFFER, vbo); gl.glBindBuffer(GL3.GL_ELEMENT_ARRAY_BUFFER, ibo); gl.glEnableVertexAttribArray(posLoc); gl.glEnableVertexAttribArray(colorLoc); final int stride = 6 * Buffers.SIZEOF_FLOAT; final int cOff = 3 * Buffers.SIZEOF_FLOAT; gl.glVertexAttribPointer(posLoc, 3, GL3.GL_FLOAT, false, stride, 0L); gl.glVertexAttribPointer(colorLoc, 3, GL3.GL_FLOAT, false, stride, cOff); gl.glBindVertexArray(0); // See class documentation above! gl.glBindBuffer(GL3.GL_ARRAY_BUFFER, 0); gl.glBindBuffer(GL3.GL_ELEMENT_ARRAY_BUFFER, 0); return vao; }
private void displayVBOVAO(final GL3 gl) { try { gl.glBindVertexArray(vao); gl.glDrawElements(GL3.GL_TRIANGLES, 3, GL3.GL_UNSIGNED_SHORT, 0L); gl.glBindVertexArray(0); } catch (GLException ex) { Logger.getLogger(TestBug692GL3VAONEWT.class.getName()).log(Level.SEVERE, null, ex); } }
/** * Constructor that creates a Vertex Buffer Object with the specified GLSL attributes. (typically * location, texture coordinates, normals, etc.) * * @param gl The global openGL instance. * @param attribs One or more attributes that represent this VBO, @see GLSLAttrib */ public VBO(GL3 gl, GLSLAttrib... attribs) { this.attribs = attribs; // Generate a new internal OpenGL VBO pointer this.vboPointer = Buffers.newDirectIntBuffer(1); gl.glGenVertexArrays(1, this.vboPointer); gl.glBindVertexArray(this.vboPointer.get(0)); // Generate a new internal OpenGL Array Buffer pointer this.bufferPointer = Buffers.newDirectIntBuffer(1); gl.glGenBuffers(1, this.bufferPointer); gl.glBindBuffer(GL3.GL_ARRAY_BUFFER, this.bufferPointer.get(0)); // Allocate enough memory int size = 0; for (final GLSLAttrib attrib : attribs) { size += attrib.buffer.capacity() * Buffers.SIZEOF_FLOAT; } gl.glBufferData(GL3.GL_ARRAY_BUFFER, size, (Buffer) null, GL3.GL_STATIC_DRAW); // Copy the GLSL Attribute data into the internal OpenGL buffer int nextStart = 0; for (final GLSLAttrib attrib : attribs) { gl.glBufferSubData( GL3.GL_ARRAY_BUFFER, nextStart, attrib.buffer.capacity() * Buffers.SIZEOF_FLOAT, attrib.buffer); nextStart += attrib.buffer.capacity() * Buffers.SIZEOF_FLOAT; } }
@Override public void init(GLAutoDrawable glad) { System.out.println("init"); canvas.setAutoSwapBufferMode(false); GL3 gl3 = glad.getGL().getGL3(); buildShaders(gl3); programObject.bind(gl3); { programObject.setUniform(gl3, "frustumScale", new float[] {1.0f}, 1); programObject.setUniform(gl3, "zNear", new float[] {1.0f}, 1); programObject.setUniform(gl3, "zFar", new float[] {3.0f}, 1); } programObject.unbind(gl3); initializeVertexBuffer(gl3); gl3.glGenVertexArrays(1, IntBuffer.wrap(vertexArrayObject)); gl3.glBindVertexArray(vertexArrayObject[0]); gl3.glEnable(GL3.GL_CULL_FACE); gl3.glCullFace(GL3.GL_BACK); gl3.glFrontFace(GL3.GL_CW); }
/** * A utility method to load vertex data into an OpenGL "vertex array object" (VAO) for efficient * rendering. The VAO stores several "vertex buffer objects" (VBOs) that contain the vertex * attribute data. * * @param data reference to the vertex data to be loaded into a VAO */ private void initArrayBuffer(GLVertexData data) { // Make a vertex array object (VAO) for this vertex data // and store a reference to it GLVertexArrayObject vao = new GLVertexArrayObject(gl, data.getElements().size() + 1); data.setVAO(vao); // Bind (activate) the VAO for the vertex data in OpenGL. // The subsequent OpenGL operations on VBOs will be recorded (stored) // in the VAO. vao.bind(); // Store all vertex attributes in vertex buffer objects (VBOs) ListIterator<VertexData.VertexElement> itr = data.getElements().listIterator(0); data.getVAO().rewindVBO(); while (itr.hasNext()) { VertexData.VertexElement e = itr.next(); // Bind the vertex buffer object (VBO) gl.glBindBuffer(GL3.GL_ARRAY_BUFFER, data.getVAO().getNextVBO()); // Upload vertex data gl.glBufferData( GL3.GL_ARRAY_BUFFER, e.getData().length * 4, FloatBuffer.wrap(e.getData()), GL3.GL_DYNAMIC_DRAW); } // Bind the default vertex buffer objects gl.glBindBuffer(GL3.GL_ARRAY_BUFFER, 0); // Store the vertex data indices into the last vertex buffer gl.glBindBuffer(GL3.GL_ELEMENT_ARRAY_BUFFER, data.getVAO().getNextVBO()); gl.glBufferData( GL3.GL_ELEMENT_ARRAY_BUFFER, data.getIndices().length * 4, IntBuffer.wrap(data.getIndices()), GL3.GL_DYNAMIC_DRAW); // Bind the default vertex array object. This "deactivates" the VAO // of the vertex data gl.glBindVertexArray(0); }
/** * Delete this VBO properly. * * @param gl The global openGL instance. */ public void delete(GL3 gl) { gl.glBindVertexArray(0); gl.glDeleteVertexArrays(1, this.vboPointer); gl.glDeleteBuffers(1, this.bufferPointer); }
/** * Bind the VBO, so that it is ready for use. * * @param gl The global openGL instance. */ public void bind(GL3 gl) { gl.glBindVertexArray(this.vboPointer.get(0)); gl.glBindBuffer(GL3.GL_ARRAY_BUFFER, bufferPointer.get(0)); }
/** * The main rendering method. * * @param renderItem the object that needs to be drawn */ private void draw(RenderItem renderItem) { // Set the material of the shape to be rendered setMaterial(renderItem.getShape().getMaterial()); // Get reference to the vertex data of the render item to be rendered GLVertexData vertexData = (GLVertexData) renderItem.getShape().getVertexData(); // Check if the vertex data has been uploaded to OpenGL via a // "vertex array object" (VAO). The VAO will store the vertex data // in several "vertex buffer objects" (VBOs) on the GPU. We do this // only once for performance reasons. Once the data is in the VBOs // asscociated with a VAO, it is stored on the GPU and rendered more // efficiently. if (vertexData.getVAO() == null) { initArrayBuffer(vertexData); } // Set modelview and projection matrices in shader (has to be done in // every step, since they usually have changed) setTransformation(renderItem.getT()); // Bind the VAO of this shape. This activates the VBOs that we // associated with the VAO. We already loaded the vertex data into the // VBOs on the GPU, so we do not have to send them again. vertexData.getVAO().bind(); // Try to connect the vertex buffers to the corresponding variables // in the current vertex shader. // Note: This is not part of the vertex array object, because the active // shader may have changed since the vertex array object was initialized. // We need to make sure the vertex buffers are connected to the right // variables in the shader ListIterator<VertexData.VertexElement> itr = vertexData.getElements().listIterator(0); vertexData.getVAO().rewindVBO(); while (itr.hasNext()) { VertexData.VertexElement e = itr.next(); int dim = e.getNumberOfComponents(); // Bind the next vertex buffer object gl.glBindBuffer(GL3.GL_ARRAY_BUFFER, vertexData.getVAO().getNextVBO()); // Tell OpenGL which "in" variable in the vertex shader corresponds // to the current vertex buffer object. // We use our own convention to name the variables, i.e., // "position", "normal", "color", "texcoord", or others if // necessary. int attribIndex = -1; switch (e.getSemantic()) { case POSITION: attribIndex = gl.glGetAttribLocation(activeShaderID, "position"); break; case NORMAL: attribIndex = gl.glGetAttribLocation(activeShaderID, "normal"); break; case COLOR: attribIndex = gl.glGetAttribLocation(activeShaderID, "color"); break; case TEXCOORD: attribIndex = gl.glGetAttribLocation(activeShaderID, "texcoord"); break; } gl.glVertexAttribPointer(attribIndex, dim, GL3.GL_FLOAT, false, 0, 0); gl.glEnableVertexAttribArray(attribIndex); } // Render the vertex buffer objects gl.glDrawElements( GL3.GL_TRIANGLES, renderItem.getShape().getVertexData().getIndices().length, GL3.GL_UNSIGNED_INT, 0); // We are done with this shape, bind the default vertex array gl.glBindVertexArray(0); cleanMaterial(renderItem.getShape().getMaterial()); }