本文介绍了不能加速像素改性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,真),我用的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.

我的code:

   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
        }

我希望你明白了code。请修改以任何方式来帮助我找到解决我的问题。

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

注意:除非你是绝对的把握,我不能得到这个工作,没有他们,请不要发布有关外部库什么

此外,会不会是我的显卡不支持加速? (因为我看到的帖子,其中硬件加速适用于其他人,但不适合我)顺便说一句,这是一个的GeForce GT 430

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);
    }
}

输出我得到的硬件accelaration不可用。 java.exe的是采取12%的CPU。 700 FPS

然后,我添加系统变量:

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 FPS。动画是伟大的!

上面的东西是要检查硬件加速是否工作在你的系统中。

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)设计你的逻辑,它可以使使用图形和挥发性图像的Graphics2D像素。但是,不要去让黑客就像画1像素的线。

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)写code更好,如:

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)对于耗时像开方数学运算(),SIN(),COS(),这些操作的缓存结果,并创建查找表。

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

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

10-21 23:08