Программа отображает по-разному при использовании графического интерфейса, даже если используется тот же код? - PullRequest
0 голосов
/ 20 июня 2019

Я пишу raytracer и хотел реализовать пользовательский интерфейс. Когда я инициализирую рендеринг с этим вместо того, чтобы делать это через main, я получаю другой результат.


Я пытался + отключение многопоточности, + не использовать рекомендацию запуска 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 здесь такой же, как в 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();
            }

Модуль не сработал, поэтому я попробовал его без него, но безрезультатно.


Вот так это выглядит, когда я использую графический интерфейс

А вот так (пока) должно выглядеть

...