Fixed lighting issues, added Patch example.

This commit is contained in:
codeanticode
2012-04-10 21:03:47 +00:00
parent 5e7c3d9b61
commit a018d78c2f
7 changed files with 227 additions and 33 deletions
+3 -1
View File
@@ -344,6 +344,7 @@ public class PGraphics extends PImage implements PConstants {
public int ambientColor;
public float ambientR, ambientG, ambientB;
protected boolean setAmbient;
public int specularColor;
public float specularR, specularG, specularB;
@@ -6062,7 +6063,8 @@ public class PGraphics extends PImage implements PConstants {
ambientColor = calcColor;
ambientR = calcR;
ambientG = calcG;
ambientB = calcB;
ambientB = calcB;
setAmbient = true;
}
/**
@@ -0,0 +1,161 @@
// Bezier patch By Maritus Watz:
// http://www.openprocessing.org/sketch/57709
// Normal calculation added by Andres Colubri
// Direct port of sample code by Paul Bourke.
// Original code: http://paulbourke.net/geometry/bezier/
int ni=4, nj=5, RESI=ni*10, RESJ=nj*10;
PVector outp[][], inp[][];
PVector normp[][];
boolean autoNormals = false;
void setup() {
size(600, 600, P3D);
build();
}
void draw() {
background(255);
translate(width/2,height/2);
lights();
scale(0.9);
rotateY(map(mouseX,0,width,-PI,PI));
rotateX(map(mouseY,0,height,-PI,PI));
noStroke();
fill(255);
for(int i=0; i<RESI-1; i++) {
beginShape(QUAD_STRIP);
for(int j=0; j<RESJ; j++) {
if (!autoNormals) {
normal(normp[i][j].x, normp[i][j].y, normp[i][j].z);
}
vertex(outp[i][j].x,outp[i][j].y,outp[i][j].z);
vertex(outp[i+1][j].x,outp[i+1][j].y,outp[i+1][j].z);
}
endShape();
}
}
void keyPressed() {
if(key==' ') build();
if(!online)saveFrame("bezPatch.png");
}
void build() {
int i, j, ki, kj;
double mui, muj, bi, bj, dbi, dbj;
outp=new PVector[RESI][RESJ];
normp=new PVector[RESI][RESJ];
inp=new PVector[ni+1][nj+1];
PVector uitang = new PVector();
PVector ujtang = new PVector();
for (i=0;i<=ni;i++) {
for (j=0;j<=nj;j++) {
inp[i][j]=new PVector(i,j,random(-3,3));
}
}
for (i=0;i<RESI;i++) {
mui = i / (double)(RESI-1);
for (j=0;j<RESJ;j++) {
muj = j / (double)(RESJ-1);
outp[i][j]=new PVector();
uitang.set(0, 0, 0);
ujtang.set(0, 0, 0);
for (ki=0;ki<=ni;ki++) {
bi = BezierBlend(ki, mui, ni);
dbi = DBezierBlend(ki, mui, ni);
for (kj=0;kj<=nj;kj++) {
bj = BezierBlend(kj, muj, nj);
dbj = DBezierBlend(kj, muj, nj);
outp[i][j].x += (inp[ki][kj].x * bi * bj);
outp[i][j].y += (inp[ki][kj].y * bi * bj);
outp[i][j].z += (inp[ki][kj].z * bi * bj);
uitang.x += (inp[ki][kj].x * dbi * bj);
uitang.y += (inp[ki][kj].y * dbi * bj);
uitang.z += (inp[ki][kj].z * dbi * bj);
ujtang.x += (inp[ki][kj].x * bi * dbj);
ujtang.y += (inp[ki][kj].y * bi * dbj);
ujtang.z += (inp[ki][kj].z * bi * dbj);
}
}
outp[i][j].add(new PVector(-ni/2,-nj/2,0));
outp[i][j].mult(100);
uitang.normalize();
ujtang.normalize();
normp[i][j] = uitang.cross(ujtang);
}
}
}
double BezierBlend(int k, double mu, int n) {
int nn, kn, nkn;
double blend=1;
nn = n;
kn = k;
nkn = n - k;
while (nn >= 1) {
blend *= nn;
nn--;
if (kn > 1) {
blend /= (double)kn;
kn--;
}
if (nkn > 1) {
blend /= (double)nkn;
nkn--;
}
}
if (k > 0)
blend *= Math.pow(mu, (double)k);
if (n-k > 0)
blend *= Math.pow(1-mu, (double)(n-k));
return(blend);
}
double DBezierBlend(int k, double mu, int n) {
int nn, kn, nkn;
double dblendf = 1;
nn = n;
kn = k;
nkn = n - k;
while (nn >= 1) {
dblendf *= nn;
nn--;
if (kn > 1) {
dblendf /= (double)kn;
kn--;
}
if (nkn > 1) {
dblendf /= (double)nkn;
nkn--;
}
}
double fk = 1;
double dk = 0;
double fnk = 1;
double dnk = 0;
if (k > 0) {
fk = Math.pow(mu, (double)k);
dk = k*Math.pow(mu, (double)k-1);
}
if (n-k > 0) {
fnk = Math.pow(1-mu, (double)(n-k));
dnk = (k-n)*Math.pow(1-mu, (double)(n-k-1));
}
dblendf *= (dk * fnk + fk * dnk);
return(dblendf);
}
@@ -65,12 +65,14 @@ float spotFactor(vec3 lightPos, vec3 vertPos, vec3 lightNorm, float minCos, floa
}
float lambertFactor(vec3 lightDir, vec3 vecNormal) {
return max(zero_float, dot(lightDir, vecNormal));
//return max(zero_float, dot(lightDir, vecNormal));
return abs(dot(lightDir, vecNormal));
}
float blinnPhongFactor(vec3 lightDir, vec3 lightPos, vec3 vecNormal, float shine) {
vec3 ldp = normalize(lightDir - lightPos);
return pow(max(zero_float, dot(ldp, vecNormal)), shine);
//return pow(max(zero_float, dot(ldp, vecNormal)), shine);
return pow(abs(dot(ldp, vecNormal)), shine);
}
void main() {
@@ -62,12 +62,14 @@ float spotFactor(vec3 lightPos, vec3 vertPos, vec3 lightNorm, float minCos, floa
}
float lambertFactor(vec3 lightDir, vec3 vecNormal) {
return max(zero_float, dot(lightDir, vecNormal));
//return max(zero_float, dot(lightDir, vecNormal));
return abs(dot(lightDir, vecNormal));
}
float blinnPhongFactor(vec3 lightDir, vec3 lightPos, vec3 vecNormal, float shine) {
vec3 ldp = normalize(lightDir - lightPos);
return pow(max(zero_float, dot(ldp, vecNormal)), shine);
//return pow(max(zero_float, dot(ldp, vecNormal)), shine);
return pow(abs(dot(ldp, vecNormal)), shine);
}
void main() {
@@ -143,12 +143,16 @@ public class PGL {
public static final int GL_FALSE = GL.GL_FALSE;
public static final int GL_TRUE = GL.GL_TRUE;
public static final int GL_LESS = GL.GL_LESS;
public static final int GL_LEQUAL = GL.GL_LEQUAL;
public static final int GL_CCW = GL.GL_CCW;
public static final int GL_CW = GL.GL_CW;
public static final int GL_FRONT = GL.GL_FRONT;
public static final int GL_BACK = GL.GL_BACK;
public static final int GL_LESS = GL.GL_LESS;
public static final int GL_LEQUAL = GL.GL_LEQUAL;
public static final int GL_CCW = GL.GL_CCW;
public static final int GL_CW = GL.GL_CW;
public static final int GL_CULL_FACE = GL.GL_CULL_FACE;
public static final int GL_FRONT = GL.GL_FRONT;
public static final int GL_BACK = GL.GL_BACK;
public static final int GL_FRONT_AND_BACK = GL.GL_FRONT_AND_BACK;
public static final int GL_VIEWPORT = GL.GL_VIEWPORT;
@@ -658,6 +662,11 @@ public class PGL {
gl.glFrontFace(mode);
}
public void glCullFace(int mode) {
gl.glCullFace(mode);
}
public void glDepthMask(boolean flag) {
gl.glDepthMask(flag);
@@ -1493,8 +1493,11 @@ public class PGraphicsOpenGL extends PGraphics {
lightFalloff(1, 0, 0);
lightSpecular(0, 0, 0);
// because y is flipped
// 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.
pgl.glFrontFace(PGL.GL_CW);
pgl.glDisable(PGL.GL_CULL_FACE);
// Processing uses only one texture unit.
pgl.glActiveTexture(PGL.GL_TEXTURE0);
@@ -1625,6 +1628,7 @@ public class PGraphicsOpenGL extends PGraphics {
pgl.glViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
pgl.glFrontFace(PGL.GL_CW);
pgl.glDisable(PGL.GL_CULL_FACE);
pgl.glActiveTexture(PGL.GL_TEXTURE0);
@@ -1845,6 +1849,9 @@ public class PGraphicsOpenGL extends PGraphics {
specular(125);
emissive(0);
shininess(1);
// To indicate that the user hasn't set ambient
setAmbient = false;
}
@@ -4102,11 +4109,14 @@ public class PGraphicsOpenGL extends PGraphics {
protected void fillFromCalc() {
super.fillFromCalc();
// Setting the ambient color from the current fill
// is what the old P3D did and allows to have an
// default ambient color when the user doesn't specify
// it explicitly.
ambientFromCalc();
if (!setAmbient) {
// Setting the ambient color from the current fill
// is what the old P3D did and allows to have an
// default ambient color when the user doesn't specify
// it explicitly.
ambientFromCalc();
setAmbient = false;
}
}
@@ -6377,15 +6387,17 @@ public class PGraphicsOpenGL extends PGraphics {
float v10y = y0 - y1;
float v10z = z0 - z1;
// n = v10 x v12 (so the normal points out following the
// clockwise direction along the vertices of the triangle).
float nx = v10y * v12z - v12y * v10z;
float ny = v10z * v12x - v12z * v10x;
float nz = v10x * v12y - v12x * v10y;
// The automatic normal calculation in Processing assumes
// that vertices as given in CCW order so:
// n = v12 x v10
// so that the normal outwards.
float nx = v12y * v10z - v10y * v12z;
float ny = v12z * v10x - v10z * v12x;
float nz = v12x * v10y - v10x * v12y;
float d = PApplet.sqrt(nx * nx + ny * ny + nz * nz);
nx /= -d;
ny /= -d;
nz /= -d;
nx /= d;
ny /= d;
nz /= d;
index = 3 * i0;
normals[index++] = nx;
@@ -6622,9 +6634,11 @@ public class PGraphicsOpenGL extends PGraphics {
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
i0 = i - 1;
i2 = i + 1;
}
@@ -6680,11 +6694,11 @@ public class PGraphicsOpenGL extends PGraphics {
for (int qd = 1; qd < (lastVertex - firstVertex + 1) / 2; qd++) {
int i0 = firstVertex + 2 * (qd - 1);
int i1 = firstVertex + 2 * (qd - 1) + 1;
int i2 = firstVertex + 2 * qd + 1;
int i3 = firstVertex + 2 * qd;
int i2 = firstVertex + 2 * qd;
int i3 = firstVertex + 2 * qd + 1;
calcTriangleNormal(i0, i1, i3);
calcTriangleNormal(i3, i2, i0);
calcTriangleNormal(i0, i3, i1);
calcTriangleNormal(i0, i2, i3);
}
}
@@ -8580,15 +8594,16 @@ public class PGraphicsOpenGL extends PGraphics {
}
break;
case TRIANGLE_STRIP:
for (int i = 1; i < tessCount - 1; i++) {
addIndex(i);
for (int i = 1; i < tessCount - 1; i++) {
if (i % 2 == 0) {
addIndex(i - 1);
addIndex(i + 1);
addIndex(i);
addIndex(i - 1);
if (calcNormals) calcTriNormal(i + 1, i, i - 1);
} else {
addIndex(i + 1);
addIndex(i - 1);
addIndex(i);
addIndex(i + 1);
if (calcNormals) calcTriNormal(i - 1, i, i + 1);
}
}
@@ -2605,6 +2605,9 @@ public class PShape3D extends PShape {
d = params[2];
}
//in.generateBox(w, h, d);
float x1 = -w/2f; float x2 = w/2f;
float y1 = -h/2f; float y2 = h/2f;
float z1 = -d/2f; float z2 = d/2f;