Hi, I am having a hard time changing the fill(); on the following terrain code. How can I fill(); in a black and white pattern?
import processing.svg.*;
boolean record;
// a class to representing a point on our grid.
// This should/would/could be done better by defining it as faces (of a triangle mesh).
// but would it keep as simple as possible
class GridPoint {
float x, y, v;
public GridPoint(float px, float py, float pv) {
x = px; // x-pos of the grid point
y = py; // y-pos of the grid point
v = pv; // height of the grid point
}
}
//helper variables
float halfWidth, halfHeight;
boolean mode = false;
// storage of out grid
int rows, cols;
GridPoint[][] grid;
// image used for texture and heightmap
PImage img;
void setup() {
size(980, 980, P3D); //OPENGL?
noLoop();
frameRate(1);
smooth(8);
halfWidth = width/2.;
halfHeight = height/2.;
initGrid(7.);
// use textureMode IMAGE as the grid is not normalized
textureMode(IMAGE);
}
void initGrid(float scl) {
// load the image, used for texture and heightmap.
// usually more than one picture will be used. One for heightmap, one for normalmap and one with the texture.
// for simplicity it has the same size than our grid to not make the code more math intensive.
// to get this work our image is somehow a bit blurred (like noise is), otherwise the mesh isn't smooth enough
img = loadImage("gradients88_2.jpg");
img.loadPixels();
img.resize(980,980);
// initialize our gridpoints
rows = floor(height/scl);
cols = floor(width/scl);
grid= new GridPoint[rows][cols];
for (int y = 0; y < rows; y++) {
for (int x = 0; x < cols; x++) {
int sx = floor(x*scl);
int sy = floor(y*scl);
// set x and y coordinates (center origin) and the height of the current point.
// height is the normalized brightness value [0..1] of the pixel color from the image.
// Subtract 0.5 to align it to center [-0.5..0.5]
// scaling it by 50, so the range is [50.0*(-0.5)..50.0*(0.5)]
grid[y][x] = new GridPoint(-halfWidth+sx+scl/2, -halfHeight+sy+scl/2, 50.*(brightness(img.get(sx, sy))/255-0.9));
}
}
}
void draw()
{
background(0);
if (record) {
beginRaw(SVG, "output_September19_2023.svg");
}
// set the origin to the center of the screen, and move it 400px far away on z-axis
translate(halfWidth, halfHeight, 0.05); // zoom in (lower numbers) zoom out (higher numbers around 200)
// switch between mesh and texured mode
//if (frameCount % int(TAU*100.) == 0) {
// mode = !mode;
//}
if (mode)
{
//if textured mode no strokes and a light from viewpoint to object
noStroke();
directionalLight(255, 255, 255, 0, 0, -1);
} else {
// if mesh mode only show strokes
noFill();
stroke(128);
strokeWeight(2);
smooth(8);
}
// apply the rotation after lighting, otherwhile the light gets also rotated, which we not want.
// tipping 30degree back on X-axis
//rotateX(radians(30));
// tipping left/right a bit per frame from -PI/4 - +PI/4 on Y-axis
//rotateY(sin(frameCount/100.)*QUARTER_PI);
// build the surface/terrain by triangle strips to display it
for (int y = 0; y < rows-1; y ++)
{
beginShape (QUAD_STRIP); // or (TRIANGLE_STRIP),(QUAD_STRIP),
if (mode) {
// on textured mode set the texture
texture(img);
}
// common triangle strips
for (int x = 0; x < cols; x++) {
GridPoint ca = grid[y][x];
GridPoint cb = grid[y+1][x];
vertex(ca.x, ca.y, ca.v, ca.x+halfWidth, ca.y+halfHeight);
if (mode) {
// on textured mode we need to set the normal vector, so the light knows how to behave on hittng the surface
// usually there are better calculation than this cheap hack
// comment it out to see the difference if normals are messed up
PVector na = new PVector(ca.x-cb.x, ca.y-cb.y, 0).sub(new PVector(ca.x-cb.x, ca.y-cb.y, 1)).normalize();
normal(na.x, na.y, na.z);
}
vertex(cb.x, cb.y, cb.v, cb.x+halfWidth, cb.y+halfHeight);
if (mode) {
// on textured mode we need to set the normal vector, so the light knows how to behave on hittng the surface
// usually there are better calculation than this cheap hack
// comment it out to see the difference if normals are messed up
PVector nb = new PVector(cb.x-ca.x, cb.y-ca.y, 0).sub(new PVector(cb.x-ca.x, cb.y-ca.y, 1)).normalize();
normal(nb.x, nb.y, nb.z);
}
}
endShape();
}
if (record) {
endRaw();
record = false;
}
}
// Hit 'p' to record a single frame
void keyPressed(){
if (key == 'p')
{
record = true;
}
redraw();
}