Вопрос:
Я просто хочу что-то вроде этого видео: Он показывает, как использовать glTranslate, glRotate, gluOrtho2d в OpenGL, но это не gluOrtho2d мне ничего
В моем случае я рисую алмаз вместо треугольника, и вот мое условие
состояние:
- когда я нажимаю r или R на клавиатуре, алмаз будет вращаться по часовой стрелке
- когда я нажимаю t или T на клавиатуре, алмаз переместится в правую сторону
- когда я нажимаю + на клавиатуре, алмаз будет больше
вот мой код:
#include <stdlib.h> #include <windows.h> #include <GL/glut.h> #include <iostream> using namespace std; float angle = 0; float t,s=0.5,m=0; void myinit(void){ glClearColor(1.0,1.0,1.0,0.0); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0.0,1.0,0.0,1.0,-1.0,1.0); } void keyboard(unsigned char key, int x, int y){ if(key==27) { exit(0); }else if(key == 82 || key == 114){ angle-=0.1; glRotatef(angle,0,0,1); glutPostRedisplay(); }else if(key == 84 || key == 116 ) { t+=0.01; glTranslatef(t,0,0); glutPostRedisplay(); }else if(key == 43){ s+=0.01; // m-=0.1; // glTranslatef(m,m,0.0); glScalef(s,s,0); glutPostRedisplay(); } (void)(x); (void)(y); } void hut(void){ glClear(GL_COLOR_BUFFER_BIT); glBegin(GL_TRIANGLE_FAN); glVertex3f(0.5,0.4,0.0); glVertex3f(0.42,0.5,0.0); // GREEN glVertex3f(0.44,0.5,0.0); glColor3f(1.5,1.0,0.0); glVertex3f(0.46,0.5,0.0); glColor3f(0.25,0.0,0.0); glVertex3f(0.57,0.5,0.0); glEnd(); glFlush(); glColor3f(1.5,1.0,0.0); glBegin(GL_TRIANGLE_FAN); glVertex3f(0.44,0.55,0.0); glVertex3f(0.42,0.5,0.0); glVertex3f(0.46,0.5,0.0); glColor3f(0.25,0.0,0.0); glVertex3f(0.48,0.55,0.0); glEnd(); glColor3f(1.5,1.0,0.0); glBegin(GL_TRIANGLE_FAN); glVertex3f(0.48,0.55,0.0); glVertex3f(0.46,0.5,0.0); glVertex3f(0.50,0.5,0.0); glColor3f(0.25,0.0,0.0); glVertex3f(0.52,0.55,0.0); glEnd(); glColor3f(1.5,1.0,0.0); glBegin(GL_TRIANGLE_FAN); glVertex3f(0.52,0.55,0.0); glVertex3f(0.50,0.5,0.0); glVertex3f(0.54,0.5,0.0); glColor3f(0.25,0.0,0.0); glVertex3f(0.56,0.55,0.0); glEnd(); glColor3f(1.5,1.0,0.0); glBegin(GL_TRIANGLE_FAN); glVertex3f(0.56,0.55,0.0); glVertex3f(0.54,0.5,0.0); glVertex3f(0.57,0.5,0.0); glEnd(); glFlush(); } int main(int argc,char** argv){ glutInit(&argc,argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); glutInitWindowPosition(100,100); glutInitWindowSize(640,480); glutCreateWindow(«Polygon with viewport»); myinit(); glutDisplayFunc(hut); glutKeyboardFunc(keyboard); glutMainLoop(); }
И вот мой вывод: Это не похоже на это
Лучший ответ:
Операции в стеке матрицы основаны друг на друге. Система отсчета каждой операции представляет собой текущее преобразование.
См. Документацию glTranslate:
glTranslate производит перевод по xyz. Текущая матрица (см. glMatrixMode) умножается на эту матрицу перевода, при этом продукт заменяет текущую матрицу,
и см. документацию glRotate:
glRotate производит поворот угловых градусов вокруг вектора xyz. Текущая матрица (см. glMatrixMode) умножается на матрицу вращения с заменой текущей матрицы.
Это означает, что glRotate выполняет вращение вокруг источника текущей локальной системы.
В то время как glRotatetf за которым следует glTranslatef приводит к:
glTranslatef за которым следует glRotatef приводит к:
Поскольку вы перемещаете объект, вы должны перевести его таким образом, чтобы точка поворота помещалась в начало координат:
glTranslatef(-0.5f, -0.5f, 0.0f);
Тогда вы можете собрать его:
glRotatef(angle, 0.0f, 0.0f, 1.0f);
И переместите его обратно:
glTranslatef(0.5f, 0.5f, 0.0f);
Обратите внимание: в стеке с фиксированной функциональной связью вы должны “нажимать” эти операции в обратном порядке. Далее вы должны использовать GL_MODELVIEW матрицы GL_MODELVIEW. (См. glMatrixMode).
Удалите все операции с матрицей из функциональной keyboard и добавьте followig в служебную hut:
void hut(void) { glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(t, 0.0f, 0.0f); glTranslatef(0.5f, 0.5f, 0.0f); glRotatef(angle, 0.0f, 0.0f, 1.0f); glScalef(s, s, 0.0f); glTranslatef(-0.5f, -0.5f, 0.0f); …..
Кроме того, ваш объект будет уничтожен пропорцией представления. Это можно устранить, если при настройке матрицы проекции следить за соотношением сторон:
float w = 640.0f; float h = 480.0f; glOrtho(0.0,w/h,0.0,1.0,-1.0,1.0); Ответ №1
glRotate вращается вокруг начала координат (0,0). Учитывая вашу матрицу проекций (которую вы установили с помощью glOrtho), начало координат находится в левом нижнем углу экрана, если вы не используете glTranslate. Ваш алмаз не центрирован в начале координат, но расположен немного от него. Вам нужно изменить значения вершин в методе void hut (void), чтобы алмаз был центрирован на 0,0. Затем используйте glTranslate, чтобы переместить рендеринг (и, следовательно, алмаз) туда, где вы хотите, затем используйте glRotate.