如何实现glMultMatrixf

时间:2013-06-21 15:28:31

标签: c opengl

我正在研究Matrix产品功能,我是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破坏这些对象的正确方法。我当然可以遍历temp数组并在常规数组中设置值,但这似乎效率低下。有没有更好的方法来解决这个问题?

3 个答案:

答案 0 :(得分:0)

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

鉴于glMultMatrix必须同时读取当前矩阵并写入它,并且无法在适当的位置执行操作(除了使用大量临时变量),那么您有两种选择:

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

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

答案 1 :(得分: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");
}

答案 2 :(得分:0)

以下是一项实施:[R] <- [A][B] =&gt; 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][B]的排序。


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