[英]why does set and get method in java persistence model should have the same name?
[英]Why does VolatileImage have no set/getPixel() method
我是游戲編程方面的新手。 我知道如何使用setPixel()
將像素繪制到BufferedImage
。 在使用大尺寸格式時,速度非常慢,所以我繼續前進,找到了VolatileImage
(花了我一周左右的時間)。 繪制線條,字符串,矩形等非常容易,但我無法繪制單個像素。 我已經嘗試過使用drawLine(x,y,x,y)
但是在800x600的圖像上可以獲得3-4 FPS。 Java在VolatileImage
沒有包含setPixel()
或setRGB()
的事實使我非常生氣和困惑。
我有四個問題:
有沒有辦法在VolatileImage上繪制單個像素? (在FPS> 40的1440x900格式上)
我可以使用更快的方法在BufferedImage中繪制像素嗎? (相同的1440x900,FPS> 40)
還有其他方法可以足夠快地為3D游戲繪制像素嗎?
我可以使我的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。
好吧,您基本上是在使用CPU繪制一個像素。 沒有辦法可以加速,因此這種方法對於VolatileImage根本沒有任何意義。 您得到的低FPS暗示這甚至會造成很大的開銷,因為每個像素繪制操作都發送到圖形卡(帶有位置和顏色等信息),這比修改3或4個字節的RAM需要更長的時間。
我建議要么停止分別繪制每個像素,要么想出一種方法使繪圖算法直接在圖形卡上運行(這很可能需要Java以外的其他語言)。
此帖子獲得答案已經有4年了。 我也在尋找這個問題的答案,並偶然發現了這篇文章。 經過更多搜索后,我開始使用它。 在下面,我將發布源代碼以使用VolatileImage渲染像素。
似乎Java隱藏了我們直接將像素繪制到VolatileImage的功能,但是我們可以向其繪制緩沖的圖像。 有充分的理由。 使用軟件繪制像素並不能真正幫助加速(在Java中看來)。 如果您可以將像素繪制到BufferedImage上,然后在VolatileImage上進行渲染,則可能會獲得速度上的好處,因為從該點開始硬件已加速。
下面的來源是一個獨立的示例。 您幾乎可以將所有內容復制粘貼到您的項目中並運行它。
在構造函數中,我保存了應用程序/游戲的圖形環境。
private GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
private GraphicsConfiguration gc = ge.getDefaultScreenDevice().getDefaultConfiguration();
然后,當我調用啟用硬件的方法時,我們創建了一個緩沖區。 我將透明度設置為不透明。 在我的小引擎中,我處理管道中另一個線程上的透明度/ alpha混合。
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獲取Graphics並在那里渲染緩沖區。 如果我不flush(),什么也不會渲染。
@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可寫柵格上繪制像素時,仍然會有一點開銷。 但是,當我們更新屏幕時,使用揮發性圖像而不是緩沖圖像時,速度得到了提高。
希望這可以幫助一些人。 干杯。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.