Java 为什么VolatileImage没有set/getPixel()方法
我是游戏编程的新手。我知道如何使用Java 为什么VolatileImage没有set/getPixel()方法,java,3d,rendering,Java,3d,Rendering,我是游戏编程的新手。我知道如何使用setPixel()将像素绘制到buffereImage。在更大的格式上速度非常慢,所以我继续前进,找到了VolatileImage(花了我一周左右的时间)。画线、字符串、矩形等相当容易,但我不能画单个像素。我已经试过使用抽绳(x,y,x,y),但是在800x600图像上我得到了3-4fps。 java在VolatileImage中没有包含setPixel()或setRGB(),这让我非常生气和困惑 我有4个问题: 有没有办法在图像上绘制单个像素?(在FPS>4
setPixel()
将像素绘制到buffereImage
。在更大的格式上速度非常慢,所以我继续前进,找到了VolatileImage
(花了我一周左右的时间)。画线、字符串、矩形等相当容易,但我不能画单个像素。我已经试过使用抽绳(x,y,x,y)
,但是在800x600图像上我得到了3-4fps。
java在VolatileImage
中没有包含setPixel()
或setRGB()
,这让我非常生气和困惑
我有4个问题:
setAccelerationPriority(1F)
但不起作用)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);
}
publicstaticvoiddrawImageRendered(intx,inty,intw,inth){//这只是一个测试性能的方法
int a[]=new int[3];//包含每个像素的R、G和B值的数组
bImg=Launcher.contObj.getGraphicsConfiguration().createCompatibleImage(800600);//为我正在使用的JPanel对象(800x600)创建兼容映像
bImg.setAccelerationPriority(1F);//我正在尝试加速此图像
WritableRaster wr=bImg.getRaster();//图像的可写光栅
对于(int i=0;i
我更喜欢不使用OpenGL或任何其他外部库,只使用普通Java。好吧,基本上你是在使用CPU一个接一个地绘制像素。这是不可能被加速的,因此这样的方法对于VolatileImage根本没有任何意义。您获得的低FPS表明,这甚至会导致很大的开销,因为每个像素绘制操作都会发送到图形卡(带有位置和颜色等信息),修改3或4个字节的RAM所需的时间更长
我建议你要么停止单独绘制每个像素,要么想办法让你的绘制算法直接在图形卡上运行(这很可能需要Java以外的另一种语言)。这篇文章已经有4年多没有得到答案了。我也在寻找这个问题的答案,无意中发现了这篇文章。经过更多的搜索,我让它工作了。下面我将发布源代码,以使用VolatileImage渲染像素 Java似乎隐藏了我们将像素直接绘制到VolatileImage的能力,但我们可以在上面绘制缓冲图像。有充分的理由。使用软件绘制像素并不能真正帮助加速(在Java中似乎是这样)。如果您可以将像素打印到BuffereImage,然后在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中获取图形并在那里渲染缓冲区。如果不刷新(),则不会渲染任何内容
当调用在BuffereImage可写光栅上绘制像素时,仍有一点开销。但是当我们更新屏幕时,当使用易失性图像而不是使用缓冲图像时,我们会获得速度提升
希望这能帮助一些人。干杯。干得好,伙计,我不知道你要如何绘制目标图像,但我对缓冲图像和绘制(完全使用纯像素setRGB())的刷新时间没有问题,可能会有帮助,这是一个类似屏幕保护程序的东西,我只用CPU就有60多帧的刷新速度,使用GPUStill的500多FPS没有找到任何可以帮助meso的东西。您是否以并行方式绘制图像?如何管理目标图像/框架绘图都德?
@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();
}
}