mirror of
https://github.com/processing/processing4.git
synced 2026-02-04 06:09:17 +01:00
Merge branch 'master' of github.com:processing/processing
This commit is contained in:
@@ -2664,8 +2664,8 @@ public class PGraphics extends PImage implements PConstants {
|
||||
}
|
||||
|
||||
if (stop - start > TWO_PI) {
|
||||
start = 0;
|
||||
stop = TWO_PI;
|
||||
// don't change start, it is visible in PIE mode
|
||||
stop = start + TWO_PI;
|
||||
}
|
||||
arcImpl(x, y, w, h, start, stop, mode);
|
||||
}
|
||||
|
||||
31
core/src/processing/opengl/LightFrag.glsl
Normal file
31
core/src/processing/opengl/LightFrag.glsl
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
Part of the Processing project - http://processing.org
|
||||
|
||||
Copyright (c) 2011-13 Ben Fry and Casey Reas
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License version 2.1 as published by the Free Software Foundation.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General
|
||||
Public License along with this library; if not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
precision mediump int;
|
||||
#endif
|
||||
|
||||
varying vec4 vertColor;
|
||||
varying vec4 backVertColor;
|
||||
|
||||
void main() {
|
||||
gl_FragColor = gl_FrontFacing ? vertColor : backVertColor;
|
||||
}
|
||||
@@ -43,6 +43,7 @@ attribute vec4 emissive;
|
||||
attribute float shininess;
|
||||
|
||||
varying vec4 vertColor;
|
||||
varying vec4 backVertColor;
|
||||
|
||||
const float zero_float = 0.0;
|
||||
const float one_float = 1.0;
|
||||
@@ -82,17 +83,17 @@ void main() {
|
||||
|
||||
// Normal vector in eye coordinates
|
||||
vec3 ecNormal = normalize(normalMatrix * normal);
|
||||
|
||||
if (dot(-one_float * ecVertex, ecNormal) < zero_float) {
|
||||
// If normal is away from camera, choose its opposite.
|
||||
// If we add backface culling, this will be backfacing
|
||||
ecNormal *= -one_float;
|
||||
}
|
||||
vec3 ecNormalInv = ecNormal * -one_float;
|
||||
|
||||
// Light calculations
|
||||
vec3 totalAmbient = vec3(0, 0, 0);
|
||||
vec3 totalDiffuse = vec3(0, 0, 0);
|
||||
vec3 totalSpecular = vec3(0, 0, 0);
|
||||
|
||||
vec3 totalFrontDiffuse = vec3(0, 0, 0);
|
||||
vec3 totalFrontSpecular = vec3(0, 0, 0);
|
||||
|
||||
vec3 totalBackDiffuse = vec3(0, 0, 0);
|
||||
vec3 totalBackSpecular = vec3(0, 0, 0);
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if (lightCount == i) break;
|
||||
|
||||
@@ -118,24 +119,33 @@ void main() {
|
||||
: one_float;
|
||||
|
||||
if (any(greaterThan(lightAmbient[i], zero_vec3))) {
|
||||
totalAmbient += lightAmbient[i] * falloff;
|
||||
totalAmbient += lightAmbient[i] * falloff;
|
||||
}
|
||||
|
||||
if (any(greaterThan(lightDiffuse[i], zero_vec3))) {
|
||||
totalDiffuse += lightDiffuse[i] * falloff * spotf *
|
||||
lambertFactor(lightDir, ecNormal);
|
||||
totalFrontDiffuse += lightDiffuse[i] * falloff * spotf *
|
||||
lambertFactor(lightDir, ecNormal);
|
||||
totalBackDiffuse += lightDiffuse[i] * falloff * spotf *
|
||||
lambertFactor(lightDir, ecNormalInv);
|
||||
}
|
||||
|
||||
if (any(greaterThan(lightSpecular[i], zero_vec3))) {
|
||||
totalSpecular += lightSpecular[i] * falloff * spotf *
|
||||
blinnPhongFactor(lightDir, ecVertex, ecNormal, shininess);
|
||||
totalFrontSpecular += lightSpecular[i] * falloff * spotf *
|
||||
blinnPhongFactor(lightDir, ecVertex, ecNormal, shininess);
|
||||
totalBackSpecular += lightSpecular[i] * falloff * spotf *
|
||||
blinnPhongFactor(lightDir, ecVertex, ecNormalInv, shininess);
|
||||
}
|
||||
}
|
||||
|
||||
// Calculating final color as result of all lights (plus emissive term).
|
||||
// Transparency is determined exclusively by the diffuse component.
|
||||
vertColor = vec4(totalAmbient, 0) * ambient +
|
||||
vec4(totalDiffuse, 1) * color +
|
||||
vec4(totalSpecular, 0) * specular +
|
||||
vec4(emissive.rgb, 0);
|
||||
vertColor = vec4(totalAmbient, 0) * ambient +
|
||||
vec4(totalFrontDiffuse, 1) * color +
|
||||
vec4(totalFrontSpecular, 0) * specular +
|
||||
vec4(emissive.rgb, 0);
|
||||
|
||||
backVertColor = vec4(totalAmbient, 0) * ambient +
|
||||
vec4(totalBackDiffuse, 1) * color +
|
||||
vec4(totalBackSpecular, 0) * specular +
|
||||
vec4(emissive.rgb, 0);
|
||||
}
|
||||
@@ -160,6 +160,11 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
PGraphicsOpenGL.class.getResource("ColorFrag.glsl");
|
||||
static protected URL defTextureShaderFragURL =
|
||||
PGraphicsOpenGL.class.getResource("TextureFrag.glsl");
|
||||
static protected URL defLightShaderFragURL =
|
||||
PGraphicsOpenGL.class.getResource("LightFrag.glsl");
|
||||
static protected URL defTexlightShaderFragURL =
|
||||
PGraphicsOpenGL.class.getResource("TexlightFrag.glsl");
|
||||
|
||||
static protected URL defLineShaderVertURL =
|
||||
PGraphicsOpenGL.class.getResource("LineVert.glsl");
|
||||
static protected URL defLineShaderFragURL =
|
||||
@@ -379,9 +384,9 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
/** PImage that wraps filterTexture. */
|
||||
protected PImage filterImage;
|
||||
|
||||
/** Flag to indicate if the user is manipulating the
|
||||
* pixels array through the set()/get() methods */
|
||||
protected boolean setgetPixels;
|
||||
/** Flag to indicate that pixels array is up-to-date and
|
||||
* ready to be manipulated through the set()/get() methods */
|
||||
protected boolean arePixelsUpToDate;
|
||||
|
||||
// ........................................................
|
||||
|
||||
@@ -2151,6 +2156,9 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
if ((flushMode == FLUSH_CONTINUOUSLY) ||
|
||||
(flushMode == FLUSH_WHEN_FULL && tessGeo.isFull())) {
|
||||
flush();
|
||||
} else {
|
||||
// pixels array is not up-to-date anymore
|
||||
arePixelsUpToDate = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2166,6 +2174,9 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
if (flushMode == FLUSH_CONTINUOUSLY ||
|
||||
(flushMode == FLUSH_WHEN_FULL && tessGeo.isFull())) {
|
||||
flush();
|
||||
} else {
|
||||
// pixels array is not up-to-date anymore
|
||||
arePixelsUpToDate = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2443,7 +2454,7 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
|
||||
tessGeo.clear();
|
||||
texCache.clear();
|
||||
setgetPixels = false;
|
||||
arePixelsUpToDate = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -3237,6 +3248,7 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
normalMode = NORMAL_MODE_SHAPE;
|
||||
inGeo.setMaterial(fillColor, strokeColor, strokeWeight,
|
||||
ambientColor, specularColor, emissiveColor, shininess);
|
||||
|
||||
inGeo.setNormal(normalX, normalY, normalZ);
|
||||
inGeo.addArc(x, y, w, h, start, stop, fill, stroke, mode);
|
||||
endShape();
|
||||
@@ -5435,7 +5447,7 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
needEndDraw = true;
|
||||
}
|
||||
|
||||
if (!setgetPixels) {
|
||||
if (!arePixelsUpToDate) {
|
||||
// Draws any remaining geometry in case the user is still not
|
||||
// setting/getting new pixels.
|
||||
flush();
|
||||
@@ -5443,10 +5455,13 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
|
||||
allocatePixels();
|
||||
|
||||
if (!setgetPixels) {
|
||||
if (!arePixelsUpToDate) {
|
||||
readPixels();
|
||||
}
|
||||
|
||||
// Pixels are now up-to-date, set the flag.
|
||||
arePixelsUpToDate = true;
|
||||
|
||||
if (needEndDraw) {
|
||||
endDraw();
|
||||
}
|
||||
@@ -5566,7 +5581,6 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
@Override
|
||||
public int get(int x, int y) {
|
||||
loadPixels();
|
||||
setgetPixels = true;
|
||||
return super.get(x, y);
|
||||
}
|
||||
|
||||
@@ -5576,7 +5590,6 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
int sourceWidth, int sourceHeight,
|
||||
PImage target, int targetX, int targetY) {
|
||||
loadPixels();
|
||||
setgetPixels = true;
|
||||
super.getImpl(sourceX, sourceY, sourceWidth, sourceHeight,
|
||||
target, targetX, targetY);
|
||||
}
|
||||
@@ -5585,7 +5598,6 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
@Override
|
||||
public void set(int x, int y, int argb) {
|
||||
loadPixels();
|
||||
setgetPixels = true;
|
||||
super.set(x, y, argb);
|
||||
}
|
||||
|
||||
@@ -5596,7 +5608,6 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
int sourceWidth, int sourceHeight,
|
||||
int targetX, int targetY) {
|
||||
loadPixels();
|
||||
setgetPixels = true;
|
||||
super.setImpl(sourceImage, sourceX, sourceY, sourceWidth, sourceHeight,
|
||||
targetX, targetY);
|
||||
// do we need this?
|
||||
@@ -6531,8 +6542,12 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
lightSpecular(0, 0, 0);
|
||||
}
|
||||
|
||||
// Because y is flipped, the vertices that should be specified by
|
||||
// the user in CCW order to define a front-facing facet, end up being CW.
|
||||
// Vertices should be specified by user in CW order (left-handed)
|
||||
// That is CCW order (right-handed). Vertex shader inverts
|
||||
// Y-axis and outputs vertices in CW order (right-handed).
|
||||
// Culling occurs after the vertex shader, so FRONT FACE
|
||||
// has to be set to CW (right-handed) for OpenGL to correctly
|
||||
// recognize FRONT and BACK faces.
|
||||
pgl.frontFace(PGL.CW);
|
||||
pgl.disable(PGL.CULL_FACE);
|
||||
|
||||
@@ -6540,7 +6555,8 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
pgl.activeTexture(PGL.TEXTURE0);
|
||||
|
||||
// The current normal vector is set to be parallel to the Z axis.
|
||||
normalX = normalY = normalZ = 0;
|
||||
normalX = normalY = 0;
|
||||
normalZ = 1;
|
||||
|
||||
// Clear depth and stencil buffers.
|
||||
pgl.depthMask(true);
|
||||
@@ -6569,7 +6585,7 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
clearColorBuffer = false;
|
||||
|
||||
modified = false;
|
||||
setgetPixels = false;
|
||||
arePixelsUpToDate = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -6740,7 +6756,7 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
if (useDefault || !polyShader.checkPolyType(PShader.TEXLIGHT)) {
|
||||
if (ppg.defTexlightShader == null) {
|
||||
String[] vertSource = pgl.loadVertexShader(defTexlightShaderVertURL, 120);
|
||||
String[] fragSource = pgl.loadFragmentShader(defTextureShaderFragURL, 120);
|
||||
String[] fragSource = pgl.loadFragmentShader(defTexlightShaderFragURL, 120);
|
||||
ppg.defTexlightShader = new PShader(parent, vertSource, fragSource);
|
||||
}
|
||||
shader = ppg.defTexlightShader;
|
||||
@@ -6751,7 +6767,7 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
if (useDefault || !polyShader.checkPolyType(PShader.LIGHT)) {
|
||||
if (ppg.defLightShader == null) {
|
||||
String[] vertSource = pgl.loadVertexShader(defLightShaderVertURL, 120);
|
||||
String[] fragSource = pgl.loadFragmentShader(defColorShaderFragURL, 120);
|
||||
String[] fragSource = pgl.loadFragmentShader(defLightShaderFragURL, 120);
|
||||
ppg.defLightShader = new PShader(parent, vertSource, fragSource);
|
||||
}
|
||||
shader = ppg.defLightShader;
|
||||
@@ -7798,6 +7814,7 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
//
|
||||
// Normal calculation
|
||||
|
||||
// Expects vertices in CW (left-handed) order.
|
||||
void calcTriangleNormal(int i0, int i1, int i2) {
|
||||
int index;
|
||||
|
||||
@@ -7825,9 +7842,9 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
float v10z = z0 - z1;
|
||||
|
||||
// The automatic normal calculation in Processing assumes
|
||||
// that vertices as given in CCW order so:
|
||||
// that vertices as given in CCW order (right-handed) so:
|
||||
// n = v12 x v10
|
||||
// so that the normal outwards.
|
||||
// so that the normal extends from the front face.
|
||||
float nx = v12y * v10z - v10y * v12z;
|
||||
float ny = v12z * v10x - v10z * v12x;
|
||||
float nz = v12x * v10y - v10x * v12y;
|
||||
@@ -7876,14 +7893,18 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
for (int i = 1; i < vertexCount - 1; i++) {
|
||||
int i1 = i;
|
||||
int i0, i2;
|
||||
if (i % 2 == 0) {
|
||||
// The even triangles (0, 2, 4...) should be CW
|
||||
i0 = i + 1;
|
||||
i2 = i - 1;
|
||||
} else {
|
||||
// The even triangles (1, 3, 5...) should be CCW
|
||||
// Vertices are specified by user as:
|
||||
// 1-3 ...
|
||||
// |\|\ ...
|
||||
// 0-2-4 ...
|
||||
if (i % 2 == 1) {
|
||||
// The odd triangles (1, 3, 5...) should be CW (left-handed)
|
||||
i0 = i - 1;
|
||||
i2 = i + 1;
|
||||
} else {
|
||||
// The even triangles (2, 4, 6...) should be CCW (left-handed)
|
||||
i0 = i + 1;
|
||||
i2 = i - 1;
|
||||
}
|
||||
calcTriangleNormal(i0, i1, i2);
|
||||
}
|
||||
@@ -7908,8 +7929,14 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
int i2 = 2 * qd;
|
||||
int i3 = 2 * qd + 1;
|
||||
|
||||
calcTriangleNormal(i0, i3, i1);
|
||||
calcTriangleNormal(i0, i2, i3);
|
||||
// Vertices are specified by user as:
|
||||
// 1-3-5 ...
|
||||
// |\|\| ...
|
||||
// 0-2-4 ...
|
||||
// thus (0, 1, 2) and (2, 1, 3) are triangles
|
||||
// in CW order (left-handed).
|
||||
calcTriangleNormal(i0, i1, i2);
|
||||
calcTriangleNormal(i2, i1, i3);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8081,56 +8108,108 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
int startLUT = (int) (0.5f + (start / TWO_PI) * SINCOS_LENGTH);
|
||||
int stopLUT = (int) (0.5f + (stop / TWO_PI) * SINCOS_LENGTH);
|
||||
|
||||
int idx0 = addVertex(centerX, centerY, VERTEX, true);
|
||||
// get length before wrapping indexes so (startLUT <= stopLUT);
|
||||
int length = PApplet.constrain(stopLUT - startLUT, 0, SINCOS_LENGTH);
|
||||
|
||||
int increment = 1; // what's a good algorithm? stopLUT - startLUT;
|
||||
int pidx = 0, idx = 0;
|
||||
for (int i = startLUT; i < stopLUT; i += increment) {
|
||||
int ii = i % SINCOS_LENGTH;
|
||||
// modulo won't make the value positive
|
||||
if (ii < 0) ii += SINCOS_LENGTH;
|
||||
boolean fullCircle = length == SINCOS_LENGTH;
|
||||
|
||||
if (fullCircle && arcMode == CHORD) {
|
||||
// get rid of overlapping vertices,
|
||||
// solves problem with closing edge in P3D
|
||||
length -= 1;
|
||||
stopLUT -= 1;
|
||||
}
|
||||
|
||||
{ // wrap indexes so they are safe to use in LUT
|
||||
startLUT %= SINCOS_LENGTH;
|
||||
if (startLUT < 0) startLUT += SINCOS_LENGTH;
|
||||
|
||||
stopLUT %= SINCOS_LENGTH;
|
||||
if (stopLUT < 0) stopLUT += SINCOS_LENGTH;
|
||||
}
|
||||
|
||||
int idx0;
|
||||
if (arcMode == CHORD || arcMode == OPEN) {
|
||||
// move center to the middle of flat side
|
||||
// to properly display arcs smaller than PI
|
||||
float relX = (cosLUT[startLUT] + cosLUT[stopLUT]) * 0.5f * hr;
|
||||
float relY = (sinLUT[startLUT] + sinLUT[stopLUT]) * 0.5f * vr;
|
||||
idx0 = addVertex(centerX + relX, centerY + relY, VERTEX, true);
|
||||
} else {
|
||||
idx0 = addVertex(centerX, centerY, VERTEX, true);
|
||||
}
|
||||
|
||||
int inc;
|
||||
{ // initializes inc the same way ellipse does
|
||||
float sx1 = pg.screenX(x, y);
|
||||
float sy1 = pg.screenY(x, y);
|
||||
float sx2 = pg.screenX(x + w, y + h);
|
||||
float sy2 = pg.screenY(x + w, y + h);
|
||||
|
||||
int accuracy =
|
||||
PApplet.min(MAX_POINT_ACCURACY, PApplet.max(MIN_POINT_ACCURACY,
|
||||
(int) (TWO_PI * PApplet.dist(sx1, sy1, sx2, sy2) /
|
||||
POINT_ACCURACY_FACTOR)));
|
||||
inc = PApplet.max(1, SINCOS_LENGTH / accuracy);
|
||||
}
|
||||
|
||||
int idx = idx0;
|
||||
int pidx;
|
||||
|
||||
int i = -inc;
|
||||
int ii;
|
||||
|
||||
// i: (0 -> length) inclusive
|
||||
// ii: (startLUT -> stopLUT) inclusive, going CW (left-handed),
|
||||
// wrapping around end of LUT
|
||||
do {
|
||||
i += inc;
|
||||
i = PApplet.min(i, length); // clamp so last vertex won't go over
|
||||
|
||||
ii = startLUT + i; // ii from 0 to (2 * SINCOS_LENGTH - 1)
|
||||
if (ii >= SINCOS_LENGTH) ii -= SINCOS_LENGTH;
|
||||
|
||||
pidx = idx;
|
||||
idx = addVertex(centerX + cosLUT[ii] * hr,
|
||||
centerY + sinLUT[ii] * vr,
|
||||
VERTEX, i == startLUT && !fill);
|
||||
VERTEX, i == 0 && !fill);
|
||||
|
||||
if (stroke) {
|
||||
if (arcMode == PIE) {
|
||||
addEdge(pidx, idx, i == startLUT, false);
|
||||
} else if (startLUT < i) {
|
||||
addEdge(pidx, idx, i == startLUT + 1, arcMode == 0 &&
|
||||
i == stopLUT - 1);
|
||||
if (arcMode == CHORD || arcMode == PIE) {
|
||||
addEdge(pidx, idx, i == 0, false);
|
||||
} else if (0 < i) {
|
||||
// when drawing full circle, the edge is closed later
|
||||
addEdge(pidx, idx, i == inc, i == length && !fullCircle);
|
||||
}
|
||||
}
|
||||
} while (i < length);
|
||||
|
||||
// keeping last vertex as idx and second last vertex as pidx
|
||||
|
||||
pidx = idx;
|
||||
}
|
||||
// draw last point explicitly for accuracy
|
||||
idx = addVertex(centerX + cosLUT[stopLUT % SINCOS_LENGTH] * hr,
|
||||
centerY + sinLUT[stopLUT % SINCOS_LENGTH] * vr,
|
||||
VERTEX, false);
|
||||
if (stroke) {
|
||||
if (arcMode == PIE) {
|
||||
if (arcMode == CHORD || arcMode == PIE) {
|
||||
addEdge(idx, idx0, false, false);
|
||||
closeEdge(idx, idx0);
|
||||
}
|
||||
}
|
||||
if (arcMode == CHORD || arcMode == OPEN) {
|
||||
// Add a last vertex coincident with the first along the perimeter
|
||||
pidx = idx;
|
||||
int i = startLUT;
|
||||
int ii = i % SINCOS_LENGTH;
|
||||
if (ii < 0) ii += SINCOS_LENGTH;
|
||||
idx = addVertex(centerX + cosLUT[ii] * hr,
|
||||
centerY + sinLUT[ii] * vr,
|
||||
VERTEX, false);
|
||||
if (stroke && arcMode == CHORD) {
|
||||
addEdge(pidx, idx, false, true);
|
||||
} else if (fullCircle) {
|
||||
closeEdge(pidx, idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void addBox(float w, float h, float d,
|
||||
boolean fill, boolean stroke) {
|
||||
|
||||
// Correct normals if some dimensions are negative so they always
|
||||
// extend from front face. We could just take absolute value
|
||||
// of dimensions, but that would affect texturing.
|
||||
boolean invertNormX = (h > 0) != (d > 0);
|
||||
boolean invertNormY = (w > 0) != (d > 0);
|
||||
boolean invertNormZ = (w > 0) != (h > 0);
|
||||
|
||||
int normX = invertNormX ? -1 : 1;
|
||||
int normY = invertNormY ? -1 : 1;
|
||||
int normZ = invertNormZ ? -1 : 1;
|
||||
|
||||
float x1 = -w/2f; float x2 = w/2f;
|
||||
float y1 = -h/2f; float y2 = h/2f;
|
||||
float z1 = -d/2f; float z2 = d/2f;
|
||||
@@ -8138,11 +8217,11 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
int idx1 = 0, idx2 = 0, idx3 = 0, idx4 = 0;
|
||||
if (fill || stroke) {
|
||||
// back face
|
||||
setNormal(0, 0, -1);
|
||||
setNormal(0, 0, -normZ);
|
||||
idx1 = addVertex(x1, y1, z1, 0, 0, VERTEX, true);
|
||||
idx2 = addVertex(x2, y1, z1, 1, 0, VERTEX, false);
|
||||
idx2 = addVertex(x1, y2, z1, 0, 1, VERTEX, false);
|
||||
idx3 = addVertex(x2, y2, z1, 1, 1, VERTEX, false);
|
||||
idx4 = addVertex(x1, y2, z1, 0, 1, VERTEX, false);
|
||||
idx4 = addVertex(x2, y1, z1, 1, 0, VERTEX, false);
|
||||
if (stroke) {
|
||||
addEdge(idx1, idx2, true, false);
|
||||
addEdge(idx2, idx3, false, false);
|
||||
@@ -8152,10 +8231,10 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
}
|
||||
|
||||
// front face
|
||||
setNormal(0, 0, 1);
|
||||
idx1 = addVertex(x2, y1, z2, 0, 0, VERTEX, false);
|
||||
setNormal(0, 0, normZ);
|
||||
idx1 = addVertex(x1, y2, z2, 1, 1, VERTEX, false);
|
||||
idx2 = addVertex(x1, y1, z2, 1, 0, VERTEX, false);
|
||||
idx3 = addVertex(x1, y2, z2, 1, 1, VERTEX, false);
|
||||
idx3 = addVertex(x2, y1, z2, 0, 0, VERTEX, false);
|
||||
idx4 = addVertex(x2, y2, z2, 0, 1, VERTEX, false);
|
||||
if (stroke) {
|
||||
addEdge(idx1, idx2, true, false);
|
||||
@@ -8166,11 +8245,11 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
}
|
||||
|
||||
// right face
|
||||
setNormal(1, 0, 0);
|
||||
setNormal(normX, 0, 0);
|
||||
idx1 = addVertex(x2, y1, z1, 0, 0, VERTEX, false);
|
||||
idx2 = addVertex(x2, y1, z2, 1, 0, VERTEX, false);
|
||||
idx2 = addVertex(x2, y2, z1, 0, 1, VERTEX, false);
|
||||
idx3 = addVertex(x2, y2, z2, 1, 1, VERTEX, false);
|
||||
idx4 = addVertex(x2, y2, z1, 0, 1, VERTEX, false);
|
||||
idx4 = addVertex(x2, y1, z2, 1, 0, VERTEX, false);
|
||||
if (stroke) {
|
||||
addEdge(idx1, idx2, true, false);
|
||||
addEdge(idx2, idx3, false, false);
|
||||
@@ -8180,10 +8259,10 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
}
|
||||
|
||||
// left face
|
||||
setNormal(-1, 0, 0);
|
||||
idx1 = addVertex(x1, y1, z2, 0, 0, VERTEX, false);
|
||||
setNormal(-normX, 0, 0);
|
||||
idx1 = addVertex(x1, y2, z1, 1, 1, VERTEX, false);
|
||||
idx2 = addVertex(x1, y1, z1, 1, 0, VERTEX, false);
|
||||
idx3 = addVertex(x1, y2, z1, 1, 1, VERTEX, false);
|
||||
idx3 = addVertex(x1, y1, z2, 0, 0, VERTEX, false);
|
||||
idx4 = addVertex(x1, y2, z2, 0, 1, VERTEX, false);
|
||||
if (stroke) {
|
||||
addEdge(idx1, idx2, true, false);
|
||||
@@ -8193,26 +8272,26 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
closeEdge(idx4, idx1);
|
||||
}
|
||||
|
||||
// bottom face
|
||||
setNormal(0, -1, 0);
|
||||
idx1 = addVertex(x1, y1, z2, 0, 0, VERTEX, false);
|
||||
idx2 = addVertex(x2, y1, z2, 1, 0, VERTEX, false);
|
||||
idx3 = addVertex(x2, y1, z1, 1, 1, VERTEX, false);
|
||||
idx4 = addVertex(x1, y1, z1, 0, 1, VERTEX, false);
|
||||
if (stroke) {
|
||||
addEdge(idx1, idx2, true, false);
|
||||
addEdge(idx2, idx3, false, false);
|
||||
addEdge(idx3, idx4, false, false);
|
||||
addEdge(idx4, idx1, false, false);
|
||||
closeEdge(idx4, idx1);
|
||||
}
|
||||
|
||||
// top face
|
||||
setNormal(0, 1, 0);
|
||||
setNormal(0, -normY, 0);
|
||||
idx1 = addVertex(x2, y1, z1, 1, 1, VERTEX, false);
|
||||
idx2 = addVertex(x2, y1, z2, 1, 0, VERTEX, false);
|
||||
idx3 = addVertex(x1, y1, z2, 0, 0, VERTEX, false);
|
||||
idx4 = addVertex(x1, y1, z1, 0, 1, VERTEX, false);
|
||||
if (stroke) {
|
||||
addEdge(idx1, idx2, true, false);
|
||||
addEdge(idx2, idx3, false, false);
|
||||
addEdge(idx3, idx4, false, false);
|
||||
addEdge(idx4, idx1, false, false);
|
||||
closeEdge(idx4, idx1);
|
||||
}
|
||||
|
||||
// bottom face
|
||||
setNormal(0, normY, 0);
|
||||
idx1 = addVertex(x1, y2, z1, 0, 0, VERTEX, false);
|
||||
idx2 = addVertex(x2, y2, z1, 1, 0, VERTEX, false);
|
||||
idx2 = addVertex(x1, y2, z2, 0, 1, VERTEX, false);
|
||||
idx3 = addVertex(x2, y2, z2, 1, 1, VERTEX, false);
|
||||
idx4 = addVertex(x1, y2, z2, 0, 1, VERTEX, false);
|
||||
idx4 = addVertex(x2, y2, z1, 1, 0, VERTEX, false);
|
||||
if (stroke) {
|
||||
addEdge(idx1, idx2, true, false);
|
||||
addEdge(idx2, idx3, false, false);
|
||||
@@ -8342,8 +8421,8 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
int i0 = vert0 + i;
|
||||
int i1 = vert0 + i + detailU + 1;
|
||||
|
||||
indices[indCount + 3 * i + 0] = i0;
|
||||
indices[indCount + 3 * i + 1] = i1;
|
||||
indices[indCount + 3 * i + 0] = i1;
|
||||
indices[indCount + 3 * i + 1] = i0;
|
||||
indices[indCount + 3 * i + 2] = i0 + 1;
|
||||
|
||||
addEdge(i0, i0 + 1, true, true);
|
||||
@@ -9169,6 +9248,7 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
//
|
||||
// Normal calculation
|
||||
|
||||
// Expects vertices in CW (left-handed) order.
|
||||
void calcPolyNormal(int i0, int i1, int i2) {
|
||||
int index;
|
||||
|
||||
|
||||
@@ -167,7 +167,7 @@ public class PJOGL extends PGL {
|
||||
|
||||
/** This countdown latch is used to maintain the synchronization between
|
||||
* Processing's drawing thread and JOGL's rendering thread */
|
||||
protected CountDownLatch drawLatch;
|
||||
protected CountDownLatch drawLatch = new CountDownLatch(0);
|
||||
|
||||
/** Flag used to do request final display() call to make sure that the
|
||||
* buffers are properly swapped.
|
||||
|
||||
36
core/src/processing/opengl/TexlightFrag.glsl
Normal file
36
core/src/processing/opengl/TexlightFrag.glsl
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
Part of the Processing project - http://processing.org
|
||||
|
||||
Copyright (c) 2011-13 Ben Fry and Casey Reas
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License version 2.1 as published by the Free Software Foundation.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General
|
||||
Public License along with this library; if not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
precision mediump int;
|
||||
#endif
|
||||
|
||||
uniform sampler2D texture;
|
||||
|
||||
uniform vec2 texOffset;
|
||||
|
||||
varying vec4 vertColor;
|
||||
varying vec4 backVertColor;
|
||||
varying vec4 vertTexCoord;
|
||||
|
||||
void main() {
|
||||
gl_FragColor = texture2D(texture, vertTexCoord.st) * (gl_FrontFacing ? vertColor : backVertColor);
|
||||
}
|
||||
@@ -45,6 +45,7 @@ attribute vec4 emissive;
|
||||
attribute float shininess;
|
||||
|
||||
varying vec4 vertColor;
|
||||
varying vec4 backVertColor;
|
||||
varying vec4 vertTexCoord;
|
||||
|
||||
const float zero_float = 0.0;
|
||||
@@ -85,17 +86,17 @@ void main() {
|
||||
|
||||
// Normal vector in eye coordinates
|
||||
vec3 ecNormal = normalize(normalMatrix * normal);
|
||||
|
||||
if (dot(-one_float * ecVertex, ecNormal) < zero_float) {
|
||||
// If normal is away from camera, choose its opposite.
|
||||
// If we add backface culling, this will be backfacing
|
||||
ecNormal *= -one_float;
|
||||
}
|
||||
vec3 ecNormalInv = ecNormal * -one_float;
|
||||
|
||||
// Light calculations
|
||||
vec3 totalAmbient = vec3(0, 0, 0);
|
||||
vec3 totalDiffuse = vec3(0, 0, 0);
|
||||
vec3 totalSpecular = vec3(0, 0, 0);
|
||||
|
||||
vec3 totalFrontDiffuse = vec3(0, 0, 0);
|
||||
vec3 totalFrontSpecular = vec3(0, 0, 0);
|
||||
|
||||
vec3 totalBackDiffuse = vec3(0, 0, 0);
|
||||
vec3 totalBackSpecular = vec3(0, 0, 0);
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if (lightCount == i) break;
|
||||
|
||||
@@ -121,27 +122,36 @@ void main() {
|
||||
: one_float;
|
||||
|
||||
if (any(greaterThan(lightAmbient[i], zero_vec3))) {
|
||||
totalAmbient += lightAmbient[i] * falloff;
|
||||
totalAmbient += lightAmbient[i] * falloff;
|
||||
}
|
||||
|
||||
if (any(greaterThan(lightDiffuse[i], zero_vec3))) {
|
||||
totalDiffuse += lightDiffuse[i] * falloff * spotf *
|
||||
lambertFactor(lightDir, ecNormal);
|
||||
totalFrontDiffuse += lightDiffuse[i] * falloff * spotf *
|
||||
lambertFactor(lightDir, ecNormal);
|
||||
totalBackDiffuse += lightDiffuse[i] * falloff * spotf *
|
||||
lambertFactor(lightDir, ecNormalInv);
|
||||
}
|
||||
|
||||
if (any(greaterThan(lightSpecular[i], zero_vec3))) {
|
||||
totalSpecular += lightSpecular[i] * falloff * spotf *
|
||||
blinnPhongFactor(lightDir, ecVertex, ecNormal, shininess);
|
||||
}
|
||||
totalFrontSpecular += lightSpecular[i] * falloff * spotf *
|
||||
blinnPhongFactor(lightDir, ecVertex, ecNormal, shininess);
|
||||
totalBackSpecular += lightSpecular[i] * falloff * spotf *
|
||||
blinnPhongFactor(lightDir, ecVertex, ecNormalInv, shininess);
|
||||
}
|
||||
}
|
||||
|
||||
// Calculating final color as result of all lights (plus emissive term).
|
||||
// Transparency is determined exclusively by the diffuse component.
|
||||
vertColor = vec4(totalAmbient, 0) * ambient +
|
||||
vec4(totalDiffuse, 1) * color +
|
||||
vec4(totalSpecular, 0) * specular +
|
||||
vec4(emissive.rgb, 0);
|
||||
vertColor = vec4(totalAmbient, 0) * ambient +
|
||||
vec4(totalFrontDiffuse, 1) * color +
|
||||
vec4(totalFrontSpecular, 0) * specular +
|
||||
vec4(emissive.rgb, 0);
|
||||
|
||||
backVertColor = vec4(totalAmbient, 0) * ambient +
|
||||
vec4(totalBackDiffuse, 1) * color +
|
||||
vec4(totalBackSpecular, 0) * specular +
|
||||
vec4(emissive.rgb, 0);
|
||||
|
||||
// Calculating texture coordinates, with r and q set both to one
|
||||
vertTexCoord = texMatrix * vec4(texCoord, 1.0, 1.0);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user