0

私はマトリックス製品関数に取り組んでおり、C は初めてです。これが私が思いついたものです...

static float *currentMatrix;
...
glMultMatrixf(const float *m){
  int i;
  int i2=0;
  int i3=0;
  float result[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
  printf("starting \n");
  for(i=0; i < (MATRIX_HEIGHT); i++){
    float dotProduct = 0.0f;
    for(i2=0; i2 < (MATRIX_WIDTH); i2++){
      float dotProduct = 0.0f;
      for(i3=0;i3 < (MATRIX_WIDTH); i3++){
        dotProduct+=currentMatrix[i3+i*4]*m[i3*4+i2];
      }
      result[i2+i*4]=dotProduct;
    }
  }
  currentMatrix = &result[0];
  printf("Finished \n");
}

もちろん、これは結果の範囲のために失敗します。

これは機能します...

static float *currentMatrix;
float result[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
...
glMultMatrixf(const float *m){
  int i;
  int i2=0;
  int i3=0;

  printf("starting \n");
  for(i=0; i < (MATRIX_HEIGHT); i++){
    float dotProduct = 0.0f;
    for(i2=0; i2 < (MATRIX_WIDTH); i2++){
      float dotProduct = 0.0f;
      for(i3=0;i3 < (MATRIX_WIDTH); i3++){
        dotProduct+=currentMatrix[i3+i*4]*m[i3*4+i2];
      }
      result[i2+i*4]=dotProduct;
    }
  }
  currentMatrix = &result[0];
  printf("Finished \n");
}

しかし、複数のスレッドが同時に関数を呼び出している場合、これが問題を引き起こすように思われるため、これは正しくないようです (私は C に慣れていないことを思い出してください)。

そのため、GC がこれらのオブジェクトを破棄するのを防ぐ正しい方法がよくわかりません。もちろん、一時配列を反復処理して通常の配列に値を設定することもできますが、それは非効率的です。これを処理するより良い方法はありますか?

4

3 に答える 3

0

これが実装です: [R] <- [A][B]=>matrix4_mul(r, a, b);
シンプルな ISO C90。結果:(r)別名(x)および/または(y). テストされていません:

/* inline */ void
matrix4_mul (float r[16], const float a[16], const float b[16])
{
    float t[16]; /* (tmp result) */
    int i, j, k;

    for (i = 0; i < 4; i++)
    {
        const float *ai = a + (i * 4);
        float *ti = t + (i * 4);

        for (j = 0; j < 4; j++)
        {
            float tij = 0.0;

            for (k = 0; k < 4; k++)
                tij += ai[k] * b[k * 4 + j];

            ti[j] = tij; /* r[i][j] (inner product) */
        }
    }

    for (i = 0; i < 16; i++) /* copy elements back to result: */
        r[i] = t[i];
}

行優先と列優先の問題は、 と の順序に依存し[A]ます[B]


の動作を模倣したい場合glMultMatrixfは、現在のマトリックス/マトリックス スタックの概念を維持する必要があります。少なくとも、この関数は実際の連結を行うことができます。

于 2013-06-21T17:45:34.700 に答える
0

+FVU が正しかったようです。memcpy は機能しているようです...

glMultMatrixf(const float *m){
  int i;
  int i2=0;
  int i3=0;
  printf("starting \n");
  float result[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
  for(i=0; i < (MATRIX_HEIGHT); i++){
   float dotProduct = 0.0f;
   for(i2=0; i2 < (MATRIX_WIDTH); i2++){
     float dotProduct = 0.0f;
     for(i3=0;i3 < (MATRIX_WIDTH); i3++){
       printf("Multiplying... currentLoc %d New M Loc %d | %f * %f", i3+i*4, i3*4+i2, currentMatrix[i3+i*4],m[i3*4+i2]);
       dotProduct+=currentMatrix[i3+i*4]*m[i3*4+i2];
       printf(" Dot Product = %f \n", dotProduct);
     }
     result[i2+i*4]=dotProduct;
   }
  }

  memcpy(currentMatrix, &result, 16 * sizeof(float) );
  printf("Finished \n");
}
于 2013-06-21T17:05:29.810 に答える
0

OpenGL ルーチンを実装しようとしていますglMultMatrix。結果を返す方法について選択の余地はありません。OpenGL には「現在の行列」という概念があります。私は OpenGL に精通していません。現在のマトリックスは、パラメーターとして渡されないため、グローバルまたはスレッド固有の状態の一部であると思いglMultMatrixます。を実装するglMultMatrixには、OpenGL のグローバル ステートも実装する必要があります。OpenGL について何かを学ぶ必要があるようです。

が現在の行列からの読み取りと書き込みの両方を行うglMultMatrix必要があり、(多数の一時変数を使用する場合を除いて) その場で操作を実行できない場合、次の 2 つの選択肢があります。

  • 結果を一時行列に生成し、一時行列を現在の行列にコピーします。または、同等に、現在の行列を一時的な行列にコピーし、現在の行列で結果を生成しながら、一時的な行列を入力に使用します。
  • 現在の行列を 2 つ以上の実際の行列へのポインタとして維持します。などのルーチンglMultMatrixでは、現在のマトリックスの現在ポイントされているバージョンから読み取り、別のバージョンのマトリックスに書き込みます。ルーチンの最後で、新しい結果を指すようにポインターを変更します。

後者のオプションは比較的単純で、現在のマトリックスが小さいため、余分なスペースを消費しません。通常は現在の行列を 1 つだけ保持し、必要に応じて他の領域にスペースを割り当てたり、ポインターを使用してどれが実際の現在の行列であるかを示すなどのバリエーションが可能です。

于 2013-06-21T15:32:09.727 に答える