gpt4 book ai didi

c++ - 我的矩阵堆栈实现 (OpenGL ES 2.0) 有什么问题?

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:07:54 24 4
gpt4 key购买 nike

我正在将我的 OpenGL 1.1 应用程序移植到 OpenGL ES 2.0,并且正在编写一个包装器来实现 OpenGL 1.1 功能。在我开始调用 glPushMatrix()glPopMatrix() 之前,我的代码似乎工作正常。我认为我对这些应该如何实现的理解是不正确的。

我是否在将其推回堆栈之前计算最终的旋转/平移/缩放?我应该只保留一个模型 View 矩阵(而不是将其分成三个)吗?转换应用的顺序是否正确?

这是我的转换矩阵的代码

static std::vector<GLfloat> vertices;
static std::vector<std::vector<GLfloat>> rotationMatrixStack;
static std::vector<std::vector<GLfloat>> scalingMatrixStack;

static std::vector<GLfloat> rotationMatrix =
{
1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f
};

static std::vector<GLfloat> scalingMatrix =
{
1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f
};

static std::vector<GLfloat> translationMatrix =
{
1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f
};

static std::vector<GLfloat> orthographicMatrix =
{
.0025f, 0.0f, 0.0f, -1.0f,
0.0f, .0025f, 0.0f, -1.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f
};

