mirror of
https://github.com/processing/processing4.git
synced 2026-06-16 04:26:26 +02:00
GLU tessellator for Android, some corrections in examples
This commit is contained in:
@@ -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];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user