GLRenderer: remaining portion of VAO support
This commit is contained in:
parent
bee759bddc
commit
e8f344a0db
@ -137,6 +137,11 @@ class BitmapTextPage extends Geometry {
|
||||
Mesh m = getMesh();
|
||||
int vertCount = pageQuads.size() * 4;
|
||||
int triCount = pageQuads.size() * 2;
|
||||
|
||||
if (vertCount > m.getVertexCount() ||
|
||||
triCount > m.getTriangleCount()) {
|
||||
m.setUpdateNeeded();
|
||||
}
|
||||
|
||||
VertexBuffer pb = m.getBuffer(Type.Position);
|
||||
VertexBuffer tb = m.getBuffer(Type.TexCoord);
|
||||
|
@ -283,6 +283,12 @@ public interface Renderer {
|
||||
* the per-instance attributes.
|
||||
*/
|
||||
public void renderMesh(Mesh mesh, int lod, int count, VertexBuffer[] instanceData);
|
||||
|
||||
/**
|
||||
* Delete a Mesh (or Vertex Array Object in GL terms) from the GPU.
|
||||
* @param mesh The mesh to delete.
|
||||
*/
|
||||
public void deleteMesh(Mesh mesh);
|
||||
|
||||
/**
|
||||
* Resets all previously used {@link NativeObject Native Objects} on this Renderer.
|
||||
|
@ -42,6 +42,7 @@ import com.jme3.math.Matrix4f;
|
||||
import com.jme3.math.Triangle;
|
||||
import com.jme3.math.Vector2f;
|
||||
import com.jme3.math.Vector3f;
|
||||
import com.jme3.renderer.Renderer;
|
||||
import com.jme3.scene.VertexBuffer.Format;
|
||||
import com.jme3.scene.VertexBuffer.Type;
|
||||
import com.jme3.scene.VertexBuffer.Usage;
|
||||
@ -49,6 +50,7 @@ import com.jme3.scene.mesh.*;
|
||||
import com.jme3.util.BufferUtils;
|
||||
import com.jme3.util.IntMap;
|
||||
import com.jme3.util.IntMap.Entry;
|
||||
import com.jme3.util.NativeObject;
|
||||
import com.jme3.util.SafeArrayList;
|
||||
import java.io.IOException;
|
||||
import java.nio.*;
|
||||
@ -71,7 +73,7 @@ import java.util.ArrayList;
|
||||
*
|
||||
* @author Kirill Vainer
|
||||
*/
|
||||
public class Mesh implements Savable, Cloneable {
|
||||
public class Mesh extends NativeObject implements Savable {
|
||||
|
||||
/**
|
||||
* The mode of the Mesh specifies both the type of primitive represented
|
||||
@ -127,19 +129,14 @@ public class Mesh implements Savable, Cloneable {
|
||||
*/
|
||||
TriangleFan(false),
|
||||
|
||||
/**
|
||||
* A combination of various triangle modes. It is best to avoid
|
||||
* using this mode as it may not be supported by all renderers.
|
||||
* The {@link Mesh#setModeStart(int[]) mode start points} and
|
||||
* {@link Mesh#setElementLengths(int[]) element lengths} must
|
||||
* be specified for this mode.
|
||||
*/
|
||||
Hybrid(false),
|
||||
Reserved(false),
|
||||
|
||||
/**
|
||||
* Used for Tesselation only. Requires to set the number of vertices
|
||||
* for each patch (default is 3 for triangle tesselation)
|
||||
*/
|
||||
Patch(true);
|
||||
|
||||
private boolean listMode = false;
|
||||
|
||||
private Mode(boolean listMode){
|
||||
@ -182,9 +179,6 @@ public class Mesh implements Savable, Cloneable {
|
||||
private int patchVertexCount=3; //only used for tesselation
|
||||
private int maxNumWeights = -1; // only if using skeletal animation
|
||||
|
||||
private int[] elementLengths;
|
||||
private int[] modeStart;
|
||||
|
||||
private Mode mode = Mode.Triangles;
|
||||
|
||||
/**
|
||||
@ -193,6 +187,10 @@ public class Mesh implements Savable, Cloneable {
|
||||
public Mesh(){
|
||||
}
|
||||
|
||||
protected Mesh(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a shallow clone of this Mesh. The {@link VertexBuffer vertex
|
||||
* buffers} are shared between this and the clone mesh, the rest
|
||||
@ -202,23 +200,12 @@ public class Mesh implements Savable, Cloneable {
|
||||
*/
|
||||
@Override
|
||||
public Mesh clone() {
|
||||
try {
|
||||
Mesh clone = (Mesh) super.clone();
|
||||
clone.meshBound = meshBound.clone();
|
||||
clone.collisionTree = collisionTree != null ? collisionTree : null;
|
||||
clone.buffers = buffers.clone();
|
||||
clone.buffersList = new SafeArrayList<VertexBuffer>(VertexBuffer.class,buffersList);
|
||||
clone.vertexArrayID = -1;
|
||||
if (elementLengths != null) {
|
||||
clone.elementLengths = elementLengths.clone();
|
||||
}
|
||||
if (modeStart != null) {
|
||||
clone.modeStart = modeStart.clone();
|
||||
}
|
||||
return clone;
|
||||
} catch (CloneNotSupportedException ex) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
Mesh clone = (Mesh) super.clone();
|
||||
clone.meshBound = meshBound.clone();
|
||||
clone.collisionTree = collisionTree != null ? collisionTree : null;
|
||||
clone.buffers = buffers.clone();
|
||||
clone.buffersList = new SafeArrayList<VertexBuffer>(VertexBuffer.class,buffersList);
|
||||
return clone;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -229,37 +216,30 @@ public class Mesh implements Savable, Cloneable {
|
||||
* @return a deep clone of this mesh.
|
||||
*/
|
||||
public Mesh deepClone(){
|
||||
try{
|
||||
Mesh clone = (Mesh) super.clone();
|
||||
clone.meshBound = meshBound != null ? meshBound.clone() : null;
|
||||
Mesh clone = (Mesh) super.clone();
|
||||
clone.meshBound = meshBound != null ? meshBound.clone() : null;
|
||||
|
||||
// TODO: Collision tree cloning
|
||||
//clone.collisionTree = collisionTree != null ? collisionTree : null;
|
||||
clone.collisionTree = null; // it will get re-generated in any case
|
||||
// TODO: Collision tree cloning
|
||||
//clone.collisionTree = collisionTree != null ? collisionTree : null;
|
||||
clone.collisionTree = null; // it will get re-generated in any case
|
||||
|
||||
clone.buffers = new IntMap<VertexBuffer>();
|
||||
clone.buffersList = new SafeArrayList<VertexBuffer>(VertexBuffer.class);
|
||||
for (VertexBuffer vb : buffersList.getArray()){
|
||||
VertexBuffer bufClone = vb.clone();
|
||||
clone.buffers.put(vb.getBufferType().ordinal(), bufClone);
|
||||
clone.buffersList.add(bufClone);
|
||||
}
|
||||
|
||||
clone.vertexArrayID = -1;
|
||||
clone.vertCount = vertCount;
|
||||
clone.elementCount = elementCount;
|
||||
clone.instanceCount = instanceCount;
|
||||
|
||||
// although this could change
|
||||
// if the bone weight/index buffers are modified
|
||||
clone.maxNumWeights = maxNumWeights;
|
||||
|
||||
clone.elementLengths = elementLengths != null ? elementLengths.clone() : null;
|
||||
clone.modeStart = modeStart != null ? modeStart.clone() : null;
|
||||
return clone;
|
||||
}catch (CloneNotSupportedException ex){
|
||||
throw new AssertionError();
|
||||
clone.buffers = new IntMap<VertexBuffer>();
|
||||
clone.buffersList = new SafeArrayList<VertexBuffer>(VertexBuffer.class);
|
||||
for (VertexBuffer vb : buffersList.getArray()){
|
||||
VertexBuffer bufClone = vb.clone();
|
||||
clone.buffers.put(vb.getBufferType().ordinal(), bufClone);
|
||||
clone.buffersList.add(bufClone);
|
||||
}
|
||||
|
||||
clone.vertCount = vertCount;
|
||||
clone.elementCount = elementCount;
|
||||
clone.instanceCount = instanceCount;
|
||||
|
||||
// although this could change
|
||||
// if the bone weight/index buffers are modified
|
||||
clone.maxNumWeights = maxNumWeights;
|
||||
|
||||
return clone;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -475,40 +455,6 @@ public class Mesh implements Savable, Cloneable {
|
||||
return lodLevels[lod];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the element lengths for {@link Mode#Hybrid} mesh mode.
|
||||
*
|
||||
* @return element lengths
|
||||
*/
|
||||
public int[] getElementLengths() {
|
||||
return elementLengths;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the element lengths for {@link Mode#Hybrid} mesh mode.
|
||||
*
|
||||
* @param elementLengths The element lengths to set
|
||||
*/
|
||||
public void setElementLengths(int[] elementLengths) {
|
||||
this.elementLengths = elementLengths;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the mode start indices for {@link Mode#Hybrid} mesh mode.
|
||||
*
|
||||
* @return mode start indices
|
||||
*/
|
||||
public int[] getModeStart() {
|
||||
return modeStart;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the mode start indices for {@link Mode#Hybrid} mesh mode.
|
||||
*/
|
||||
public void setModeStart(int[] modeStart) {
|
||||
this.modeStart = modeStart;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the mesh mode
|
||||
*
|
||||
@ -899,23 +845,6 @@ public class Mesh implements Savable, Cloneable {
|
||||
indices[2] = ib.get(vertIndex+2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the mesh's VAO ID. Internal use only.
|
||||
*/
|
||||
public int getId(){
|
||||
return vertexArrayID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the mesh's VAO ID. Internal use only.
|
||||
*/
|
||||
public void setId(int id){
|
||||
if (vertexArrayID != -1)
|
||||
throw new IllegalStateException("ID has already been set.");
|
||||
|
||||
vertexArrayID = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a collision tree for the mesh.
|
||||
* Called automatically by {@link #collideWith(com.jme3.collision.Collidable,
|
||||
@ -1109,20 +1038,17 @@ public class Mesh implements Savable, Cloneable {
|
||||
* @return A virtual or wrapped index buffer to read the data as a list
|
||||
*/
|
||||
public IndexBuffer getIndicesAsList(){
|
||||
if (mode == Mode.Hybrid)
|
||||
throw new UnsupportedOperationException("Hybrid mode not supported");
|
||||
|
||||
IndexBuffer ib = getIndexBuffer();
|
||||
if (ib != null){
|
||||
if (mode.isListMode()){
|
||||
if (ib != null) {
|
||||
if (mode.isListMode()) {
|
||||
// already in list mode
|
||||
return ib;
|
||||
}else{
|
||||
return ib;
|
||||
} else {
|
||||
// not in list mode but it does have an index buffer
|
||||
// wrap it so the data is converted to list format
|
||||
return new WrappedIndexBuffer(this);
|
||||
}
|
||||
}else{
|
||||
} else {
|
||||
// return a virtual index buffer that will supply
|
||||
// "fake" indices in list format
|
||||
return new VirtualIndexBuffer(vertCount, mode);
|
||||
@ -1385,16 +1311,30 @@ public class Mesh implements Savable, Cloneable {
|
||||
return patchVertexCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetObject() {
|
||||
id = -1;
|
||||
setUpdateNeeded();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteObject(Object rendererObject) {
|
||||
((Renderer)rendererObject).deleteMesh(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NativeObject createDestructableClone() {
|
||||
return new Mesh(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getUniqueId() {
|
||||
return ((long)OBJTYPE_MESH << 32) | ((long)id);
|
||||
}
|
||||
|
||||
public void write(JmeExporter ex) throws IOException {
|
||||
OutputCapsule out = ex.getCapsule(this);
|
||||
|
||||
// HashMap<String, VertexBuffer> map = new HashMap<String, VertexBuffer>();
|
||||
// for (Entry<VertexBuffer> buf : buffers){
|
||||
// if (buf.getValue() != null)
|
||||
// map.put(buf.getKey()+"a", buf.getValue());
|
||||
// }
|
||||
// out.writeStringSavableMap(map, "buffers", null);
|
||||
|
||||
out.write(meshBound, "modelBound", null);
|
||||
out.write(vertCount, "vertCount", -1);
|
||||
out.write(elementCount, "elementCount", -1);
|
||||
@ -1402,8 +1342,6 @@ public class Mesh implements Savable, Cloneable {
|
||||
out.write(maxNumWeights, "max_num_weights", -1);
|
||||
out.write(mode, "mode", Mode.Triangles);
|
||||
out.write(collisionTree, "collisionTree", null);
|
||||
out.write(elementLengths, "elementLengths", null);
|
||||
out.write(modeStart, "modeStart", null);
|
||||
out.write(pointSize, "pointSize", 1f);
|
||||
|
||||
//Removing HW skinning buffers to not save them
|
||||
@ -1439,21 +1377,16 @@ public class Mesh implements Savable, Cloneable {
|
||||
instanceCount = in.readInt("instanceCount", -1);
|
||||
maxNumWeights = in.readInt("max_num_weights", -1);
|
||||
mode = in.readEnum("mode", Mode.class, Mode.Triangles);
|
||||
elementLengths = in.readIntArray("elementLengths", null);
|
||||
modeStart = in.readIntArray("modeStart", null);
|
||||
collisionTree = (BIHTree) in.readSavable("collisionTree", null);
|
||||
elementLengths = in.readIntArray("elementLengths", null);
|
||||
modeStart = in.readIntArray("modeStart", null);
|
||||
pointSize = in.readFloat("pointSize", 1f);
|
||||
|
||||
// in.readStringSavableMap("buffers", null);
|
||||
buffers = (IntMap<VertexBuffer>) in.readIntSavableMap("buffers", null);
|
||||
for (Entry<VertexBuffer> entry : buffers){
|
||||
buffersList.add(entry.getValue());
|
||||
}
|
||||
|
||||
//creating hw animation buffers empty so that they are put in the cache
|
||||
if(isAnimated()){
|
||||
if (isAnimated()) {
|
||||
VertexBuffer hwBoneIndex = new VertexBuffer(Type.HWBoneIndex);
|
||||
hwBoneIndex.setUsage(Usage.CpuOnly);
|
||||
setBuffer(hwBoneIndex);
|
||||
|
@ -524,6 +524,17 @@ public class VertexBuffer extends NativeObject implements Savable, Cloneable {
|
||||
this.usage = usage;
|
||||
}
|
||||
|
||||
/**
|
||||
* The size of an element in bytes.
|
||||
*
|
||||
* The number of components multiplied by the size of a component.
|
||||
*
|
||||
* @return size of an element in bytes.
|
||||
*/
|
||||
public int getElementSize() {
|
||||
return componentsLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param normalized Set to true if integer components should be converted
|
||||
* from their maximal range into the range 0.0 - 1.0 when converted to
|
||||
@ -976,6 +987,10 @@ public class VertexBuffer extends NativeObject implements Savable, Cloneable {
|
||||
* of the parameters. The buffer will be of the type specified by
|
||||
* {@link Format format} and would be able to contain the given number
|
||||
* of elements with the given number of components in each element.
|
||||
* @param format The format of the buffer to create
|
||||
* @param components The number of components (aka dimensions)
|
||||
* @param numElements Capacity of the buffer in number of elements.
|
||||
* @return A buffer satisfying the given requirements.
|
||||
*/
|
||||
public static Buffer createBuffer(Format format, int components, int numElements){
|
||||
if (components < 1 || components > 4)
|
||||
@ -1010,7 +1025,7 @@ public class VertexBuffer extends NativeObject implements Savable, Cloneable {
|
||||
* @return Deep clone of this buffer
|
||||
*/
|
||||
@Override
|
||||
public VertexBuffer clone(){
|
||||
public VertexBuffer clone() {
|
||||
// NOTE: Superclass GLObject automatically creates shallow clone
|
||||
// e.g re-use ID.
|
||||
VertexBuffer vb = (VertexBuffer) super.clone();
|
||||
|
@ -274,6 +274,16 @@ public final class Shader extends NativeObject {
|
||||
return attrib;
|
||||
}
|
||||
|
||||
public boolean isAttributeDefined(VertexBuffer.Type attribType) {
|
||||
int ordinal = attribType.ordinal();
|
||||
Attribute attrib = attribs.get(ordinal);
|
||||
if (attrib == null){
|
||||
return false;
|
||||
} else {
|
||||
return attrib.location != -1 && attrib.location != 2;
|
||||
}
|
||||
}
|
||||
|
||||
public ListMap<String, Uniform> getUniformMap(){
|
||||
return uniforms;
|
||||
}
|
||||
|
@ -164,4 +164,7 @@ public class NullRenderer implements Renderer {
|
||||
public void readFrameBufferWithFormat(FrameBuffer fb, ByteBuffer byteBuf, Image.Format format) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteMesh(Mesh mesh) {
|
||||
}
|
||||
}
|
||||
|
@ -52,7 +52,8 @@ public abstract class NativeObject implements Cloneable {
|
||||
OBJTYPE_SHADERSOURCE = 5,
|
||||
OBJTYPE_AUDIOBUFFER = 6,
|
||||
OBJTYPE_AUDIOSTREAM = 7,
|
||||
OBJTYPE_FILTER = 8;
|
||||
OBJTYPE_FILTER = 8,
|
||||
OBJTYPE_MESH = 9;
|
||||
|
||||
/**
|
||||
* The object manager to which this NativeObject is registered to.
|
||||
|
Loading…
x
Reference in New Issue
Block a user