From 87e6ea3230dac5b89f89d22bc536c94f04e031ba Mon Sep 17 00:00:00 2001 From: "jul..om" Date: Thu, 25 Oct 2012 11:18:37 +0000 Subject: [PATCH] Adds a few missing features into the shader-based renderer relying on JOGL 2.0 git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@9888 75d07b2b-3a1a-0410-a2c5-0572b91ccdca --- .../com/jme3/renderer/jogl/JoglRenderer.java | 546 +++++++++++++----- 1 file changed, 389 insertions(+), 157 deletions(-) diff --git a/engine/src/jogl/com/jme3/renderer/jogl/JoglRenderer.java b/engine/src/jogl/com/jme3/renderer/jogl/JoglRenderer.java index af919ddc3..23e09801d 100644 --- a/engine/src/jogl/com/jme3/renderer/jogl/JoglRenderer.java +++ b/engine/src/jogl/com/jme3/renderer/jogl/JoglRenderer.java @@ -51,6 +51,7 @@ import com.jme3.scene.Mesh.Mode; import com.jme3.scene.VertexBuffer; import com.jme3.scene.VertexBuffer.Type; import com.jme3.scene.VertexBuffer.Usage; +import com.jme3.shader.Attribute; import com.jme3.shader.Shader; import com.jme3.shader.Shader.ShaderSource; import com.jme3.shader.Uniform; @@ -64,10 +65,7 @@ import com.jme3.util.IntMap; import com.jme3.util.IntMap.Entry; import com.jme3.util.ListMap; import com.jme3.util.NativeObjectManager; -import java.nio.Buffer; -import java.nio.ByteBuffer; -import java.nio.FloatBuffer; -import java.nio.IntBuffer; +import java.nio.*; import java.util.EnumSet; import java.util.List; import java.util.logging.Level; @@ -91,6 +89,7 @@ public class JoglRenderer implements Renderer { private final StringBuilder stringBuf = new StringBuilder(250); private final IntBuffer intBuf1 = BufferUtils.createIntBuffer(1); private final IntBuffer intBuf16 = BufferUtils.createIntBuffer(16); + protected FloatBuffer fb16 = BufferUtils.createFloatBuffer(16); private RenderContext context = new RenderContext(); private NativeObjectManager objManager = new NativeObjectManager(); private EnumSet caps = EnumSet.noneOf(Caps.class); @@ -118,11 +117,6 @@ public class JoglRenderer implements Renderer { private final Statistics statistics = new Statistics(); private int vpX, vpY, vpW, vpH; private int clipX, clipY, clipW, clipH; - //TODO: remove? - protected Matrix4f worldMatrix = new Matrix4f(); - protected Matrix4f viewMatrix = new Matrix4f(); - protected Matrix4f projMatrix = new Matrix4f(); - protected FloatBuffer fb16 = BufferUtils.createFloatBuffer(16); public JoglRenderer() { } @@ -423,15 +417,23 @@ public class JoglRenderer implements Renderer { } public void resetGLObjects() { + logger.log(Level.INFO, "Reseting objects and invalidating state"); objManager.resetObjects(); statistics.clearMemory(); - boundShader = null; - lastFb = null; - context.reset(); + invalidateState(); } public void cleanup() { + logger.log(Level.INFO, "Deleting objects and invalidating state"); objManager.deleteAllObjects(this); + statistics.clearMemory(); + invalidateState(); + } + + private void checkCap(Caps cap) { + if (!caps.contains(cap)) { + throw new UnsupportedOperationException("Required capability missing: " + cap.name()); + } } /*********************************************************************\ @@ -446,9 +448,23 @@ public class JoglRenderer implements Renderer { GL gl = GLContext.getCurrentGL(); int bits = 0; if (color) { + //See explanations of the depth below, we must enable color write to be able to clear the color buffer + if (context.colorWriteEnabled == false) { + gl.glColorMask(true, true, true, true); + context.colorWriteEnabled = true; + } bits = GL.GL_COLOR_BUFFER_BIT; } if (depth) { + + //glClear(GL_DEPTH_BUFFER_BIT) seems to not work when glDepthMask is false + //here s some link on openl board + //http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=257223 + //if depth clear is requested, we enable the depthMask + if (context.depthWriteEnabled == false) { + gl.glDepthMask(true); + context.depthWriteEnabled = true; + } bits |= GL.GL_DEPTH_BUFFER_BIT; } if (stencil) { @@ -476,15 +492,15 @@ public class JoglRenderer implements Renderer { } public void applyRenderState(RenderState state) { - //FIXME implement missing features GL gl = GLContext.getCurrentGL(); if (state.isWireframe() && !context.wireframe) { - gl.getGL2().glPolygonMode(GL.GL_FRONT_AND_BACK, GL2GL3.GL_LINE); + gl.getGL2().glPolygonMode(GL.GL_FRONT_AND_BACK, GL2.GL_LINE); context.wireframe = true; } else if (!state.isWireframe() && context.wireframe) { - gl.getGL2().glPolygonMode(GL.GL_FRONT_AND_BACK, GL2GL3.GL_FILL); + gl.getGL2().glPolygonMode(GL.GL_FRONT_AND_BACK, GL2.GL_FILL); context.wireframe = false; } + if (state.isDepthTest() && !context.depthTestEnabled) { gl.glEnable(GL.GL_DEPTH_TEST); gl.glDepthFunc(GL.GL_LEQUAL); @@ -493,14 +509,16 @@ public class JoglRenderer implements Renderer { gl.glDisable(GL.GL_DEPTH_TEST); context.depthTestEnabled = false; } + if (state.isAlphaTest() && context.alphaTestFallOff == 0) { - gl.glEnable(GL2ES1.GL_ALPHA_TEST); + gl.glEnable(GL2.GL_ALPHA_TEST); gl.getGL2().glAlphaFunc(GL.GL_GREATER, state.getAlphaFallOff()); context.alphaTestFallOff = state.getAlphaFallOff(); } else if (!state.isAlphaTest() && context.alphaTestFallOff != 0) { - gl.glDisable(GL2ES1.GL_ALPHA_TEST); + gl.glDisable(GL2.GL_ALPHA_TEST); context.alphaTestFallOff = 0; } + if (state.isDepthWrite() && !context.depthWriteEnabled) { gl.glDepthMask(true); context.depthWriteEnabled = true; @@ -508,6 +526,7 @@ public class JoglRenderer implements Renderer { gl.glDepthMask(false); context.depthWriteEnabled = false; } + if (state.isColorWrite() && !context.colorWriteEnabled) { gl.glColorMask(true, true, true, true); context.colorWriteEnabled = true; @@ -515,17 +534,43 @@ public class JoglRenderer implements Renderer { gl.glColorMask(false, false, false, false); context.colorWriteEnabled = false; } + + if (state.isPointSprite() && !context.pointSprite) { + // Only enable/disable sprite + if (context.boundTextures[0] != null) { + if (context.boundTextureUnit != 0) { + gl.glActiveTexture(GL.GL_TEXTURE0); + context.boundTextureUnit = 0; + } + gl.glEnable(GL2.GL_POINT_SPRITE); + gl.glEnable(GL2.GL_VERTEX_PROGRAM_POINT_SIZE); + } + context.pointSprite = true; + } else if (!state.isPointSprite() && context.pointSprite) { + if (context.boundTextures[0] != null) { + if (context.boundTextureUnit != 0) { + gl.glActiveTexture(GL.GL_TEXTURE0); + context.boundTextureUnit = 0; + } + gl.glDisable(GL2.GL_POINT_SPRITE); + gl.glDisable(GL2.GL_VERTEX_PROGRAM_POINT_SIZE); + context.pointSprite = false; + } + } + if (state.isPolyOffset()) { if (!context.polyOffsetEnabled) { gl.glEnable(GL.GL_POLYGON_OFFSET_FILL); - gl.glPolygonOffset(state.getPolyOffsetFactor(), state.getPolyOffsetUnits()); + gl.glPolygonOffset(state.getPolyOffsetFactor(), + state.getPolyOffsetUnits()); context.polyOffsetEnabled = true; context.polyOffsetFactor = state.getPolyOffsetFactor(); context.polyOffsetUnits = state.getPolyOffsetUnits(); } else { if (state.getPolyOffsetFactor() != context.polyOffsetFactor || state.getPolyOffsetUnits() != context.polyOffsetUnits) { - gl.glPolygonOffset(state.getPolyOffsetFactor(), state.getPolyOffsetUnits()); + gl.glPolygonOffset(state.getPolyOffsetFactor(), + state.getPolyOffsetUnits()); context.polyOffsetFactor = state.getPolyOffsetFactor(); context.polyOffsetUnits = state.getPolyOffsetUnits(); } @@ -538,6 +583,7 @@ public class JoglRenderer implements Renderer { context.polyOffsetUnits = 0; } } + if (state.getFaceCullMode() != context.cullMode) { if (state.getFaceCullMode() == RenderState.FaceCullMode.Off) { gl.glDisable(GL.GL_CULL_FACE); @@ -570,39 +616,78 @@ public class JoglRenderer implements Renderer { gl.glDisable(GL.GL_BLEND); } else { gl.glEnable(GL.GL_BLEND); - } - - switch (state.getBlendMode()) { - case Off: - break; - case Additive: - gl.glBlendFunc(GL.GL_ONE, GL.GL_ONE); - break; - case AlphaAdditive: - gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE); - break; - case Alpha: - gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA); - break; - case Color: - gl.glBlendFunc(GL.GL_ONE, GL.GL_ONE_MINUS_SRC_COLOR); - break; - case PremultAlpha: - gl.glBlendFunc(GL.GL_ONE, GL.GL_ONE_MINUS_SRC_ALPHA); - break; - case Modulate: - gl.glBlendFunc(GL.GL_DST_COLOR, GL.GL_ZERO); - break; - case ModulateX2: - gl.glBlendFunc(GL.GL_DST_COLOR, GL.GL_SRC_COLOR); - break; - default: - throw new UnsupportedOperationException("Unrecognized blend mode: " - + state.getBlendMode()); + switch (state.getBlendMode()) { + case Off: + break; + case Additive: + gl.glBlendFunc(GL.GL_ONE, GL.GL_ONE); + break; + case AlphaAdditive: + gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE); + break; + case Color: + gl.glBlendFunc(GL.GL_ONE, GL.GL_ONE_MINUS_SRC_COLOR); + break; + case Alpha: + gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA); + break; + case PremultAlpha: + gl.glBlendFunc(GL.GL_ONE, GL.GL_ONE_MINUS_SRC_ALPHA); + break; + case Modulate: + gl.glBlendFunc(GL.GL_DST_COLOR, GL.GL_ZERO); + break; + case ModulateX2: + gl.glBlendFunc(GL.GL_DST_COLOR, GL.GL_SRC_COLOR); + break; + default: + throw new UnsupportedOperationException("Unrecognized blend mode: " + + state.getBlendMode()); + } } context.blendMode = state.getBlendMode(); } + + if (context.stencilTest != state.isStencilTest() + || context.frontStencilStencilFailOperation != state.getFrontStencilStencilFailOperation() + || context.frontStencilDepthFailOperation != state.getFrontStencilDepthFailOperation() + || context.frontStencilDepthPassOperation != state.getFrontStencilDepthPassOperation() + || context.backStencilStencilFailOperation != state.getBackStencilStencilFailOperation() + || context.backStencilDepthFailOperation != state.getBackStencilDepthFailOperation() + || context.backStencilDepthPassOperation != state.getBackStencilDepthPassOperation() + || context.frontStencilFunction != state.getFrontStencilFunction() + || context.backStencilFunction != state.getBackStencilFunction()) { + + context.frontStencilStencilFailOperation = state.getFrontStencilStencilFailOperation(); //terrible looking, I know + context.frontStencilDepthFailOperation = state.getFrontStencilDepthFailOperation(); + context.frontStencilDepthPassOperation = state.getFrontStencilDepthPassOperation(); + context.backStencilStencilFailOperation = state.getBackStencilStencilFailOperation(); + context.backStencilDepthFailOperation = state.getBackStencilDepthFailOperation(); + context.backStencilDepthPassOperation = state.getBackStencilDepthPassOperation(); + context.frontStencilFunction = state.getFrontStencilFunction(); + context.backStencilFunction = state.getBackStencilFunction(); + + if (state.isStencilTest()) { + gl.glEnable(GL.GL_STENCIL_TEST); + gl.getGL2().glStencilOpSeparate(GL.GL_FRONT, + convertStencilOperation(state.getFrontStencilStencilFailOperation()), + convertStencilOperation(state.getFrontStencilDepthFailOperation()), + convertStencilOperation(state.getFrontStencilDepthPassOperation())); + gl.getGL2().glStencilOpSeparate(GL.GL_BACK, + convertStencilOperation(state.getBackStencilStencilFailOperation()), + convertStencilOperation(state.getBackStencilDepthFailOperation()), + convertStencilOperation(state.getBackStencilDepthPassOperation())); + gl.getGL2().glStencilFuncSeparate(GL.GL_FRONT, + convertTestFunction(state.getFrontStencilFunction()), + 0, Integer.MAX_VALUE); + gl.getGL2().glStencilFuncSeparate(GL.GL_BACK, + convertTestFunction(state.getBackStencilFunction()), + 0, Integer.MAX_VALUE); + } else { + gl.glDisable(GL.GL_STENCIL_TEST); + } + } } private int convertStencilOperation(RenderState.StencilOperation stencilOp) { @@ -654,13 +739,15 @@ public class JoglRenderer implements Renderer { /*********************************************************************\ |* Camera and World transforms *| \*********************************************************************/ - public void setViewPort(int x, int y, int width, int height) { - GL gl = GLContext.getCurrentGL(); - gl.glViewport(x, y, width, height); - vpX = x; - vpY = y; - vpW = width; - vpH = height; + public void setViewPort(int x, int y, int w, int h) { + if (x != vpX || vpY != y || vpW != w || vpH != h) { + GL gl = GLContext.getCurrentGL(); + gl.glViewport(x, y, w, h); + vpX = x; + vpY = y; + vpW = w; + vpH = h; + } } public void setClipRect(int x, int y, int width, int height) { @@ -669,7 +756,13 @@ public class JoglRenderer implements Renderer { gl.glEnable(GL.GL_SCISSOR_TEST); context.clipRectEnabled = true; } - gl.glScissor(x, y, width, height); + if (clipX != x || clipY != y || clipW != width || clipH != height) { + gl.glScissor(x, y, width, height); + clipX = x; + clipY = y; + clipW = width; + clipH = height; + } } public void clearClipRect() { @@ -677,6 +770,11 @@ public class JoglRenderer implements Renderer { GL gl = GLContext.getCurrentGL(); gl.glDisable(GL.GL_SCISSOR_TEST); context.clipRectEnabled = false; + + clipX = 0; + clipY = 0; + clipW = 0; + clipH = 0; } } @@ -1088,13 +1186,13 @@ public class JoglRenderer implements Renderer { if (gl.isExtensionAvailable("GL_EXT_framebuffer_blit")) { int srcX0 = 0; int srcY0 = 0; - int srcX1 = 0; - int srcY1 = 0; + int srcX1/* = 0*/; + int srcY1/* = 0*/; int dstX0 = 0; int dstY0 = 0; - int dstX1 = 0; - int dstY1 = 0; + int dstX1/* = 0*/; + int dstY1/* = 0*/; int prevFBO = context.boundFBO; @@ -1800,6 +1898,7 @@ public class JoglRenderer implements Renderer { img.clearUpdateNeeded(); } + //FIXME remove it private void checkTexturingUsed() { IDList textureList = context.textureIndexList; GL gl = GLContext.getCurrentGL(); @@ -1878,6 +1977,9 @@ public class JoglRenderer implements Renderer { } } + /*********************************************************************\ + |* Vertex Buffers and Attributes *| + \*********************************************************************/ private int convertUsage(Usage usage) { switch (usage) { case Static: @@ -1890,30 +1992,69 @@ public class JoglRenderer implements Renderer { throw new RuntimeException("Unknown usage type: " + usage); } } + + private int convertFormat(VertexBuffer.Format format) { + switch (format) { + case Byte: + return GL.GL_BYTE; + case UnsignedByte: + return GL.GL_UNSIGNED_BYTE; + case Short: + return GL.GL_SHORT; + case UnsignedShort: + return GL.GL_UNSIGNED_SHORT; + case Int: + return GL2.GL_INT; + case UnsignedInt: + return GL.GL_UNSIGNED_INT; +// case Half: +// return NVHalfFloat.GL_HALF_FLOAT_NV; +// return ARBHalfFloatVertex.GL_HALF_FLOAT; + case Float: + return GL.GL_FLOAT; + case Double: + return GL2.GL_DOUBLE; + default: + throw new UnsupportedOperationException("Unknown buffer format."); + + } + } public void updateBufferData(VertexBuffer vb) { GL gl = GLContext.getCurrentGL(); int bufId = vb.getId(); + boolean created = false; if (bufId == -1) { // create buffer gl.glGenBuffers(1, intBuf1); bufId = intBuf1.get(0); vb.setId(bufId); objManager.registerForCleanup(vb); + + //statistics.onNewVertexBuffer(); + + created = true; } + // bind buffer int target; if (vb.getBufferType() == VertexBuffer.Type.Index) { target = GL.GL_ELEMENT_ARRAY_BUFFER; if (context.boundElementArrayVBO != bufId) { gl.glBindBuffer(target, bufId); context.boundElementArrayVBO = bufId; + //statistics.onVertexBufferUse(vb, true); + } else { + //statistics.onVertexBufferUse(vb, false); } } else { target = GL.GL_ARRAY_BUFFER; if (context.boundArrayVBO != bufId) { gl.glBindBuffer(target, bufId); context.boundArrayVBO = bufId; + //statistics.onVertexBufferUse(vb, true); + } else { + //statistics.onVertexBufferUse(vb, false); } } @@ -1921,7 +2062,12 @@ public class JoglRenderer implements Renderer { Buffer data = vb.getData(); data.rewind(); - gl.glBufferData(target, data.capacity() * vb.getFormat().getComponentSize(), data, usage); + if (created || vb.hasDataSizeChanged()) { + // upload data based on format + gl.glBufferData(target, data.capacity() * vb.getFormat().getComponentSize(), data, usage); + } else { + gl.glBufferSubData(target, 0, data.capacity() * vb.getFormat().getComponentSize(), data); + } vb.clearUpdateNeeded(); } @@ -1935,9 +2081,101 @@ public class JoglRenderer implements Renderer { intBuf1.position(0).limit(1); gl.glDeleteBuffers(1, intBuf1); vb.resetObject(); + + //statistics.onDeleteVertexBuffer(); } } + + public void clearVertexAttribs() { + IDList attribList = context.attribIndexList; + for (int i = 0; i < attribList.oldLen; i++) { + int idx = attribList.oldList[i]; + GL gl = GLContext.getCurrentGL(); + gl.getGL2().glDisableVertexAttribArray(idx); + context.boundAttribs[idx] = null; + } + context.attribIndexList.copyNewToOld(); + } + + public void setVertexAttrib(VertexBuffer vb, VertexBuffer idb) { + if (vb.getBufferType() == VertexBuffer.Type.Index) { + throw new IllegalArgumentException("Index buffers not allowed to be set to vertex attrib"); + } + + int programId = context.boundShaderProgram; + if (programId > 0) { + GL gl = GLContext.getCurrentGL(); + Attribute attrib = boundShader.getAttribute(vb.getBufferType()); + int loc = attrib.getLocation(); + if (loc == -1) { + return; // not defined + } + if (loc == -2) { + stringBuf.setLength(0); + stringBuf.append("in").append(vb.getBufferType().name()).append('\0'); + updateNameBuffer(); + loc = gl.getGL2().glGetAttribLocation(programId, stringBuf.toString()); + + // not really the name of it in the shader (inPosition\0) but + // the internal name of the enum (Position). + if (loc < 0) { + attrib.setLocation(-1); + return; // not available in shader. + } else { + attrib.setLocation(loc); + } + } + + if (vb.isUpdateNeeded() && idb == null) { + updateBufferData(vb); + } + VertexBuffer[] attribs = context.boundAttribs; + if (!context.attribIndexList.moveToNew(loc)) { + gl.getGL2().glEnableVertexAttribArray(loc); + //System.out.println("Enabled ATTRIB IDX: "+loc); + } + if (attribs[loc] != vb) { + // NOTE: Use id from interleaved buffer if specified + int bufId = idb != null ? idb.getId() : vb.getId(); + assert bufId != -1; + if (context.boundArrayVBO != bufId) { + gl.glBindBuffer(GL.GL_ARRAY_BUFFER, bufId); + context.boundArrayVBO = bufId; + //statistics.onVertexBufferUse(vb, true); + } else { + //statistics.onVertexBufferUse(vb, false); + } + + gl.getGL2().glVertexAttribPointer(loc, + vb.getNumComponents(), + convertFormat(vb.getFormat()), + vb.isNormalized(), + vb.getStride(), + vb.getOffset()); + + attribs[loc] = vb; + } + } else { + throw new IllegalStateException("Cannot render mesh without shader bound"); + } + } + + public void setVertexAttrib(VertexBuffer vb) { + setVertexAttrib(vb, null); + } + + public void drawTriangleArray(Mesh.Mode mode, int count, int vertCount) { + GL gl = GLContext.getCurrentGL(); + if (count > 1) { + gl.getGL2().glDrawArraysInstanced(convertElementMode(mode), 0, + vertCount, count); + } else { + gl.glDrawArrays(convertElementMode(mode), 0, vertCount); + } + } + + //FIXME remove private int convertArrayType(VertexBuffer.Type type) { switch (type) { case Position: @@ -1953,6 +2191,7 @@ public class JoglRenderer implements Renderer { } } + //FIXME remove private int convertVertexFormat(VertexBuffer.Format fmt) { switch (fmt) { case Byte: @@ -1977,7 +2216,94 @@ public class JoglRenderer implements Renderer { throw new UnsupportedOperationException("Unrecognized vertex format: " + fmt); } } + + public void drawTriangleList(VertexBuffer indexBuf, Mesh mesh, int count) { + if (indexBuf.getBufferType() != VertexBuffer.Type.Index) { + throw new IllegalArgumentException("Only index buffers are allowed as triangle lists."); + } + + if (indexBuf.isUpdateNeeded()) { + updateBufferData(indexBuf); + } + + int bufId = indexBuf.getId(); + assert bufId != -1; + + GL gl = GLContext.getCurrentGL(); + if (context.boundElementArrayVBO != bufId) { + gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, bufId); + context.boundElementArrayVBO = bufId; + //statistics.onVertexBufferUse(indexBuf, true); + } else { + //statistics.onVertexBufferUse(indexBuf, true); + } + + int vertCount = mesh.getVertexCount(); + boolean useInstancing = count > 1 && caps.contains(Caps.MeshInstancing); + + if (mesh.getMode() == Mode.Hybrid) { + int[] modeStart = mesh.getModeStart(); + int[] elementLengths = mesh.getElementLengths(); + int elMode = convertElementMode(Mode.Triangles); + int fmt = convertFormat(indexBuf.getFormat()); + int elSize = indexBuf.getFormat().getComponentSize(); + int listStart = modeStart[0]; + int stripStart = modeStart[1]; + int fanStart = modeStart[2]; + int curOffset = 0; + for (int i = 0; i < elementLengths.length; i++) { + if (i == stripStart) { + elMode = convertElementMode(Mode.TriangleStrip); + } else if (i == fanStart) { + elMode = convertElementMode(Mode.TriangleStrip); + } + int elementLength = elementLengths[i]; + + if (useInstancing) { + + indexBuf.getData().position(curOffset); + indexBuf.getData().limit(curOffset + elementLength); + + gl.getGL2GL3().glDrawElementsInstanced(elMode, + elementLength, + fmt, + indexBuf.getData(), + count); + + } else { + gl.getGL2().glDrawRangeElements(elMode, + 0, + vertCount, + elementLength, + fmt, + curOffset); + } + + //FIXME check whether elSize is required + curOffset += elementLength/* * elSize*/; + } + } else { + if (useInstancing) { + gl.getGL2GL3().glDrawElementsInstanced(convertElementMode(mesh.getMode()), + indexBuf.getData().limit(), + convertFormat(indexBuf.getFormat()), + indexBuf.getData(), + count); + } else { + gl.getGL2().glDrawRangeElements(convertElementMode(mesh.getMode()), + 0, + vertCount, + indexBuf.getData().limit(), + convertFormat(indexBuf.getFormat()), + 0); + } + } + } + + /*********************************************************************\ + |* Render Calls *| + \*********************************************************************/ private int convertElementMode(Mesh.Mode mode) { switch (mode) { case Points: @@ -2095,102 +2421,8 @@ public class JoglRenderer implements Renderer { } } - public void setVertexAttrib(VertexBuffer vb, VertexBuffer idb) { - GL gl = GLContext.getCurrentGL(); - int arrayType = convertArrayType(vb.getBufferType()); - if (arrayType == -1) { - return; // unsupported - } - - gl.getGL2().glEnableClientState(arrayType); - context.boundAttribs[vb.getBufferType().ordinal()] = vb; - - if (vb.getBufferType() == Type.Normal) { - // normalize if requested - if (vb.isNormalized() && !context.normalizeEnabled) { - gl.glEnable(GLLightingFunc.GL_NORMALIZE); - context.normalizeEnabled = true; - } else if (!vb.isNormalized() && context.normalizeEnabled) { - gl.glDisable(GLLightingFunc.GL_NORMALIZE); - context.normalizeEnabled = false; - } - } - - // NOTE: Use data from interleaved buffer if specified - Buffer data = idb != null ? idb.getData() : vb.getData(); - int comps = vb.getNumComponents(); - int type = convertVertexFormat(vb.getFormat()); - data.clear(); - data.position(vb.getOffset()); - - switch (vb.getBufferType()) { - case Position: - gl.getGL2().glVertexPointer(comps, type, vb.getStride(), data); - break; - case Normal: - gl.getGL2().glNormalPointer(type, vb.getStride(), data); - break; - case Color: - gl.getGL2().glColorPointer(comps, type, vb.getStride(), data); - break; - case TexCoord: - gl.getGL2().glTexCoordPointer(comps, type, vb.getStride(), data); - break; - } - } - - public void setVertexAttrib(VertexBuffer vb) { - setVertexAttrib(vb, null); - } - - public void clearVertexAttribs() { - GL gl = GLContext.getCurrentGL(); - for (int i = 0; i < 16; i++) { - VertexBuffer vb = context.boundAttribs[i]; - if (vb != null) { - int arrayType = convertArrayType(vb.getBufferType()); - gl.getGL2().glDisableClientState(arrayType); - context.boundAttribs[vb.getBufferType().ordinal()] = null; - } - } - } - - public void drawTriangleList(VertexBuffer indexBuf, Mesh mesh, int count) { - GL gl = GLContext.getCurrentGL(); - Mesh.Mode mode = mesh.getMode(); - - Buffer indexData = indexBuf.getData(); - indexData.clear(); - if (mesh.getMode() == Mode.Hybrid) { - int[] modeStart = mesh.getModeStart(); - int[] elementLengths = mesh.getElementLengths(); - - int elMode = convertElementMode(Mode.Triangles); - int fmt = convertVertexFormat(indexBuf.getFormat()); - // int elSize = indexBuf.getFormat().getComponentSize(); - // int listStart = modeStart[0]; - int stripStart = modeStart[1]; - int fanStart = modeStart[2]; - int curOffset = 0; - for (int i = 0; i < elementLengths.length; i++) { - if (i == stripStart) { - elMode = convertElementMode(Mode.TriangleStrip); - } else if (i == fanStart) { - elMode = convertElementMode(Mode.TriangleStrip); - } - int elementLength = elementLengths[i]; - indexData.position(curOffset); - gl.glDrawElements(elMode, elementLength, fmt, indexData); - curOffset += elementLength; - } - } else { - gl.glDrawElements(convertElementMode(mode), indexData.capacity(), - convertVertexFormat(indexBuf.getFormat()), indexData); - } - } - private void renderMeshDefault(Mesh mesh, int lod, int count) { - VertexBuffer indices = null; + VertexBuffer indices/* = null*/; VertexBuffer interleavedData = mesh.getBuffer(Type.InterleavedData); IntMap buffers = mesh.getBuffers(); if (mesh.getNumLodLevels() > 0) { @@ -2230,7 +2462,7 @@ public class JoglRenderer implements Renderer { private void renderMeshVBO(Mesh mesh, int lod, int count) { GL gl = GLContext.getCurrentGL(); - VertexBuffer indices = null; + VertexBuffer indices/* = null*/; VertexBuffer interleavedData = mesh.getBuffer(Type.InterleavedData); if (interleavedData != null && interleavedData.isUpdateNeeded()) { updateBufferData(interleavedData);