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

您正在尝试实现 OpenGL 例程glMultMatrix。没有选择如何返回结果。OpenGL 有一些“当前矩阵”的概念。我不熟悉OpenGL。我认为当前矩阵是某些全局或线程特定状态的一部分,因为它没有glMultMatrix作为参数传递。要实现glMultMatrix,您还必须实现 OpenGL 的全局状态。看来您必须学习一些有关 OpenGL 的知识。

鉴于glMultMatrix必须从当前矩阵中读取和写入,并且无法就地执行操作(除非使用大量临时变量),那么您有两种选择:

  • 在临时矩阵中生成结果,然后将临时矩阵复制到当前矩阵。或者,等效地,将当前矩阵复制到临时矩阵,然后使用临时矩阵作为输入,同时在当前矩阵中生成结果。
  • 将当前矩阵保持为指向两个或更多实际矩阵的指针。在诸如 的例程中glMultMatrix,从当前矩阵的当前指向版本读取并写入矩阵的另一个版本。在例程结束时,将指针更改为指向新结果。

后一种选择相对简单并且不会占用过多的空间,因为当前矩阵很小。变化是可能的,例如通常只保留一个当前矩阵,但根据需要为其他矩阵分配空间,并使用指针来指示哪一个是真正的当前矩阵。

于 2013-06-21T15:32:09.727 回答
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

这是一个实现:[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];
}

任何 row-major 与 col-major 问题仅取决于[A]and的顺序[B]


如果要模仿 的行为glMultMatrixf,则需要保持当前矩阵/矩阵堆栈的概念。至少这个函数可以做实际的连接。

于 2013-06-21T17:45:34.700 回答