2016-12-16 19 views
0

这是任天堂用GX接口做的事情......有没有办法发送一个原始类型的数组,并将顶点(或facepoints)关联到OpenGL?

在GX中,你有一个CP命令来设置原始类型,接着是顶点数,接着是由顶点属性描述的顶点数据。
接下来是另一个基本类型。

在十六进制,这看起来像:

90 0003 
00 0000 0000 0000 
00 0001 0001 0001 
00 0002 0002 0002 

0×90描述了一个三角形图元,而为0x0003描述3含有顶点(或facepoints)。

实际facepoints由属性描述:
为0x00将是XF影响矩阵索引
0×0000将是顶点索引
0×0000将是正常索引
0×0000将是UV [0]索引

注意:这些属性还可以描述更多类型的索引,甚至是直接数据。

所以我想知道是否有办法将这些数据直接传递给缓冲区并通过GPU对其进行操作。
(当然需要一些转换来使事物兼容)

+0

我看到这被标记为可能的重复,但我没有看到链接的问题提到有关正在改变基元的任何事情......是的,这涉及索引,这已经超过了已经支持,但这不是这个问题的焦点。 – Tcll

+1

GPU不能按原样处理顶点数据的唯一原因是因为每个顶点的数据不是一个索引而是几个。因此,多索引技术正是您所需要的。这只是一个适应GameCube特性的问题。 –

回答

2

您可以use the ability of more advanced hardware to allow the use of multiple indices。这需要明确的着色器代码。它还要求着色器知道并理解数据的格式,以便它可以正确处理它。其中一些描述可以通过制服来处理,但请注意,对于每个顶点,内置着色器逻辑将被完成。因此,围绕某种格式构建着色器可能会更高效。

您遇到的最大问题是阵列中每个顶点的数据都是奇怪的格式。你可能错位排列短裤等等。所以处理它需要特别小心。为了处理7个字节的顶点,如上图所示,你需要做的是:

uniform usamplerBuffer vertexData; //Format is unsigned bytes. 

uniform samplerBuffer positionArray; 
uniform samplerBuffer normalArray; 
uniform samplerBuffer texCoordArray; 

uint ExtractShortFromVertex(in uint firstIndex) 
{ 
    uint highByte = texelFetch(vertexData, firstIndex); 
    uint lowByte = texelFetch(vertexData, firstIndex + 1); 
    return (highByte << 8) | lowByte; 
} 

void main() 
{ 
    uint baseIndex = gl_VertexID * 7; 
    uint matrixIndex =  texelFetch(vertexData, baseIndex); 

    uint positionIndex = ExtractShortFromVertex(baseIndex + 1); 
    uint normalIndex =  ExtractShortFromVertex(baseIndex + 3); 
    uint texCoordIndex = ExtractShortFromVertex(baseIndex + 5); 

    vec4 position =  texelFetch(positionArray, positionIndex); 
    vec4 normal =  texelFetch(normalArray, normalIndex); 
    vec4 texCoord =  texelFetch(texCoordArray, texCoordIndex); 

    //Do your stuff 
} 

显然,如果你在那里有直接的数据,你将需要专门的逻辑来解压。

vertexData是一个缓冲区对象(作为buffer texture访问),用于存储您呈现的GX数据。当然,它应该只指向实际的每个顶点数据,而不是指向90 0003前缀。你仍然需要手动处理。所以CPU仍然需要快速访问数据,所以当它调用glDrawArrays时,它可以传递正确的原语并绘制计数。

请注意,vertexData的格式为GL_R8UI,因为我们需要按字节访问。

处理“直接数据”更麻烦,因为这需要将字节序列转换为像float或some这样的复杂类型。但是现代GLSL确实有许多应该能够完成的功能。

可能使用Compute Shaders来处理每个渲染命令的某些方面。这里的目标是将它们变成间接渲染命令。

的问题是,虽然间接命令可以有不同的顶点数量,他们不能做的是改变统一的数据,程序或基本类型。因此,如果格式在不同命令之间改变,那么将无法构建一系列间接命令。不是没有CPU知道它并基于它发出不同的绘图调用参数。

在这一点上,你可以让CPU只处理命令本身。

+0

好的,谢谢,最好是它看起来像我将不得不将原语组织到数组中,并使用原始重置来处理来自那里的索引...我相信有些东西可以使用顶点属性来处理索引在格式是,不知道我是否有这个参考,但我一定会考虑你的建议:) – Tcll

+0

我知道我可以做的事情,但它会在GPU上做更多的工作,而不是确定每帧是否有副作用......但将整个命令列表传递给着色器并从那里处理每个面(手动转换为三角形)。如果每帧都不能通过这个来避免,那么在CPU上转换为原始数组可能只是最好的选择。 – Tcll

+0

是的,我确实有这个参考资料:(行234)https://www.dropbox.com/s/z8a8v3urgr2dtdr/3d_viewer.py?dl=0它不是与索引,但它可以升级。 – Tcll

相关问题