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个问题:

  • 有没有办法在图像上绘制单个像素?(在FPS>40的1440x900格式上)

  • 我可以用更快的方法在BuffereImage中绘制像素吗?(相同1440x900,FPS>40)

  • 有没有其他方法可以快速绘制3D游戏所需的像素

  • 我可以使我的BuffereImage硬件加速(尝试使用
    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);
    }
    
    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();
        }
    }