Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用大型图像时出现的二维图形性能问题_Java_Performance_Opengl_Slick2d - Fatal编程技术网

Java 使用大型图像时出现的二维图形性能问题

Java 使用大型图像时出现的二维图形性能问题,java,performance,opengl,slick2d,Java,Performance,Opengl,Slick2d,我正在用Java编写一个2D月球着陆器风格的游戏,并使用Slick2D库处理图形。我在处理背景图像时遇到问题 我的问题是: 我在飞船后面的背景上画了三层细节(星星、山脉和陆地,包括着陆点)。随着飞船(屏幕中心)的移动,这些都会在每个循环中重新绘制 这些层的图像宽4500像素,高1440像素。这主要是为了创造某种多样性(星星),并且足够宽以容纳生成的山脉和土地(土地包括着陆点)。每转一圈都会生成山脉和陆地,它们是多边形,被绘制到保存图像中 Slick2d(或opengl)抱怨它不能处理这种大小的图

我正在用Java编写一个2D月球着陆器风格的游戏,并使用Slick2D库处理图形。我在处理背景图像时遇到问题

我的问题是: 我在飞船后面的背景上画了三层细节(星星、山脉和陆地,包括着陆点)。随着飞船(屏幕中心)的移动,这些都会在每个循环中重新绘制

这些层的图像宽4500像素,高1440像素。这主要是为了创造某种多样性(星星),并且足够宽以容纳生成的山脉和土地(土地包括着陆点)。每转一圈都会生成山脉和陆地,它们是多边形,被绘制到保存图像中

Slick2d(或opengl)抱怨它不能处理这种大小的图像-它说它只能处理在我的开发PC上512 x 512的纹理。所以。。。如果我一直在探索解决这一问题的不同方法,包括:

a。在每个循环中进行多边形剪裁以将多边形(山脉和陆地)缩小到可显示的屏幕大小(640 x 480),但这在数学上似乎具有挑战性,或者

b。将我的图层图像分割成512x512块,然后用这些块更新屏幕,这是我已经做过的工作的扩展(包装图层以创建一个“无限”世界),因此,考虑到我的能力,似乎可以做得更多

我的第一个问题(或感觉检查,真的)是我遗漏了什么吗?我的图片虽然很大,但内容却很少,例如黑色背景和几行文字。是否有办法在Slick2D/opengl中压缩这些图像,或者我是否遗漏了一些与设置有关的内容,这些设置意味着我可以使我的卡处理更大的图像?(根据我读到的内容,我假设不是这样,而是希望永远存在。)

所以,假设我没有错过任何明显的东西,在第2部分

作为一个快速的“我可能会侥幸逃脱”解决方案,我已经恢复到使用BuffereImage来保存层,然后将这些层的一部分提取到光滑的2D图像中,并在每个渲染循环中在屏幕上绘制这些层。这样做,我得到了约3帧,这显然是一个有点慢的实时游戏

要创建我正在使用的BuffereImage,请执行以下操作:

   BufferedImage im_stars = new BufferedImage(bWIDTH, bHEIGHT, BufferedImage.TYPE_INT_ARGB);
   Graphics2D gr_stars = im_stars.createGraphics();
。。。然后我把我的内容画在上面(星星等)

在我的渲染循环中,我会做一些数学运算,计算出需要显示哪些图像块(以应对包装/提供“无限”体验),然后将BuffereImage的相关部分提取到光滑的2D图像,如下所示:

Image i1_star = Tools.getImage(stars.getStarImg().getSubimage((int) x1, (int) y1, width, height));
g.drawImage(i1_star, 0, 0);
   protected static Image getImage(BufferedImage bi) {
     Image im = null;
     try {
       im = new Image(BufferedImageUtil.getTexture("", bi));
     } catch (IOException ex) {
       Logger.getLogger(Tools.class.getName()).log(Level.SEVERE, null, ex);
     }
     return im;
   }
我已经编写了一个静态助手方法,将我的BuffereImage块转换为Slick2D图像,如下所示:

Image i1_star = Tools.getImage(stars.getStarImg().getSubimage((int) x1, (int) y1, width, height));
g.drawImage(i1_star, 0, 0);
   protected static Image getImage(BufferedImage bi) {
     Image im = null;
     try {
       im = new Image(BufferedImageUtil.getTexture("", bi));
     } catch (IOException ex) {
       Logger.getLogger(Tools.class.getName()).log(Level.SEVERE, null, ex);
     }
     return im;
   }

我猜这是一个糟糕的方式做事情的基础上,我得到的FPS,虽然3似乎非常低。当我使用我自己编写的代码做同样的事情时,我得到了大约25 FPS!那么,有没有一种加速的Slick2D/opengl方法可以做到这一点,而我没有,或者我又回到了必须平铺背景图像或将它们作为多边形保存并开发多边形剪裁例程的状态?

做了更多的研究后,我发现我的图形卡可以使用Slick2D支持高达4096 x 4096像素的图像:

BigImage.getMaxSingleImageSize();

在我的程序中,我已恢复使用宽度不大于此大小的Slick2D图像文件,现在速度约为350 FPS,因此BuffereImage的解决方案肯定是个坏主意。

还有一个发现。。。我已经将代码中从不同背景层提取子图像的部分提取到一个子类中,出于通常的原因(可编辑性、紧凑性等)。作为子类的一部分,我在每个渲染循环中创建了一个新的Slick2D图像,以将提取的子部分连接到整个层图像中。你瞧,当我运行游戏时,我又获得了3-4 FPS。因此,可能是BuffereImage解决方案工作正常,而导致问题的只是错误代码(在每个循环中重新创建映像)。。。。最后,我不再使用大型图像,现在将数据存储在数组中,并在每个渲染循环中动态构建屏幕图像。事实证明,它比使用大型图像更快,这意味着我可以拥有更大的环境,而不必担心图像大小。我在游戏开发网站上发布了一个相关的答案,在这里更详细地解释了我的方法: