/** * Copyright 2012 Jason Sorensen (sorensenj@smert.net) * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * specific language governing permissions and limitations under the License. */ package net.smert.frameworkgl.opengl.renderable.shared; import net.smert.frameworkgl.opengl.GL; import net.smert.frameworkgl.opengl.VertexBufferObject; import net.smert.frameworkgl.opengl.mesh.Mesh; import net.smert.frameworkgl.opengl.renderable.AbstractRenderable; import net.smert.frameworkgl.opengl.renderable.Renderable; import net.smert.frameworkgl.opengl.renderable.RenderableConfiguration; /** * * @author Jason Sorensen <sorensenj@smert.net> */ public abstract class AbstractVertexBufferObjectNonInterleavedRenderable extends AbstractRenderable { protected int bufferUsage; protected int renderableConfigID; protected RenderCall renderCall; protected VertexBufferObject vboColor; protected VertexBufferObject vboNormal; protected VertexBufferObject vboTexCoord; protected VertexBufferObject vboVertex; protected VertexBufferObject vboVertexIndex; public AbstractVertexBufferObjectNonInterleavedRenderable() { bufferUsage = -1; renderableConfigID = -1; renderCall = null; vboColor = null; vboNormal = null; vboTexCoord = null; vboVertex = null; vboVertexIndex = null; } protected void bindGL1() { // Switch the renderable configuration first Renderable.bindState.switchRenderableConfiguration(renderableConfigID); // Bind each VBO if (vboColor != null) { GL.vboHelper.enableColors(); Renderable.bindState.bindColorGL1(vboColor.getVboID(), 0, 0); } else { GL.vboHelper.disableColors(); } if (vboNormal != null) { GL.vboHelper.enableNormals(); Renderable.bindState.bindNormalGL1(vboNormal.getVboID(), 0, 0); } else { GL.vboHelper.disableNormals(); } if (vboTexCoord != null) { GL.vboHelper.enableTexCoords(); Renderable.bindState.bindTexCoordGL1(vboTexCoord.getVboID(), 0, 0); } else { GL.vboHelper.disableTexCoords(); } if (vboVertex != null) { GL.vboHelper.enableVertices(); Renderable.bindState.bindVertexGL1(vboVertex.getVboID(), 0, 0); } else { GL.vboHelper.disableVertices(); } if (vboVertexIndex != null) { Renderable.bindState.bindVertexIndex(vboVertexIndex.getVboID()); } else { Renderable.bindState.bindVertexIndex(0); } } protected void bindGL2() { // Switch the renderable configuration first Renderable.bindState.switchRenderableConfiguration(renderableConfigID); // Bind each VBO if (vboColor != null) { GL.vboHelper.enableVertexAttribArray(Renderable.bindState.getColorIndex()); Renderable.bindState.bindColorGL2(vboColor.getVboID(), 0, 0); } else { GL.vboHelper.disableVertexAttribArray(Renderable.bindState.getColorIndex()); } if (vboNormal != null) { GL.vboHelper.enableVertexAttribArray(Renderable.bindState.getNormalIndex()); Renderable.bindState.bindNormalGL2(vboNormal.getVboID(), 0, 0); } else { GL.vboHelper.disableVertexAttribArray(Renderable.bindState.getNormalIndex()); } if (vboTexCoord != null) { GL.vboHelper.enableVertexAttribArray(Renderable.bindState.getTexCoord0Index()); Renderable.bindState.bindTexCoordGL2(vboTexCoord.getVboID(), 0, 0); } else { GL.vboHelper.disableVertexAttribArray(Renderable.bindState.getTexCoord0Index()); } if (vboVertex != null) { GL.vboHelper.enableVertexAttribArray(Renderable.bindState.getVertexIndex()); Renderable.bindState.bindVertexGL2(vboVertex.getVboID(), 0, 0); } else { GL.vboHelper.disableVertexAttribArray(Renderable.bindState.getVertexIndex()); } if (vboVertexIndex != null) { Renderable.bindState.bindVertexIndex(vboVertexIndex.getVboID()); } else { Renderable.bindState.bindVertexIndex(0); } } protected void createGL1AndGL2(Mesh mesh) { // Get configuration renderableConfigID = mesh.getRenderableConfigID(); RenderableConfiguration config = Renderable.configPool.get(renderableConfigID); // Destroy existing VBOs destroy(); // Create non interleaved buffer data if (mesh.hasColors() || mesh.hasNormals() || mesh.hasTexCoords() || mesh.hasVertices()) { Renderable.renderableBuilder.createNonInterleavedBufferData(mesh, Renderable.byteBuffers, config); } // Create VBO and send byte buffer data for colors if (mesh.hasColors()) { vboColor = GL.glFactory.createVertexBufferObject(); vboColor.create(); GL.vboHelper.setBufferData(vboColor.getVboID(), Renderable.byteBuffers.getColor(), bufferUsage); } // Create VBO and send byte buffer data for normals if (mesh.hasNormals()) { vboNormal = GL.glFactory.createVertexBufferObject(); vboNormal.create(); GL.vboHelper.setBufferData(vboNormal.getVboID(), Renderable.byteBuffers.getNormal(), bufferUsage); } // Create VBO and send byte buffer data for texture coordinates if (mesh.hasTexCoords()) { vboTexCoord = GL.glFactory.createVertexBufferObject(); vboTexCoord.create(); GL.vboHelper.setBufferData(vboTexCoord.getVboID(), Renderable.byteBuffers.getTexCoord(), bufferUsage); } // Create VBO and send byte buffer data for vertices if (mesh.hasVertices()) { vboVertex = GL.glFactory.createVertexBufferObject(); vboVertex.create(); GL.vboHelper.setBufferData(vboVertex.getVboID(), Renderable.byteBuffers.getVertex(), bufferUsage); } // Create VBO, byte buffer data and send byte buffer data for indexes if (mesh.hasIndexes()) { vboVertexIndex = GL.glFactory.createVertexBufferObject(); vboVertexIndex.create(); Renderable.renderableBuilder.createIndexBufferData(mesh, Renderable.byteBuffers, config); GL.vboHelper.setBufferElementData(vboVertexIndex.getVboID(), Renderable.byteBuffers.getVertexIndex(), bufferUsage); } GL.vboHelper.unbind(); // Create render call renderCall = Renderable.vboDrawCallBuilder.createRenderCall(mesh, config); } protected void renderGL1() { bindGL1(); renderCall.render(); } protected void renderGL2() { bindGL2(); renderCall.render(); } protected void updateGL1AndGL2(Mesh mesh) { // Get configuration RenderableConfiguration config = Renderable.configPool.get(renderableConfigID); // Create non interleaved buffer data if (mesh.hasColors() || mesh.hasNormals() || mesh.hasTexCoords() || mesh.hasVertices()) { Renderable.renderableBuilder.createNonInterleavedBufferData(mesh, Renderable.byteBuffers, config); } // Send byte buffer data for colors if (mesh.hasColors() && (vboColor != null)) { GL.vboHelper.updateBufferData(vboColor.getVboID(), 0, Renderable.byteBuffers.getColor()); } // Send byte buffer data for normals if (mesh.hasNormals() && (vboNormal != null)) { GL.vboHelper.updateBufferData(vboNormal.getVboID(), 0, Renderable.byteBuffers.getNormal()); } // Send byte buffer data for texture coordinates if (mesh.hasTexCoords() && (vboTexCoord != null)) { GL.vboHelper.updateBufferData(vboTexCoord.getVboID(), 0, Renderable.byteBuffers.getTexCoord()); } // Send byte buffer data for vertices if (mesh.hasVertices() && (vboVertex != null)) { GL.vboHelper.updateBufferData(vboVertex.getVboID(), 0, Renderable.byteBuffers.getVertex()); } // Create byte buffer data and send byte buffer data for indexes if (mesh.hasIndexes() && (vboVertexIndex != null)) { Renderable.renderableBuilder.createIndexBufferData(mesh, Renderable.byteBuffers, config); GL.vboHelper.updateBufferElementData(vboVertexIndex.getVboID(), 0, Renderable.byteBuffers.getVertexIndex()); } GL.vboHelper.unbind(); // Create render call renderCall = Renderable.vboDrawCallBuilder.createRenderCall(mesh, config); } @Override public void destroy() { if (vboColor != null) { vboColor.destroy(); vboColor = null; } if (vboNormal != null) { vboNormal.destroy(); vboNormal = null; } if (vboTexCoord != null) { vboTexCoord.destroy(); vboTexCoord = null; } if (vboVertex != null) { vboVertex.destroy(); vboVertex = null; } if (vboVertexIndex != null) { vboVertexIndex.destroy(); vboVertexIndex = null; } } }