无法加速像素修改的 BufferedImages [英] Can't accelerate pixel-modified BufferedImages

查看:17
本文介绍了无法加速像素修改的 BufferedImages的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

很长一段时间,1-2 个月,我一直试图找到这个特定问题的答案:

For quite a long time, 1-2 months, I have been trying to find an answer to this particular problem:

我的图像硬件无法加速!

I can't get my image hardware accelerated!

我一直在网上搜索,创建自己的方法,用键盘敲我的头(仍然感到疼痛)但没有成功.

I've been searching on the net, created my own methods, hit my head with the keyboard (still feel the pain) but no success.

尽管我讨厌 Java SDK 以外的库,但我尝试了 LWJGL 和 JOGL,但由于某些愚蠢的原因,它们在我的计算机上无法运行.

Although I hate libraries other than Java SDK, I tried LWJGL and JOGL but for some stupid reason they dont work on my computer.

我尝试使用 System.setProperty("Dsun.java2d.opengl", "True"),我使用了 VolatileImage 但我无法向它绘制单个像素.(我尝试使用 drawLine(x,y,x,y) 但它很慢)

I tried using System.setProperty("Dsun.java2d.opengl", "True"), I used VolatileImage but I can't draw individual pixels to it.(I tried using drawLine(x,y,x,y) but it's slow)

现在我好绝望.我会做任何事情来解决这个问题!所以,如果你知道解决方案(我知道你们中的一些人知道),请告诉我,这样我就可以摆脱这个.

Now I am so desperate. I will do anything to fix this! So please, if you know the solution (I know some of you do) tell me so I can get rid of this.

我的代码:

   public static void render(int x, int y, int w, int h, ) {

            int a[] = new int[3]; // The array that contains RGB values for every pixel
            BufferedImage bImg = Launcher.contObj.getGraphicsConfiguration().createCompatibleImage(800, 600, Transparency.TRANSLUCENT); // Creates an image compatible to my JPanel (Runs at 20-24 FPS on 800x600 resolution)
            int[] wr = ((DataBufferInt) bImg.getRaster().getDataBuffer()).getData(); // Contains the image data, used for drawing pixels
            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] = i * j % 256;
                    wr[i + j * bImg.getWidth()] = new Color(a[0], a[1], a[2]).getRGB(); // Sets the pixels from a[]
                }
            }
            bImg.flush();
            g.drawImage(bImg, x, y, w, h, null); // Draws the image on the JPanel
            g.dispose();
            System.out.println(bImg.getCapabilities(Launcher.contObj.getGraphicsConfiguration()).isAccelerated()); // Prints out whether I was successful and made the image accelerated or failed and made everything worse
        }

我希望你理解代码.请以任何方式修改它以帮助我找到解决问题的方法.

I hope you understand the code. Please modify it in any way to help me find the solution to my problems.

注意:请不要发布有关外部库的任何内容,除非您完全确定没有它们我无法正常工作.

还有,会不会是我的显卡不支持加速?(因为我看到了一些帖子,硬件加速对其他人有效,但对我无效)顺便说一句,它是 GeForce 430 GT.

Also, could it be that my graphics card doesn't support acceleration? (because I saw posts where hardware accel works for other people but not for me) Btw, it's a GeForce 430 GT.

提前致谢!

推荐答案

复制自:Java 硬件加速不适用于英特尔集成显卡

试试这个:

package graphicstest;

import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferStrategy;

