OpenGL Мерцание вращения камеры - PullRequest
0 голосов
/ 18 января 2012

с некоторых пор я застрял с проблемой поворота камеры в OpenGL.

Я пытаюсь повернуть камеру с помощью движения мыши, но камера только мигает (объект, на который попадает камерамерцание).

Я инициализирую камеру следующим образом:

Camera::Camera(float x, float y, float z) {
    memset(Transform, 0, 16*sizeof(float));
    Transform[0] = 1.0f;
    Transform[5] = 1.0f;
    Transform[10] = 1.0f;
    Transform[15] = 1.0f;
    Transform[12] = x; Transform[13] = y; Transform[14] = z;

    Left=&Transform[0];
    Up=&Transform[4];
    Forward=&Transform[8];
    Position=&Transform[12];

    old_x = 0;
    old_y = 0;
}

Здесь Transform - матрица преобразования.Поскольку OpenGL является основным столбцом, он должен быть правильным?

Следующая часть объясняет, что происходит перед рисованием кадра.

Сначала я обновляю камеру движением мыши, в зависимости отдельта х и у последней позиции указателя мыши, значение движения может быть положительным или отрицательным:

void Camera::refresh(){

    delta_x = UserInputHandler::getMouseMotion()[0];
    delta_y = UserInputHandler::getMouseMotion()[1];

}

На следующем шаге я настраиваю камеру в сцене.Если мышь перемещается вдоль оси x или y, я хочу повернуть камеру:

void Camera::adjust(){

    if(old_x != UserInputHandler::getMousePosition()[0]){

                // rotate around y axis
                rotateLocal_y(-1.0f*(delta_x));

                // save old mouse position
        old_x = UserInputHandler::getMousePosition()[0];
    }

    if(old_y != UserInputHandler::getMousePosition()[1]){

        rotateLocal_x(-1.0f*(delta_y));

        old_y = UserInputHandler::getMousePosition()[1];
    }

    // loading the calculated Transform matrix to a viewmatrix
    setView();
}

Поворот вокруг оси y является умножением матрицы на матрицу вращения и матрицу преобразования:

//rotate a matrix around y axis
void rotateMatrixf_y(float *aMatrix, float angle){

    float rotMatrix[] = {cos(angle),0,-1*sin(angle),0, 0, 1, 0, 0, sin(angle), 0, cos(angle), 0, 0, 0, 0, 1};
    multMatrixMatrix(aMatrix, rotMatrix);
}

Учитывая, что OpenGL является основным столбцом, функция умножения создается следующим образом:

void multMatrixMatrix(float *m_a, float *m_b){
    // column major
    float m_c[16] = {m_a[0]*m_b[0]+m_a[4]*m_b[1]+m_a[8]*m_b[2]+m_a[12]*m_b[3], //0
                        m_a[1]*m_b[0]+m_a[5]*m_b[1]+m_a[9]*m_b[2]+m_a[13]*m_b[3], //1
                        m_a[2]*m_b[0]+m_a[6]*m_b[1]+m_a[10]*m_b[2]+m_a[14]*m_b[3], // 2
                        m_a[3]*m_b[0]+m_a[7]*m_b[1]+m_a[11]*m_b[2]+m_a[15]*m_b[3], // 3

                        m_a[0]*m_b[4]+m_a[4]*m_b[5]+m_a[8]*m_b[6]+m_a[12]*m_b[7], //4
                        m_a[1]*m_b[4]+m_a[5]*m_b[5]+m_a[9]*m_b[6]+m_a[13]*m_b[7], //5
                        m_a[2]*m_b[4]+m_a[6]*m_b[5]+m_a[10]*m_b[6]+m_a[14]*m_b[7], // 6
                        m_a[3]*m_b[4]+m_a[7]*m_b[5]+m_a[11]*m_b[6]+m_a[15]*m_b[7], // 7

                        m_a[0]*m_b[8]+m_a[4]*m_b[9]+m_a[8]*m_b[10]+m_a[12]*m_b[11], // 8
                        m_a[1]*m_b[8]+m_a[5]*m_b[9]+m_a[9]*m_b[10]+m_a[13]*m_b[11], //9 
                        m_a[2]*m_b[8]+m_a[6]*m_b[9]+m_a[10]*m_b[10]+m_a[14]*m_b[11], // 10
                        m_a[3]*m_b[8]+m_a[7]*m_b[9]+m_a[11]*m_b[10]+m_a[15]*m_b[11], // 11

                        m_a[0]*m_b[12]+m_a[4]*m_b[13]+m_a[8]*m_b[14]+m_a[12]*m_b[15], // 12
                        m_a[1]*m_b[12]+m_a[5]*m_b[13]+m_a[9]*m_b[14]+m_a[13]*m_b[15], // 13
                        m_a[2]*m_b[12]+m_a[6]*m_b[13]+m_a[10]*m_b[14]+m_a[14]*m_b[15], // 14
                        m_a[3]*m_b[12]+m_a[7]*m_b[13]+m_a[11]*m_b[14]+m_a[15]*m_b[15] // 15

    };

     for(int i = 0; i<16;i++){
        m_a[i] = m_c[i];
     }

}

