Обновление javafx пикселей каждый кадр

Для проекта, над которым я работаю, мне нужно оживить океан с помощью цветовых карт солености. По сути, у меня есть данные солености для n временных шагов, и мне нужно обновить цвета пикселей, чтобы они соответствовали текущим значениям солености.

Прямо сейчас я просматриваю каждый пиксель на холсте во вложенном цикле for и для каждого пикселя вычисляю текущее значение солености в этом пикселе и обновляю цвет пикселя в соответствии со значением солености.

Я отслеживаю кадры с объектом AnimationTimer. Проблема в том, что я получаю около 20 кадров в секунду, а приложение отстает от событий, таких как изменение размера окна.

private void drawHeatMap(int depth, float t) {
  float meanSalt = model.getMeanSalinity(depth);
  float stdSalt = model.getSalinityStdDev(depth);
  Colorbar colorbar = new Colorbar(SALINITY_COLORMAP);
  colorbar.setValueRange(meanSalt - stdSalt, meanSalt + (stdSalt / 2));
  GraphicsContext graphicsContext = canvas.getGraphicsContext2D();
  graphicsContext.clearRect(0, 0, canvas.getWidth(), canvas.getHeight());
  PixelWriter pixelWriter = graphicsContext.getPixelWriter();
  for (int x = 0; x < canvas.getWidth(); ++x) {
    for (int y = 0; y < canvas.getHeight(); ++y) {
      GeoCoordinate coordinate = getMapCoordinates(x, y);
      if (model.isOverWater(coordinate)) {
        float salt = model.computeSalinity(coordinate, depth, t);
        pixelWriter.setColor(x, y, colorbar.getColor(salt));
      }
    }
  }
}

Это код, который запускает каждый кадр, но даже более простая версия, подобная приведенной ниже, все еще работает со скоростью 30 кадров в секунду.

private void drawHeatMapBenchmark(int depth, float t) {
  GraphicsContext graphicsContext = canvas.getGraphicsContext2D();
  graphicsContext.clearRect(0, 0, canvas.getWidth(), canvas.getHeight());
  PixelWriter pixelWriter = graphicsContext.getPixelWriter();
  for (int x = 0; x < canvas.getWidth(); ++x) {
    for (int y = 0; y < canvas.getHeight(); ++y) {
      pixelWriter.setColor(x, y, Color.gray(Math.random()));
    }
  }
}

Кто-нибудь знает лучший подход к этому? Я не знаком с компьютерной графикой, спасибо.

1 ответ

Решение

Вы делаете все это в (единственном) потоке приложения JavaFX. Это может помочь, если вы сначала визуализируете свою тепловую карту в изображение, которое затем рисуете на холсте, потому что для вашего конкретного случая очень просто выполнить рендеринг изображения на параллельных потоках, что должно ускорить весь процесс.

Другие вопросы по тегам