0
這是此Why doesn't this viewing/projection transform work?較早發佈的後續行動。投影轉換有什麼不同?
出於實驗目的,每次窗口繪製時,此代碼都會在OpenGL計算的轉換和我手動計算的轉換之間翻轉。第一次跟蹤來自OpenGL的Projection和ModelView矩陣值,所以我可以在自己做這些時使用它們。
如果我註釋掉投影變換,則視覺輸出是相同的。但隨着投影變換,它是「接近但不準確」(似乎有點扭曲)。
由於所有其他變換使用相同的邏輯工作,我相信我的數學,列與列,調換等是聲音(相對於我以前的帖子),並且必須有一些概念上的差異投影變換正在逃避我。有什麼建議?
#include <iostream>
#include <math.h>
#include "glut.h"
#include "vector3.h"
bool useOpenGL = true;
typedef GLfloat Matrix4x4[4][4];
Matrix4x4 matComposite;
void matrix4x4SetIdentity(Matrix4x4 matIdent4x4){
GLint row, col;
for(row = 0; row<4; row++){
for(col = 0; col<4; col++){
matIdent4x4[row][col] = (row == col);
}
}
}
void matrix4x4PreMultiply(Matrix4x4 m1, Matrix4x4 m2){
GLint row, col;
Matrix4x4 matTemp;
for(row=0; row<4; row++){
for(col=0; col<4; col++){
matTemp[row][col] = m1[row][0] * m2[0][col] +
m1[row][1] * m2[1][col] +
m1[row][2] * m2[2][col] +
m1[row][3] * m2[3][col];
}
}
for(row=0; row<4; row++){
for(col=0; col<4; col++){
m2[row][col] = matTemp[row][col];
}
}
}
vector3 matrixMult(GLfloat x, GLfloat y, GLfloat z){
if(useOpenGL){
return vector3(x, y, z);
} else {
GLfloat tempX = matComposite[0][0] * x + matComposite[0][1] * y + matComposite[0][2] * z + matComposite[0][3];
GLfloat tempY = matComposite[1][0] * x + matComposite[1][1] * y + matComposite[1][2] * z + matComposite[1][3];
GLfloat tempZ = matComposite[2][0] * x + matComposite[2][1] * y + matComposite[2][2] * z + matComposite[2][3];
GLfloat tempW = matComposite[3][0] + matComposite[3][1] + matComposite[3][2] + matComposite[3][3];
return vector3(tempX/tempW, tempY/tempW, tempZ/tempW);
}
}
void transpose(Matrix4x4 mat){
Matrix4x4 temp;
for(int i=0;i<4;i++) {
for(int j=0;j<4;j++) {
temp[i][j] = mat[j][i];
}
}
for(int i=0;i<4;i++) {
for(int j=0;j<4;j++) {
mat[i][j] = temp[i][j];
}
}
}
vector3 viewer(-.4, .4, .6);
GLfloat mvm[4][4];
GLfloat pm[4][4];
void storeMatrices(){
GLfloat got[16];
glGetFloatv(GL_PROJECTION_MATRIX,got);
for(int i=0;i<16;i++){
pm[i/4][i%4] = got[i];
}
glGetFloatv(GL_MODELVIEW_MATRIX,got);
for(int i=0;i<16;i++){
mvm[i/4][i%4] = got[i];
}
}
void transformOpenGL(){
std::cout << "BY OPENGL\n";
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-1, 1, -1, 1, .1, 200);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(viewer.x, viewer.y, viewer.z, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
// copy matrices before doing model transforms
storeMatrices();
// setup scene
glScalef(.5, 1, 1);
glTranslatef(.4, .4, 0);
glScalef(.2, .1, .1);
}
void transformByHand(){
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
std::cout << "BY HAND\n";
matrix4x4SetIdentity(matComposite);
GLfloat mvm[4][4] = {{0.832050, 0.269069, -0.485071, 0.000000}, {0.000000, 0.874475, 0.485071, 0.000000}, {0.554700, -0.403604, 0.727607, 0.000000}, {0.000000, 0.000000, -0.824621, 1.000000}};
GLfloat pm[4][4] = {{0.100000, 0.000000, 0.000000, 0.000000}, {0.000000, 0.100000, 0.000000, 0.000000}, {0.000000, 0.000000, -1.001001, -1.000000,}, {0.000000, 0.000000, -0.200100, 0.000000}};
// order of transforms is opposite to OpenGL, and,
// eg. translations go in col[3], not row[3]
Matrix4x4 scale3 = {{.2, 0, 0, 0}, {0, .1, 0, 0}, {0, 0, .1, 0}, {0, 0, 0, 1}};
matrix4x4PreMultiply(scale3, matComposite);
Matrix4x4 translate = {{1, 0, 0, .4}, {0, 1, 0, .4}, {0, 0, 1, 0}, {0, 0, 0, 1}};
matrix4x4PreMultiply(translate, matComposite);
Matrix4x4 scale2 = {{.5, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}};
matrix4x4PreMultiply(scale2, matComposite);
transpose(mvm);
matrix4x4PreMultiply(mvm, matComposite);
transpose(pm);
matrix4x4PreMultiply(pm, matComposite);
}
void render() {
if(useOpenGL){
transformOpenGL();
} else {
transformByHand();
}
glColor3f(1, 0, 0);
glBegin(GL_POLYGON);
vector3 vpt = matrixMult(0, 0, 0);
glVertex3f(vpt.x, vpt.y, vpt.z);
vpt = matrixMult(0, 5, 0);
glVertex3f(vpt.x, vpt.y, vpt.z);
vpt = matrixMult(5, 5, 0);
glVertex3f(vpt.x, vpt.y, vpt.z);
vpt = matrixMult(0, 5, 0);
glVertex3f(vpt.x, vpt.y, vpt.z);
glEnd();
useOpenGL = !useOpenGL;
}
void display(void) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
render();
glutSwapBuffers();
}
void main(int argc, char **argv){
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH) ;
glutInitWindowSize(500, 500);
glutInitWindowPosition(100, 100);
int windowHandle = glutCreateWindow("Testing MVM and PM Matrices");
glutSetWindow(windowHandle);
glutDisplayFunc(display);
glutMainLoop();
}
我會嘗試;我想我誤解了W變量。非常感謝您的回覆。乾杯! – GregT 2014-11-02 14:35:55