Przeglądaj źródła

GLRenderer: remaining portion of VAO support

Kirill Vainer 10 lat temu
rodzic
commit
e8f344a0db

+ 5 - 0
jme3-core/src/main/java/com/jme3/font/BitmapTextPage.java

@@ -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);

+ 6 - 0
jme3-core/src/main/java/com/jme3/renderer/Renderer.java

@@ -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.

+ 66 - 133
jme3-core/src/main/java/com/jme3/scene/Mesh.java

@@ -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;
-
-            // 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();
+        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
+
+        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);

+ 16 - 1
jme3-core/src/main/java/com/jme3/scene/VertexBuffer.java

@@ -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();

+ 10 - 0
jme3-core/src/main/java/com/jme3/shader/Shader.java

@@ -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;
     }

+ 3 - 0
jme3-core/src/main/java/com/jme3/system/NullRenderer.java

@@ -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) {
+    }
 }

+ 2 - 1
jme3-core/src/main/java/com/jme3/util/NativeObject.java

@@ -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.