我正在编写raytracer,并想要实现一个用户界面。 当我用它初始化渲染而不是通过main进行渲染时,会得到不同的结果。
我尝试过 +禁用多线程, +不建议在单独的线程中启动GUI +我正在使用(就我而言)完全相同的代码,无论是否是GUI
//in Main-class
public static void main(String[] args){
Window renderWindow = new Window(IMAGE_WIDTH, IMAGE_HEIGHT, "Blank");
draw(renderWindow);
//Start UserInterface
// UserInterface userInterface = new UserInterface();
// userInterface.setVisible(true);
// SwingUtilities.invokeLater(() -> {
// UserInterface userInterface = new UserInterface();
// userInterface.setVisible(true);
// });
}
private static void draw(Window renderWindow){
Scene renderScene = new Scene();
setupScene(renderScene);
raytraceScene(renderWindow, renderScene);
}
private static void raytraceScene(Window renderWindow, Scene renderScene){
Raytracer raytracer = new Raytracer(
renderScene,
renderWindow,
1, //number of recursions
2, //anti-aliasing factor
false); //use multithreading yes/no
raytracer.renderScene();
}
在setupScene(renderScene)灯光,对象,cornellbox和照相机中进行设置。
//in UserInterface-class
public UserInterface() {
add(root);
setTitle("Make Raytracing great again!");
setSize(600, 400);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
shapelistModel = new DefaultListModel<>();
list_shapes = new JList<>(shapelistModel);
renderScene = new Scene();
renderButton.addActionListener(evt -> {
//Set the title for the rendered image
String renderTitle = textField_Title.getText();
//Create a window to draw the image in
Window renderWindow = new Window(IMAGE_WIDTH, IMAGE_HEIGHT, renderTitle);
//Do the magic
draw(renderWindow);
});
}
这里的draw-Method与Main-class中的相同;除此之外,按一下按钮不会覆盖renderScene变量,因为我已经在构造函数中创建了一个场景
换句话说,是否有一种方法可以将图像的渲染拆分到系统中的所有核心,具体取决于有多少核心? 我已经尝试通过Runtime.getRuntime()。availableProcessors()获取内核数,并将图像拆分为多个块,但是似乎无法正常工作。也许我对每个线程的x和y的起点和终点的计算是错误的?
int coreCount = Runtime.getRuntime().availableProcessors();
int halfCoreCount = coreCount/2;
int imageWidth = mBufferedImage.getWidth();
int imageHeight = mBufferedImage.getHeight();
//
int imageWidthByCoreCount = imageWidth/halfCoreCount;
int imageHeightByCoreCount = imageHeight/halfCoreCount;
//Get an array of workers with the length of the available cores on this machine
Thread[] renderFrames = new Thread[coreCount];
//Create the workers, assign them their boxes and let them render
for (int i = 0; i < renderFrames.length; i++) {
/* Calculate start and end-point for x and y boundaries for each Thread */
//Use modulo to loop back to the beginning when the row/column of Threads was completed
int xStart = (imageWidthByCoreCount * i); // % halfCoreCount;
int xEnd = (imageWidthByCoreCount * (i + 1)); // % halfCoreCount;
int yStart = (imageHeightByCoreCount * i); // % halfCoreCount;
int yEnd = (imageHeightByCoreCount * (i + 1)); // % halfCoreCount;
Log.print(this, "x: " + xStart + "; " + xEnd + " | y: " + yStart + "; " + yEnd);
//Assign new worker to the Thread
renderFrames[i] = new Thread(new Worker(this.mBufferedImage, xStart, xEnd, yStart, yEnd));
//Get the worker going
renderFrames[i].start();
}
取模没有奏效,所以我尝试了一下,但无济于事。