@Override public void draw() { checkCreated(); // Bind the vao and enable all attributes GL30.glBindVertexArray(id); for (int i = 0; i < attributeBufferIDs.length; i++) { GL20.glEnableVertexAttribArray(i); } // Bind the indices buffer GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, indicesBufferID); // Draw all indices with the provided mode GL11.glDrawElements( drawingMode.getGLConstant(), indicesCount, GL11.GL_UNSIGNED_INT, indicesOffset * DataType.INT.getByteSize()); // Unbind the indices buffer GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0); // Disable all attributes and unbind the vao for (int i = 0; i < attributeBufferIDs.length; i++) { GL20.glDisableVertexAttribArray(i); } GL30.glBindVertexArray(0); // Check for errors LWJGLUtil.checkForGLError(); }
@Override public void create() { if (isCreated()) { throw new IllegalStateException("Vertex array has already been created"); } if (vertexData == null) { throw new IllegalStateException("Vertex data has not been set"); } // Generate and bind the vao id = GL30.glGenVertexArrays(); GL30.glBindVertexArray(id); // Generate, bind and fill the indices vbo then unbind indicesBufferID = GL15.glGenBuffers(); GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, indicesBufferID); GL15.glBufferData( GL15.GL_ELEMENT_ARRAY_BUFFER, vertexData.getIndicesBuffer(), GL15.GL_STATIC_DRAW); GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0); // Save the count of indices to draw indicesCountCache = vertexData.getIndicesCount(); resetIndicesCountAndOffset(); // Create the map for attribute index to buffer ID attributeBufferIDs = new int[vertexData.getAttributeCount()]; // For each attribute, generate, bind and fill the vbo, then setup the attribute in the vao and // save the buffer ID for the index for (int i = 0; i < vertexData.getAttributeCount(); i++) { final VertexAttribute attribute = vertexData.getAttribute(i); final int bufferID = GL15.glGenBuffers(); GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, bufferID); GL15.glBufferData(GL15.GL_ARRAY_BUFFER, attribute.getData(), GL15.GL_STATIC_DRAW); attributeBufferIDs[i] = bufferID; // Three ways to interpret integer data if (attribute.getType().isInteger() && attribute.getUploadMode() == UploadMode.KEEP_INT) { // Directly as an int GL30.glVertexAttribIPointer( i, attribute.getSize(), attribute.getType().getGLConstant(), 0, 0); } else { // Or as a float, normalized or not GL20.glVertexAttribPointer( i, attribute.getSize(), attribute.getType().getGLConstant(), attribute.getUploadMode().normalize(), 0, 0); } } // Unbind the vbo and vao GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0); GL30.glBindVertexArray(0); // Update state super.create(); // Check for errors LWJGLUtil.checkForGLError(); }
@Override public void destroy() { checkCreated(); // Unbind any bound buffer GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0); // Unbind and delete the indices buffer GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0); GL15.glDeleteBuffers(indicesBufferID); // Bind the vao for deletion GL30.glBindVertexArray(id); // Disable each attribute and delete its buffer for (int i = 0; i < attributeBufferIDs.length; i++) { GL20.glDisableVertexAttribArray(i); GL15.glDeleteBuffers(attributeBufferIDs[i]); } // Unbind the vao and delete it GL30.glBindVertexArray(0); GL30.glDeleteVertexArrays(id); super.destroy(); // Check for errors LWJGLUtil.checkForGLError(); }