GG.scene().backgroundColor(@(0,0,0)); GG.camera().position(@(0,8,0)); GG.camera().lookAt( @(0,0,0) ); GSphere s1 --> GG.scene(); GSphere s5 --> GSphere s4 --> GSphere s3 --> GSphere s2 --> s1; GPoints points --> GG.scene(); s1.mat().color(@(.030,.57,.55)); // s4.scale(@(.5,.5,.5)); // s3.scale(@(.6,.6,.6)); // s2.scale(@(.8,.8,.8)); // s1.scale(@(1,1,1)); s1.position(@(0,0,0)); points.posX(2); // points stress test 50 => int POINTS_PER_AXIS; // prepare vertex data for 1,000,000 points! POINTS_PER_AXIS * POINTS_PER_AXIS * POINTS_PER_AXIS => int numPoints; float pointPos[numPoints * 3]; float pointColor[numPoints * 4]; // populate within a 10x10x10 cube for (int i; i < POINTS_PER_AXIS; i++) { for (int j; j < POINTS_PER_AXIS; j++) { for (int k; k < POINTS_PER_AXIS; k++) { // get the index of this vertex i * POINTS_PER_AXIS * POINTS_PER_AXIS + j * POINTS_PER_AXIS + k => int index; 1.0 * POINTS_PER_AXIS => float colorScale; POINTS_PER_AXIS / 3.0 => float posScale; // caculate position i / colorScale => float x; j / colorScale => float y; k / colorScale => float z; // set position of this vertex (posScale * x) - (posScale / 2.0) => pointPos[3*index + 0]; (posScale * y) - (posScale / 2.0) => pointPos[3*index + 1]; (posScale * z) - (posScale / 2.0) => pointPos[3*index + 2]; // set color of this vertex // (same as position, so have 1:1 mapping between xyz physical space and rgb color space) x => pointColor[4*index + 0]; y => pointColor[4*index + 1]; z => pointColor[4*index + 2]; .5 => pointColor[4*index + 3]; // alpha always 1 } } } points.geo().positions(pointPos); // set vertex position data points.geo().colors(pointColor); // set vertex color data while (true) { // <<< GG.help() >>>; // GG.camera().rotY(GG.dt()); GG.camera().posX(8*Math.sin(now/second*.5)); GG.camera().posY(8*Math.cos(now/second*.5)); GG.camera().lookAt( @(0,0,0) ); GG.nextFrame() => now; }