GLU tessellator for Android, some corrections in examples

This commit is contained in:
codeanticode
2012-02-13 21:29:17 +00:00
parent b8e9aa7ccf
commit 929e9229c9
6 changed files with 306 additions and 371 deletions
@@ -219,9 +219,6 @@ public class PGL {
public static final int GL_LINE_SMOOTH = GL.GL_LINE_SMOOTH;
public static final int GL_POLYGON_SMOOTH = GL2.GL_POLYGON_SMOOTH;
/** Pipeline mode: FIXED, PROG_GL2, PROG_GL3 or PROG_GL4 */
public int pipeline;
/** Basic GL functionality, common to all profiles */
public GL gl;
@@ -310,46 +307,11 @@ public class PGL {
}
}
profile = null;
//profile = GLProfile.getDefault();
// For the time being we use the fixed function profile
// because GL3 is not supported in MacOSX Snow Leopard.
profile = GLProfile.getMaxFixedFunc();
//profile = GLProfile.getMaxProgrammable();
//profile = GLProfile.get(GLProfile.GL2ES1);
//profile = GLProfile.get(GLProfile.GL4bc);
//profile = GLProfile.getMaxProgrammable();
//pipeline = PGL.FIXED;
/*
// Profile auto-selection disabled for the time being.
// TODO: Implement programmable pipeline :-)
try {
profile = GLProfile.get(GLProfile.GL4);
pipeline = PROG_GL4;
} catch (GLException e) {}
if (profile == null) {
try {
profile = GLProfile.get(GLProfile.GL3);
pipeline = PROG_GL3;
} catch (GLException e) {}
}
if (profile == null) {
try {
profile = GLProfile.get(GLProfile.GL2ES2);
pipeline = PROG_GL2;
} catch (GLException e) {}
}
if (profile == null) {
try {
profile = GLProfile.get(GLProfile.GL2ES1);
pipeline = FIXED;
} catch (GLException e) {}
}
*/
if (profile == null) {
pg.parent.die("Cannot get a valid OpenGL profile");
}
@@ -413,52 +375,6 @@ public class PGL {
public void destroyContext() {
context.destroy();
context = null;
}
///////////////////////////////////////////////////////////////////////////////////
// Utilities
public boolean contextIsCurrent(Context other) {
return other.same(context);
}
static public int makeIndex(int intIdx) {
return intIdx;
}
public void enableTexturing(int target) {
gl.glEnable(target);
}
public void disableTexturing(int target) {
gl.glDisable(target);
}
public void initTexture(int target, int width, int height, int format, int type) {
int[] texels = new int[width * height];
gl.glTexSubImage2D(target, 0, 0, 0, width, height, format, type, IntBuffer.wrap(texels));
}
public String getShaderLog(int id) {
IntBuffer val = IntBuffer.allocate(1);
gl2.glGetObjectParameterivARB(id, GL2.GL_OBJECT_INFO_LOG_LENGTH_ARB, val);
int length = val.get();
if (length <= 1) {
return "";
}
// Some error occurred...
ByteBuffer infoLog = ByteBuffer.allocate(length);
val.flip();
gl2.glGetInfoLogARB(id, length, val, infoLog);
byte[] infoBytes = new byte[length];
infoLog.get(infoBytes);
return new String(infoBytes);
}
///////////////////////////////////////////////////////////////////////////////////
@@ -479,19 +395,19 @@ public class PGL {
return false;
}
public void beginOnscreenDraw() {
public void beginOnscreenDraw(boolean clear, int frame) {
}
public void endOnscreenDraw() {
public void endOnscreenDraw(boolean clear0) {
if (drawable != null) {
drawable.swapBuffers();
}
}
public void beginOffscreenDraw() {
public void beginOffscreenDraw(boolean clear, int frame) {
}
public void endOffscreenDraw() {
public void endOffscreenDraw(boolean clear0) {
}
public boolean canDraw() {
@@ -545,11 +461,15 @@ public class PGL {
// Error handling
public int getError() {
public int glGetError() {
return gl.glGetError();
}
public String glErrorString(int err) {
return glu.gluErrorString(err);
}
public String getErrorString(int err) {
public String gluErrorString(int err) {
return glu.gluErrorString(err);
}
@@ -557,7 +477,7 @@ public class PGL {
// Rendering options
public void setFrontFace(int mode) {
public void glFrontFace(int mode) {
gl.glFrontFace(mode);
}
@@ -565,7 +485,7 @@ public class PGL {
gl.glDepthMask(flag);
}
public void setDepthFunc(int func) {
public void glDepthFunc(int func) {
gl.glDepthFunc(func);
}
@@ -987,5 +907,51 @@ public class PGL {
public void combine(double[] coords, Object[] data,
float[] weight, Object[] outData);
public void error(int errnum);
}
}
///////////////////////////////////////////////////////////////////////////////////
// Utility functions
public boolean contextIsCurrent(Context other) {
return other.same(context);
}
static public int makeIndex(int intIdx) {
return intIdx;
}
public void enableTexturing(int target) {
gl.glEnable(target);
}
public void disableTexturing(int target) {
gl.glDisable(target);
}
public void initTexture(int target, int width, int height, int format, int type) {
int[] texels = new int[width * height];
gl.glTexSubImage2D(target, 0, 0, 0, width, height, format, type, IntBuffer.wrap(texels));
}
public String getShaderLog(int id) {
IntBuffer val = IntBuffer.allocate(1);
gl2.glGetObjectParameterivARB(id, GL2.GL_OBJECT_INFO_LOG_LENGTH_ARB, val);
int length = val.get();
if (length <= 1) {
return "";
}
// Some error occurred...
ByteBuffer infoLog = ByteBuffer.allocate(length);
val.flip();
gl2.glGetInfoLogARB(id, length, val, infoLog);
byte[] infoBytes = new byte[length];
infoLog.get(infoBytes);
return new String(infoBytes);
}
}
@@ -314,6 +314,10 @@ public class PGraphicsOpenGL extends PGraphics {
protected int[] savedViewport = {0, 0, 0, 0};
protected int[] viewport = {0, 0, 0, 0};
/** Used to register calls to glClear. */
protected boolean clearColorBuffer;
protected boolean clearColorBuffer0;
protected boolean openContour = false;
protected boolean breakShape = false;
protected boolean defaultEdges = false;
@@ -1391,7 +1395,7 @@ public class PGraphicsOpenGL extends PGraphics {
pgl.glEnable(PGL.GL_DEPTH_TEST);
}
// use <= since that's what processing.core does
pgl.setDepthFunc(PGL.GL_LEQUAL);
pgl.glDepthFunc(PGL.GL_LEQUAL);
if (hints[DISABLE_DEPTH_MASK]) {
pgl.glDepthMask(false);
@@ -1450,7 +1454,7 @@ public class PGraphicsOpenGL extends PGraphics {
lightSpecular(0, 0, 0);
// because y is flipped
pgl.setFrontFace(PGL.GL_CW);
pgl.glFrontFace(PGL.GL_CW);
// Processing uses only one texture unit.
pgl.glActiveTexture(PGL.GL_TEXTURE0);
@@ -1463,13 +1467,16 @@ public class PGraphicsOpenGL extends PGraphics {
pgl.glClear(PGL.GL_DEPTH_BUFFER_BIT | PGL.GL_STENCIL_BUFFER_BIT);
if (primarySurface) {
pgl.beginOnscreenDraw();
pgl.beginOnscreenDraw(clearColorBuffer, parent.frameCount);
} else {
pgl.beginOffscreenDraw();
pgl.beginOffscreenDraw(clearColorBuffer, parent.frameCount);
}
drawing = true;
clearColorBuffer0 = clearColorBuffer;
clearColorBuffer = false;
report("bot beginDraw()");
}
@@ -1499,7 +1506,7 @@ public class PGraphicsOpenGL extends PGraphics {
// operation. Thus, only the main renderer (the primary surface)
// should call it at the end of draw, and none of the offscreen
// renderers...
pgl.endOnscreenDraw();
pgl.endOnscreenDraw(clearColorBuffer0);
pgl.glFlush();
pgl.releaseContext();
} else {
@@ -1508,7 +1515,7 @@ public class PGraphicsOpenGL extends PGraphics {
}
popFramebuffer();
pgl.endOffscreenDraw();
pgl.endOffscreenDraw(clearColorBuffer0);
pg.restoreGLState();
}
@@ -1569,8 +1576,8 @@ public class PGraphicsOpenGL extends PGraphics {
// but we want to make sure they return to the Processing
// defaults (plus these cannot be changed through the API
// so they should remain constant anyways):
pgl.setFrontFace(PGL.GL_CW);
pgl.setDepthFunc(PGL.GL_LEQUAL);
pgl.glFrontFace(PGL.GL_CW);
pgl.glDepthFunc(PGL.GL_LEQUAL);
}
@@ -2045,7 +2052,7 @@ public class PGraphicsOpenGL extends PGraphics {
}
if (breakShape) {
code = BREAK;
code = PShape.BREAK;
breakShape = false;
}
@@ -4273,6 +4280,7 @@ public class PGraphicsOpenGL extends PGraphics {
protected void backgroundImpl(PImage image) {
backgroundImpl();
set(0, 0, image);
clearColorBuffer = true;
}
protected void backgroundImpl() {
@@ -4283,7 +4291,8 @@ public class PGraphicsOpenGL extends PGraphics {
pgl.glClear(PGL.GL_DEPTH_BUFFER_BIT);
pgl.glClearColor(backgroundR, backgroundG, backgroundB, 1);
pgl.glClear(PGL.GL_COLOR_BUFFER_BIT);
pgl.glClear(PGL.GL_COLOR_BUFFER_BIT);
clearColorBuffer = true;
}
//////////////////////////////////////////////////////////////
@@ -4332,10 +4341,9 @@ public class PGraphicsOpenGL extends PGraphics {
*/
public void report(String where) {
if (!hints[DISABLE_OPENGL_ERROR_REPORT]) {
int err = pgl.getError();
int err = pgl.glGetError();
if (err != 0) {
//String errString = glu.gluErrorString(err);
String errString = pgl.getErrorString(err);
String errString = pgl.glErrorString(err);
String msg = "OpenGL error " + err + " at " + where + ": " + errString;
PGraphics.showWarning(msg);
}
@@ -5490,8 +5498,6 @@ public class PGraphicsOpenGL extends PGraphics {
offscreenFramebufferMultisample.clear();
offscreenMultisample = true;
pg.report("after cleaning fbm");
// The offscreen framebuffer where the multisampled image is finally drawn to doesn't
// need depth and stencil buffers since they are part of the multisampled framebuffer.
offscreenFramebuffer = new PFramebuffer(parent, texture.glWidth, texture.glHeight, 1, 1,
@@ -8710,12 +8716,35 @@ public class PGraphicsOpenGL extends PGraphics {
gluTess.beginContour();
}
// Separting colors into individual rgba components for interpolation.
int fa = (in.colors[i] >> 24) & 0xFF;
int fr = (in.colors[i] >> 16) & 0xFF;
int fg = (in.colors[i] >> 8) & 0xFF;
int fb = (in.colors[i] >> 0) & 0xFF;
int aa = (in.ambient[i] >> 24) & 0xFF;
int ar = (in.ambient[i] >> 16) & 0xFF;
int ag = (in.ambient[i] >> 8) & 0xFF;
int ab = (in.ambient[i] >> 0) & 0xFF;
int sa = (in.specular[i] >> 24) & 0xFF;
int sr = (in.specular[i] >> 16) & 0xFF;
int sg = (in.specular[i] >> 8) & 0xFF;
int sb = (in.specular[i] >> 0) & 0xFF;
int ea = (in.emissive[i] >> 24) & 0xFF;
int er = (in.emissive[i] >> 16) & 0xFF;
int eg = (in.emissive[i] >> 8) & 0xFF;
int eb = (in.emissive[i] >> 0) & 0xFF;
// Vertex data includes coordinates, colors, normals, texture coordinates, and material properties.
double[] vertex = new double[] { in.vertices [3 * i + 0], in.vertices [3 * i + 1], in.vertices[3 * i + 2],
in.colors [i],
fa, fr, fg, fb,
in.normals [3 * i + 0], in.normals [3 * i + 1], in.normals [3 * i + 2],
in.texcoords[2 * i + 0], in.texcoords[2 * i + 1],
in.ambient[i], in.specular[i], in.emissive[i], in.shininess[i] };
aa, ar, ag, ab, sa, sr, sg, sb, ea, er, eg, eb,
in.shininess[i] };
gluTess.addVertex(vertex);
}
gluTess.endContour();
@@ -8876,19 +8905,26 @@ public class PGraphicsOpenGL extends PGraphics {
public void vertex(Object data) {
if (data instanceof double[]) {
double[] d = (double[]) data;
if (d.length < 13) {
throw new RuntimeException("TessCallback vertex() data is not of length 13");
if (d.length < 25) {
throw new RuntimeException("TessCallback vertex() data is not of length 25");
}
// We need to use separate rgba components for correct interpolation...
if (tess.fillVertexCount < PGL.MAX_TESS_VERTICES) {
tess.addFillVertex((float) d[0], (float) d[ 1], (float) d[ 2],
(int) d[3],
(float) d[4], (float) d[ 5], (float) d[ 6],
(float) d[7], (float) d[ 8],
(int) d[9], (int) d[10], (int) d[11], (float) d[12]);
tessCount++;
// Combining individual rgba components back into int color values
int fcolor = ((int) d[ 3] << 24) | ((int) d[ 4] << 16) | ((int) d[ 5] << 8) | (int) d[ 6];
int acolor = ((int) d[12] << 24) | ((int) d[13] << 16) | ((int) d[14] << 8) | (int) d[15];
int scolor = ((int) d[16] << 24) | ((int) d[17] << 16) | ((int) d[18] << 8) | (int) d[19];
int ecolor = ((int) d[20] << 24) | ((int) d[21] << 16) | ((int) d[22] << 8) | (int) d[23];
tess.addFillVertex((float) d[ 0], (float) d[ 1], (float) d[ 2],
fcolor,
(float) d[ 7], (float) d[ 8], (float) d[ 9],
(float) d[10], (float) d[11],
acolor, scolor, ecolor,
(float) d[24]);
tessCount++;
} else {
throw new RuntimeException("P3D: the tessellator is generating too many vertices, reduce complexity of shape.");
}
@@ -8899,7 +8935,7 @@ public class PGraphicsOpenGL extends PGraphics {
}
public void error(int errnum) {
String estring = pgl.getErrorString(errnum);
String estring = pgl.gluErrorString(errnum);
PGraphics.showWarning("Tessellation Error: " + estring);
}
@@ -8918,7 +8954,7 @@ public class PGraphicsOpenGL extends PGraphics {
*/
public void combine(double[] coords, Object[] data,
float[] weight, Object[] outData) {
double[] vertex = new double[13];
double[] vertex = new double[25];
vertex[0] = coords[0];
vertex[1] = coords[1];
vertex[2] = coords[2];
@@ -8928,35 +8964,12 @@ public class PGraphicsOpenGL extends PGraphics {
// Calculating the rest of the vertex parameters (color,
// normal, texcoords) as the linear combination of the
// combined vertices.
for (int i = 3; i < 13; i++) {
for (int i = 3; i < 25; i++) {
vertex[i] = 0;
for (int j = 0; j < 4; j++) {
double[] vertData = (double[])data[j];
if (vertData != null) {
if (i == 3 || 8 < i) {
// Color data, needs to be split into rgba components
// for interpolation.
int colorj = (int) vertData[i];
int xj = (colorj >> 24) & 0xFF;
int yj = (colorj >> 16) & 0xFF;
int zj = (colorj >> 8) & 0xFF;
int wj = (colorj >> 0) & 0xFF;
int colori = (int) vertex[i];
int xi = (colori >> 24) & 0xFF;
int yi = (colori >> 16) & 0xFF;
int zi = (colori >> 8) & 0xFF;
int wi = (colori >> 0) & 0xFF;
xi += weight[j] * xj;
yi += weight[j] * yj;
zi += weight[j] * zj;
wi += weight[j] * wj;
vertex[i] = (xi << 24) | (yi << 16) | (zi << 8) | wi;
} else {
vertex[i] += weight[j] * vertData[i];
}
vertex[i] += weight[j] * vertData[i];
}
}
}