1

4 つの次元頂点 (X、Y、A、B) を 6 つの個別の 2D プロット (XxY、XxA、XxB、YxA、...) として描画したい

私の頂点は次のように定義されています。

GLint data[MAX_N_POINT][4];

2D プロットの最初の (X,Y) をうまく描画できます:

glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(4, GL_INT, 4*sizeof(GLint), &data[0][0]);

glDrawArrays(GL_POINTS, 0, MAX_N_POINT-1);
glDisableclientState(GL_VERTEX_ARRAY);

他の 2D プロット (XxA、AxB など...) を描画するために、描画する次元に応じて頂点の X、Y、Z、W 次元を入れ替えるシェーダーを使用することにしました。

uniform int axes;

void main()
{

vec2 point;
if (axes == 0) {
   point = gl_Vertex.xy;
} else if (axes == 1) {
   point = gl_Vertex.xz;
} else if (axes == 2) {
   point = gl_Vertex.xw;
} else if (axes == 3) {
   point = gl_Vertex.yz;
} else if (axes == 4) {
   point = gl_Vertex.yw;
} else if (axes == 5) {
   point = gl_Vertex.zw;
}

gl_Position = gl_ModelViewProjectionMatrix * vec4(point.xy, 0.0, 1.0);

gl_FrontColor = gl_Color;
gl_BackColor = gl_Color;
}

プログラムへのシェーダーのロード、コンパイル、追加、およびプログラムのリンクに成功しました。

シェーダー プログラムができたので、頂点配列の描画方法に影響を与えるようなプログラムの使用方法が明確ではありません。次のことを試しましたが、シェーダーがない場合とまったく同じように描画されるため、効果がないようです。

glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(4, GL_INT, 4*sizeof(GLint), &data1[0][0]);

//New shader code here
glUseProgram(shaderProg);
int plotAxes = rand()%4;
GLint axes = glGetUniformLocation(shaderProg, "axes"); 
glUniform1i(axes, plotAxes);

glDrawArrays(GL_POINTS, 0, MAX_N_POINT-1);
glDisableClientState(GL_VERTEX_ARRAY);  
glUseProgram(0);

私が見逃している、または正しく理解していない基本的なものはありますか?

編集 2 : クリスチャンの提案に従って、シェーダー コードを更新しました。また、シェードがエラーなしで読み込まれることも確認しましたが、glUseProgram を呼び出した後に OpenGl エラーをチェックすると、エラーが発生しOpenGL Error: invalid operationます。

編集 3 : 動作した最終的なシェーダーは次のとおりです。

uniform int axes;

void main()
{
  vec4 point; 
  if (axes == 0) {
     point = gl_Vertex; 
  } else if (axes == 1) {
     point = gl_Vertex.xzyw; 
  } else if (axes == 2) {
     point = gl_Vertex.xwzy; 
  } else if (axes == 3) {
      point = gl_Vertex.yzxw; 
  } else if (axes == 4) {
     point = gl_Vertex.ywxz; 
  } else if (axes == 5) {
     point = gl_Vertex.zwxy; 
  }

  point.z = 0.0; 
  point.w = 1.0; 

  // eliminate w point
  gl_Position = gl_ModelViewProjectionMatrix * point;

    gl_FrontColor = gl_Color;
    gl_BackColor = gl_Color;
}
4

1 に答える 1

2

プログラム ( ) を有効化/使用した後、axesユニフォーム ( )を設定する必要があります。そうしないと、効果がありません (そして、ユニフォームはデフォルト値 (0 のようです) を保持します)。しかし、固定関数フラグメント プロセッサはこの変化をどう処理するかを知らないため、プログラムに変化を使用する有効なフラグメント シェーダーも含まれていることを願っています。glUniform1iglUseProgramaxespasscolor

ところで、とにかくすべての頂点が同じパスをたどる場合はそれほどコストはかかりませんが、6 つの異なるシェーダーを使用する方がパフォーマンス的には優れています。プリプロセッサ マクロを使用して、書き込みオーバーヘッドを削減できます。

編集:更新から、特別なフラグメントシェーダーを使用していないようです。したがって、組み込みのフラグメント パイプラインを頂点シェーダーと一緒に使用するだけです。これは可能ですが、連携するには両方の段階を一致させる必要があります。passcolor固定機能パイプラインはそれをどうするか分からないので、あなたの変化はまったく役に立ちません。異なる色のbuitlinを使用して交換するだけです

passcolor = gl_Color;

gl_FrontColor = gl_Color;
gl_BackColor = gl_Color;       //just to be sure

また、シェーダーが正常にコンパイルおよびリンクされているかどうかを確認し、そうでない場合は情報ログを調べる必要があります。上記のさまざまな不一致のためにプログラムがリンクしないと思われるからです。そのため、シェーダーを使用せずに (および多数のGL_INVALID_OPERATIONs を使用して) 気付かずに終了します。

于 2011-10-12T15:47:38.873 に答える