2013-10-12 2 views
1

Я относительный новичок в программировании игр. Я знаю, как рисовать пиксели до BufferedImage, используя setPixel(). Это ужасно медленно в больших форматах, поэтому я переехал и нашел VolatileImage (занял у меня неделю или около того). Довольно легко рисовать линии, строки, прямоугольники и т. Д., Но я не могу рисовать отдельные пиксели. Я уже пробовал использовать drawLine(x,y,x,y), но я получаю 3-4 FPS на изображении 800x600. Тот факт, что java не включал setPixel() или setRGB() в VolatileImage, делает меня довольно злым и смущенным.Почему у VolatileImage нет метода set/getPixel()

У меня 4 вопроса:

  1. Есть ли способ, чтобы сделать отдельные пиксели на VolatileImage? (в форматах 1440x900 с FPS> 40)

  2. Можно ли рисовать пиксели в BufferedImage с помощью более быстрого метода? (такие же 1440x900, FPS> 40)

  3. Есть ли другой способ рисовать пиксели достаточно быстро для 3D-игр?

  4. Могу ли я сделать мой BufferedImage аппаратное ускорение (пробовал использовать setAccelerationPriority(1F), но он не работает)

Пожалуйста, если у вас есть какие-либо идеи сказать мне. Я не могу продолжать делать свою игру без этой информации. Я уже сделал 3D-рендеринг алгоритмов, но мне нужно иметь возможность рисовать быстрые пиксели. У меня есть хорошее представление об этой игре.

Вот код, если он может помочь вам помочь мне:

public static void drawImageRendered (int x, int y, int w, int h) { // This is just a method to test the performance 

    int a[] = new int[3]; // The array containing R, G and B value for each pixel 
    bImg = Launcher.contObj.getGraphicsConfiguration().createCompatibleImage(800, 600); // Creates a compatible image for the JPanel object i am working with (800x600) 
    bImg.setAccelerationPriority(1F); // I am trying to get this image accelerated 
    WritableRaster wr = bImg.getRaster(); // The image's writable raster 
    for (int i = 0; i < bImg.getWidth(); i++) { 
     for (int j = 0; j < bImg.getHeight(); j++) { 
      a[0] = i % 256; 
      a[2] = j % 256; 
      a[1] = (j * i) % 256; 
      wr.setPixel(i, j, a); // Sets the pixels (You get a nice pattern) 
     } 
    } 
    g.drawImage(bImg, x, y, w, h, null); 
} 

Я предпочел бы не использовать OpenGL или какие-либо другие внешние библиотеки, просто Java.

+1

Хороший рабочий чувак, ну, я не знаю, как вы собираетесь нарисовать изображение цели, но у меня нет проблем с временем обновления буферизованным изображением и живописью (точно с чистыми пикселями setRGB()), [это пример] (http://arashmd.blogspot.com/2013/07/java-thread-example.html#lc) может помочь, речь идет о чем-то вроде экранной заставки, и у меня есть более 60 FPS с только процессором, более 500 FPS с GPU –

+0

Все еще не нашел ничего, что могло бы мне помочь –

+0

, так вы рисуете изображение параллельно? как вы управляете целевым изображением/фальш-рисунком чуваком? –

ответ

1

Ну, вы в основном рисуете один пиксель после другого с использованием CPU. Невозможно ускорить это, поэтому такой метод просто не имеет смысла для VolatileImage. Низкий FPS, который вы получаете, предполагает, что это даже вызывает значительные накладные расходы, так как каждая операция рисования пикселей отправляется на графическую карту (с информацией, такой как местоположение &), что занимает больше времени, чем для изменения 3 или 4 байта ОЗУ.

Я предлагаю либо прекратить рисовать каждый пиксель отдельно, либо выяснить, как сделать алгоритм рисования прямо на графической карте (что, скорее всего, требует другого языка, чем Java).

0

Прошло более 4 лет с момента получения ответа. Я тоже искал ответ на этот вопрос и наткнулся на этот пост. После нескольких поисков я получил его на работу. Ниже я отправлю источник для рендеринга пикселей с помощью VolatileImage.

Кажется, что Java скрывает нашу способность отображать пиксели непосредственно в VolatileImage, но мы можем рисовать на нем буферизованные изображения. Не зря. Использование программного обеспечения для построения пикселя на самом деле не помогает с ускорением (похоже, в Java). Если вы можете отображать пиксели в BufferedImage, а затем визуализировать их на VolatileImage, вы можете получить бонус скорости, так как это аппаратное ускорение с этой точки.

Источник внизу - это автономный пример. Вы можете копировать макароны практически все из них в свой проект и запускать его.

https://github.com/Miekpeeps/JavaSnippets-repo/blob/master/src/graphics_rendering/pixels_03/PlottingVolatile.java

В конструкторе я сохранить графики среду приложения/игры.

private GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); 
private GraphicsConfiguration gc = ge.getDefaultScreenDevice().getDefaultConfiguration(); 

Затем, когда я вызываю метод для включения оборудования, мы создаем буфер. Я установил прозрачность Opaque. В моем маленьком движке я занимаюсь прозрачностью/альфа-смешением на другом потоке в конвейере.

public void setHardwareAcceleration(Boolean hw) 
{ 
    useHW = hw; 
    if (hw) 
    { 
     vbuffer = gc.createCompatibleVolatileImage(width, height, Transparency.OPAQUE); 
     System.setProperty("sun.java2d.opengl", hw.toString()); // may not be needed. 
    } 
} 

Для каждого кадра, который я обновляю, я получаю Графика из VolatileImage и визуализирую там свой буфер. Ничего не получается, если я не очищаю().

@Override 
public void paintComponent(Graphics g) 
{ 
    if(useHW) 
    { 
     g = vbuffer.getGraphics(); 
     g.drawImage(buffer, 0, 0, null); 
     vbuffer.flush(); 
    } 
    else 
    { 
     g.drawImage(buffer, 0, 0, null); 
     buffer.flush(); 
    } 
} 

Существует еще немного накладных расходов при вызове построить пиксель на BufferedImage записываемый растра. Но когда мы обновляем экран, мы получаем ускорение скорости при использовании изображения Volatile вместо использования буферизованного изображения.

Надеюсь, что это поможет некоторым людям выйти. Приветствия.

Смежные вопросы