Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/378.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 LWJGL:缓冲区内存管理_Java_Opengl_Native_Lwjgl - Fatal编程技术网

Java LWJGL:缓冲区内存管理

Java LWJGL:缓冲区内存管理,java,opengl,native,lwjgl,Java,Opengl,Native,Lwjgl,我正在寻找关于哪种方法更好的内存/性能建议 假设一个网格有4个属性 Vertex 3f Normal 3f TexCoords 2f jointID 4i [Integer Joint Indices For Skeleton Animation] 我需要这些在cpu内存中,因为它们可以随时修改 这样更好吗 a、 为每个组件创建4个单独的缓冲区 //3,2,4 are the strides i.e vertex is 3 floats,texCoord is 2 floats

我正在寻找关于哪种方法更好的内存/性能建议

假设一个网格有4个属性

Vertex    3f
Normal    3f
TexCoords 2f
jointID   4i [Integer Joint Indices For Skeleton Animation]
我需要这些在cpu内存中,因为它们可以随时修改

这样更好吗

a、 为每个组件创建4个单独的缓冲区

//3,2,4 are the strides i.e vertex is 3 floats,texCoord is 2 floats so on
FloatBuffer vertices=BufferUtils.createFloatBuffer(numOfVertices*3);
FloatBuffer normals=BufferUtils.createFloatBuffer(numOfVertices*3);
FloatBuffer texCoords=BufferUtils.createFloatBuffer(numOfVertices*2);
IntBuffer   vertexJoints=BufferUtils.createIntBuffer(numOfVertices*4);

b、 创建一个容量足够大的bytebuffer来存储所有4个属性,并为每个属性创建单独的Float/Int缓冲区视图

 ByteBuffer  meshData=BufferUtils.createByteBuffer(((numOfVertices*3)+(numOfVertices*3)+(numOfVertices*2)+(numOfVertices*4))*4); //*4 because both float/int is 4 bytes
 FloatBuffer vertices=meshData.position(0).limit(endVertexByte).asFloatBuffer();
 FloatBuffer normals=meshData.position(endVertexByte).limit(endNormalByte).asFloatBuffer();
 FloatBuffer texCoords=meshData.position(endNormalByte).limit(endTexCoordByte).asFloatBuffer();
 IntBuffer   jointIDs=meshData.position(endTexCoordByte).limit(endJointIndexByte or end of buffer in this case).asIntBuffer();
从文档中,所有BufferUtils方法都创建了一个存储在本机内存中的directBuffer,尽管第二种方法创建的缓冲区比所有单个属性缓冲区的总和大[因为我们乘以4],但与第一种方法中的4个独立内存区相比,它只创建了一个大的本机内存块


但这只是我的观点,想法?

从CPU的角度来看,将(新)数据写入这些缓冲区的方式不会有性能差异。 在这两种情况下,在更新顶点的属性数据时,只有四个连续的内存区域可供点击。只是在前一种情况下,这些内存区域的偏移量未知(因为JVM的内存分配器将分别分配每个区域),而在后一种情况下,您知道每个连续内存区域之间的偏移量,因为您在单个JVM缓冲区内存分配中分配了这些区域

然而,真正不同的是如何将这些客户端主机内存区域映射到服务器端OpenGL缓冲区对象内存。 我假设,一旦您更新了主机端内存,您将实际将其上载到服务器端OpenGL缓冲区对象中,而不会将客户端/主机端内存指针用于OpenGL顶点规范命令(仅在OpenGL兼容上下文中可用)

在这种情况下,创建四个独立的连续客户端内存区域将需要执行四个OpenGL缓冲区内存上载命令(
glBufferSubData()
)和OpenGL驱动程序通过PCIe执行四个不同的直接内存访问(DMA)上载。 如果只有一个连续的客户端内存区域,则可以对单个缓冲区对象中的所有顶点属性数据发出一个
glBufferSubData()
调用,在该对象中,您只需在OpenGL顶点规范调用中使用字节偏移量(例如,对于
glvertexattributepointer()

另一种可能性是不自己分配客户端主机内存,而是让OpenGL(
glBufferStorage()
+
glMapBufferRange()
)为您提供主机可见、持久映射的缓冲区,然后您可以写入并显式刷新或让OpenGL驱动程序隐式/一致地更新这些缓冲区。 与四个单独的客户端内存区域一样,在映射和刷新四个不同的OpenGL缓冲区对象区域时,您也可能需要支付“四个不同的DMA传输”成本


因此,归根结底,客户端内存上是否有一个或四个NIO缓冲区视图并不重要,而是与映射这些内存区域的服务器端OpenGL缓冲区对象的数量有关——越少越好。

因此,如果在交错缓冲区的情况下只有一个glBuffer,则第二种方法更好[我们在VertexAttributePointer中指定步幅和偏移]但是,如果您有4个单独的glBuffer对象,则不会产生差异如果您希望保持属性分离,这是结论,对吗?glMapBuffer不能有效地用于多线程设置,在多线程设置中,需要切换上下文以使调用工作,唯一的选项是首先将顶点数据加载到cpu中,然后创建glBuffers在主线程中。但就jni内存而言,我是否节省了一些钱?说到打包,当涉及gpu读取速度时,所有东西都是交错的glBuffer比4个单独的glBuffers好,或者这是另一个线程的单独问题?我不太确定我是否需要一些时间进行实验,以及我的结论是否与你的一致那我就做标记