double[] xform, double[] nxform,
float[] varray, int[] indexCoord) {
if (VERBOSE) System.err.println("JoglPipeline.buildIndexedGeometry()");
JoglContext ctx = (JoglContext) absCtx;
GL2 gl = context(ctx).getGL().getGL2();
boolean useInterleavedArrays;
int iaFormat = 0;
int primType = 0;
int stride = 0, coordoff = 0, normoff = 0, coloroff = 0, texCoordoff = 0;
int texSize = 0, texStride = 0;
int vAttrOff = 0;
int vAttrStride = 0;
int bstride = 0, cbstride = 0;
FloatBuffer verts = null;
FloatBuffer clrs = null;
int[] sarray = null;
int strip_len = 0;
boolean useAlpha = false;
if ((vformat & GeometryArray.COORDINATES) != 0) {
gl.glEnableClientState(GL2.GL_VERTEX_ARRAY);
stride += 3;
} else {
gl.glDisableClientState(GL2.GL_VERTEX_ARRAY);
}
if ((vformat & GeometryArray.NORMALS) != 0) {
gl.glEnableClientState(GL2.GL_NORMAL_ARRAY);
stride += 3;
coordoff += 3;
} else {
gl.glDisableClientState(GL2.GL_NORMAL_ARRAY);
}
if ((vformat & GeometryArray.COLOR) != 0) {
gl.glEnableClientState(GL2.GL_COLOR_ARRAY);
stride += 4;
normoff += 4;
coordoff += 4;
} else {
gl.glDisableClientState(GL2.GL_COLOR_ARRAY);
}
if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) {
if ((vformat & GeometryArray.TEXTURE_COORDINATE_2) != 0) {
texSize = 2;
texStride = 2 * texCoordSetCount;
} else if ((vformat & GeometryArray.TEXTURE_COORDINATE_3) != 0) {
texSize = 3;
texStride = 3 * texCoordSetCount;
} else if ((vformat & GeometryArray.TEXTURE_COORDINATE_4) != 0) {
texSize = 4;
texStride = 4 * texCoordSetCount;
}
stride += texStride;
normoff += texStride;
coloroff += texStride;
coordoff += texStride;
}
if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) {
for (int i = 0; i < vertexAttrCount; i++) {
vAttrStride += vertexAttrSizes[i];
}
stride += vAttrStride;
normoff += vAttrStride;
coloroff += vAttrStride;
coordoff += vAttrStride;
texCoordoff += vAttrStride;
}
bstride = stride * Buffers.SIZEOF_FLOAT;
// process alpha for geometryArray without alpha
if (updateAlpha && !ignoreVertexColors) {
useAlpha = true;
}
if (geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_STRIP_SET ||
geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_FAN_SET ||
geo_type == GeometryRetained.GEO_TYPE_INDEXED_LINE_STRIP_SET) {
sarray = ((IndexedGeometryStripArrayRetained) geo).stripIndexCounts;
strip_len = sarray.length;
}
// Copy data into NIO array
verts = getVertexArrayBuffer(varray);
// Apply normal transform if necessary
if ((vformat & GeometryArray.NORMALS) != 0 && nxform != null) {
int off = normoff;
for (int i = 0; i < vertexCount * 3; i+=3) {
verts.put(off , (float) (nxform[0] * varray[off] +
nxform[1] * varray[off+1] +
nxform[2] * varray[off+2]));
verts.put(off+1, (float) (nxform[4] * varray[off] +
nxform[5] * varray[off+1] +
nxform[6] * varray[off+2]));
verts.put(off+2, (float) (nxform[8] * varray[off] +
nxform[9] * varray[off+1] +
nxform[10] * varray[off+2]));
off += stride;
}
}
// Apply coordinate transform if necessary
if ((vformat & GeometryArray.COORDINATES) != 0 && xform != null) {
int off = coordoff;
for (int i = 0; i < vertexCount * 3; i+=3) {
verts.put(off , (float) (xform[0] * varray[off] +
xform[1] * varray[off+1] +
xform[2] * varray[off+2]));
verts.put(off+1, (float) (xform[4] * varray[off] +
xform[5] * varray[off+1] +
xform[6] * varray[off+2]));
verts.put(off+2, (float) (xform[8] * varray[off] +
xform[9] * varray[off+1] +
xform[10] * varray[off+2]));
off += stride;
}
}
if (geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_STRIP_SET ||
geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_FAN_SET ||
geo_type == GeometryRetained.GEO_TYPE_INDEXED_LINE_STRIP_SET) {
// Note we can use interleaved arrays even if we have a
// non-null xform since we use the same data layout unlike the
// C code
if (ignoreVertexColors ||
(((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) && ((texCoordSetMapLen > 1) ||
(texCoordSetCount > 1)))) {
useInterleavedArrays = false;
} else {
boolean[] tmp = new boolean[1];
int[] tmp2 = new int[1];
testForInterleavedArrays(vformat, tmp, tmp2);
useInterleavedArrays = tmp[0];
iaFormat = tmp2[0];
}
if (useInterleavedArrays) {
verts.position(0);
gl.glInterleavedArrays(iaFormat, bstride, verts);
} else {
if ((vformat & GeometryArray.NORMALS) != 0) {
verts.position(normoff);
gl.glNormalPointer(GL.GL_FLOAT, bstride, verts);
}
if (!ignoreVertexColors && ((vformat & GeometryArray.COLOR) != 0)) {
verts.position(coloroff);
if (((vformat & GeometryArray.WITH_ALPHA) != 0) || useAlpha) {
gl.glColorPointer(4, GL.GL_FLOAT, bstride, verts);
} else {
gl.glColorPointer(3, GL.GL_FLOAT, bstride, verts);
}
}
if ((vformat & GeometryArray.COORDINATES) != 0) {
verts.position(coordoff);
gl.glVertexPointer(3, GL.GL_FLOAT, bstride, verts);
}
if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) {
executeTexture(texCoordSetMapLen,
texSize, bstride, texCoordoff,
texCoordSetMapOffset,
texCoordSetMapLen,
verts, gl);
}
if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) {
int vAttrOffset = vAttrOff;
for (int i = 0; i < vertexAttrCount; i++) {
ctx.enableVertexAttrArray(gl, i);
verts.position(vAttrOffset);
ctx.vertexAttrPointer(gl, i, vertexAttrSizes[i],
GL.GL_FLOAT, bstride, verts);
vAttrOffset += vertexAttrSizes[i];
}
}
}
switch (geo_type) {
case GeometryRetained.GEO_TYPE_INDEXED_TRI_STRIP_SET:
primType = GL.GL_TRIANGLE_STRIP;
break;
case GeometryRetained.GEO_TYPE_INDEXED_TRI_FAN_SET:
primType = GL.GL_TRIANGLE_FAN;
break;
case GeometryRetained.GEO_TYPE_INDEXED_LINE_STRIP_SET:
primType = GL.GL_LINE_STRIP;
break;
}
lockArray(gl, vertexCount);
// Note: using MultiDrawElements is probably more expensive than
// not in this case due to the need to allocate more temporary
// direct buffers and slice up the incoming indices array
int offset = initialIndexIndex;
IntBuffer indicesBuffer = IntBuffer.wrap(indexCoord);
for (int i = 0; i < strip_len; i++) {
indicesBuffer.position(offset);
int count = sarray[i];
gl.glDrawElements(primType, count, GL.GL_UNSIGNED_INT, indicesBuffer);
offset += count;
}
} else if ((geo_type == GeometryRetained.GEO_TYPE_INDEXED_QUAD_SET) ||
(geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_SET) ||
(geo_type == GeometryRetained.GEO_TYPE_INDEXED_POINT_SET) ||
(geo_type == GeometryRetained.GEO_TYPE_INDEXED_LINE_SET)) {
// Note we can use interleaved arrays even if we have a
// non-null xform since we use the same data layout unlike the
// C code
if (ignoreVertexColors ||
(((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) && ((texCoordSetMapLen > 1) ||
(texCoordSetCount > 1)))) {
useInterleavedArrays = false;
} else {
boolean[] tmp = new boolean[1];
int[] tmp2 = new int[1];
testForInterleavedArrays(vformat, tmp, tmp2);
useInterleavedArrays = tmp[0];
iaFormat = tmp2[0];
}
if (useInterleavedArrays) {
verts.position(0);
gl.glInterleavedArrays(iaFormat, bstride, verts);
} else {
if ((vformat & GeometryArray.NORMALS) != 0) {
verts.position(normoff);
gl.glNormalPointer(GL.GL_FLOAT, bstride, verts);
}
if (!ignoreVertexColors && ((vformat & GeometryArray.COLOR) != 0)) {
verts.position(coloroff);
if (((vformat & GeometryArray.WITH_ALPHA) != 0) || useAlpha) {
gl.glColorPointer(4, GL.GL_FLOAT, bstride, verts);
} else {
gl.glColorPointer(3, GL.GL_FLOAT, bstride, verts);
}
}
if ((vformat & GeometryArray.COORDINATES) != 0) {
verts.position(coordoff);
gl.glVertexPointer(3, GL.GL_FLOAT, bstride, verts);
}
if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) {
executeTexture(texCoordSetMapLen,
texSize, bstride, texCoordoff,
texCoordSetMapOffset,
texCoordSetMapLen,
verts, gl);
}
if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) {
int vAttrOffset = vAttrOff;
for (int i = 0; i < vertexAttrCount; i++) {
ctx.enableVertexAttrArray(gl, i);
verts.position(vAttrOffset);
ctx.vertexAttrPointer(gl, i, vertexAttrSizes[i],
GL.GL_FLOAT, bstride, verts);
vAttrOffset += vertexAttrSizes[i];
}
}
switch (geo_type) {
case GeometryRetained.GEO_TYPE_INDEXED_QUAD_SET :
primType = GL2.GL_QUADS;
break;
case GeometryRetained.GEO_TYPE_INDEXED_TRI_SET :
primType = GL.GL_TRIANGLES;
break;
case GeometryRetained.GEO_TYPE_INDEXED_POINT_SET :
primType = GL.GL_POINTS;
break;
case GeometryRetained.GEO_TYPE_INDEXED_LINE_SET :
primType = GL.GL_LINES;
break;
}
lockArray(gl, vertexCount);
IntBuffer indicesBuffer = IntBuffer.wrap(indexCoord);
indicesBuffer.position(initialIndexIndex);
gl.glDrawElements(primType, validIndexCount, GL.GL_UNSIGNED_INT, indicesBuffer);
}
}
unlockArray(gl);