|
@@ -65,6 +65,7 @@ import com.jme3.util.IntMap;
|
|
|
import com.jme3.util.IntMap.Entry;
|
|
|
import com.jme3.util.ListMap;
|
|
|
import com.jme3.util.NativeObjectManager;
|
|
|
+import com.jme3.util.SafeArrayList;
|
|
|
import java.nio.*;
|
|
|
import java.util.EnumSet;
|
|
|
import java.util.List;
|
|
@@ -1898,18 +1899,6 @@ public class JoglRenderer implements Renderer {
|
|
|
img.clearUpdateNeeded();
|
|
|
}
|
|
|
|
|
|
- //FIXME remove it
|
|
|
- private void checkTexturingUsed() {
|
|
|
- IDList textureList = context.textureIndexList;
|
|
|
- GL gl = GLContext.getCurrentGL();
|
|
|
- // old mesh used texturing, new mesh doesn't use it
|
|
|
- // should actually go through entire oldLen and
|
|
|
- // disable texturing for each unit.. but that's for later.
|
|
|
- if (textureList.oldLen > 0 && textureList.newLen == 0) {
|
|
|
- gl.glDisable(GL.GL_TEXTURE_2D);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
public void setTexture(int unit, Texture tex) {
|
|
|
GL gl = GLContext.getCurrentGL();
|
|
|
Image image = tex.getImage();
|
|
@@ -2175,48 +2164,6 @@ public class JoglRenderer implements Renderer {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- //FIXME remove
|
|
|
- private int convertArrayType(VertexBuffer.Type type) {
|
|
|
- switch (type) {
|
|
|
- case Position:
|
|
|
- return GLPointerFunc.GL_VERTEX_ARRAY;
|
|
|
- case Normal:
|
|
|
- return GLPointerFunc.GL_NORMAL_ARRAY;
|
|
|
- case TexCoord:
|
|
|
- return GLPointerFunc.GL_TEXTURE_COORD_ARRAY;
|
|
|
- case Color:
|
|
|
- return GLPointerFunc.GL_COLOR_ARRAY;
|
|
|
- default:
|
|
|
- return -1; // unsupported
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- //FIXME remove
|
|
|
- private int convertVertexFormat(VertexBuffer.Format fmt) {
|
|
|
- switch (fmt) {
|
|
|
- case Byte:
|
|
|
- return GL.GL_BYTE;
|
|
|
- case Double:
|
|
|
- return GL2GL3.GL_DOUBLE;
|
|
|
- case Float:
|
|
|
- return GL.GL_FLOAT;
|
|
|
- case Half:
|
|
|
- return GL.GL_HALF_FLOAT;
|
|
|
- case Int:
|
|
|
- return GL2ES2.GL_INT;
|
|
|
- case Short:
|
|
|
- return GL.GL_SHORT;
|
|
|
- case UnsignedByte:
|
|
|
- return GL.GL_UNSIGNED_BYTE;
|
|
|
- case UnsignedInt:
|
|
|
- return GL2ES2.GL_UNSIGNED_INT;
|
|
|
- case UnsignedShort:
|
|
|
- return GL.GL_UNSIGNED_SHORT;
|
|
|
- default:
|
|
|
- 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.");
|
|
@@ -2324,215 +2271,136 @@ public class JoglRenderer implements Renderer {
|
|
|
throw new UnsupportedOperationException("Unrecognized mesh mode: " + mode);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- private void setVertexAttribVBO(VertexBuffer vb, VertexBuffer idb) {
|
|
|
+
|
|
|
+ public void updateVertexArray(Mesh mesh) {
|
|
|
+ int id = mesh.getId();
|
|
|
GL gl = GLContext.getCurrentGL();
|
|
|
- int arrayType = convertArrayType(vb.getBufferType());
|
|
|
- if (arrayType == -1) {
|
|
|
- return; // unsupported
|
|
|
+ if (id == -1) {
|
|
|
+ IntBuffer temp = intBuf1;
|
|
|
+ gl.getGL2GL3().glGenVertexArrays(1, temp);
|
|
|
+ id = temp.get(0);
|
|
|
+ mesh.setId(id);
|
|
|
}
|
|
|
|
|
|
- if (vb.isUpdateNeeded() && idb == null) {
|
|
|
- updateBufferData(vb);
|
|
|
+ if (context.boundVertexArray != id) {
|
|
|
+ gl.getGL2GL3().glBindVertexArray(id);
|
|
|
+ context.boundVertexArray = id;
|
|
|
}
|
|
|
|
|
|
- int bufId = idb != null ? idb.getId() : vb.getId();
|
|
|
- if (context.boundArrayVBO != bufId) {
|
|
|
- gl.glBindBuffer(GL.GL_ARRAY_BUFFER, bufId);
|
|
|
- context.boundArrayVBO = bufId;
|
|
|
+ VertexBuffer interleavedData = mesh.getBuffer(Type.InterleavedData);
|
|
|
+ if (interleavedData != null && interleavedData.isUpdateNeeded()) {
|
|
|
+ updateBufferData(interleavedData);
|
|
|
}
|
|
|
|
|
|
- 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;
|
|
|
+ for (VertexBuffer vb : mesh.getBufferList().getArray()) {
|
|
|
+ if (vb.getBufferType() == Type.InterleavedData
|
|
|
+ || vb.getUsage() == Usage.CpuOnly // ignore cpu-only buffers
|
|
|
+ || vb.getBufferType() == Type.Index) {
|
|
|
+ continue;
|
|
|
}
|
|
|
- }
|
|
|
-
|
|
|
- int comps = vb.getNumComponents();
|
|
|
- int type = convertVertexFormat(vb.getFormat());
|
|
|
|
|
|
- switch (vb.getBufferType()) {
|
|
|
- case Position:
|
|
|
- gl.getGL2().glVertexPointer(comps, type, vb.getStride(), vb.getOffset());
|
|
|
- break;
|
|
|
- case Normal:
|
|
|
- gl.getGL2().glNormalPointer(type, vb.getStride(), vb.getOffset());
|
|
|
- break;
|
|
|
- case Color:
|
|
|
- gl.getGL2().glColorPointer(comps, type, vb.getStride(), vb.getOffset());
|
|
|
- break;
|
|
|
- case TexCoord:
|
|
|
- gl.getGL2().glTexCoordPointer(comps, type, vb.getStride(), vb.getOffset());
|
|
|
- break;
|
|
|
+ if (vb.getStride() == 0) {
|
|
|
+ // not interleaved
|
|
|
+ setVertexAttrib(vb);
|
|
|
+ } else {
|
|
|
+ // interleaved
|
|
|
+ setVertexAttrib(vb, interleavedData);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- private void drawTriangleListVBO(VertexBuffer indexBuf, Mesh mesh, int count) {
|
|
|
- GL gl = GLContext.getCurrentGL();
|
|
|
- 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;
|
|
|
-
|
|
|
- if (context.boundElementArrayVBO != bufId) {
|
|
|
- gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, bufId);
|
|
|
- context.boundElementArrayVBO = bufId;
|
|
|
+
|
|
|
+ private void renderMeshVertexArray(Mesh mesh, int lod, int count) {
|
|
|
+ if (mesh.getId() == -1) {
|
|
|
+ updateVertexArray(mesh);
|
|
|
+ } else {
|
|
|
+ // TODO: Check if it was updated
|
|
|
}
|
|
|
|
|
|
- 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) {
|
|
|
- //TriangleStrip?
|
|
|
- elMode = convertElementMode(Mode.TriangleFan);
|
|
|
- }
|
|
|
- int elementLength = elementLengths[i];
|
|
|
- gl.glDrawElements(elMode, elementLength, fmt, curOffset);
|
|
|
- curOffset += elementLength * elSize;
|
|
|
- }
|
|
|
- } else {
|
|
|
- gl.glDrawElements(convertElementMode(mesh.getMode()), indexBuf.getData().capacity(),
|
|
|
- convertVertexFormat(indexBuf.getFormat()), 0);
|
|
|
+ if (context.boundVertexArray != mesh.getId()) {
|
|
|
+ GL gl = GLContext.getCurrentGL();
|
|
|
+ gl.getGL2GL3().glBindVertexArray(mesh.getId());
|
|
|
+ context.boundVertexArray = mesh.getId();
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- private void renderMeshDefault(Mesh mesh, int lod, int count) {
|
|
|
- VertexBuffer indices/* = null*/;
|
|
|
- VertexBuffer interleavedData = mesh.getBuffer(Type.InterleavedData);
|
|
|
- IntMap<VertexBuffer> buffers = mesh.getBuffers();
|
|
|
+// IntMap<VertexBuffer> buffers = mesh.getBuffers();
|
|
|
+ VertexBuffer indices;
|
|
|
if (mesh.getNumLodLevels() > 0) {
|
|
|
indices = mesh.getLodLevel(lod);
|
|
|
} else {
|
|
|
- indices = buffers.get(Type.Index.ordinal());
|
|
|
+ indices = mesh.getBuffer(Type.Index);
|
|
|
}
|
|
|
- for (Entry<VertexBuffer> entry : buffers) {
|
|
|
- VertexBuffer vb = entry.getValue();
|
|
|
-
|
|
|
- if (vb.getBufferType() == Type.InterleavedData || vb.getUsage() == Usage.CpuOnly) {
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- if (vb.getBufferType() == Type.Index) {
|
|
|
- indices = vb;
|
|
|
- } else {
|
|
|
- if (vb.getStride() == 0) {
|
|
|
- // not interleaved
|
|
|
- setVertexAttrib(vb);
|
|
|
- } else {
|
|
|
- // interleaved
|
|
|
- setVertexAttrib(vb, interleavedData);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
if (indices != null) {
|
|
|
drawTriangleList(indices, mesh, count);
|
|
|
} else {
|
|
|
- GL gl = GLContext.getCurrentGL();
|
|
|
- gl.glDrawArrays(convertElementMode(mesh.getMode()), 0, mesh.getVertexCount());
|
|
|
+ drawTriangleArray(mesh.getMode(), count, mesh.getVertexCount());
|
|
|
}
|
|
|
clearVertexAttribs();
|
|
|
clearTextureUnits();
|
|
|
}
|
|
|
+
|
|
|
+ private void renderMeshDefault(Mesh mesh, int lod, int count) {
|
|
|
+ VertexBuffer indices;
|
|
|
|
|
|
- private void renderMeshVBO(Mesh mesh, int lod, int count) {
|
|
|
- GL gl = GLContext.getCurrentGL();
|
|
|
- VertexBuffer indices/* = null*/;
|
|
|
VertexBuffer interleavedData = mesh.getBuffer(Type.InterleavedData);
|
|
|
if (interleavedData != null && interleavedData.isUpdateNeeded()) {
|
|
|
updateBufferData(interleavedData);
|
|
|
}
|
|
|
- IntMap<VertexBuffer> buffers = mesh.getBuffers();
|
|
|
+
|
|
|
+// IntMap<VertexBuffer> buffers = mesh.getBuffers();
|
|
|
+ SafeArrayList<VertexBuffer> buffersList = mesh.getBufferList();
|
|
|
+
|
|
|
if (mesh.getNumLodLevels() > 0) {
|
|
|
indices = mesh.getLodLevel(lod);
|
|
|
} else {
|
|
|
- indices = buffers.get(Type.Index.ordinal());
|
|
|
+ indices = mesh.getBuffer(Type.Index);
|
|
|
}
|
|
|
- for (Entry<VertexBuffer> entry : buffers) {
|
|
|
- VertexBuffer vb = entry.getValue();
|
|
|
|
|
|
- if (vb.getBufferType() == Type.InterleavedData || vb.getUsage() == Usage.CpuOnly // ignore
|
|
|
- // cpu-only
|
|
|
- // buffers
|
|
|
+// for (Entry<VertexBuffer> entry : buffers) {
|
|
|
+// VertexBuffer vb = entry.getValue();
|
|
|
+ for (VertexBuffer vb : mesh.getBufferList().getArray()) {
|
|
|
+ if (vb.getBufferType() == Type.InterleavedData
|
|
|
+ || vb.getUsage() == Usage.CpuOnly // ignore cpu-only buffers
|
|
|
|| vb.getBufferType() == Type.Index) {
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
if (vb.getStride() == 0) {
|
|
|
// not interleaved
|
|
|
- setVertexAttribVBO(vb, null);
|
|
|
+ setVertexAttrib(vb);
|
|
|
} else {
|
|
|
// interleaved
|
|
|
- setVertexAttribVBO(vb, interleavedData);
|
|
|
+ setVertexAttrib(vb, interleavedData);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (indices != null) {
|
|
|
- drawTriangleListVBO(indices, mesh, count);
|
|
|
+ drawTriangleList(indices, mesh, count);
|
|
|
} else {
|
|
|
- gl.glDrawArrays(convertElementMode(mesh.getMode()), 0, mesh.getVertexCount());
|
|
|
+ drawTriangleArray(mesh.getMode(), count, mesh.getVertexCount());
|
|
|
}
|
|
|
clearVertexAttribs();
|
|
|
clearTextureUnits();
|
|
|
}
|
|
|
|
|
|
- private void updateDisplayList(Mesh mesh) {
|
|
|
- GL gl = GLContext.getCurrentGL();
|
|
|
- if (mesh.getId() != -1) {
|
|
|
- // delete list first
|
|
|
- gl.getGL2().glDeleteLists(mesh.getId(), mesh.getId());
|
|
|
- mesh.setId(-1);
|
|
|
+ public void renderMesh(Mesh mesh, int lod, int count) {
|
|
|
+ if (mesh.getVertexCount() == 0) {
|
|
|
+ return;
|
|
|
}
|
|
|
|
|
|
- // create new display list
|
|
|
- // first set state to NULL
|
|
|
- applyRenderState(RenderState.NULL);
|
|
|
-
|
|
|
- // disable lighting
|
|
|
- setLighting(null);
|
|
|
-
|
|
|
- int id = gl.getGL2().glGenLists(1);
|
|
|
- mesh.setId(id);
|
|
|
- gl.getGL2().glNewList(id, GL2.GL_COMPILE);
|
|
|
- renderMeshDefault(mesh, 0, 1);
|
|
|
- gl.getGL2().glEndList();
|
|
|
- }
|
|
|
-
|
|
|
- private void renderMeshDisplayList(Mesh mesh) {
|
|
|
GL gl = GLContext.getCurrentGL();
|
|
|
- if (mesh.getId() == -1) {
|
|
|
- updateDisplayList(mesh);
|
|
|
+ if (context.pointSprite && mesh.getMode() != Mode.Points) {
|
|
|
+ // XXX: Hack, disable point sprite mode if mesh not in point mode
|
|
|
+ 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;
|
|
|
+ }
|
|
|
}
|
|
|
- gl.getGL2().glCallList(mesh.getId());
|
|
|
- }
|
|
|
|
|
|
- public void renderMesh(Mesh mesh, int lod, int count) {
|
|
|
- GL gl = GLContext.getCurrentGL();
|
|
|
if (context.pointSize != mesh.getPointSize()) {
|
|
|
gl.getGL2().glPointSize(mesh.getPointSize());
|
|
|
context.pointSize = mesh.getPointSize();
|
|
@@ -2542,32 +2410,11 @@ public class JoglRenderer implements Renderer {
|
|
|
context.lineWidth = mesh.getLineWidth();
|
|
|
}
|
|
|
|
|
|
- checkTexturingUsed();
|
|
|
-
|
|
|
- /*if (vbo) {*/
|
|
|
- renderMeshVBO(mesh, lod, count);
|
|
|
- /*} else {
|
|
|
- boolean dynamic = false;
|
|
|
- if (mesh.getNumLodLevels() == 0) {
|
|
|
- IntMap<VertexBuffer> bufs = mesh.getBuffers();
|
|
|
- for (Entry<VertexBuffer> entry : bufs) {
|
|
|
- if (entry.getValue().getUsage() != VertexBuffer.Usage.Static) {
|
|
|
- dynamic = true;
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- } else {
|
|
|
- dynamic = true;
|
|
|
- }
|
|
|
-
|
|
|
- if (!dynamic) {
|
|
|
- // dealing with a static object, generate display list
|
|
|
- renderMeshDisplayList(mesh);
|
|
|
- } else {
|
|
|
- renderMeshDefault(mesh, lod, count);
|
|
|
- }
|
|
|
- }*/
|
|
|
+ statistics.onMeshDrawn(mesh, lod);
|
|
|
+// if (GLContext.getCapabilities().GL_ARB_vertex_array_object){
|
|
|
+// renderMeshVertexArray(mesh, lod, count);
|
|
|
+// }else{
|
|
|
+ renderMeshDefault(mesh, lod, count);
|
|
|
+// }
|
|
|
}
|
|
|
-
|
|
|
-
|
|
|
}
|