immediate mode fixes

This commit is contained in:
codeanticode
2011-11-28 21:00:38 +00:00
parent b8d49de883
commit 58a80d9e12
2 changed files with 154 additions and 136 deletions
@@ -227,9 +227,14 @@ public class PGraphicsOpenGL extends PGraphics {
protected boolean matricesAllocated = false;
static protected boolean usingGLMatrixStack;
static protected GLMatrixStack modelviewStack;
static protected GLMatrixStack projectionStack;
/** Camera and model transformation (translate/rotate/scale) matrix stack **/
static protected GLMatrixStack modelviewStack;
/** Projection (ortho/perspective) matrix stack **/
static protected GLMatrixStack projectionStack;
/** Model transformation (translate/rotate/scale) matrix stack **/
static protected GLMatrixStack transformStack;
// ........................................................
@@ -423,7 +428,8 @@ public class PGraphicsOpenGL extends PGraphics {
protected float[] currentNormal = { 0, 0, 1 };
protected float[] currentTexcoord = { 0, 0 };
protected float[] currentStroke = { 0, 0, 0, 1, 1 };
protected boolean breakShape;
public static final int DEFAULT_TESS_VERTICES = 512;
public static final int DEFAULT_TESS_INDICES = 1024;
@@ -1086,6 +1092,9 @@ public class PGraphicsOpenGL extends PGraphics {
ogl.disableLights();
}
in.reset();
tess.reset();
// Each frame starts with textures disabled.
noTexture();
@@ -1187,7 +1196,7 @@ public class PGraphicsOpenGL extends PGraphics {
public void endDraw() {
report("top endDraw()");
//flushTess();
flushTess();
if (!drawing) {
System.err.println("P3D: Cannot call endDraw() before beginDraw().");
@@ -1448,14 +1457,15 @@ public class PGraphicsOpenGL extends PGraphics {
setFramebuffer(screenFramebuffer);
}
if (usingGLMatrixStack) {
if (modelviewStack == null) {
modelviewStack = new GLMatrixStack();
}
if (projectionStack == null) {
projectionStack = new GLMatrixStack();
}
}
if (modelviewStack == null) {
modelviewStack = new GLMatrixStack();
}
if (projectionStack == null) {
projectionStack = new GLMatrixStack();
}
if (transformStack == null) {
transformStack = new GLMatrixStack();
}
// easiest for beginners
textureMode(IMAGE);
@@ -1529,6 +1539,10 @@ public class PGraphicsOpenGL extends PGraphics {
in.reset();
}
public void breakShape() {
breakShape = true;
}
public void vertex(float x, float y) {
vertex(x, y, 0, 0, 0);
}
@@ -1542,14 +1556,14 @@ public class PGraphicsOpenGL extends PGraphics {
}
public void vertex(float x, float y, float z, float u, float v) {
float[] mm = modelviewStack.current;
float[] mm = transformStack.current;
currentVertex[0] = x;
currentVertex[1] = y;
currentVertex[2] = z;
// currentVertex[0] = x * mm[0] + y * mm[4] + z * mm[8] + mm[12];
// currentVertex[1] = x * mm[1] + y * mm[5] + z * mm[9] + mm[13];
// currentVertex[2] = x * mm[2] + y * mm[6] + z * mm[10] + mm[14];
// currentVertex[0] = x;
// currentVertex[1] = y;
// currentVertex[2] = z;
currentVertex[0] = x * mm[0] + y * mm[4] + z * mm[8] + mm[12];
currentVertex[1] = x * mm[1] + y * mm[5] + z * mm[9] + mm[13];
currentVertex[2] = x * mm[2] + y * mm[6] + z * mm[10] + mm[14];
boolean textured = textureImage != null;
if (fill || textured) {
@@ -1573,12 +1587,12 @@ public class PGraphicsOpenGL extends PGraphics {
}
}
currentNormal[0] = normalX;
currentNormal[1] = normalY;
currentNormal[2] = normalZ;
// currentNormal[0] = normalX + mm[12];
// currentNormal[1] = normalY + mm[13];
// currentNormal[2] = normalZ + mm[14];
// currentNormal[0] = normalX;
// currentNormal[1] = normalY;
// currentNormal[2] = normalZ;
currentNormal[0] = normalX + mm[12];
currentNormal[1] = normalY + mm[13];
currentNormal[2] = normalZ + mm[14];
currentTexcoord[0] = u;
currentTexcoord[1] = v;
@@ -1596,8 +1610,16 @@ public class PGraphicsOpenGL extends PGraphics {
currentStroke[3] = 0;
currentStroke[4] = 0;
}
int code;
if (breakShape) {
code = BREAK;
breakShape = false;
} else {
code = VERTEX;
}
in.addVertex(currentVertex, currentColor, currentNormal, currentTexcoord, currentStroke, VERTEX);
in.addVertex(currentVertex, currentColor, currentNormal, currentTexcoord, currentStroke, code);
}
public void endShape(int mode) {
@@ -1621,10 +1643,8 @@ public class PGraphicsOpenGL extends PGraphics {
} else if (shape == POLYGON) {
tessellator.tessellatePolygon(false, mode == CLOSE);
}
flushTess();
//flushTess();
}
protected void flushTess() {
@@ -1632,19 +1652,46 @@ public class PGraphicsOpenGL extends PGraphics {
boolean hasLines = 0 < tess.lineVertexCount && 0 < tess.lineIndexCount;
boolean hasPoints = 0 < tess.pointVertexCount && 0 < tess.pointIndexCount;
if (hasFill) {
renderFill(textureImage);
if (hasFill || hasLines || hasPoints) {
gl2f.glPushMatrix();
// Note for my future self: Since this geometry already contains the
// geometric transformations that were applied at the moment of drawing,
// the current modelview should be reset to the camera state.
// In this way, the transformations can be stored in the matrix stack of
// the buffer but also being applied in order to affect other geometry
// that is not accumulated (PShape3D, for instance).
// we need to set the modelview matrix to the camera state
// to eliminate the transformations that are duplicated in GL's
// modelview and the vertices.
// In the finished code handling general scenarios, using the camera
// matrix might not be enough (maybe we need to save the current modelview
// matrix at the moment of applying the transformation to the vertices of
// the buffer), not sure though.
// It is also worth noting that these calculations makes the accumulation
// method slower under certain scenarios (lots of geometry buffers sent per
// frame and lots of geometric tranformations)... This is to say that in the
// limit whe the accumulator doesn't actually accumulate because the buffer
// is sent at each beginShape/endShape call, then this additional modelview
// stack manipulation takes away around 10-12 fps
gl2f.glLoadMatrixf(pcamera, 0);
if (hasFill) {
renderFill(textureImage);
}
if (hasLines) {
renderLines();
}
if (hasPoints) {
renderPoints();
}
gl2f.glPopMatrix();
}
if (hasLines) {
renderLines();
}
if (hasPoints) {
renderPoints();
}
tess.reset();
}
@@ -2544,31 +2591,21 @@ public class PGraphicsOpenGL extends PGraphics {
// MATRIX STACK
public void pushMatrix() {
// if (USE_GEO_BUFFER && GEO_BUFFER_ACCUM_ALL && UPDATE_GEO_BUFFER_MATRIX_STACK) {
// geoBuffer.stack.push();
// if (!UPDATE_GL_MATRIX_STACK) return;
// }
gl2f.glPushMatrix();
if (usingGLMatrixStack) {
modelviewStack.push();
}
modelviewStack.push();
transformStack.push();
}
public void popMatrix() {
// if (USE_GEO_BUFFER && GEO_BUFFER_ACCUM_ALL && UPDATE_GEO_BUFFER_MATRIX_STACK) {
// geoBuffer.stack.pop();
// if (!UPDATE_GL_MATRIX_STACK) return;
// }
gl2f.glPopMatrix();
if (usingGLMatrixStack) {
modelviewStack.pop();
}
modelviewStack.pop();
transformStack.pop();
}
//////////////////////////////////////////////////////////////
// MATRIX TRANSFORMATIONS
@@ -2579,10 +2616,9 @@ public class PGraphicsOpenGL extends PGraphics {
public void translate(float tx, float ty, float tz) {
gl2f.glTranslatef(tx, ty, tz);
if (usingGLMatrixStack) {
modelviewStack.translate(tx, ty, tz);
modelviewUpdated = false;
}
modelviewStack.translate(tx, ty, tz);
transformStack.translate(tx, ty, tz);
modelviewUpdated = false;
}
/**
@@ -2613,10 +2649,9 @@ public class PGraphicsOpenGL extends PGraphics {
*/
public void rotate(float angle, float v0, float v1, float v2) {
gl2f.glRotatef(PApplet.degrees(angle), v0, v1, v2);
if (usingGLMatrixStack) {
modelviewStack.rotate(angle, v0, v1, v2);
modelviewUpdated = false;
}
modelviewStack.rotate(angle, v0, v1, v2);
transformStack.rotate(angle, v0, v1, v2);
modelviewUpdated = false;
}
/**
@@ -2641,10 +2676,9 @@ public class PGraphicsOpenGL extends PGraphics {
scalingDuringCamManip = true;
}
gl2f.glScalef(sx, sy, sz);
if (usingGLMatrixStack) {
modelviewStack.scale(sx, sy, sz);
modelviewUpdated = false;
}
modelviewStack.scale(sx, sy, sz);
transformStack.scale(sx, sy, sz);
modelviewUpdated = false;
}
public void shearX(float angle) {
@@ -2663,12 +2697,10 @@ public class PGraphicsOpenGL extends PGraphics {
public void resetMatrix() {
gl2f.glLoadIdentity();
if (usingGLMatrixStack) {
modelviewStack.setIdentity();
modelviewUpdated = false;
}
gl2f.glLoadIdentity();
modelviewStack.setIdentity();
transformStack.setIdentity();
modelviewUpdated = false;
}
public void applyMatrix(PMatrix2D source) {
@@ -2723,10 +2755,9 @@ public class PGraphicsOpenGL extends PGraphics {
gl2f.glMultMatrixf(gltemp, 0);
if (usingGLMatrixStack) {
modelviewStack.mult(gltemp);
modelviewUpdated = false;
}
modelviewStack.mult(gltemp);
transformStack.mult(gltemp);
modelviewUpdated = false;
// TODO: add inverse calculation!
}
@@ -2743,9 +2774,8 @@ public class PGraphicsOpenGL extends PGraphics {
copyPMatrixToGLArray(modelviewInv, glmodelviewInv);
}
gl2f.glLoadMatrixf(glmodelview, 0);
if (usingGLMatrixStack) {
modelviewStack.set(glmodelview);
}
modelviewStack.set(glmodelview);
transformStack.set(glmodelview);
modelviewUpdated = true;
}
@@ -2756,9 +2786,7 @@ public class PGraphicsOpenGL extends PGraphics {
}
copyPMatrixToGLArray(camera, glmodelview);
gl2f.glLoadMatrixf(glmodelview, 0);
if (usingGLMatrixStack) {
modelviewStack.set(glmodelview);
}
modelviewStack.set(glmodelview);
scalingDuringCamManip = true; // Assuming general transformation.
modelviewUpdated = true;
}
@@ -2895,11 +2923,7 @@ public class PGraphicsOpenGL extends PGraphics {
// PROJECTION
protected void getProjectionMatrix() {
if (usingGLMatrixStack) {
projectionStack.get(glprojection);
} else {
gl2f.glGetFloatv(GL2.GL_PROJECTION_MATRIX, glprojection, 0);
}
projectionStack.get(glprojection);
copyGLArrayToPMatrix(glprojection, projection);
projectionUpdated = true;
}
@@ -2909,9 +2933,7 @@ public class PGraphicsOpenGL extends PGraphics {
gl2f.glMatrixMode(GL2.GL_PROJECTION);
gl2f.glLoadMatrixf(glprojection, 0);
gl2f.glMatrixMode(GL2.GL_MODELVIEW);
if (usingGLMatrixStack) {
projectionStack.set(glprojection);
}
projectionStack.set(glprojection);
projectionUpdated = true;
}
@@ -2922,9 +2944,7 @@ public class PGraphicsOpenGL extends PGraphics {
gl2f.glMatrixMode(GL2.GL_PROJECTION);
gl2f.glLoadMatrixf(glprojection, 0);
gl2f.glMatrixMode(GL2.GL_MODELVIEW);
if (usingGLMatrixStack) {
projectionStack.set(glprojection);
}
projectionStack.set(glprojection);
projectionUpdated = true;
}
@@ -3027,11 +3047,7 @@ public class PGraphicsOpenGL extends PGraphics {
}
protected void getModelviewMatrix() {
if (usingGLMatrixStack) {
modelviewStack.get(glmodelview);
} else {
gl2f.glGetFloatv(GL2.GL_MODELVIEW_MATRIX, glmodelview, 0);
}
modelviewStack.get(glmodelview);
copyGLArrayToPMatrix(glmodelview, modelview);
modelviewUpdated = true;
}
@@ -3318,9 +3334,8 @@ public class PGraphicsOpenGL extends PGraphics {
gl2f.glMatrixMode(GL2.GL_MODELVIEW);
gl2f.glLoadMatrixf(glmodelview, 0);
if (usingGLMatrixStack) {
modelviewStack.set(glmodelview);
}
modelviewStack.set(glmodelview);
transformStack.setIdentity();
copyGLArrayToPMatrix(glmodelview, modelview);
modelviewUpdated = true;
@@ -3340,9 +3355,8 @@ public class PGraphicsOpenGL extends PGraphics {
gl2f.glMatrixMode(GL2.GL_MODELVIEW);
gl2f.glLoadMatrixf(glmodelview, 0);
if (usingGLMatrixStack) {
modelviewStack.set(glmodelview);
}
modelviewStack.set(glmodelview);
transformStack.setIdentity();
copyGLArrayToPMatrix(glmodelview, modelview);
modelviewUpdated = true;
}
@@ -5635,9 +5649,6 @@ public class PGraphicsOpenGL extends PGraphics {
blendEqSupported = true;
//usingGLMatrixStack = !matrixGetSupported;
usingGLMatrixStack = true;
int temp[] = new int[2];
gl.glGetIntegerv(GL.GL_MAX_TEXTURE_SIZE, temp, 0);
@@ -7063,21 +7074,22 @@ public class PGraphicsOpenGL extends PGraphics {
// of this polygon are stroked.
int lineCount = 0;
int lnCount = inGeo.lastVertex - inGeo.firstVertex + 1;
int offset = tessGeo.firstFillVertex;
//int offset = tessGeo.firstFillVertex;
int first = inGeo.firstVertex;
if (!closed) {
lnCount--;
}
int contour0 = 0;
int contour0 = first;
for (int ln = 0; ln < lnCount; ln++) {
int i0 = offset + ln;
int i1 = offset + ln + 1;
int i0 = first + ln;
int i1 = first + ln + 1;
if (inGeo.codes[i0] == PShape.BREAK) {
contour0 = i0;
}
if ((i1 == lnCount || inGeo.codes[i1] == PShape.BREAK) && closed) {
// Make line with the first vertex of the current contour.
// Draw line with the first vertex of the current contour.
i0 = contour0;
i1 = offset + ln;
i1 = first + ln;
}
if (inGeo.codes[i1] != PShape.BREAK &&
@@ -7100,17 +7112,17 @@ public class PGraphicsOpenGL extends PGraphics {
int vcount = tessGeo.firstLineVertex;
int icount = tessGeo.firstLineIndex;
contour0 = 0;
contour0 = first;
for (int ln = 0; ln < lnCount; ln++) {
int i0 = offset + ln;
int i1 = offset + ln + 1;
int i0 = first + ln;
int i1 = first + ln + 1;
if (inGeo.codes[i0] == PShape.BREAK) {
contour0 = i0;
}
if ((i1 == lnCount || inGeo.codes[i1] == PShape.BREAK) && closed) {
// Make line with the first vertex of the current contour.
// Draw line with the first vertex of the current contour.
i0 = contour0;
i1 = offset + ln;
i1 = first + ln;
}
if (inGeo.codes[i1] != PShape.BREAK &&
@@ -99,7 +99,7 @@ public class PShape3D extends PShape {
// For polygons
protected boolean modified;
protected boolean addBreak;
protected boolean breakShape;
protected boolean isSolid;
protected boolean isClosed;
@@ -239,7 +239,7 @@ public class PShape3D extends PShape {
}
public void breakShape() {
addBreak = true;
breakShape = true;
}
public void vertex(float x, float y) {
@@ -268,9 +268,9 @@ public class PShape3D extends PShape {
currentTexcoord[1] = v;
int code;
if (addBreak) {
if (breakShape) {
code = BREAK;
addBreak = false;
breakShape = false;
} else {
code = type;
}
@@ -1303,8 +1303,7 @@ public class PShape3D extends PShape {
getGl().glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, root.glFillIndexBufferID);
getGl().glDrawElements(GL.GL_TRIANGLES, tess.lastFillIndex - tess.firstFillIndex + 1, GL.GL_UNSIGNED_INT,
tess.firstFillIndex * PGraphicsOpenGL.SIZEOF_INT);
getGl().glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, 0);
tess.firstFillIndex * PGraphicsOpenGL.SIZEOF_INT);
if (tex != null) {
getGl().glActiveTexture(GL.GL_TEXTURE0);
@@ -1312,6 +1311,9 @@ public class PShape3D extends PShape {
getGl().glDisable(tex.glTarget);
}
getGl().glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, 0);
getGl().glBindBuffer(GL.GL_ARRAY_BUFFER, 0);
getGl().glDisableClientState(GL2.GL_VERTEX_ARRAY);
getGl().glDisableClientState(GL2.GL_TEXTURE_COORD_ARRAY);
getGl().glDisableClientState(GL2.GL_COLOR_ARRAY);
@@ -1319,7 +1321,7 @@ public class PShape3D extends PShape {
}
protected void renderLines() {
ogl.lineShader.start();
PGraphicsOpenGL.lineShader.start();
getGl().glEnableClientState(GL2.GL_NORMAL_ARRAY);
getGl().glBindBuffer(GL.GL_ARRAY_BUFFER, root.glLineNormalBufferID);
@@ -1335,9 +1337,9 @@ public class PShape3D extends PShape {
int[] viewport = {0, 0, 0, 0};
getGl().glGetIntegerv(GL.GL_VIEWPORT, viewport, 0);
ogl.lineShader.setVecUniform("viewport", viewport[0], viewport[1], viewport[2], viewport[3]);
PGraphicsOpenGL.lineShader.setVecUniform("viewport", viewport[0], viewport[1], viewport[2], viewport[3]);
int attribsID = ogl.lineShader.getAttribLocation("attribs");
int attribsID = PGraphicsOpenGL.lineShader.getAttribLocation("attribs");
ogl.gl2x.glEnableVertexAttribArray(attribsID);
getGl().glBindBuffer(GL.GL_ARRAY_BUFFER, root.glLineAttribBufferID);
ogl.gl2x.glVertexAttribPointer(attribsID, 4, GL.GL_FLOAT, false, 0, 0);
@@ -1345,19 +1347,21 @@ public class PShape3D extends PShape {
getGl().glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, root.glLineIndexBufferID);
getGl().glDrawElements(GL.GL_TRIANGLES, tess.lastLineIndex - tess.firstLineIndex + 1, GL.GL_UNSIGNED_INT,
tess.firstLineIndex * PGraphicsOpenGL.SIZEOF_INT);
getGl().glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, 0);
ogl.gl2x.glDisableVertexAttribArray(attribsID);
getGl().glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, 0);
getGl().glBindBuffer(GL.GL_ARRAY_BUFFER, 0);
getGl().glDisableClientState(GL2.GL_VERTEX_ARRAY);
getGl().glDisableClientState(GL2.GL_COLOR_ARRAY);
getGl().glDisableClientState(GL2.GL_NORMAL_ARRAY);
ogl.lineShader.stop();
PGraphicsOpenGL.lineShader.stop();
}
protected void renderPoints() {
ogl.pointShader.start();
PGraphicsOpenGL.pointShader.start();
getGl().glEnableClientState(GL2.GL_NORMAL_ARRAY);
getGl().glBindBuffer(GL.GL_ARRAY_BUFFER, root.glPointNormalBufferID);
@@ -1371,7 +1375,7 @@ public class PShape3D extends PShape {
getGl().glBindBuffer(GL.GL_ARRAY_BUFFER, root.glPointVertexBufferID);
getGl().glVertexPointer(3, GL.GL_FLOAT, 0, 0);
int attribsID = ogl.pointShader.getAttribLocation("vertDisp");
int attribsID = PGraphicsOpenGL.pointShader.getAttribLocation("vertDisp");
ogl.gl2x.glEnableVertexAttribArray(attribsID);
getGl().glBindBuffer(GL.GL_ARRAY_BUFFER, root.glPointAttribBufferID);
ogl.gl2x.glVertexAttribPointer(attribsID, 2, GL.GL_FLOAT, false, 0, 0);
@@ -1379,15 +1383,17 @@ public class PShape3D extends PShape {
getGl().glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, root.glPointIndexBufferID);
getGl().glDrawElements(GL.GL_TRIANGLES, tess.lastPointIndex - tess.firstPointIndex + 1, GL.GL_UNSIGNED_INT,
tess.firstPointIndex * PGraphicsOpenGL.SIZEOF_INT);
getGl().glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, 0);
ogl.gl2x.glDisableVertexAttribArray(attribsID);
getGl().glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, 0);
getGl().glBindBuffer(GL.GL_ARRAY_BUFFER, 0);
getGl().glDisableClientState(GL2.GL_VERTEX_ARRAY);
getGl().glDisableClientState(GL2.GL_COLOR_ARRAY);
getGl().glDisableClientState(GL2.GL_NORMAL_ARRAY);
ogl.pointShader.stop();
PGraphicsOpenGL.pointShader.stop();
}