2016-12-16 1 views
0

これは任天堂がGXインターフェイスで行っていることから来ています...プリミティブ型の配列を送信し、頂点(またはフェイスポイント)をOpenGLに関連付ける方法はありますか?

GXでは、プリミティブタイプを設定し、その後に頂点数を設定し、その後に頂点属性で記述された頂点データを設定するCPコマンドがあります。
これには別のプリミティブ型が続きます。 0x0003 3は頂点(またはfacepoints)を含有説明しながら

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

0x90をプリミティブ三角形を説明します

進では、これは次のようになります。

実際facepointsが属性によって記述される:
0x00がXF影響行列インデックス
0000は、頂点インデックス
0000は、通常、インデックス
0000は、UV [0]インデックスであろうであろうであろうであろう

注:属性には、さらに多くのタイプのインデックス、または直接データが記述されている場合もあります。

このデータをバッファに直接渡してGPU経由で処理する方法があるのだろうかと思いました。
(もちろん、互換性を持たせるにはコンバージョンが必要です)

+0

これは可能な重複としてマークされていますが、私はリンクされた質問には、その場でプリミティブを変更することについて何も言及していませんね...はい、これはすでにサポートされている以上のインデックス作成を扱います。この質問の焦点。 – Tcll

+1

GPUがその頂点データをそのまま処理することができない唯一の理由は、各頂点のデータが1つのインデックスではなく複数であるためです。だから、マルチインデックス技術はまさにあなたが必要とするものです。 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は、提示したGXデータを格納するバッファオブジェクト(buffer textureとしてアクセス)です。もちろん、実際の頂点データだけを指し、接頭語は90 0003ではありません。あなたはまだ手動で処理する必要があります。したがって、CPUは依然としてデータへの高速アクセスを必要とするため、glDrawArraysを呼び出すと、正しいプリミティブと描画回数を渡すことができます。

vertexDataの形式は、バイト単位のアクセスが必要なので、GL_R8UIです。

"直接データ"を扱うのは、一連のバイトを浮動小数点数のような複雑な型に変換する必要があるため、面倒です。しかし、現代の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

関連する問題