GluLookAt कैसे काम करता है?


9

मेरी समझ से,

gluLookAt(
        eye_x, eye_y, eye_z,
        center_x, center_y, center_z,   
        up_x, up_y, up_z
    );

के बराबर है:

glRotatef(B, 0.0, 0.0, 1.0);
glRotatef(A, wx, wy, wz);
glTranslatef(-eye_x, -eye_y, -eye_z);

लेकिन जब मैं ModelViewमैट्रिक्स को प्रिंट करता हूं , तो कॉल glTranslatef()ठीक से काम नहीं करता है। यहाँ कोड स्निपेट है:

#include <stdlib.h>
#include <stdio.h>
#include <GL/glut.h>

#include <iomanip>
#include <iostream>
#include <string>

using namespace std;

static const int Rx = 0;
static const int Ry = 1;
static const int Rz = 2;

static const int Ux = 4;
static const int Uy = 5;
static const int Uz = 6;

static const int Ax = 8;
static const int Ay = 9;
static const int Az = 10;

static const int Tx = 12;
static const int Ty = 13;
static const int Tz = 14;

void init() {
    glClearColor(0.0, 0.0, 0.0, 0.0);
    glEnable(GL_DEPTH_TEST);
    glShadeModel(GL_SMOOTH);
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    GLfloat lmodel_ambient[] = { 0.8, 0.0, 0.0, 0.0 };
    glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
}

void displayModelviewMatrix(float MV[16]) {
    int SPACING = 12;
    cout << left;
    cout << "\tMODELVIEW MATRIX\n";
    cout << "--------------------------------------------------" << endl;
    cout << setw(SPACING) << "R" << setw(SPACING) << "U" << setw(SPACING) << "A" << setw(SPACING) << "T" << endl;   
    cout << "--------------------------------------------------" << endl;
    cout << setw(SPACING) << MV[Rx] << setw(SPACING) << MV[Ux] << setw(SPACING) << MV[Ax]  << setw(SPACING) << MV[Tx] << endl;
    cout << setw(SPACING) << MV[Ry] << setw(SPACING) << MV[Uy] << setw(SPACING) << MV[Ay]  << setw(SPACING) << MV[Ty] << endl;
    cout << setw(SPACING) << MV[Rz] << setw(SPACING) << MV[Uz] << setw(SPACING) << MV[Az] << setw(SPACING)  << MV[Tz] << endl;
    cout << setw(SPACING) << MV[3] << setw(SPACING) << MV[7] << setw(SPACING) << MV[11] << setw(SPACING) << MV[15] << endl;
    cout << "--------------------------------------------------" << endl;
    cout << endl;
}

void reshape(int w, int h) {
    float ratio = static_cast<float>(w)/h;
    glViewport(0, 0, w, h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45.0, ratio, 1.0, 425.0);
}

void draw() {
    float m[16];
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glGetFloatv(GL_MODELVIEW_MATRIX, m);
    gluLookAt(
        300.0f, 0.0f, 0.0f,
        0.0f, 0.0f, 0.0f,
        0.0f, 1.0f, 0.0f
    );
    glColor3f(1.0, 0.0, 0.0);
    glutSolidCube(100.0);
    glGetFloatv(GL_MODELVIEW_MATRIX, m);
    displayModelviewMatrix(m);
    glutSwapBuffers();
}


int main(int argc, char** argv) {
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
    glutInitWindowSize(400, 400);
    glutInitWindowPosition(100, 100);
    glutCreateWindow("Demo");
    glutReshapeFunc(reshape);
    glutDisplayFunc(draw);
    init();
    glutMainLoop();
    return 0;
} 

कोई फर्क नहीं पड़ता मूल्य मैं के लिए उपयोग eyeवेक्टर:
300, 0, 0या
0, 300, 0या
0, 0, 300
अनुवाद वेक्टर एक ही है, क्योंकि कोड के आदेश पिछड़े ऐसा है जो किसी भी मतलब नहीं है है glTranslatefपहले 2 चक्र चलाना चाहिए, तो। साथ ही, रोटेशन मैट्रिक्स, अनुवाद कॉलम (मॉडलव्यू मैट्रिक्स में) से पूरी तरह से स्वतंत्र है, फिर इस अजीब व्यवहार का क्या कारण होगा? यहाँ आँख वेक्टर के साथ आउटपुट है(0.0f, 300.0f, 0.0f)

        MODELVIEW MATRIX
