Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/344.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
使用大型画布时JavaFX中的空指针_Java_Javafx_Graphics_Nullpointerexception_Textures - Fatal编程技术网

使用大型画布时JavaFX中的空指针

使用大型画布时JavaFX中的空指针,java,javafx,graphics,nullpointerexception,textures,Java,Javafx,Graphics,Nullpointerexception,Textures,我在我的应用程序中使用画布对象,确切地说,在StackPane中有两个大小相同的对象。当这些对象变大时,JavaFX在尝试绘制/渲染时开始崩溃: java.lang.NullPointerException: Cannot invoke "com.sun.prism.RTTexture.createGraphics()" because "<local9>" is null at javafx.graphics/com.sun.javafx.s

我在我的应用程序中使用画布对象,确切地说,在StackPane中有两个大小相同的对象。当这些对象变大时,JavaFX在尝试绘制/渲染时开始崩溃:

java.lang.NullPointerException: Cannot invoke "com.sun.prism.RTTexture.createGraphics()" because "<local9>" is null
at javafx.graphics/com.sun.javafx.sg.prism.NGCanvas$RenderBuf.validate(NGCanvas.java:214)
at javafx.graphics/com.sun.javafx.sg.prism.NGCanvas.initCanvas(NGCanvas.java:644)
at javafx.graphics/com.sun.javafx.sg.prism.NGCanvas.renderContent(NGCanvas.java:607)
at javafx.graphics/com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2072)
(...)
java.lang.NullPointerException:无法调用“com.sun.prism.RTTexture.createGraphics()”,因为“”为null
位于javafx.graphics/com.sun.javafx.sg.prism.NGCanvas$RenderBuf.validate(NGCanvas.java:214)
位于javafx.graphics/com.sun.javafx.sg.prism.NGCanvas.initCanvas(NGCanvas.java:644)
位于javafx.graphics/com.sun.javafx.sg.prism.NGCanvas.renderContent(NGCanvas.java:607)
位于javafx.graphics/com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2072)
(...)
和类似的(都与javafx.graphics/com.sun.javafx.sg.prism.NGCanvas相关)。现在,过去有一些关于这类东西的讨论(例如),一半的互联网基本上只是通过关闭硬件加速来回答这个问题,这是像
-Dprism.order=sw
这样的标志所做的

我认为这不是答案。

我的图形硬件支持16384x16384纹理(至少在OpenGL驱动程序中)和8GB的VRAM。我甚至编写了一个小的测试程序来验证支持是否“正确”,并且可以正常工作,因为我过去被一些劣质的集成笔记本电脑的图形设备烧坏了,该设备声称支持OpenGL-v3,但当有人试图分配8k+纹理时崩溃了。 我的电脑中只有一个图形卡,所以JavaFX应用程序不可能使用错误的设备

当我将画布对象从4156x4156调整为8252x8252时,我的应用程序崩溃。即使我们接受它将使用两个大小的下一个更高的幂来渲染这些东西,我声称我的硬件应该能够处理这个设置。即使是多个16384x16384纹理也可以与其他材质一起轻松放入内存

我在Windows10上,在版本15.0.1中使用OpenJDK和JavaFX,尽管画布很旧,这不应该是一个问题

有人知道这里到底发生了什么吗?

编辑:正如评论中所建议的,我做了一些更精确的测试。使用两个画布对象的硬编码大小进行进一步的手动测试,结果如下:

将两者设置为4096x4096和4097x4097都有效。记住,后者应该在内部使用纹理8192x8192,因为这就是图形卡的工作方式。内部表示在图形卡上,而不是在其他任何地方

然而,在这里它变得有趣:

将两个画布对象中的一个设置为8192x8192(另一个设置为2x2)也可以正常工作。如果将两者都设置为8192x8192,则不会导致上述空值问题

这表明这毕竟是一个内存问题,可能与分配有关。然而,如前所述,图形设备应该能够处理这个问题,并且似乎也能够处理,考虑到将两者都设置为4097x4097是可行的。 我怀疑这是在Java方面,可能与堆栈窗格有关。 有人知道StackPane是否有某种内部像素阵列或其他机制吗?可能检测到变化?显然,这将是非常不幸的,因为它与硬件加速纹理的使用背道而驰

此外,我还使用
-Dprism.order=sw
进行了更精确的测试。从4156x4156到8252x8252的转换在该模式下工作。当进一步推动(仅用于实验目的)时,最终会出现完全相同的问题,再次表明内存问题


我可以选择只使用一个画布,并在该画布内更频繁地重新绘制,以减少内存占用(我想性能折衷在这里是可以的),但我首先想了解这里到底出了什么问题…

因为您已经验证了您创建的纹理没有超过硬件的最大大小,听起来好像你的VRAM快用完了。据我所知,默认最大值为512MB。您可以通过在VM参数中传递以下内容来请求不同的最大值

-Dprism.maxvram=xx


示例:对于2GB,您可以使用-Dprism.maxvram=2G。

您尝试过8192x8192吗?您使用的是哪个版本的JavaFX和哪个操作系统?更新了主要帖子,因为第一个问题的答案很长……关于大画布尺寸,即f.i.存在一些悬而未决的问题。有些人可能会有黑客攻击(或者不是,我的深水区:)存在VRAM限制,天哪。我不知道JavaFX在这方面也有限制,类似于堆栈。。。谢谢:-)