void glTranslatef (GLfloat x, GLfloat y, GLfloat z)
{
float translation[] =
{
1.0f, 0.0f, 0.0f, x,
0.0f, 1.0f, 0.0f, y,
0.0f, 0.0f, 1.0f, z,
0.0f, 0.0f, 0.0f, 1.0f
};

multiplyMatrix(translation , &translationMatrix[0], &translationMatrix[0]);
}
void glScalef (GLfloat x, GLfloat y, GLfloat z)
{
float scaling[] =
{
x, 0.0f, 0.0f, 0.0f,
0.0f, y, 0.0f, 0.0f,
0.0f, 0.0f, z, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f
};

multiplyMatrix(scaling , &scalingMatrix[0], &scalingMatrix[0]);
}
void glRotatef (GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
{
glTranslatef(-x, -y, -z);
GLfloat radians = angle * M_PI/180;
float zRotation[] =
{
cos(radians), -sin(radians), 0.0f, 0.0f,
sin(radians), cos(radians), 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f
};

multiplyMatrix(zRotation , &rotationMatrix[0], &rotationMatrix[0]);
glTranslatef(x,y,z);
}

void glLoadIdentity (void)
{
rotationMatrix, scalingMatrix, translationMatrix =
{
1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f
};
}

void multiplyMatrix(float* a, float* b, float* product)
{
int a_heigth = 4;
int a_width = 4;
int b_heigth = 4;
int b_width = 4;
int product_heigth = a_heigth;
int product_width = b_width;

float intermediateMatrix[product_heigth * product_width] = {0};
for (int product_row = 0; product_row < product_heigth; product_row++)
{
for (int product_column = 0; product_column < product_width; product_column++)
{
float value = 0;
//std::cout << "r[" << (product_row*product_width) + product_column << "] = ";
for (int multiplication_index = 0; multiplication_index < a_width ; multiplication_index++)
{
value += a[(product_row * a_width) + multiplication_index] * b[product_column + (b_heigth * multiplication_index)];
//std::cout << "( a[" << (product_row * a_width) + multiplication_index << "] * b[" << product_column + (b_heigth * multiplication_index) << "] ) + ";
}
//std::cout << std::endl;
intermediateMatrix[(product_row*product_width) + product_column] = value;
}
}

for (int i = 0; i < product_heigth * product_width; i++)
{
product[i] = intermediateMatrix[i];
}
}

这是矩阵栈的代码

static std::vector<std::vector<GLfloat>> translationMatrixStack;
void glPushMatrix()
{
rotationMatrixStack.push_back(rotationMatrix);
scalingMatrixStack.push_back(scalingMatrix);
translationMatrixStack.push_back(translationMatrix);
}

void glPopMatrix()
{
rotationMatrix = rotationMatrixStack.back();
scalingMatrix = scalingMatrixStack.back();
translationMatrix = translationMatrixStack.back();

rotationMatrixStack.pop_back();
scalingMatrixStack.pop_back();
translationMatrix.pop_back();
}

这是顶点着色器代码

attribute highp vec4    myVertex;
uniform mediump mat4 orthographicMatrix;
uniform mediump mat4 translationMatrix;
uniform mediump mat4 scalingMatrix;
uniform mediump mat4 rotationMatrix;
void main(void)
{
gl_Position = orthographicMatrix * translationMatrix * scalingMatrix * rotationMatrix * ( myVertex) ;
}";

最佳答案

您没有用于旋转、平移和缩放的单独矩阵堆栈。在 OpenGL 中,每种矩阵模式都有一个矩阵堆栈(参见 glMatrixMode)。矩阵模式是 GL_MODELVIEWGL_PROJECTIONGL_TEXTURE


请参阅 glTranslate 的文档:

glTranslate produces a translation by x y z . The current matrix (see glMatrixMode) is multiplied by this translation matrix, with the product replacing the current matrix.

glRotate 的文档:

glRotate produces a rotation of angle degrees around the vector x y z . The current matrix (see glMatrixMode) is multiplied by a rotation matrix with the product replacing the current matrix.

glScale 的文档:

glScaleproduces a nonuniform scaling along the x, y, and z axes. The three parameters indicate the desired scale factor along each of the three axes. The current matrix (see glMatrixMode) is multiplied by this scale matrix.


这意味着您需要一个矩阵堆栈,并且所有操作都在同一个矩阵堆栈上进行。

请注意,矩阵乘法 C = A * B 的工作原理如下:

Matrix4x4 A, B, C;

// C = A * B
for ( int k = 0; k < 4; ++ k )
for ( int j = 0; j < 4; ++ j )
C[k][j] = A[0][l] * B[k][0] + A[1][j] * B[k][1] + A[2][j] * B[k][2] + A[3][j] * B[k][3];


一个 4*4 矩阵看起来像这样:

  c0  c1  c2  c3            c0  c1  c2  c3
[ Xx Yx Zx Tx ] [ 0 4 8 12 ]
[ Xy Yy Zy Ty ] [ 1 5 9 13 ]
[ Xz Yz Zz Tz ] [ 2 6 10 14 ]
[ 0 0 0 1 ] [ 3 7 11 15 ]

而一个 4*4 矩阵的内存图像是这样的:

[ Xx, Xy, Xz, 0, Yx, Yy, Yz, 0, Zx, Zy, Zz, 0, Tx, Ty, Tz, 1 ]


这意味着您必须调整矩阵操作:

static std::vector<std::vector<GLfloat>> modelViewMatrixStack;

static std::vector<GLfloat> modelViewMatrix{
1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f };

void multiplyMatrix( float A[], float B[], float P[] )
{
float C[16];
for ( int k = 0; k < 4; ++ k ) {
for ( int l = 0; l < 4; ++ l ) {
C[k*4+j] =
A[0*4+j] * B[k*4+0] +
A[1*4+j] * B[k*4+1] +
A[2*4+j] * B[k*4+2] +
A[3*4+j] * B[k*4+3];
}
}
std::copy(C, C+16, P);
}

void glTranslatef( GLfloat x, GLfloat y, GLfloat z )
{
float translation[]{
1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
x, y, z, 1.0f };

multiplyMatrix(&modelViewMatrix[0], translation, &modelViewMatrix[0]);
}

void glScalef( GLfloat x, GLfloat y, GLfloat z )
{
float scaling[]{
x, 0.0f, 0.0f, 0.0f,
0.0f, y, 0.0f, 0.0f,
0.0f, 0.0f, z, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f };

multiplyMatrix(&modelViewMatrix[0], scaling, &modelViewMatrix[0]);
}

void glRotatef( GLfloat angle, GLfloat x, GLfloat y, GLfloat z )
{
float radians = angle * M_PI/180;
float c = cos(radians);
float s = sin(radians);

float rotation[16]{
x*x*(1.0f-c)+c, x*y*(1.0f-c)-z*s, x*z*(1.0f-c)+y*s, 0.0f,
y*x*(1.0f-c)+z*s, y*y*(1.0f-c)+c, y*z*(1.0f-c)-x*s, 0.0f,
z*x*(1.0f-c)-y*s z*y*(1.0f-c)+x*s, z*z*(1.0f-c)+c, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f };

multiplyMatrix(&rotationMatrix[0], rotation, &rotationMatrix[0]);
}


进一步查看:

关于c++ - 我的矩阵堆栈实现 (OpenGL ES 2.0) 有什么问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46732918/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com