Java - Multithreading a Raytracer Loop - java

I am trying to parallelize the raytracer im currently working on for university, but i cant quite seem to get it to work. Ive tried multiple implementations, but the problem stays the same.rendering stops after a few milliseconds and at most a small chunk of the picture is rendered.
final ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
long start = System.currentTimeMillis();
for (int i = 0; i < image.getWidth(); i++) {
final int ii =i;
executor.execute(new Runnable() {
public void run() {
for (int j = 0; j < image.getHeight(); j++) {
raster.setDataElements(ii, image.getHeight()-j-1, model.getDataElements(
getPixelColor(width,height,ii,j,world,pcameras2),0, null));
}
}
});
}
g.drawImage(this.image, 0, 0, this);
System.out.println("Rednering finished in: " + (System.currentTimeMillis()-start)/1000.0 + " seconds");
}
public static float[] getPixelColor(final int width,final int height,
final int x,final int y,final World world,final Camera camera){
final Hit hit = world.hit(camera.rayFor(width,height, x, y));
if(hit != null){
return new float[]{(float) hit.geo.material.ColorFor(hit,world).r,
(float) hit.geo.material.ColorFor(hit,world).g,(float) hit.geo.material.ColorFor(hit,world).b, 1};
} else {
return new float[]{(float) world.backgroundColor.r, (float) world.backgroundColor.g, (float) world.backgroundColor.b, 1};
}
}
I found out, that if i exlude the world.hit() method it works just fine, but as this contains most of the computation, thats not an option.

As explained here, you want to call shutdown to tell the Exector to shutdown after all currently queued tasks have been finished, and then awaitTermination to wait until they are all done.
executor.shutdown();
try {
executor.awaitTermination(100, TimeUnit.SECONDS);
}
catch (InterruptedException e) {
// what should happen if timeout was hit
}
// image is complete here (if InterruptedException was not thrown)
g.drawImage(this.image, 0, 0, this);

Related

Processing function does nothing but freezes the program

I'm working on a pathfinding algorithm in processing. If I don't draw a line that crosses the path between the green and the red dot, it works, but if I do, I've got a problem, that if I call a function, the program does absolutely nothing but freezes, and I have no idea why. The pixelss stores what you draw, and there are all kinds of stuff, that don't matter at this problem.
When you paste it to processing, press ctrl+t to auto-format it so you can understand it better, but I'd bet it's a newbie issue.
int[][] pixelss = new int[500][500];
void setup() {
background(255);
size(500, 500);}
int[][] badcoos = new int[500][500];
void golinego() {
stroke(200, 200, 255);
line(30, 30, 470, 470);
int j = 30;
int i = 30;
while (dist(i, j, 470, 470) > 10) {
stroke(0, 0, 180);
circle(i, j, 1);
if (pixelss[i+1][j+1]==0) {
i++;j++;}
if (pixelss[i][j]==1) {
if (pixelss[i][j+1]==1) {
if (pixelss[i+1][j]==0) {
i++;}
} else if (pixelss[i+1][j]==1) {
if (pixelss[i][j+1]==0) {
j++;}
} else {
i-=1;
j-=1;}}}}
void draw() {
stroke(0, 255, 0);
fill(0, 255, 0);
circle(30, 30, 10);
stroke(255, 0, 0);
fill(255, 0, 0);
circle(470, 470, 10);
if (mousePressed == true) {
try {
stroke(0);
fill(0);
circle(mouseX, mouseY, 2);
pixelss[mouseX][mouseY] = 1;
pixelss[mouseX+1][mouseY] = 1;
pixelss[mouseX-1][mouseY] = 1;
pixelss[mouseX][mouseY+1] = 1;
pixelss[mouseX][mouseY-1] = 1;
pixelss[mouseX+1][mouseY+1] = 1;
pixelss[mouseX-1][mouseY+1] = 1;
pixelss[mouseX+1][mouseY-1] = 1;
pixelss[mouseX-1][mouseY-1] = 1;
}catch(ArrayIndexOutOfBoundsException e) {}}}
void keyPressed() {
if (key=='r') {
pixelss = new int[500][500];
badcoos = new int[500][500];
background(255);}
if (key==' ') {
golinego();}
if (key=='d') {
background(0);
for (int i = 0; i < 500; i++) {
for (int j = 0; j < 500; j++) {
if (pixelss[i][j]==1) {
stroke(255);
circle(i, j, 1);}}}}}
The program is getting caught in your while loop.
You can see this if you print out the values of i and j inside the loop. They never meet the condition to escape the loop, so that chunk of code runs repeatedly with no change.
while (dist(i, j, 470, 470) > 10) {
println(i, j);
// etc...
}
This hangs the app because the while loop needs to complete before the the draw function gets called again to update the screen.
It's not clear to me what you're actually doing in the while loop, but that's where you should look. Either alter your logic inside the loop, or change the condition to ensure that the code doesn't get stuck in an infinite loop.
You should at least print something when the ArrayIndexOutOfBoundsException is caught.
It looks like you are working with some kind of gui library, make sure you are doing any processing in separate thread from the gui or the gui will become unresponsive and appear to 'freeze' like you describe.
https://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html

