Merge branch 'master' of github.com:processing/processing

This commit is contained in:
Ben Fry
2014-07-22 17:30:38 -04:00
7 changed files with 295 additions and 128 deletions

View File

@@ -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);
}

View 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;
}

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -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.

View 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);
}

View File

@@ -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);
}