我正在尝试使用Java2D在运行时使用某种类似的抗锯齿插值(例如双线性)来扩展后备缓冲区。我的想法是将场景渲染到此图像,然后在全屏模式下放大图像以匹配用户的任何分辨率。
请注意,全屏模式很重要。在窗口模式下不会发生这种情况。
使用硬件扩展有一种快速的方法吗? Javadocs表明它存在(-Dsun.java2d.ddscale = true)但它对我没有影响。
以下是代码:
// Initialization in AWT Canvas
buffer_ = createImage(1280, 800);
// Several hundred large draw calls into the buffer that renders the entire scene - executes fast (~10ms)
drawScene(buffer_.getGraphics());
// Upscaling buffer to screen. If I don't upscale it executes very fast (<1ms)
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.drawImage(buffer_, 0, 0, 1920, 1200, null);
结果:
图像是一个TYPE_INT_RGB不透明的BufferedImage,我正在绘制一个AWT画布。
我尝试过的其他事情:
g.drawImage
完全一样)其他一些有用的说明:
buffer_.getCapabilities(gc).isAccelerated()
返回false
(在窗口模式下为true
)感谢您的帮助。在这一点上,我很遗憾地考虑将所有内容转换为GL只是为了这一件事......但必须有答案!
答案 0 :(得分:0)
虽然我认为你的方法在技术上是可行的,但我想知道你为什么要这样设置固定分辨率的渲染。
从图形质量的角度来看,应该立即将事物渲染到目标分辨率,完全消除缩放。我意识到位图图形(如瓷砖等)需要在某个时刻进行缩放,只是我不明白为什么需要在关键路径上进行(实时)。我对此的首选方法是将位图预先缩放到所需的分辨率一次(然后将它们缓存在内存中甚至在磁盘上缓存,具体取决于哪种更新)。
您可能需要检查一些内容,确保内部使用的图像类型与渲染表面兼容(而不是使用硬编码的TYPE_INT_RGB,使用createCompatibleImage的变体创建后台缓冲区,以确保不需要格式转换)。此外,还有一大堆选项可以改变Graphics2D在幕后使用的内容:http://docs.oracle.com/javase/7/docs/technotes/guides/2d/flags.html。
最后,您可能想要检查您是否正在使用缓冲图像执行任何“禁止”操作,例如直接访问底层缓冲区数组(Can't accelerate pixel-modified BufferedImages),这会干扰javas的能力使用硬件加速。
答案 1 :(得分:0)
我还没有在上述情况下使用全屏独占模式,但我确实有一个解决方法。
保持窗口模式,将窗口大小设置为与屏幕大小相匹配,将其位置设置为graphicsDevice.getDefaultConfiguration().getBounds()
,然后设置为setUndecorated(true)
。最后,使用java.awt.Robot
将鼠标指针限制在窗口中。
不理想,但在视觉上它与全屏无法区分,至少现在双线性刻度很快。不幸的是,这意味着用户无法将其全屏分辨率设置为低于其原始分辨率。
顺便说一句,我看到使用BufferedImage
(从2毫秒到1毫秒)有一些非常显着的绘制性能提升,而VolatileImage
(降到0.3毫秒)则更多,只要我有{{{ 1}}在VM参数中。但在全屏模式下,这些性能改进消失了(可能采用软件扩展解决方案)