How to update Java Swing GUI using Timer and delay?

I am trying to make a sorting visualizer using a Java GUI. The problem I'm facing is updating the GUI in real time. For instance, when I shuffle the initial array I will call the following shuffle and swap methods. I expect it to repaint the GUI and then do it again after a delay but instead all it does is finish the shuffleArray method then repaints it all at once showing no "animation". What is a better way of going about this?
public void shuffleArray() {
final int milliDelay = 1000;
for (int i = NUM_BARS - 1; i >= 0; i--) {
int rand = (int) (Math.random() * i);
swap(i,rand, milliDelay);
}
}
public void swap(int firstIndex, int secondIndex, int delay) {
Timer timer = new Timer(delay, e -> {
int temp = data[firstIndex];
data[firstIndex] = data[secondIndex];
data[secondIndex] = temp;
barColors[firstIndex] = Color.RED;
barColors[secondIndex] = Color.RED;
repaint();
barColors[firstIndex] = Color.WHITE;
barColors[secondIndex] = Color.WHITE;
});
timer.setRepeats(false);
timer.start();
}

Rendering an Image Using Threads Cause Noisy Pictures

I've built my own basic ray tracer.
I've tried to optimize its performance, so I thought of using threads.
When I render without threads - all looks good, but when I've tried to use threads - I've got a noisy picture with black stripes on it.
This is the code. for every line of pixels, I've created a new executor to calculate the pixel colors in that line:
public void renderImage(){
Camera camera = _scene.get_camera();
for (int i = 0; i < _imageWriter.getWidth(); ++i){
final int iFinal = i;
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(() -> {
for (int j = 0; j < _imageWriter.getHeight(); ++j){
ArrayList<Ray> rays = camera.constructRaysThroughPixel(
_imageWriter.getNx(), _imageWriter.getNy(),
iFinal, j, _scene.get_screenDistance(),
_imageWriter.getWidth(), _imageWriter.getHeight()
);
Color color = new Color();
for (Ray ray: rays) {
ArrayList<GeoPoint> intersectionPoints = _scene.get_geometries().findIntersections(ray);
if (intersectionPoints.isEmpty() == true) {
color = color.add(_scene.get_background());
}
else {
GeoPoint closestPoint = getClosestPoint(intersectionPoints);
color = color.add(new Color(calcColor(closestPoint, new Ray(camera.get_origin(), closestPoint.point.subtract(camera.get_origin())))));
}
}
int length = rays.size();
color = color.scale(1.0/length);
_imageWriter.writePixel(iFinal, j, color.getColor());
}
});
}
}
This is what I've gotten when I used threads:
This is what I've gotten when I didnt use threads:

Decreasing an int from 10 to 0 every second in Java

I define an
int x = 10;
Now I want x to decrease every second until its 0:
if (Obstacle.activeItem == true) {
game.font.draw(game.batch, "Item active for: " + x, 100, 680);
}
How can I do that?
I've seen people do similar things using the Class Timer, but I don't know how it should look like for this case.
I tried
int x = 10;
ScheduledExecutorService execService = Executors.newScheduledThreadPool(1);
And then
if (Obstacle.activeItem == true) {
game.font.draw(game.batch, "Item active for: " + x, 100, 680);
}
execService.scheduleAtFixedRate(new Runnable() {
public void run() {
x--;
}
}, 0L, 10L, TimeUnit.SECONDS);
But that doesn't work as I want it to.
You tagged your question with libGdx so I think you work with libgdx.
Instead of creating a extra ExecutorService why you don't use the update(float delta) method to decrease your timer?
private float timer = 10;
#Override
public void render(float delta) {
timer -= delta;
if (Obstacle.activeItem == true) {
font.draw(batch, "Item active for: " + (int)timer, 100, 680);
}
}
Here's a sample of how you can implement a Timer type functionality using Executors
public class Main {
static int x = 10;
public static void main(String[] args) {
ScheduledExecutorService execService = Executors.newScheduledThreadPool(1);
execService.scheduleAtFixedRate(() -> {
System.out.println(x);
x--;
if (x == 0)
execService.shutdownNow();
}, 1L, 1L, TimeUnit.SECONDS); //initial delay, period, time unit
}
}
It is highly recommended that you read up on Executors. Consider this as a hint and implement it in your use case accordingly.
if that is libGdx i have some working sphagetti code for you:
int reducedInt = 10;
bool isReduce = false;
float timer = 1f;
in Render
timer -= delta;
if(timer<=0){
isReduce = true;
timer = 1;
}
if(isReduce){
reducedInt--;
isReduce = false;
}
This is classic LibGDX sphagetti timer code. Since you have tagged it as LibGDX.

