Я пытаюсь реализовать простую свободную движущуюся камеру в OpenGL.
Я хочу понять операции, поэтому я не использую gluLookAt.
Я попробовал несколько вещей, но это не работает, как ожидалось.
Это мой рендер
// Every frame
glViewport(0, 0, windowWidth, windowHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, windowWidth, 0, windowHeight, 0, 40);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// camera transforms:
glTranslatef(eye_x, eye_y, eye_z);
glRotatef(x_angular, 0, 1, 0);
// foreach object:
glPushMatrix();
{
glTranslatef( (*obj_i)->anchor[0] , (*obj_i)->anchor[1], (*obj_i)->anchor[2]);
glutWireSphere((*obj_i)->r, 15, 15);
}
glPopMatrix();
И моя обработка ввода
// VK_UP
else if ( (*event_it)->key == 129 ) {
buffer << " Key press: VK_UP \n";
eye_z += 1;
}
// VK_DOWN
else if ( (*event_it)->key == 131 ) {
buffer << " Key press: VK_DOWN \n";
eye_z -= 1;
}
// VK_LEFT
else if ( (*event_it)->key == 128 ) {
//eye_x += 10;
buffer << " Key press: VK_LEFT \n";
x_angular -= 2;
//glRotatef(x_angular, 0, 0, 1);
}
// VK_RIGHT
else if ( (*event_it)->key == 130 ) {
//eye_x -= 10;
buffer << " Key press: VK_RIGHT \n";
x_angular += 2;
}
else if ( (*event_it)->key == 'i' ) {
}
else if ( (*event_it)->key == 'j' ) {
eye_x += 10;
}
else if ( (*event_it)->key == 'k' ) {
eye_x -= 10;
}
Что я пытаюсь сделать:
Есть 3 сферы при z = 0, я хочу войти (передать их), а затем VK_LEFT (повернуть налево) сделать 180, и тогда я смогу увидеть сферы.
Не совсем уверен, что не так, может быть, моя обработка ввода не так, или операции отключены?
С glOrtho (0, ширина окна, 0, высота окна, 0, 40)
z_near равно 0 и z_far = 40 верно?
если бы я рисовал при z = 0 и glTranslate (0,0, -10), я бы подошел к z_far? И передать то, что было нарисовано при z = 0?
Я прочитал много вопросов и учебников, но не могу связать объяснение с моим кодом.
редактировать
Это выглядит ближе к тому, что я хочу. Нужно будет запустить больше тестов, я думаю, что все еще может быть сбой или два.
glTranslatef(windowWidth/2.0, windowHeight/2.0,-1);
glRotatef(x_angular, 0, 1, 0);
glTranslatef(-windowWidth/2.0,-windowHeight/2.0,1);
glTranslatef(eye_x, eye_y, eye_z);
Перевод и вращение в OpenGL выполняются с использованием умножения матриц. В используемом конвейере фиксированных функций эти операции не являются коммутативными, т. Е. [T] x [R] не равно [R] x [T]. В вашем коде вы переводите первым, что меняет источник для следующего поворота.
Если вы посмотрите внимательно на то, как реализован gluLookAt (). Перевод камеры должен быть инвертирован. помните, что перевод и вращение будут применяться к объектам. В OpenGL нет такой вещи, как камера. Мы просто моделируем это, применяя обратное преобразование камеры к сцене.
Единственный способ понять это — изучить математику OpenGL. Я бы предложил найти книгу.
Попробуйте код ниже. Помните, что мы моделируем камеру, так что используйте glTranslate и glRotate, чтобы сделать обратное.
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// camera transforms:
glTranslatef(-eye_x, -eye_y, -eye_z);
glRotatef(-x_angular, 0, 1, 0);
// foreach object:
glPushMatrix();
{
glTranslatef( (*obj_i)->anchor[0] , (*obj_i)->anchor[1], (*obj_i)- >anchor[2]);
glutWireSphere((*obj_i)->r, 15, 15);
}
glPopMatrix();