--------------------------------------------------
R           U           A           T
--------------------------------------------------
0           0           0           0
0           0           0           0
0           1           0           -300
0           0           0           1
--------------------------------------------------

मुझे उम्मीद है कि Tकॉलम होगा (0, -300, 0)! तो क्या कोई मुझे यह समझाने में मदद कर सकता है?

Http://www.mesa3d.orggluLookAt से कार्यान्वयन

void GLAPIENTRY
gluLookAt(GLdouble eyex, GLdouble eyey, GLdouble eyez, GLdouble centerx,
      GLdouble centery, GLdouble centerz, GLdouble upx, GLdouble upy,
      GLdouble upz)
{
    float forward[3], side[3], up[3];
    GLfloat m[4][4];

    forward[0] = centerx - eyex;
    forward[1] = centery - eyey;
    forward[2] = centerz - eyez;

    up[0] = upx;
    up[1] = upy;
    up[2] = upz;

    normalize(forward);

    /* Side = forward x up */
    cross(forward, up, side);
    normalize(side);

    /* Recompute up as: up = side x forward */
    cross(side, forward, up);

    __gluMakeIdentityf(&m[0][0]);
    m[0][0] = side[0];
    m[1][0] = side[1];
    m[2][0] = side[2];

    m[0][1] = up[0];
    m[1][1] = up[1];
    m[2][1] = up[2];

    m[0][2] = -forward[0];
    m[1][2] = -forward[1];
    m[2][2] = -forward[2];

    glMultMatrixf(&m[0][0]);
    glTranslated(-eyex, -eyey, -eyez);
}

जवाबों:


7

gluLookAtएक तरह से दुनिया को घुमाएगा और अनुवाद करेगा, जिससे कैमरा {0, 0, 0}नकारात्मक z- अक्ष पर स्थित होगा । यह OpenGL में प्रयुक्त कैमरा सेटअप है। कैमरा वास्तव में कभी नहीं चलता, दुनिया करती है। भ्रामक लगता है? नरक हाँ, मुझे समझाने की कोशिश :)

इस उदाहरण को लें:

eye    :  {300, 0, 0}
lookat :  {  0, 0, 0}
up     :  {  0, 1, 0}

MODELVIEW MATRIX
--------------------------------------------------
R           U           A           T           
--------------------------------------------------
0           0           -1          0           
0           1           0           0           
1           0           0           -300        
0           0           0           1           
--------------------------------------------------

पहले हम मैट्रिक्स की घूर्णन हिस्सा विश्लेषण करने की जरूरत: R, Uऔर A। जैसा कि आप देख सकते हैं कि सही वेक्टर ( R) अब x- अक्ष में नहीं है {1, 0, 0}, यह z- अक्ष में है {0, 0, 1}। इसका मतलब है कि इसे y- अक्ष के चारों ओर 90 डिग्री तक घुमाया जाता है। आंख की स्थिति के साथ भी ऐसा ही होता है। घूर्णन {-300, 0, 0}y- अक्ष के चारों ओर 90 डिग्री से इसे खत्म करने देता {0, 0, -300}देखा, तो, वहाँ यह है।

यह है -300और 300इसलिए नहीं कि दुनिया को स्थानांतरित किया गया है और कैमरा नहीं है, इसलिए दुनिया को विपरीत दिशा में ले जाया जाता है, अभी भी कैमरे से 300 यूनिट दूर है {0, 0, 0}। और फिर, इसे नकारात्मक z- अक्ष की ओर ले जाया जाता है, क्योंकि यही वह जगह है जहां OpenGL कैमरा ऊपर वर्णित है।


ध्यान दें: आपके उदाहरण में एक विसंगति है, आंख-स्थिति से सामान्यीकृत वेक्टर-अप-वेक्टर के समान नहीं होना चाहिए, इसलिए:

eye    : {0, 300, 0}
lookat : {0,   0, 0}
up     : {0,   1, 0}    

normalize(eye - lookat): {0, 1, 0} -> the same as the up-vector

वास्तव में काम नहीं करेगा, हमें उदाहरण के लिए एक और अप-वेक्टर चुनना होगा {1, 0, 0}


बहुत बहुत धन्यवाद, हालांकि मैं अभी भी थोड़ा भ्रमित हूं, हालांकि मैं आपके स्पष्टीकरण को समझता हूं।
चैन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.