Objects sharing another object (Processing 3.3.7)

Hello Stack Overflow people :)
I'm a huge newbie when it comes to coding, and I've just ran into a problem that my brain just won't get over...
Before I start blabbering about this issue, I'll paste my code so as to give a little bit of context (sorry in advance if looking at it makes you wanna puke). The main focus of the issue is commented and should therefore be fairly visible :
Main
ArrayList<Individual> individuals = new ArrayList<Individual>();
void setup()
{
size(500,500);
for(int i = 0; i < 2; i++)
{
individuals.add(new Individual());
}
println(frameRate);
}
void draw()
{
background(230);
for(int i = 0; i < individuals.size(); i++)
{
individuals.get(i).move();
individuals.get(i).increaseTimers();
individuals.get(i).display();
}
}
Individual
class Individual
{
float x;
float y;
int size = 5;
Timer rdyBreed; /* Here is the object that appears to be shared
between individuals of the ArrayList */
float breedRate;
float breedLimit;
Individual()
{
x = random(0, width);
y = random(0, height);
rdyBreed = new Timer("rdyBreed", 0);
breedRate = random(.2, 3);
breedLimit = random(10, 20);
}
void move()
{
int i = (int)random(0, 1.999);
int j = (int)random(0, 1.999);
if (i == 0)
{
x = x + 1;
} else
{
x = x - 1;
}
if (j == 0)
{
y = y + 1;
} else
{
y = y - 1;
}
checkWalls();
}
void checkWalls()
{
if (x < size/2)
{
x = width - size/2;
}
if (x > width - size/2)
{
x = size/2;
}
if (y < size/2)
{
y = width - size/2;
}
if (y > width - size/2)
{
y = size/2;
}
}
void display()
{
noStroke();
if (!rdyBreed.finished)
{
fill(255, 0, 0);
} else
{
fill(0, 255, 0);
}
rect(x - size/2, y - size/2, size, size);
}
void increaseTimers()
{
updateBreedTimer();
}
void updateBreedTimer()
{
rdyBreed.increase(frameRate/1000);
rdyBreed.checkLimit(breedLimit);
rdyBreed.display(x, y);
}
}
Timer
class Timer
{
float t;
String name;
boolean finished = false;
Timer(String name, float t)
{
this.t = t;
this.name = name;
}
void increase(float step)
{
if (!finished)
{
t = t + step;
}
}
void checkLimit(float limit)
{
if (t >= limit)
{
t = 0;
finished = true;
}
}
void display(float x, float y)
{
textAlign(RIGHT);
textSize(12);
text(nf(t, 2, 1), x - 2, y - 2);
}
}
Now that that's done, let's get to my question.
Basically, I'm trying to create some sort of a personal Conway's Game of Life, and I'm encountering a lot of issues right off the bat.
Now my idea when writing this piece of code was that every individual making up the small simulated "society" would have different timers and values for different life events, like mating to have children for example.
Problem is, I'm not a huge pro at object-oriented programming, and I'm therefore quite clueless as to why the objects are not having each their own Timer but both a reference to the same timer.
I would guess making an ArrayList of timers and using polymorphism to my advantage could make a change, but I'm not really certain of it or really how to do it so... yeah, I need help.
Thanks in advance :)
EDIT : Here is a screenshot of the debugger. The values keep being the same with each iteration of the updates.
Screenshot
What makes you think they reference the same Timer object? The values of t displayed in the debugger are going to be the same until one of them reaches the breedLimit and gets set to 0, because they're being initialized at the same time.
Try this and see that the values of t are different.
void setup() {
size(500,500);
}
void mouseClicked() {
individuals.add(new Individual());
}
I'd recommend setting the breakpoint somewhere around here:
t = 0;
finished = true;
They do not share the same timer, you create a new Timer object for each Individual.
class Individual {
// ...
Timer rdyBreed;
Individual() {
// ...
rdyBreed = new Timer("rdyBreed", 0);
//...
The only way they could be sharing the same Timer is if you were setting rdyBreed elsewhere, but since you don't want that I recommend making it final.
If you did want to share the same Timer instance across all individuals then you could declare it static.

Categories

Resources