diff --git a/SPD-classes/src/main/java/com/watabou/glwrap/Attribute.java b/SPD-classes/src/main/java/com/watabou/glwrap/Attribute.java
index ea8ab4532..9b495b25a 100644
--- a/SPD-classes/src/main/java/com/watabou/glwrap/Attribute.java
+++ b/SPD-classes/src/main/java/com/watabou/glwrap/Attribute.java
@@ -48,4 +48,8 @@ public class Attribute {
public void vertexPointer( int size, int stride, FloatBuffer ptr ) {
GLES20.glVertexAttribPointer( location, size, GLES20.GL_FLOAT, false, stride * Float.SIZE / 8, ptr );
}
+
+ public void vertexBuffer( int size, int stride, int offset) {
+ GLES20.glVertexAttribPointer( location, size, GLES20.GL_FLOAT, false, stride * Float.SIZE / 8, offset * Float.SIZE / 8 );
+ }
}
diff --git a/SPD-classes/src/main/java/com/watabou/glwrap/Vertexbuffer.java b/SPD-classes/src/main/java/com/watabou/glwrap/Vertexbuffer.java
new file mode 100644
index 000000000..de2de3815
--- /dev/null
+++ b/SPD-classes/src/main/java/com/watabou/glwrap/Vertexbuffer.java
@@ -0,0 +1,85 @@
+/*
+ * Pixel Dungeon
+ * Copyright (C) 2012-2015 Oleg Dolya
+ *
+ * Shattered Pixel Dungeon
+ * Copyright (C) 2014-2016 Evan Debenham
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see
+ */
+
+package com.watabou.glwrap;
+
+import android.opengl.GLES20;
+
+import java.nio.FloatBuffer;
+import java.util.ArrayList;
+
+public class Vertexbuffer {
+
+ private int id;
+ private FloatBuffer vertices;
+ private boolean needsUpdate;
+
+ private static ArrayList buffers = new ArrayList<>();
+
+ public Vertexbuffer( FloatBuffer vertices ) {
+ int[] ptr = new int[1];
+ GLES20.glGenBuffers( 1, ptr, 0 );
+ id = ptr[0];
+
+ this.vertices = vertices;
+ buffers.add(this);
+
+ //forces an update so the GL data isn't blank
+ needsUpdate = true;
+ updateGLData();
+ }
+
+ public void updateVertices( FloatBuffer vertices ){
+ this.vertices = vertices;
+ needsUpdate = true;
+ }
+
+ public void updateGLData(){
+ if (!needsUpdate) return;
+
+ vertices.position(0);
+ bind();
+ GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, (vertices.limit()*4), vertices, GLES20.GL_DYNAMIC_DRAW);
+ release();
+ needsUpdate = false;
+ }
+
+ public void bind(){
+ GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, id);
+ }
+
+ public void release(){
+ GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
+ }
+
+ public void delete(){
+ GLES20.glDeleteBuffers(1, new int[]{id}, 0);
+ buffers.remove(this);
+ }
+
+ public static void refreshAllBuffers(){
+ for (Vertexbuffer buf : buffers) {
+ buf.needsUpdate = true;
+ buf.updateGLData();
+ }
+ }
+
+}
diff --git a/SPD-classes/src/main/java/com/watabou/noosa/BitmapText.java b/SPD-classes/src/main/java/com/watabou/noosa/BitmapText.java
index f1e5a7e38..fe9b71108 100644
--- a/SPD-classes/src/main/java/com/watabou/noosa/BitmapText.java
+++ b/SPD-classes/src/main/java/com/watabou/noosa/BitmapText.java
@@ -27,6 +27,7 @@ import com.watabou.gltextures.SmartTexture;
import com.watabou.gltextures.TextureCache;
import com.watabou.glwrap.Matrix;
import com.watabou.glwrap.Quad;
+import com.watabou.glwrap.Vertexbuffer;
import android.graphics.Bitmap;
import android.graphics.RectF;
@@ -38,6 +39,7 @@ public class BitmapText extends Visual {
protected float[] vertices = new float[16];
protected FloatBuffer quads;
+ protected Vertexbuffer buffer;
public int realLength;
@@ -58,15 +60,6 @@ public class BitmapText extends Visual {
this.font = font;
}
- @Override
- public void destroy() {
- text = null;
- font = null;
- vertices = null;
- quads = null;
- super.destroy();
- }
-
@Override
protected void updateMatrix() {
// "origin" field is ignored
@@ -80,25 +73,37 @@ public class BitmapText extends Visual {
public void draw() {
super.draw();
+
+ if (dirty) {
+ updateVertices();
+ quads.limit(quads.position());
+ if (buffer == null)
+ buffer = new Vertexbuffer(quads);
+ else
+ buffer.updateVertices(quads);
+ }
NoosaScript script = NoosaScript.get();
font.texture.bind();
- if (dirty) {
- updateVertices();
- }
-
script.camera( camera() );
script.uModel.valueM4( matrix );
script.lighting(
rm, gm, bm, am,
ra, ga, ba, aa );
- script.drawQuadSet( quads, realLength );
+ script.drawQuadSet( buffer, realLength, 0 );
}
-
+
+ @Override
+ public void destroy() {
+ super.destroy();
+ if (buffer != null)
+ buffer.delete();
+ }
+
protected void updateVertices() {
width = 0;
diff --git a/SPD-classes/src/main/java/com/watabou/noosa/Game.java b/SPD-classes/src/main/java/com/watabou/noosa/Game.java
index f9f4298c3..94d964e8e 100644
--- a/SPD-classes/src/main/java/com/watabou/noosa/Game.java
+++ b/SPD-classes/src/main/java/com/watabou/noosa/Game.java
@@ -28,6 +28,7 @@ import javax.microedition.khronos.opengles.GL10;
import com.watabou.glscripts.Script;
import com.watabou.gltextures.TextureCache;
+import com.watabou.glwrap.Vertexbuffer;
import com.watabou.input.Keys;
import com.watabou.input.Touchscreen;
import com.watabou.noosa.audio.Music;
@@ -242,9 +243,11 @@ public class Game extends Activity implements GLSurfaceView.Renderer, View.OnTou
GLES20.glBlendFunc( GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA );
GLES20.glEnable( GL10.GL_SCISSOR_TEST );
-
+
+ //refreshes texture and vertex data stored on the gpu
TextureCache.reload();
RenderedText.reloadCache();
+ Vertexbuffer.refreshAllBuffers();
}
protected void destroyGame() {
diff --git a/SPD-classes/src/main/java/com/watabou/noosa/Image.java b/SPD-classes/src/main/java/com/watabou/noosa/Image.java
index 356449687..46994522f 100644
--- a/SPD-classes/src/main/java/com/watabou/noosa/Image.java
+++ b/SPD-classes/src/main/java/com/watabou/noosa/Image.java
@@ -28,6 +28,7 @@ import android.graphics.RectF;
import com.watabou.gltextures.TextureCache;
import com.watabou.gltextures.SmartTexture;
import com.watabou.glwrap.Quad;
+import com.watabou.glwrap.Vertexbuffer;
public class Image extends Visual {
@@ -39,6 +40,7 @@ public class Image extends Visual {
protected float[] vertices;
protected FloatBuffer verticesBuffer;
+ protected Vertexbuffer buffer;
protected boolean dirty;
@@ -149,6 +151,16 @@ public class Image extends Visual {
super.draw();
+ if (dirty) {
+ verticesBuffer.position( 0 );
+ verticesBuffer.put( vertices );
+ if (buffer == null)
+ buffer = new Vertexbuffer( verticesBuffer );
+ else
+ buffer.updateVertices( verticesBuffer );
+ dirty = false;
+ }
+
NoosaScript script = NoosaScript.get();
texture.bind();
@@ -159,13 +171,15 @@ public class Image extends Visual {
script.lighting(
rm, gm, bm, am,
ra, ga, ba, aa );
-
- if (dirty) {
- verticesBuffer.position( 0 );
- verticesBuffer.put( vertices );
- dirty = false;
- }
- script.drawQuad( verticesBuffer );
+
+ script.drawQuad( buffer );
}
+
+ @Override
+ public void destroy() {
+ super.destroy();
+ if (buffer != null)
+ buffer.delete();
+ }
}
diff --git a/SPD-classes/src/main/java/com/watabou/noosa/NinePatch.java b/SPD-classes/src/main/java/com/watabou/noosa/NinePatch.java
index aaa369c98..26a060a00 100644
--- a/SPD-classes/src/main/java/com/watabou/noosa/NinePatch.java
+++ b/SPD-classes/src/main/java/com/watabou/noosa/NinePatch.java
@@ -26,6 +26,7 @@ import java.nio.FloatBuffer;
import com.watabou.gltextures.SmartTexture;
import com.watabou.gltextures.TextureCache;
import com.watabou.glwrap.Quad;
+import com.watabou.glwrap.Vertexbuffer;
import android.graphics.RectF;
@@ -34,7 +35,8 @@ public class NinePatch extends Visual {
public SmartTexture texture;
protected float[] vertices;
- protected FloatBuffer verticesBuffer;
+ protected FloatBuffer quads;
+ protected Vertexbuffer buffer;
protected RectF outterF;
protected RectF innerF;
@@ -49,6 +51,8 @@ public class NinePatch extends Visual {
protected boolean flipHorizontal;
protected boolean flipVertical;
+
+ protected boolean dirty;
public NinePatch( Object tx, int margin ) {
this( tx, margin, margin, margin, margin );
@@ -73,7 +77,7 @@ public class NinePatch extends Visual {
nHeight = height = h;
vertices = new float[16];
- verticesBuffer = Quad.createSet( 9 );
+ quads = Quad.createSet( 9 );
marginLeft = left;
marginRight = right;
@@ -88,7 +92,7 @@ public class NinePatch extends Visual {
protected void updateVertices() {
- verticesBuffer.position( 0 );
+ quads.position( 0 );
float right = width - marginRight;
float bottom = height - marginBottom;
@@ -105,33 +109,35 @@ public class NinePatch extends Visual {
Quad.fill( vertices,
0, marginLeft, 0, marginTop, outleft, inleft, outtop, intop );
- verticesBuffer.put( vertices );
+ quads.put( vertices );
Quad.fill( vertices,
marginLeft, right, 0, marginTop, inleft, inright, outtop, intop );
- verticesBuffer.put( vertices );
+ quads.put( vertices );
Quad.fill( vertices,
right, width, 0, marginTop, inright, outright, outtop, intop );
- verticesBuffer.put( vertices );
+ quads.put( vertices );
Quad.fill( vertices,
0, marginLeft, marginTop, bottom, outleft, inleft, intop, inbottom );
- verticesBuffer.put( vertices );
+ quads.put( vertices );
Quad.fill( vertices,
marginLeft, right, marginTop, bottom, inleft, inright, intop, inbottom );
- verticesBuffer.put( vertices );
+ quads.put( vertices );
Quad.fill( vertices,
right, width, marginTop, bottom, inright, outright, intop, inbottom );
- verticesBuffer.put( vertices );
+ quads.put( vertices );
Quad.fill( vertices,
0, marginLeft, bottom, height, outleft, inleft, inbottom, outbottom );
- verticesBuffer.put( vertices );
+ quads.put( vertices );
Quad.fill( vertices,
marginLeft, right, bottom, height, inleft, inright, inbottom, outbottom );
- verticesBuffer.put( vertices );
+ quads.put( vertices );
Quad.fill( vertices,
right, width, bottom, height, inright, outright, inbottom, outbottom );
- verticesBuffer.put( vertices );
+ quads.put( vertices );
+
+ dirty = true;
}
public int marginLeft() {
@@ -195,6 +201,14 @@ public class NinePatch extends Visual {
super.draw();
+ if (dirty){
+ if (buffer == null)
+ buffer = new Vertexbuffer(quads);
+ else
+ buffer.updateVertices(quads);
+ dirty = false;
+ }
+
NoosaScript script = NoosaScript.get();
texture.bind();
@@ -206,7 +220,14 @@ public class NinePatch extends Visual {
rm, gm, bm, am,
ra, ga, ba, aa );
- script.drawQuadSet( verticesBuffer, 9 );
+ script.drawQuadSet( buffer, 9, 0 );
}
+
+ @Override
+ public void destroy() {
+ super.destroy();
+ if (buffer != null)
+ buffer.delete();
+ }
}
diff --git a/SPD-classes/src/main/java/com/watabou/noosa/NoosaScript.java b/SPD-classes/src/main/java/com/watabou/noosa/NoosaScript.java
index 36392015b..a59e5a558 100644
--- a/SPD-classes/src/main/java/com/watabou/noosa/NoosaScript.java
+++ b/SPD-classes/src/main/java/com/watabou/noosa/NoosaScript.java
@@ -30,6 +30,7 @@ import com.watabou.glscripts.Script;
import com.watabou.glwrap.Attribute;
import com.watabou.glwrap.Quad;
import com.watabou.glwrap.Uniform;
+import com.watabou.glwrap.Vertexbuffer;
public class NoosaScript extends Script {
@@ -96,6 +97,20 @@ public class NoosaScript extends Script {
GLES20.glDrawElements( GLES20.GL_TRIANGLES, Quad.SIZE, GLES20.GL_UNSIGNED_SHORT, 0 );
}
+
+ public void drawQuad( Vertexbuffer buffer ) {
+
+ buffer.updateGLData();
+
+ buffer.bind();
+
+ aXY.vertexBuffer( 2, 4, 0 );
+ aUV.vertexBuffer( 2, 4, 2 );
+
+ buffer.release();
+
+ GLES20.glDrawElements( GLES20.GL_TRIANGLES, Quad.SIZE, GLES20.GL_UNSIGNED_SHORT, 0 );
+ }
public void drawQuadSet( FloatBuffer vertices, int size ) {
@@ -112,6 +127,24 @@ public class NoosaScript extends Script {
GLES20.glDrawElements( GLES20.GL_TRIANGLES, Quad.SIZE * size, GLES20.GL_UNSIGNED_SHORT, 0 );
}
+
+ public void drawQuadSet( Vertexbuffer buffer, int length, int offset ){
+
+ if (length == 0) {
+ return;
+ }
+
+ buffer.updateGLData();
+
+ buffer.bind();
+
+ aXY.vertexBuffer( 2, 4, 0 );
+ aUV.vertexBuffer( 2, 4, 2 );
+
+ buffer.release();
+
+ GLES20.glDrawElements( GLES20.GL_TRIANGLES, Quad.SIZE * length, GLES20.GL_UNSIGNED_SHORT, Quad.SIZE * offset );
+ }
public void lighting( float rm, float gm, float bm, float am, float ra, float ga, float ba, float aa ) {
uColorM.value4f( rm, gm, bm, am );
diff --git a/SPD-classes/src/main/java/com/watabou/noosa/Tilemap.java b/SPD-classes/src/main/java/com/watabou/noosa/Tilemap.java
index 029b0bcff..72acf3bcb 100644
--- a/SPD-classes/src/main/java/com/watabou/noosa/Tilemap.java
+++ b/SPD-classes/src/main/java/com/watabou/noosa/Tilemap.java
@@ -26,6 +26,7 @@ import java.nio.FloatBuffer;
import com.watabou.gltextures.SmartTexture;
import com.watabou.gltextures.TextureCache;
import com.watabou.glwrap.Quad;
+import com.watabou.glwrap.Vertexbuffer;
import com.watabou.utils.Rect;
import android.graphics.RectF;
@@ -47,6 +48,7 @@ public class Tilemap extends Visual {
protected short[] bufferPositions;
protected short bufferLength;
protected FloatBuffer quads;
+ protected Vertexbuffer buffer;
public Rect updated;
@@ -96,7 +98,6 @@ public class Tilemap extends Visual {
float x2 = x1 + cellW;
int pos = i * mapWidth + updated.left;
- quads.position( 16 * pos );
for (int j=updated.left; j < updated.right; j++) {
@@ -155,6 +156,15 @@ public class Tilemap extends Visual {
super.draw();
+ if (!updated.isEmpty()) {
+ updateVertices();
+ quads.limit(bufferLength*16);
+ if (buffer == null)
+ buffer = new Vertexbuffer(quads);
+ else
+ buffer.updateVertices(quads);
+ }
+
NoosaScript script = NoosaScript.get();
texture.bind();
@@ -164,17 +174,18 @@ public class Tilemap extends Visual {
rm, gm, bm, am,
ra, ga, ba, aa );
- if (!updated.isEmpty()) {
- quads.limit(quads.capacity());
- updateVertices();
- quads.limit(bufferLength);
- }
-
script.camera( camera );
- script.drawQuadSet( quads, bufferLength );
+ script.drawQuadSet( buffer, bufferLength, 0 );
}
+ @Override
+ public void destroy() {
+ super.destroy();
+ if (buffer != null)
+ buffer.delete();
+ }
+
protected boolean needsRender(int pos){
return true;
}