use of org.sunflow.system.Timer in project joons-renderer by joonhyublee.
the class ProgressiveRenderer method render.
public void render(Display display) {
this.display = display;
display.imageBegin(imageWidth, imageHeight, 0);
// create first bucket
SmallBucket b = new SmallBucket();
b.x = b.y = 0;
int s = Math.max(imageWidth, imageHeight);
b.size = 1;
while (b.size < s) {
b.size <<= 1;
}
smallBucketQueue = new PriorityBlockingQueue<SmallBucket>();
smallBucketQueue.add(b);
UI.taskStart("Progressive Render", 0, imageWidth * imageHeight);
Timer t = new Timer();
t.start();
counter = 0;
counterMax = imageWidth * imageHeight;
SmallBucketThread[] renderThreads = new SmallBucketThread[scene.getThreads()];
for (int i = 0; i < renderThreads.length; i++) {
renderThreads[i] = new SmallBucketThread();
renderThreads[i].start();
}
for (int i = 0; i < renderThreads.length; i++) {
try {
renderThreads[i].join();
} catch (InterruptedException e) {
UI.printError(Module.IPR, "Thread %d of %d was interrupted", i + 1, renderThreads.length);
} finally {
renderThreads[i].updateStats();
}
}
UI.taskStop();
t.end();
UI.printInfo(Module.IPR, "Rendering time: %s", t.toString());
display.imageEnd();
}
use of org.sunflow.system.Timer in project joons-renderer by joonhyublee.
the class SimpleRenderer method render.
public void render(Display display) {
this.display = display;
display.imageBegin(imageWidth, imageHeight, 32);
// set members variables
bucketCounter = 0;
// start task
Timer timer = new Timer();
timer.start();
BucketThread[] renderThreads = new BucketThread[scene.getThreads()];
for (int i = 0; i < renderThreads.length; i++) {
renderThreads[i] = new BucketThread();
renderThreads[i].start();
}
for (int i = 0; i < renderThreads.length; i++) {
try {
renderThreads[i].join();
} catch (InterruptedException e) {
UI.printError(Module.BCKT, "Bucket processing thread %d of %d was interrupted", i + 1, renderThreads.length);
} finally {
renderThreads[i].updateStats();
}
}
timer.end();
UI.printInfo(Module.BCKT, "Render time: %s", timer.toString());
display.imageEnd();
}
use of org.sunflow.system.Timer in project joons-renderer by joonhyublee.
the class KDTree method build.
@Override
public void build(PrimitiveList primitives) {
UI.printDetailed(Module.ACCEL, "KDTree settings");
UI.printDetailed(Module.ACCEL, " * Max Leaf Size: %d", maxPrims);
UI.printDetailed(Module.ACCEL, " * Max Depth: %d", MAX_DEPTH);
UI.printDetailed(Module.ACCEL, " * Traversal cost: %.2f", TRAVERSAL_COST);
UI.printDetailed(Module.ACCEL, " * Intersect cost: %.2f", INTERSECT_COST);
UI.printDetailed(Module.ACCEL, " * Empty bonus: %.2f", EMPTY_BONUS);
UI.printDetailed(Module.ACCEL, " * Dump leaves: %s", dump ? "enabled" : "disabled");
Timer total = new Timer();
total.start();
primitiveList = primitives;
// get the object space bounds
bounds = primitives.getWorldBounds(null);
int nPrim = primitiveList.getNumPrimitives(), nSplits = 0;
BuildTask task = new BuildTask(nPrim);
Timer prepare = new Timer();
prepare.start();
for (int i = 0; i < nPrim; i++) {
for (int axis = 0; axis < 3; axis++) {
float ls = primitiveList.getPrimitiveBound(i, 2 * axis + 0);
float rs = primitiveList.getPrimitiveBound(i, 2 * axis + 1);
if (ls == rs) {
// flat in this dimension
task.splits[nSplits] = pack(ls, PLANAR, axis, i);
nSplits++;
} else {
task.splits[nSplits + 0] = pack(ls, OPENED, axis, i);
task.splits[nSplits + 1] = pack(rs, CLOSED, axis, i);
nSplits += 2;
}
}
}
task.n = nSplits;
prepare.end();
Timer t = new Timer();
IntArray tempTree = new IntArray();
IntArray tempList = new IntArray();
tempTree.add(0);
tempTree.add(1);
t.start();
// sort it
Timer sorting = new Timer();
sorting.start();
radix12(task.splits, task.n);
sorting.end();
// build the actual tree
BuildStats stats = new BuildStats();
buildTree(bounds.getMinimum().x, bounds.getMaximum().x, bounds.getMinimum().y, bounds.getMaximum().y, bounds.getMinimum().z, bounds.getMaximum().z, task, 1, tempTree, 0, tempList, stats);
t.end();
// write out final arrays
// free some memory
task = null;
tree = tempTree.trim();
tempTree = null;
this.primitives = tempList.trim();
tempList = null;
total.end();
// display some extra info
stats.printStats();
UI.printDetailed(Module.ACCEL, " * Node memory: %s", Memory.sizeof(tree));
UI.printDetailed(Module.ACCEL, " * Object memory: %s", Memory.sizeof(this.primitives));
UI.printDetailed(Module.ACCEL, " * Prepare time: %s", prepare);
UI.printDetailed(Module.ACCEL, " * Sorting time: %s", sorting);
UI.printDetailed(Module.ACCEL, " * Tree creation: %s", t);
UI.printDetailed(Module.ACCEL, " * Build time: %s", total);
if (dump) {
try {
UI.printInfo(Module.ACCEL, "Dumping mtls to %s.mtl ...", dumpPrefix);
FileWriter mtlFile = new FileWriter(dumpPrefix + ".mtl");
int maxN = stats.maxObjects;
for (int n = 0; n <= maxN; n++) {
float blend = (float) n / (float) maxN;
Color nc;
if (blend < 0.25) {
nc = Color.blend(Color.BLUE, Color.GREEN, blend / 0.25f);
} else if (blend < 0.5) {
nc = Color.blend(Color.GREEN, Color.YELLOW, (blend - 0.25f) / 0.25f);
} else if (blend < 0.75) {
nc = Color.blend(Color.YELLOW, Color.RED, (blend - 0.50f) / 0.25f);
} else {
nc = Color.MAGENTA;
}
mtlFile.write(String.format("newmtl mtl%d\n", n));
float[] rgb = nc.getRGB();
mtlFile.write("Ka 0.1 0.1 0.1\n");
mtlFile.write(String.format("Kd %.12g %.12g %.12g\n", rgb[0], rgb[1], rgb[2]));
mtlFile.write("illum 1\n\n");
}
FileWriter objFile = new FileWriter(dumpPrefix + ".obj");
UI.printInfo(Module.ACCEL, "Dumping tree to %s.obj ...", dumpPrefix);
dumpObj(0, 0, maxN, new BoundingBox(bounds), objFile, mtlFile);
objFile.close();
mtlFile.close();
} catch (IOException e) {
Logger.getLogger(KDTree.class.getName()).log(Level.SEVERE, null, e);
}
}
}
use of org.sunflow.system.Timer in project joons-renderer by joonhyublee.
the class UniformGrid method build.
@Override
public void build(PrimitiveList primitives) {
Timer t = new Timer();
t.start();
this.primitives = primitives;
int n = primitives.getNumPrimitives();
// compute bounds
bounds = primitives.getWorldBounds(null);
// create grid from number of objects
bounds.enlargeUlps();
Vector3 w = bounds.getExtents();
double s = Math.pow((w.x * w.y * w.z) / n, 1 / 3.0);
nx = MathUtils.clamp((int) ((w.x / s) + 0.5), 1, 128);
ny = MathUtils.clamp((int) ((w.y / s) + 0.5), 1, 128);
nz = MathUtils.clamp((int) ((w.z / s) + 0.5), 1, 128);
voxelwx = w.x / nx;
voxelwy = w.y / ny;
voxelwz = w.z / nz;
invVoxelwx = 1 / voxelwx;
invVoxelwy = 1 / voxelwy;
invVoxelwz = 1 / voxelwz;
UI.printDetailed(Module.ACCEL, "Creating grid: %dx%dx%d ...", nx, ny, nz);
IntArray[] buildCells = new IntArray[nx * ny * nz];
// add all objects into the grid cells they overlap
int[] imin = new int[3];
int[] imax = new int[3];
int numCellsPerObject = 0;
for (int i = 0; i < n; i++) {
getGridIndex(primitives.getPrimitiveBound(i, 0), primitives.getPrimitiveBound(i, 2), primitives.getPrimitiveBound(i, 4), imin);
getGridIndex(primitives.getPrimitiveBound(i, 1), primitives.getPrimitiveBound(i, 3), primitives.getPrimitiveBound(i, 5), imax);
for (int ix = imin[0]; ix <= imax[0]; ix++) {
for (int iy = imin[1]; iy <= imax[1]; iy++) {
for (int iz = imin[2]; iz <= imax[2]; iz++) {
int idx = ix + (nx * iy) + (nx * ny * iz);
if (buildCells[idx] == null) {
buildCells[idx] = new IntArray();
}
buildCells[idx].add(i);
numCellsPerObject++;
}
}
}
}
UI.printDetailed(Module.ACCEL, "Building cells ...");
int numEmpty = 0;
int numInFull = 0;
cells = new int[nx * ny * nz][];
int i = 0;
for (IntArray cell : buildCells) {
if (cell != null) {
if (cell.getSize() == 0) {
numEmpty++;
cell = null;
} else {
cells[i] = cell.trim();
numInFull += cell.getSize();
}
} else {
numEmpty++;
}
i++;
}
t.end();
UI.printDetailed(Module.ACCEL, "Uniform grid statistics:");
UI.printDetailed(Module.ACCEL, " * Grid cells: %d", cells.length);
UI.printDetailed(Module.ACCEL, " * Used cells: %d", cells.length - numEmpty);
UI.printDetailed(Module.ACCEL, " * Empty cells: %d", numEmpty);
UI.printDetailed(Module.ACCEL, " * Occupancy: %.2f%%", 100.0 * (cells.length - numEmpty) / cells.length);
UI.printDetailed(Module.ACCEL, " * Objects/Cell: %.2f", (double) numInFull / (double) cells.length);
UI.printDetailed(Module.ACCEL, " * Objects/Used Cell: %.2f", (double) numInFull / (double) (cells.length - numEmpty));
UI.printDetailed(Module.ACCEL, " * Cells/Object: %.2f", (double) numCellsPerObject / (double) n);
UI.printDetailed(Module.ACCEL, " * Build time: %s", t.toString());
}
use of org.sunflow.system.Timer in project joons-renderer by joonhyublee.
the class SCAbstractParser method parse.
@Override
public boolean parse(String filename, SunflowAPIInterface api) {
Timer timer = new Timer();
timer.start();
UI.printInfo(Module.API, "Parsing \"%s\" ...", filename);
try {
openParser(filename);
parseloop: while (true) {
Keyword k = parseKeyword();
switch(k) {
case RESET:
api.reset();
break;
case PARAMETER:
parseParameter(api);
break;
case GEOMETRY:
{
String name = parseString();
String type = parseString();
api.geometry(name, type);
break;
}
case INSTANCE:
{
String name = parseString();
String geoname = parseString();
api.instance(name, geoname);
break;
}
case SHADER:
{
String name = parseString();
String type = parseString();
api.shader(name, type);
break;
}
case MODIFIER:
{
String name = parseString();
String type = parseString();
api.modifier(name, type);
break;
}
case LIGHT:
{
String name = parseString();
String type = parseString();
api.light(name, type);
break;
}
case CAMERA:
{
String name = parseString();
String type = parseString();
api.camera(name, type);
break;
}
case OPTIONS:
{
api.options(parseString());
break;
}
case INCLUDE:
{
String file = parseString();
UI.printInfo(Module.API, "Including: \"%s\" ...", file);
api.include(file);
break;
}
case REMOVE:
{
api.remove(parseString());
break;
}
case FRAME:
{
api.currentFrame(parseInt());
break;
}
case PLUGIN:
{
String type = parseString();
String name = parseString();
String code = parseVerbatimString();
api.plugin(type, name, code);
break;
}
case SEARCHPATH:
{
String type = parseString();
api.searchpath(type, parseString());
break;
}
case END_OF_FILE:
{
// clean exit
break parseloop;
}
default:
{
UI.printWarning(Module.API, "Unexpected token %s", k);
break;
}
}
}
closeParser();
} catch (Exception e) {
// catch all exceptions
Logger.getLogger(SCAbstractParser.class.getName()).log(Level.SEVERE, null, e);
UI.printError(Module.API, "%s", e.getMessage());
return false;
}
timer.end();
UI.printInfo(Module.API, "Done parsing (took %s)", timer.toString());
return true;
}
Aggregations