На этом этапе матрица должна быть в порядке и загружена в OpenGL.Метод setView был вызван в Adjust ():

void Camera::setView() {


    float viewmatrix[16]={//Remove the three - for non-inverted z-axis
                          Transform[0], Transform[4], -Transform[8], 0,
                          Transform[1], Transform[5], -Transform[9], 0,
                          Transform[2], Transform[6], -Transform[10], 0,

                          -(Transform[0]*Transform[12] +
                          Transform[1]*Transform[13] +
                          Transform[2]*Transform[14]),

                          -(Transform[4]*Transform[12] +
                          Transform[5]*Transform[13] +
                          Transform[6]*Transform[14]),

                          //add a - like above for non-inverted z-axis
                          (Transform[8]*Transform[12] +
                          Transform[9]*Transform[13] +
                          Transform[10]*Transform[14]), 1};

                          }

    glLoadMatrixf(viewmatrix);
}

Функции вызываются в полной сцене следующим образом:

int DrawGLScene (GLvoid) {// Вот где мы делаем всеЧертеж

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);         // Clear The Screen And The Depth Buffer


glMatrixMode(GL_MODELVIEW);
glLoadIdentity();                           // Reset The Current Modelview Matrix

glPushMatrix();
cam.refresh();
cam.adjust();

// distance between object and near plane
glTranslatef(0.0f, 0.0f,-30.0f);        

   // testwise rotating the drawn object
float rotX,rotY,rotZ;
rotX = -90.0f;
rotZ = 0.0f;
rotY = 0.0f;


MeshNode* aMeshNode = myMeshLoader.getMeshNode();

while(aMeshNode->next){

    Mesh aMesh = *aMeshNode->theMesh;
    FaceNode* aFaceNode = aMesh.getFirstFaceNode();

    while(aFaceNode->next){
        Face theFace = *aFaceNode->aFace;

        Vertex theFaceVertexA = aMesh.getVertexAt((*theFace.myVertices)[0]);
        Vertex theFaceVertexB = aMesh.getVertexAt((*theFace.myVertices)[1]);
        Vertex theFaceVertexC = aMesh.getVertexAt((*theFace.myVertices)[2]);

        glColor3f(1.0f,1.0f,1.0f);
        glBegin(GL_TRIANGLES);                      // Drawing Using Triangles
    //  glNormal3f(*theFace.myNormal[0],*theFace.myNormal[1],*theFace.myNormal[2]);
        glVertex3f( theFaceVertexA.position[0], theFaceVertexA.position[1], theFaceVertexA.position[2]);
        glVertex3f( theFaceVertexB.position[0], theFaceVertexB.position[1], theFaceVertexB.position[2]);
        glVertex3f( theFaceVertexC.position[0], theFaceVertexC.position[1], theFaceVertexC.position[2]);
        glEnd();                            // Finished Drawing The Triangle

        aFaceNode = aFaceNode->next;
    }

    aMeshNode = aMeshNode->next;
}
glPopMatrix();

return TRUE;                                // Everything Went OK

}

Здесь я выбираю матрицу просмотра модели, затем загружаю матрицу идентичности.Между нажатием и выдвижением матрицы происходит обновление и настройка камеры (которая включает setView), затем я устанавливаю трансформацию для объекта, который я хочу нарисовать, после чего рисуем объект.

Вот и все.Я много играл с некоторыми нажатиями и всплесками матрицы, посмотрел учебник по флипкоду (http://www.flipcode.com/archives/OpenGL_Camera.shtml),, но мерцание все еще остается. У кого-нибудь есть идеи, что может быть не так?

Ответы [ 2 ]

0 голосов
/ 18 января 2012

Я нашел проблему, потому что я использовал градусы, а не радианты.Так что вращение составляет около 90 градусов или около 0 градусов, глупо, но верно!

0 голосов
/ 18 января 2012

Это может зависеть от того, что DEPTH_TEST в вашем приложении отключен.

В качестве альтернативы это может зависеть от размера буфера глубины, поддерживаемого вашим устройством.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...