public class GraphicsTest extends JFrame {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new GraphicsTest();
            }
        });
    }

    GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
    BufferCapabilities bufferCapabilities;
    BufferStrategy bufferStrategy;

    int y = 0;
    int delta = 1;

    public GraphicsTest() {

        setTitle("Hardware Acceleration Test");
        setSize(500, 300);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        setVisible(true);

        createBufferStrategy(2);
        bufferStrategy = getBufferStrategy();

        bufferCapabilities = gc.getBufferCapabilities();

        new AnimationThread().start();
    }

    class AnimationThread extends Thread {
        @Override
        public void run() {

            while(true) {
                Graphics2D g2 = null;
                try {
                    g2 = (Graphics2D) bufferStrategy.getDrawGraphics();
                    draw(g2);
                } finally {
                    if(g2 != null) g2.dispose();
                }
                bufferStrategy.show();

                try {
                    // CHANGE HERE, DONT SLEEP
                    //Thread.sleep(16);
                } catch(Exception err) {
                    err.printStackTrace();
                }
            }
        }
    }

    public void draw(Graphics2D g2) {
        if(!bufferCapabilities.isPageFlipping() || bufferCapabilities.isFullScreenRequired()) {
            g2.setColor(Color.black);
            g2.fillRect(0, 0, getWidth(), getHeight());
            g2.setColor(Color.red);
            g2.drawString("Hardware Acceleration is not supported...", 100, 100);
            g2.setColor(Color.white);
            g2.drawString("Page Flipping: " + (bufferCapabilities.isPageFlipping() ? "Available" : "Not Supported"), 100, 130);
            g2.drawString("Full Screen Required: " + (bufferCapabilities.isFullScreenRequired() ? "Required" : "Not Required"), 100, 160);
            g2.drawString("Multiple Buffer Capable: " + (bufferCapabilities.isMultiBufferAvailable() ? "Yes" : "No"), 100, 190);
        } else {
            g2.setColor(Color.black);
            g2.fillRect(0, 0, getWidth(), getHeight());
            g2.setColor(Color.white);
            g2.drawString("Hardware Acceleration is Working...", 100, 100);
            g2.drawString("Page Flipping: " + (bufferCapabilities.isPageFlipping() ? "Available" : "Not Supported"), 100, 130);
            g2.drawString("Full Screen Required: " + (bufferCapabilities.isFullScreenRequired() ? "Required" : "Not Required"), 100, 160);
            g2.drawString("Multiple Buffer Capable: " + (bufferCapabilities.isMultiBufferAvailable() ? "Yes" : "No"), 100, 190);
        }

        y += delta;
        if((y + 50) > getHeight() || y < 0) {
            delta *= -1;
        }

        g2.setColor(Color.blue);
        g2.fillRect(getWidth()-50, y, 50, 50);
    }
}

输出 我的硬件加速不可用.java.exe 占用了 12% 的 CPU.700 帧/秒

然后我添加了系统变量:

Then I added System variable:

Variable name: J2D_D3D_NO_HWCHECK
         Variable value: true

然后重新启动IDE,并运行程序:

then restarted IDE, and ran program:

我得到了惊人的结果.我有可用的硬件加速.java.exe 占用了 5% 的 CPU.1700 帧/秒.动画很棒!

以上是检查硬件加速是否在你的系统中工作.

Above things are to check whether hardware acceleration works in your system.

现在回答您的问题:

AFAIK:您无法通过 BufferedImage 获得真正的硬件加速.您应该使用 VolatileImage 来获得硬件加速.但是使用 VolatileImage,您无法获得像素数据缓冲区来修改像素.使用硬件逐像素渲染没有意义.

AFAIK: You can't get real hardware acceleration with BufferedImage. You should work with VolatileImage to get hardware acceleration. But with VolatileImage, you can't get pixel data buffer to modify pixels. And rendering pixel by pixel using hardware doesn't make sense.

我的建议:

1) 设计您的逻辑,它可以使用可变图像的 Graphics 和 Graphics2D 来渲染像素.但是不要像画 1 像素的线那样做 hack.

1) Design your logic, which can render pixels using Graphics and Graphics2D of volatile image. But don't go to make hack like drawing lines of 1 pixel.

2) 使用缓冲策略,双/三缓冲.

2) Use buffer strategies, double / triple buffering.

3) 如果您想坚持使用 BufferedImage 来设置每个像素,请使用 BufferedImage 作为数据模型,同时在易失性图像上渲染绘制缓冲图像.如果您要缩放图像,这将很有帮助.

3) If you want to stick with BufferedImage for setting each pixel, use BufferedImage as data model, while rendering draw buffered image on volatile image. This will help a lot if you are scaling image.

4) 缓存经常渲染的图像.

4) Cache the images frequently being rendered.

5) 更好地编写代码,例如:

5) Write code better, like:

int wi = bImg.getWidth();
int he = bImg.getHeight();
for (int i = 0; i < wi; i++) {
    for (int j = 0; j < he; j++) {
        wr[i + j * wi] = ((i % 256) << 16) | ((i * j % 256) << 8) | (j % 256);
    }
}

6) 对于耗时的数学运算,如 sqrt()、sin()、cos(),缓存这些运算的结果并创建查找表.

6) For time consuming math operation like sqrt(), sin(), cos(), cache results of these operations and create lookup tables.

这篇关于无法加速像素修改的 BufferedImages的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