很长一段时间,1-2 个月,我一直在努力寻找这个特定问题的答案:
我无法让我的图像硬件加速!
我一直在网上搜索,创建自己的方法,用键盘敲打我的头(仍然感到疼痛)但没有成功。
虽然我讨厌 Java SDK 以外的库,但我尝试了 LWJGL 和 JOGL,但出于某些愚蠢的原因,它们在我的计算机上不起作用。
我尝试使用 System.setProperty("Dsun.java2d.opengl", "True")
,我使用了 VolatileImage,但我无法向其绘制单个像素。(我尝试使用 drawLine(x,y,x,y)
但它很慢)
现在我很绝望。我会做任何事情来解决这个问题!所以,如果您知道解决方案(我知道你们中的一些人知道),请告诉我,这样我就可以摆脱它。
我的代码:
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
}
希望您能理解代码。请以任何方式修改它以帮助我找到解决问题的方法。
注意:请不要发布任何有关外部库的信息,除非您绝对确定没有它们我无法正常工作。
还有,会不会是我的显卡不支持加速? (因为我看到了硬件加速适用于其他人但不适用于我的帖子)顺便说一句,它是 GeForce 430 GT。
提前致谢!
最佳答案
来源复制自:Java Hardware Acceleration not working with Intel Integrated Graphics
试试这个:
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 帧/秒
然后我添加了系统变量:
Variable name: J2D_D3D_NO_HWCHECK
Variable value: true
然后重启IDE,运行程序:
我得到了惊人的结果。我有可用的硬件加速。 java.exe 占用了 5% 的 CPU。 1700 帧每秒。动画很棒!
以上是检查硬件加速是否在您的系统中工作。
现在回答您的问题:
据我所知:您无法使用 BufferedImage 获得真正的硬件加速。您应该使用 VolatileImage 来获得硬件加速。但是使用 VolatileImage,您无法获取像素数据缓冲区来修改像素。使用硬件逐像素渲染没有意义。
我的建议:
1) 设计你的逻辑,它可以使用易变图像的 Graphics 和 Graphics2D 渲染像素。但是不要像绘制 1 像素的线条那样进行 hack。
2)使用缓冲策略,双/三缓冲。
3) 如果您想坚持使用 BufferedImage 来设置每个像素,请使用 BufferedImage 作为数据模型,同时在 volatile 图像上渲染绘制缓冲图像。如果您正在缩放图像,这将有很大帮助。
4) 缓存频繁渲染的图像。
5) 更好地编写代码,例如:
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() 这样耗时的数学运算,缓存这些运算的结果并创建查找表。
关于java - 无法加速像素修改的 BufferedImages,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19429959/