mirror of
https://github.com/processing/processing4.git
synced 2026-06-16 04:26:26 +02:00
loadShape properly implemented across renderers
This commit is contained in:
@@ -22,8 +22,16 @@
|
||||
|
||||
package processing.opengl;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
|
||||
import processing.core.PApplet;
|
||||
import processing.core.PGraphics;
|
||||
import processing.core.PMatrix3D;
|
||||
import processing.core.PShape;
|
||||
import processing.core.PShapeSVG;
|
||||
import processing.data.XML;
|
||||
|
||||
public class PGraphics2D extends PGraphicsOpenGL {
|
||||
|
||||
@@ -44,17 +52,110 @@ public class PGraphics2D extends PGraphicsOpenGL {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
// SHAPE CREATORS
|
||||
// SHAPE
|
||||
|
||||
|
||||
public void shape(PShape shape) {
|
||||
if (shape.is2D()) {
|
||||
super.shape(shape);
|
||||
} else {
|
||||
showWarning("The shape object is not 2D, cannot be displayed with this renderer");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void shape(PShape shape, float x, float y) {
|
||||
if (shape.is2D()) {
|
||||
super.shape(shape, x, y);
|
||||
} else {
|
||||
showWarning("The shape object is not 2D, cannot be displayed with this renderer");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void shape(PShape shape, float a, float b, float c, float d) {
|
||||
if (shape.is2D()) {
|
||||
super.shape(shape, a, b, c, d);
|
||||
} else {
|
||||
showWarning("The shape object is not 2D, cannot be displayed with this renderer");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void shape(PShape shape, float x, float y, float z) {
|
||||
showDepthWarningXYZ("shape");
|
||||
}
|
||||
|
||||
|
||||
public void shape(PShape shape, float x, float y, float z, float c, float d, float e) {
|
||||
showDepthWarningXYZ("shape");
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
// SHAPE I/O
|
||||
|
||||
|
||||
static protected boolean isSupportedExtension(String extension) {
|
||||
return extension.equals("svg") || extension.equals("svgz");
|
||||
}
|
||||
|
||||
|
||||
static protected PShape2D loadShapeImpl(PGraphics pg, String filename, String extension) {
|
||||
PShapeSVG svg = null;
|
||||
|
||||
if (extension.equals("svg")) {
|
||||
svg = new PShapeSVG(pg.parent, filename);
|
||||
|
||||
} else if (extension.equals("svgz")) {
|
||||
try {
|
||||
InputStream input = new GZIPInputStream(pg.parent.createInput(filename));
|
||||
XML xml = new XML(PApplet.createReader(input));
|
||||
svg = new PShapeSVG(xml);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
if (svg != null) {
|
||||
PShape2D p2d = PShape2D.createShape(pg.parent, svg);
|
||||
return p2d;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
// SHAPE CREATION
|
||||
|
||||
|
||||
public PShape createShape(PShape source) {
|
||||
return PShape2D.createShape(parent, source);
|
||||
}
|
||||
|
||||
|
||||
public PShape createShape() {
|
||||
return createShape(POLYGON);
|
||||
}
|
||||
|
||||
|
||||
public PShape createShape(int type) {
|
||||
return createShapeImpl(parent, type);
|
||||
}
|
||||
|
||||
|
||||
public PShape createShape(int kind, float... p) {
|
||||
return createShapeImpl(parent, kind, p);
|
||||
}
|
||||
|
||||
|
||||
static protected PShape2D createShapeImpl(PApplet parent, int type) {
|
||||
PShape2D shape = null;
|
||||
if (type == PShape.GROUP) {
|
||||
shape = new PShape2D(parent, PShape.GROUP);
|
||||
@@ -89,7 +190,7 @@ public class PGraphics2D extends PGraphicsOpenGL {
|
||||
}
|
||||
|
||||
|
||||
public PShape createShape(int kind, float... p) {
|
||||
static protected PShape2D createShapeImpl(PApplet parent, int kind, float... p) {
|
||||
PShape2D shape = null;
|
||||
int len = p.length;
|
||||
|
||||
@@ -156,27 +257,7 @@ public class PGraphics2D extends PGraphicsOpenGL {
|
||||
|
||||
return shape;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
// SHAPE I/O
|
||||
|
||||
protected String[] getSupportedShapeFormats() {
|
||||
return new String[] { "svg" };
|
||||
}
|
||||
|
||||
|
||||
public PShape loadShape(String filename) {
|
||||
// TODO: loadShape in PApplet probably needs to be
|
||||
// re-implemented.
|
||||
PShape svg = parent.loadShape(filename);
|
||||
|
||||
// TODO: rework base API in PShape to do this...
|
||||
PShape2D p2d = (PShape2D) svg.copy(this);
|
||||
|
||||
return p2d;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ import java.util.ArrayList;
|
||||
import java.util.Hashtable;
|
||||
|
||||
import processing.core.PApplet;
|
||||
import processing.core.PGraphics;
|
||||
import processing.core.PImage;
|
||||
import processing.core.PShape;
|
||||
import processing.core.PVector;
|
||||
@@ -37,18 +38,151 @@ public class PGraphics3D extends PGraphicsOpenGL {
|
||||
|
||||
// RENDERER SUPPORT QUERIES
|
||||
|
||||
|
||||
public boolean is2D() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public boolean is3D() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
// SHAPE CREATORS
|
||||
// SHAPE I/O
|
||||
|
||||
|
||||
static protected boolean isSupportedExtension(String extension) {
|
||||
return extension.equals("obj");
|
||||
}
|
||||
|
||||
|
||||
static protected PShape loadShapeImpl(PGraphics pg, String filename, String ext) {
|
||||
ArrayList<PVector> vertices = new ArrayList<PVector>();
|
||||
ArrayList<PVector> normals = new ArrayList<PVector>();
|
||||
ArrayList<PVector> textures = new ArrayList<PVector>();
|
||||
ArrayList<OBJFace> faces = new ArrayList<OBJFace>();
|
||||
ArrayList<OBJMaterial> materials = new ArrayList<OBJMaterial>();
|
||||
|
||||
BufferedReader reader = pg.parent.createReader(filename);
|
||||
parseOBJ(pg.parent, reader, vertices, normals, textures, faces, materials);
|
||||
|
||||
int prevColorMode = pg.colorMode;
|
||||
float prevColorModeX = pg.colorModeX;
|
||||
float prevColorModeY = pg.colorModeY;
|
||||
float prevColorModeZ = pg.colorModeZ;
|
||||
float prevColorModeA = pg.colorModeA;
|
||||
boolean prevStroke = pg.stroke;
|
||||
int prevTextureMode = pg.textureMode;
|
||||
pg.colorMode(RGB, 1);
|
||||
pg.stroke = false;
|
||||
pg.textureMode = NORMAL;
|
||||
|
||||
// The OBJ geometry is stored in a group shape,
|
||||
// with each face in a separate child geometry
|
||||
// shape.
|
||||
PShape root = createShapeImpl(pg.parent, GROUP);
|
||||
|
||||
int mtlIdxCur = -1;
|
||||
OBJMaterial mtl = null;
|
||||
for (int i = 0; i < faces.size(); i++) {
|
||||
OBJFace face = faces.get(i);
|
||||
|
||||
// Getting current material.
|
||||
if (mtlIdxCur != face.matIdx) {
|
||||
mtlIdxCur = PApplet.max(0, face.matIdx); // To make sure that at least we get the default material.
|
||||
mtl = materials.get(mtlIdxCur);
|
||||
}
|
||||
|
||||
// Creating child shape for current face.
|
||||
PShape child;
|
||||
if (face.vertIdx.size() == 3) {
|
||||
child = createShapeImpl(pg.parent, TRIANGLES); // Face is a triangle, so using appropriate shape kind.
|
||||
} else if (face.vertIdx.size() == 4) {
|
||||
child = createShapeImpl(pg.parent, QUADS); // Face is a quad, so using appropriate shape kind.
|
||||
} else {
|
||||
child = createShapeImpl(pg.parent, POLYGON); // Face is a general polygon
|
||||
}
|
||||
|
||||
// Setting material properties for the new face
|
||||
child.fill(mtl.kd.x, mtl.kd.y, mtl.kd.z);
|
||||
child.ambient(mtl.ka.x, mtl.ka.y, mtl.ka.z);
|
||||
child.specular(mtl.ks.x, mtl.ks.y, mtl.ks.z);
|
||||
child.shininess(mtl.ns);
|
||||
if (mtl.kdMap != null) {
|
||||
// If current material is textured, then tinting the texture using the diffuse color.
|
||||
child.tint(mtl.kd.x, mtl.kd.y, mtl.kd.z, mtl.d);
|
||||
}
|
||||
|
||||
for (int j = 0; j < face.vertIdx.size(); j++){
|
||||
int vertIdx, normIdx;
|
||||
PVector vert, norms;
|
||||
|
||||
vert = norms = null;
|
||||
|
||||
vertIdx = face.vertIdx.get(j).intValue() - 1;
|
||||
vert = vertices.get(vertIdx);
|
||||
|
||||
if (j < face.normIdx.size()) {
|
||||
normIdx = face.normIdx.get(j).intValue() - 1;
|
||||
if (-1 < normIdx) {
|
||||
norms = normals.get(normIdx);
|
||||
}
|
||||
}
|
||||
|
||||
if (mtl != null && mtl.kdMap != null) {
|
||||
// This face is textured.
|
||||
int texIdx;
|
||||
PVector tex = null;
|
||||
|
||||
if (j < face.texIdx.size()) {
|
||||
texIdx = face.texIdx.get(j).intValue() - 1;
|
||||
if (-1 < texIdx) {
|
||||
tex = textures.get(texIdx);
|
||||
}
|
||||
}
|
||||
|
||||
child.texture(mtl.kdMap);
|
||||
if (norms != null) {
|
||||
child.normal(norms.x, norms.y, norms.z);
|
||||
}
|
||||
if (tex != null) {
|
||||
child.vertex(vert.x, vert.y, vert.z, tex.x, tex.y);
|
||||
} else {
|
||||
child.vertex(vert.x, vert.y, vert.z);
|
||||
}
|
||||
} else {
|
||||
// This face is not textured.
|
||||
if (norms != null) {
|
||||
child.normal(norms.x, norms.y, norms.z);
|
||||
}
|
||||
child.vertex(vert.x, vert.y, vert.z);
|
||||
}
|
||||
}
|
||||
|
||||
child.end(CLOSE);
|
||||
root.addChild(child);
|
||||
}
|
||||
|
||||
pg.colorMode(prevColorMode, prevColorModeX, prevColorModeY, prevColorModeZ, prevColorModeA);
|
||||
pg.stroke = prevStroke;
|
||||
pg.textureMode = prevTextureMode;
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
// SHAPE CREATION
|
||||
|
||||
|
||||
public PShape createShape(PShape source) {
|
||||
return PShape3D.createShape(parent, source);
|
||||
}
|
||||
|
||||
|
||||
public PShape createShape() {
|
||||
return createShape(POLYGON);
|
||||
@@ -56,6 +190,16 @@ public class PGraphics3D extends PGraphicsOpenGL {
|
||||
|
||||
|
||||
public PShape createShape(int type) {
|
||||
return createShapeImpl(parent, type);
|
||||
}
|
||||
|
||||
|
||||
public PShape createShape(int kind, float... p) {
|
||||
return createShapeImpl(parent, kind, p);
|
||||
}
|
||||
|
||||
|
||||
static protected PShape3D createShapeImpl(PApplet parent, int type) {
|
||||
PShape3D shape = null;
|
||||
if (type == PShape.GROUP) {
|
||||
shape = new PShape3D(parent, PShape.GROUP);
|
||||
@@ -88,9 +232,9 @@ public class PGraphics3D extends PGraphicsOpenGL {
|
||||
}
|
||||
return shape;
|
||||
}
|
||||
|
||||
|
||||
public PShape createShape(int kind, float... p) {
|
||||
|
||||
|
||||
static protected PShape3D createShapeImpl(PApplet parent, int kind, float... p) {
|
||||
PShape3D shape = null;
|
||||
int len = p.length;
|
||||
|
||||
@@ -171,135 +315,15 @@ public class PGraphics3D extends PGraphicsOpenGL {
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
// SHAPE I/O
|
||||
// OBJ LOADING
|
||||
|
||||
|
||||
|
||||
protected String[] getSupportedShapeFormats() {
|
||||
return new String[] { "obj" };
|
||||
}
|
||||
|
||||
|
||||
public PShape loadShape(String filename) {
|
||||
ArrayList<PVector> vertices = new ArrayList<PVector>();
|
||||
ArrayList<PVector> normals = new ArrayList<PVector>();
|
||||
ArrayList<PVector> textures = new ArrayList<PVector>();
|
||||
ArrayList<OBJFace> faces = new ArrayList<OBJFace>();
|
||||
ArrayList<OBJMaterial> materials = new ArrayList<OBJMaterial>();
|
||||
|
||||
BufferedReader reader = parent.createReader(filename);
|
||||
parseOBJ(reader, vertices, normals, textures, faces, materials);
|
||||
|
||||
int prevColorMode = pg.colorMode;
|
||||
float prevColorModeX = pg.colorModeX;
|
||||
float prevColorModeY = pg.colorModeY;
|
||||
float prevColorModeZ = pg.colorModeZ;
|
||||
float prevColorModeA = pg.colorModeA;
|
||||
boolean prevStroke = pg.stroke;
|
||||
int prevTextureMode = pg.textureMode;
|
||||
pg.colorMode(RGB, 1);
|
||||
pg.stroke = false;
|
||||
pg.textureMode = NORMAL;
|
||||
|
||||
|
||||
// The OBJ geometry is stored in a group shape,
|
||||
// with each face in a separate child geometry
|
||||
// shape.
|
||||
PShape root = createShape(GROUP);
|
||||
|
||||
int mtlIdxCur = -1;
|
||||
OBJMaterial mtl = null;
|
||||
for (int i = 0; i < faces.size(); i++) {
|
||||
OBJFace face = faces.get(i);
|
||||
|
||||
// Getting current material.
|
||||
if (mtlIdxCur != face.matIdx) {
|
||||
mtlIdxCur = PApplet.max(0, face.matIdx); // To make sure that at least we get the default material.
|
||||
mtl = materials.get(mtlIdxCur);
|
||||
}
|
||||
|
||||
// Creating child shape for current face.
|
||||
PShape child;
|
||||
if (face.vertIdx.size() == 3) {
|
||||
child = createShape(TRIANGLES); // Face is a triangle, so using appropriate shape kind.
|
||||
} else if (face.vertIdx.size() == 4) {
|
||||
child = createShape(QUADS); // Face is a quad, so using appropriate shape kind.
|
||||
} else {
|
||||
child = createShape(POLYGON); // Face is a general polygon
|
||||
}
|
||||
|
||||
// Setting material properties for the new face
|
||||
child.fill(mtl.kd.x, mtl.kd.y, mtl.kd.z);
|
||||
child.ambient(mtl.ka.x, mtl.ka.y, mtl.ka.z);
|
||||
child.specular(mtl.ks.x, mtl.ks.y, mtl.ks.z);
|
||||
child.shininess(mtl.ns);
|
||||
if (mtl.kdMap != null) {
|
||||
// If current material is textured, then tinting the texture using the diffuse color.
|
||||
child.tint(mtl.kd.x, mtl.kd.y, mtl.kd.z, mtl.d);
|
||||
}
|
||||
|
||||
for (int j = 0; j < face.vertIdx.size(); j++){
|
||||
int vertIdx, normIdx;
|
||||
PVector vert, norms;
|
||||
|
||||
vert = norms = null;
|
||||
|
||||
vertIdx = face.vertIdx.get(j).intValue() - 1;
|
||||
vert = vertices.get(vertIdx);
|
||||
|
||||
if (j < face.normIdx.size()) {
|
||||
normIdx = face.normIdx.get(j).intValue() - 1;
|
||||
if (-1 < normIdx) {
|
||||
norms = normals.get(normIdx);
|
||||
}
|
||||
}
|
||||
|
||||
if (mtl != null && mtl.kdMap != null) {
|
||||
// This face is textured.
|
||||
int texIdx;
|
||||
PVector tex = null;
|
||||
|
||||
if (j < face.texIdx.size()) {
|
||||
texIdx = face.texIdx.get(j).intValue() - 1;
|
||||
if (-1 < texIdx) {
|
||||
tex = textures.get(texIdx);
|
||||
}
|
||||
}
|
||||
|
||||
child.texture(mtl.kdMap);
|
||||
if (norms != null) {
|
||||
child.normal(norms.x, norms.y, norms.z);
|
||||
}
|
||||
if (tex != null) {
|
||||
child.vertex(vert.x, vert.y, vert.z, tex.x, tex.y);
|
||||
} else {
|
||||
child.vertex(vert.x, vert.y, vert.z);
|
||||
}
|
||||
} else {
|
||||
// This face is not textured.
|
||||
if (norms != null) {
|
||||
child.normal(norms.x, norms.y, norms.z);
|
||||
}
|
||||
child.vertex(vert.x, vert.y, vert.z);
|
||||
}
|
||||
}
|
||||
|
||||
child.end(CLOSE);
|
||||
root.addChild(child);
|
||||
}
|
||||
|
||||
pg.colorMode(prevColorMode, prevColorModeX, prevColorModeY, prevColorModeZ, prevColorModeA);
|
||||
pg.stroke = prevStroke;
|
||||
pg.textureMode = prevTextureMode;
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
|
||||
protected void parseOBJ(BufferedReader reader, ArrayList<PVector> vertices,
|
||||
ArrayList<PVector> normals,
|
||||
ArrayList<PVector> textures,
|
||||
ArrayList<OBJFace> faces,
|
||||
ArrayList<OBJMaterial> materials) {
|
||||
static protected void parseOBJ(PApplet parent,
|
||||
BufferedReader reader, ArrayList<PVector> vertices,
|
||||
ArrayList<PVector> normals,
|
||||
ArrayList<PVector> textures,
|
||||
ArrayList<OBJFace> faces,
|
||||
ArrayList<OBJMaterial> materials) {
|
||||
Hashtable<String, Integer> mtlTable = new Hashtable<String, Integer>();
|
||||
int mtlIdxCur = -1;
|
||||
boolean readv, readvn, readvt;
|
||||
@@ -360,7 +384,7 @@ public class PGraphics3D extends PGraphicsOpenGL {
|
||||
if (elements[1] != null) {
|
||||
BufferedReader mreader = parent.createReader(elements[1]);
|
||||
if (mreader != null) {
|
||||
parseMTL(mreader, materials, mtlTable);
|
||||
parseMTL(parent, mreader, materials, mtlTable);
|
||||
}
|
||||
}
|
||||
} else if (elements[0].equals("g")) {
|
||||
@@ -446,7 +470,10 @@ public class PGraphics3D extends PGraphicsOpenGL {
|
||||
}
|
||||
}
|
||||
|
||||
protected void parseMTL(BufferedReader reader, ArrayList<OBJMaterial> materials, Hashtable<String, Integer> materialsHash) {
|
||||
|
||||
static protected void parseMTL(PApplet parent,
|
||||
BufferedReader reader, ArrayList<OBJMaterial> materials,
|
||||
Hashtable<String, Integer> materialsHash) {
|
||||
try {
|
||||
String line;
|
||||
OBJMaterial currentMtl = null;
|
||||
@@ -498,8 +525,9 @@ public class PGraphics3D extends PGraphicsOpenGL {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Stores a face from an OBJ file
|
||||
protected class OBJFace {
|
||||
static protected class OBJFace {
|
||||
ArrayList<Integer> vertIdx;
|
||||
ArrayList<Integer> texIdx;
|
||||
ArrayList<Integer> normIdx;
|
||||
@@ -517,7 +545,7 @@ public class PGraphics3D extends PGraphicsOpenGL {
|
||||
|
||||
|
||||
// Stores a material defined in an MTL file.
|
||||
protected class OBJMaterial {
|
||||
static protected class OBJMaterial {
|
||||
String name;
|
||||
PVector ka;
|
||||
PVector kd;
|
||||
|
||||
@@ -2177,6 +2177,7 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
|
||||
|
||||
protected void tessellate(int mode) {
|
||||
tessellator.set3D(is3D());
|
||||
tessellator.setInGeometry(inGeo);
|
||||
tessellator.setTessGeometry(tessGeo);
|
||||
tessellator.setFill(fill || textureImage != null);
|
||||
@@ -2186,7 +2187,7 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
tessellator.setStrokeCap(strokeCap);
|
||||
tessellator.setStrokeJoin(strokeJoin);
|
||||
tessellator.setTexCache(texCache, textureImage0, textureImage);
|
||||
|
||||
|
||||
if (shape == POINTS) {
|
||||
tessellator.tessellatePoints();
|
||||
} else if (shape == LINES) {
|
||||
@@ -2231,6 +2232,7 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
}
|
||||
}
|
||||
|
||||
tessellator.set3D(is3D());
|
||||
tessellator.setInGeometry(inGeo);
|
||||
tessellator.setTessGeometry(tessGeo);
|
||||
tessellator.setFill(fill || textureImage != null);
|
||||
@@ -2239,7 +2241,7 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
tessellator.setStrokeWeight(strokeWeight);
|
||||
tessellator.setStrokeCap(strokeCap);
|
||||
tessellator.setStrokeJoin(strokeJoin);
|
||||
tessellator.setTexCache(texCache, textureImage0, textureImage);
|
||||
tessellator.setTexCache(texCache, textureImage0, textureImage);
|
||||
|
||||
if (stroke && defaultEdges && edges == null) inGeo.addTrianglesEdges();
|
||||
if (normalMode == NORMAL_MODE_AUTO) inGeo.calcTrianglesNormals();
|
||||
@@ -3073,6 +3075,24 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
popMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
// SHAPE I/O
|
||||
|
||||
|
||||
public PShape loadShape(String filename) {
|
||||
String ext = PApplet.getExtension(filename);
|
||||
if (PGraphics2D.isSupportedExtension(ext)) {
|
||||
return PGraphics2D.loadShapeImpl(this, filename, ext);
|
||||
} if (PGraphics3D.isSupportedExtension(ext)) {
|
||||
return PGraphics3D.loadShapeImpl(this, filename, ext);
|
||||
} else {
|
||||
PGraphics.showWarning("Unsupported format");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
@@ -9101,6 +9121,7 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
PGL.Tessellator gluTess;
|
||||
TessellatorCallback callback;
|
||||
|
||||
boolean is2D, is3D;
|
||||
boolean fill;
|
||||
boolean stroke;
|
||||
int strokeColor;
|
||||
@@ -9122,6 +9143,8 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
callback = new TessellatorCallback();
|
||||
gluTess = pgl.createTessellator(callback);
|
||||
rawIndices = new int[512];
|
||||
is2D = false;
|
||||
is3D = true;
|
||||
}
|
||||
|
||||
void setInGeometry(InGeometry in) {
|
||||
@@ -9169,6 +9192,16 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
this.newTexImage = newTexImage;
|
||||
}
|
||||
|
||||
void set3D(boolean value) {
|
||||
if (value) {
|
||||
is2D = false;
|
||||
is3D = true;
|
||||
} else {
|
||||
is2D = true;
|
||||
is3D = false;
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
//
|
||||
// Point tessellation
|
||||
@@ -9193,9 +9226,9 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
}
|
||||
int nvertTot = nPtVert * nInVert;
|
||||
int nindTot = 3 * (nPtVert - 1) * nInVert;
|
||||
if (is3D()) {
|
||||
if (is3D) {
|
||||
tessellateRoundPoints3D(nvertTot, nindTot, nPtVert);
|
||||
} else if (is2D()) {
|
||||
} else if (is2D) {
|
||||
beginNoTex();
|
||||
tessellateRoundPoints2D(nvertTot, nindTot, nPtVert);
|
||||
endNoTex();
|
||||
@@ -9334,9 +9367,9 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
// So the quad is formed by 4 triangles, each requires
|
||||
// 3 indices.
|
||||
int nindTot = 12 * quadCount;
|
||||
if (is3D()) {
|
||||
if (is3D) {
|
||||
tessellateSquarePoints3D(nvertTot, nindTot);
|
||||
} else if (is2D()) {
|
||||
} else if (is2D) {
|
||||
beginNoTex();
|
||||
tessellateSquarePoints2D(nvertTot, nindTot);
|
||||
endNoTex();
|
||||
@@ -9467,9 +9500,9 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
// Each stroke line has 4 vertices, defining 2 triangles, which
|
||||
// require 3 indices to specify their connectivities.
|
||||
int nind = lineCount * 2 * 3;
|
||||
if (is3D()) {
|
||||
if (is3D) {
|
||||
tessellateLines3D(nvert, nind, lineCount);
|
||||
} else if (is2D()) {
|
||||
} else if (is2D) {
|
||||
beginNoTex();
|
||||
tessellateLines2D(nvert, nind, lineCount);
|
||||
endNoTex();
|
||||
@@ -9536,9 +9569,9 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
int lineCount = nInVert - 1;
|
||||
int nvert = lineCount * 4;
|
||||
int nind = lineCount * 2 * 3;
|
||||
if (is3D()) {
|
||||
if (is3D) {
|
||||
tessellateLineStrip3D(nvert, nind, lineCount);
|
||||
} else if (is2D()) {
|
||||
} else if (is2D) {
|
||||
beginNoTex();
|
||||
tessellateLineStrip2D(nvert, nind, lineCount);
|
||||
endNoTex();
|
||||
@@ -9606,9 +9639,9 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
int lineCount = nInVert;
|
||||
int nvert = lineCount * 4;
|
||||
int nind = lineCount * 2 * 3;
|
||||
if (is3D()) {
|
||||
if (is3D) {
|
||||
tessellateLineLoop3D(nvert, nind, lineCount);
|
||||
} else if (is2D()) {
|
||||
} else if (is2D) {
|
||||
beginNoTex();
|
||||
tessellateLineLoop2D(nvert, nind, lineCount);
|
||||
endNoTex();
|
||||
@@ -9676,9 +9709,9 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
if (stroke) {
|
||||
int nInVert = in.getNumLineVertices();
|
||||
int nInInd = in.getNumLineIndices();
|
||||
if (is3D()) {
|
||||
if (is3D) {
|
||||
tessellateEdges3D(nInVert, nInInd);
|
||||
} else if (is2D()) {
|
||||
} else if (is2D) {
|
||||
beginNoTex();
|
||||
tessellateEdges2D(nInVert, nInInd);
|
||||
endNoTex();
|
||||
|
||||
@@ -24,6 +24,7 @@ package processing.opengl;
|
||||
|
||||
import processing.core.PApplet;
|
||||
import processing.core.PGraphics;
|
||||
import processing.core.PShape;
|
||||
|
||||
public class PShape2D extends PShapeOpenGL {
|
||||
|
||||
@@ -38,6 +39,44 @@ public class PShape2D extends PShapeOpenGL {
|
||||
public boolean is3D() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Shape copy
|
||||
|
||||
|
||||
static public PShape2D createShape(PApplet parent, PShape src) {
|
||||
PShape2D dest = null;
|
||||
if (src.getFamily() == GROUP) {
|
||||
dest = PGraphics2D.createShapeImpl(parent, GROUP);
|
||||
PShape2D.copyGroup(parent, src, dest);
|
||||
} else if (src.getFamily() == PRIMITIVE) {
|
||||
dest = PGraphics2D.createShapeImpl(parent, src.getKind(), src.getParams());
|
||||
PShape.copyPrimitive(src, dest);
|
||||
} else if (src.getFamily() == GEOMETRY) {
|
||||
dest = PGraphics2D.createShapeImpl(parent, src.getKind());
|
||||
PShape.copyGeometry(src, dest);
|
||||
} else if (src.getFamily() == PATH) {
|
||||
dest = PGraphics2D.createShapeImpl(parent, PATH);
|
||||
PShape.copyPath(src, dest);
|
||||
}
|
||||
dest.setName(src.getName());
|
||||
return dest;
|
||||
}
|
||||
|
||||
|
||||
static public void copyGroup(PApplet parent, PShape src, PShape dest) {
|
||||
copyMatrix(src, dest);
|
||||
copyStyles(src, dest);
|
||||
copyImage(src, dest);
|
||||
|
||||
for (int i = 0; i < src.getChildCount(); i++) {
|
||||
PShape c = PShape2D.createShape(parent, src.getChild(i));
|
||||
dest.addChild(c);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
package processing.opengl;
|
||||
|
||||
import processing.core.PApplet;
|
||||
import processing.core.PShape;
|
||||
|
||||
public class PShape3D extends PShapeOpenGL {
|
||||
|
||||
@@ -37,5 +38,42 @@ public class PShape3D extends PShapeOpenGL {
|
||||
public boolean is3D() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Shape copy
|
||||
|
||||
|
||||
static public PShape3D createShape(PApplet parent, PShape src) {
|
||||
PShape3D dest = null;
|
||||
if (src.getFamily() == GROUP) {
|
||||
dest = PGraphics3D.createShapeImpl(parent, GROUP);
|
||||
PShape3D.copyGroup(parent, src, dest);
|
||||
} else if (src.getFamily() == PRIMITIVE) {
|
||||
dest = PGraphics3D.createShapeImpl(parent, src.getKind(), src.getParams());
|
||||
PShape.copyPrimitive(src, dest);
|
||||
} else if (src.getFamily() == GEOMETRY) {
|
||||
dest = PGraphics3D.createShapeImpl(parent, src.getKind());
|
||||
PShape.copyGeometry(src, dest);
|
||||
} else if (src.getFamily() == PATH) {
|
||||
dest = PGraphics3D.createShapeImpl(parent, PATH);
|
||||
PShape.copyPath(src, dest);
|
||||
}
|
||||
dest.setName(src.getName());
|
||||
return dest;
|
||||
}
|
||||
|
||||
|
||||
static public void copyGroup(PApplet parent, PShape src, PShape dest) {
|
||||
copyMatrix(src, dest);
|
||||
copyStyles(src, dest);
|
||||
copyImage(src, dest);
|
||||
|
||||
for (int i = 0; i < src.getChildCount(); i++) {
|
||||
PShape c = PShape3D.createShape(parent, src.getChild(i));
|
||||
dest.addChild(c);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -272,9 +272,11 @@ public class PShapeOpenGL extends PShape {
|
||||
protected int firstModifiedPointAttribute;
|
||||
protected int lastModifiedPointAttribute;
|
||||
|
||||
|
||||
PShapeOpenGL() {
|
||||
}
|
||||
|
||||
|
||||
public PShapeOpenGL(PApplet parent, int family) {
|
||||
pg = (PGraphicsOpenGL)parent.g;
|
||||
pgl = pg.pgl;
|
||||
@@ -2558,8 +2560,17 @@ public class PShapeOpenGL extends PShape {
|
||||
int[] color = tessGeo.polyColors;
|
||||
float[] uv = tessGeo.polyTexcoords;
|
||||
short[] indices = tessGeo.polyIndices;
|
||||
|
||||
PShape tess;
|
||||
if (is3D()) {
|
||||
tess = PGraphics3D.createShapeImpl(pg.parent, TRIANGLES);
|
||||
} else if (is2D()) {
|
||||
tess = PGraphics2D.createShapeImpl(pg.parent, TRIANGLES);
|
||||
} else {
|
||||
PGraphics.showWarning("This shape is not either 2D or 3D!");
|
||||
return null;
|
||||
}
|
||||
|
||||
PShape tess = pg.createShape(TRIANGLES);
|
||||
tess.noStroke();
|
||||
|
||||
IndexCache cache = tessGeo.polyIndexCache;
|
||||
@@ -2721,6 +2732,7 @@ public class PShapeOpenGL extends PShape {
|
||||
// duplication.
|
||||
inGeo.clearEdges();
|
||||
|
||||
tessellator.set3D(is3D());
|
||||
tessellator.setInGeometry(inGeo);
|
||||
tessellator.setTessGeometry(tessGeo);
|
||||
tessellator.setFill(fill || texture != null);
|
||||
|
||||
Reference in New Issue
Block a user