implemented VertexAttribute class

This commit is contained in:
codeanticode
2015-03-17 15:39:20 -04:00
parent d1056eaa32
commit c8034a37d8
@@ -95,6 +95,10 @@ public class PGraphicsOpenGL extends PGraphics {
protected boolean pointBuffersCreated = false;
protected int pointBuffersContext;
// Generic vertex attributes
protected HashMap<String, VertexAttribute> attribs;
static protected final int INIT_VERTEX_BUFFER_SIZE = 256;
static protected final int INIT_INDEX_BUFFER_SIZE = 512;
@@ -530,6 +534,8 @@ public class PGraphicsOpenGL extends PGraphics {
viewport = PGL.allocateIntBuffer(4);
attribs = new HashMap<String, VertexAttribute >();
inGeo = newInGeometry(this, IMMEDIATE);
tessGeo = newTessGeometry(this, IMMEDIATE);
texCache = newTexCache(this);
@@ -1292,6 +1298,16 @@ public class PGraphicsOpenGL extends PGraphics {
polyBuffersCreated = true;
}
boolean created = false;
for (String name: attribs.keySet()) {
VertexAttribute attrib = attribs.get(name);
if (!attrib.bufferCreated() || polyBuffersContextIsOutdated()) {
attrib.createBuffer(pgl);
created = true;
}
}
if (created) pgl.bindBuffer(PGL.ARRAY_BUFFER, 0);
}
@@ -1334,6 +1350,7 @@ public class PGraphicsOpenGL extends PGraphics {
pgl.bufferData(PGL.ARRAY_BUFFER, sizef,
tessGeo.polyShininessBuffer, PGL.STATIC_DRAW);
}
if (lit || needNormals) {
tessGeo.updatePolyNormalsBuffer();
pgl.bindBuffer(PGL.ARRAY_BUFFER, glPolyNormal);
@@ -1348,6 +1365,14 @@ public class PGraphicsOpenGL extends PGraphics {
tessGeo.polyTexCoordsBuffer, PGL.STATIC_DRAW);
}
for (String name: attribs.keySet()) {
VertexAttribute attrib = attribs.get(name);
tessGeo.updateAttribBuffer(name);
pgl.bindBuffer(PGL.ARRAY_BUFFER, attrib.glName);
pgl.bufferData(PGL.ARRAY_BUFFER, attrib.sizeInBytes(size),
tessGeo.attribBuffers.get(name), PGL.STATIC_DRAW);
}
tessGeo.updatePolyIndicesBuffer();
pgl.bindBuffer(PGL.ELEMENT_ARRAY_BUFFER, glPolyIndex);
pgl.bufferData(PGL.ELEMENT_ARRAY_BUFFER,
@@ -1408,6 +1433,14 @@ public class PGraphicsOpenGL extends PGraphics {
glPolyShininess = 0;
}
for (String name: attribs.keySet()) {
VertexAttribute attrib = attribs.get(name);
if (attrib.glName != 0) {
PGraphicsOpenGL.finalizeVertexBufferObject(attrib.glName, polyBuffersContext);
attrib.glName = 0;
}
}
if (glPolyIndex != 0) {
PGraphicsOpenGL.finalizeVertexBufferObject(glPolyIndex, polyBuffersContext);
glPolyIndex = 0;
@@ -2236,16 +2269,40 @@ public class PGraphicsOpenGL extends PGraphics {
@Override
public void attrib(String name, float... values) {
VertexAttribute attrib = attribImpl(name, PGL.FLOAT, values.length);
if (attrib != null) attrib.set(values);
}
@Override
public void attrib(String name, int... values) {
VertexAttribute attrib = attribImpl(name, PGL.INT, values.length);
if (attrib != null) attrib.set(values);
}
@Override
public void attrib(String name, boolean... values) {
VertexAttribute attrib = attribImpl(name, PGL.BOOL, values.length);
if (attrib != null) attrib.set(values);
}
protected VertexAttribute attribImpl(String name, int type, int size) {
if (4 < size) {
PGraphics.showWarning("Vertex attributes cannot have more than 4 values");
return null;
}
VertexAttribute attrib = attribs.get(name);
if (attrib == null) {
attrib = new VertexAttribute(name, PGL.FLOAT, size);
attribs.put(name, attrib);
}
if (attrib.size != size) {
PGraphics.showWarning("New value for vertex attribute has wrong number of values");
return null;
}
return attrib;
}
@@ -2528,6 +2585,14 @@ public class PGraphicsOpenGL extends PGraphics {
shader.setTexture(tex);
}
for (String name: attribs.keySet()) {
VertexAttribute attrib = attribs.get(name);
attrib.updateLoc(shader);
shader.setAttributeVBO(attrib.glLoc, attrib.glName,
attrib.size, attrib.type,
false, 0, attrib.sizeInBytes(voffset));
}
shader.draw(glPolyIndex, icount, ioffset);
}
@@ -6928,6 +6993,90 @@ public class PGraphicsOpenGL extends PGraphics {
return newSize;
}
//////////////////////////////////////////////////////////////
// Generic vertex attributes.
static protected class VertexAttribute {
static final int POSITIONAL = 0;
static final int NORMAL = 1;
static final int OTHER = 2;
String name;
int kind; // POSITIONAL, NORMAL, OTHER
int type; // GL_INT, GL_FLOAT, GL_BOOL
int size; // number of elements (1, 2, 3, or 4)
int elementSize;
int glName;
int glLoc;
float[] fvalues;
int[] ivalues;
boolean[] bvalues;
VertexAttribute(String name, int type, int size) {
this.name = name;
this.type = type;
this.size = size;
if (name.indexOf("pos") == 0) {
kind = POSITIONAL;
} else if (name.indexOf("norm") == 0) {
kind = NORMAL;
} else {
kind = OTHER;
}
if (type == PGL.FLOAT) {
elementSize = PGL.SIZEOF_FLOAT;
fvalues = new float[size];
} else if (type == PGL.INT) {
elementSize = PGL.SIZEOF_INT;
ivalues = new int[size];
} else if (type == PGL.BOOL) {
elementSize = PGL.SIZEOF_INT;
bvalues = new boolean[size];
}
glName = 0;
glLoc = -1;
}
boolean bufferCreated() {
return 0 < glName;
}
void createBuffer(PGL pgl) {
int ctx = pgl.getCurrentContext();
glName = createVertexBufferObject(ctx, pgl);
pgl.bindBuffer(PGL.ARRAY_BUFFER, glName);
pgl.bufferData(PGL.ARRAY_BUFFER, size * INIT_VERTEX_BUFFER_SIZE * elementSize,
null, PGL.STATIC_DRAW);
}
void updateLoc(PShader shader) {
if (glLoc == -1) glLoc = shader.getAttributeLoc(name);
}
int sizeInBytes(int length) {
return length * size * elementSize;
}
void set(float[] values) {
PApplet.arrayCopy(values, 0, fvalues, 0, size);
}
void set(int[] values) {
PApplet.arrayCopy(values, 0, ivalues, 0, size);
}
void set(boolean[] values) {
PApplet.arrayCopy(values, 0, bvalues, 0, size);
}
}
//////////////////////////////////////////////////////////////
// Input (raw) and Tessellated geometry, tessellator.
@@ -7202,6 +7351,12 @@ public class PGraphicsOpenGL extends PGraphics {
int[] emissive;
float[] shininess;
// Generic attributes
HashMap<String, int[]> iattribs;
HashMap<String, float[]> fattribs;
HashMap<String, boolean[]> battribs;
// Internally used by the addVertex() methods.
int fillColor;
int strokeColor;
@@ -7244,6 +7399,9 @@ public class PGraphicsOpenGL extends PGraphics {
emissive = new int[PGL.DEFAULT_IN_VERTICES];
shininess = new float[PGL.DEFAULT_IN_VERTICES];
edges = new int[PGL.DEFAULT_IN_EDGES][3];
iattribs = new HashMap<String, int[]>();
fattribs = new HashMap<String, float[]>();
battribs = new HashMap<String, boolean[]>();
clear();
}
@@ -7262,6 +7420,7 @@ public class PGraphicsOpenGL extends PGraphics {
expandSpecular(newSize);
expandEmissive(newSize);
expandShininess(newSize);
expandAttribs(newSize);
}
}
@@ -7442,6 +7601,21 @@ public class PGraphicsOpenGL extends PGraphics {
shininess = temp;
}
void expandAttribs(int n) {
for (String name: iattribs.keySet()) {
expandIntAttrib(name, n);
}
}
void expandIntAttrib(String name, int n) {
int[] attrib = iattribs.get(name);
int temp[] = new int[n];
PApplet.arrayCopy(attrib, 0, temp, 0, vertexCount);
iattribs.put(name, temp);
}
void expandCodes(int n) {
int temp[] = new int[n];
PApplet.arrayCopy(codes, 0, temp, 0, codeCount);
@@ -7470,6 +7644,7 @@ public class PGraphicsOpenGL extends PGraphics {
trimSpecular();
trimEmissive();
trimShininess();
trimAttribs();
}
if (0 < codeCount && codeCount < codes.length) {
@@ -7553,6 +7728,10 @@ public class PGraphicsOpenGL extends PGraphics {
edges = temp;
}
void trimAttribs() {
}
// -----------------------------------------------------------------
//
// Vertices
@@ -8519,6 +8698,9 @@ public class PGraphicsOpenGL extends PGraphics {
IntBuffer polyEmissiveBuffer;
FloatBuffer polyShininessBuffer;
// Generic attributes
HashMap<String, Buffer> attribBuffers;
int polyIndexCount;
int firstPolyIndex;
int lastPolyIndex;
@@ -8926,6 +9108,14 @@ public class PGraphicsOpenGL extends PGraphics {
PGL.updateFloatBuffer(polyShininessBuffer, polyShininess, offset, size);
}
protected void updateAttribBuffer(String name) {
updateAttribBuffer(name, 0, polyVertexCount);
}
protected void updateAttribBuffer(String name, int offset, int size) {
// TODO
}
protected void updatePolyIndicesBuffer() {
updatePolyIndicesBuffer(0, polyIndexCount);
}