Easyelectronics.ru

Электроника для всех
Текущее время: 24 янв 2020, 06:34

Часовой пояс: UTC + 5 часов



JLCPCB – Прототипы печатных плат за $2/10pcs (Любой цвет!)
Крупнейший производитель печатных плат и прототипов. Более 600000 клиентов и свыше 10000 заказов в день!
Получите скидку на почтовую отправку при первом заказе в JLCPCB!

Начать новую тему Ответить на тему  [ Сообщений: 17 ] 
Автор Сообщение
 Заголовок сообщения: OpenGL - glRotate
СообщениеДобавлено: 22 апр 2017, 17:04 
Только пришел

Зарегистрирован: 11 апр 2012, 14:20
Сообщения: 22
Откуда: Санкт-Петербург
Здравствуйте!
Не могу справиться с поворотом в изометрии. Во вложении архив с исходниками С++ Builder XE. Задача простая, поворачивать оси в каждом из четырех видов. В изометрии накапливается ошибка. Пробовал с glMatrixMode(GL_MODELVIEW); glLoadIdentity(); с абсолютным приращением угла. Оси начинают "прыгать". Подозреваю что необходимо копать в сторону перемножения матриц. Может быть кто-то сталкивался с подобной проблемой?! Есть ли пример или готовый обработчик поворота сразу по трем осям и углу?!
glRotate(new_anle, pos_x, pos_y, pos_z); Чтобы можно было рассчитать новое положение вектора и угла и подставить их в штатную функцию?! Спасибо.


Вложения:
glRotate.zip [8.63 Кб]
Скачиваний: 99
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: OpenGL - glRotate
СообщениеДобавлено: 02 май 2017, 20:17 
Старожил

Зарегистрирован: 17 дек 2014, 04:38
Сообщения: 683
А вы сохраняете/восстанавливаете состояние матрицы ? Дело в том что у вас каждая следующая операция с матрицей будет происходить относительно текущего состояния матрицы. Я лет 15 уже не работал с оглом, но насколько помню там состояние матриц сохраняется в стек и оттуда же восстанавливается. То есть если вы относительно исходной матрицы допустим сделали поворот на 10 градусов относительно оси X, а потом сделали поворот на 11 градусов относительно оси X, то относительно исходной матрицы это будет поворот на 21 градус. По этому если вы хотите анимацию, то - сохраняем исходную матрицу, поворот на 10 градусов, рисуем объект, восстанавливаем матрицу, следующий кадр все повторяем - сохраняем исходную матрицу поворот на 11 градусов, рисуем объект, восстанавливаем матрицу. И так далее.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: OpenGL - glRotate
СообщениеДобавлено: 02 май 2017, 21:31 
Только пришел

Зарегистрирован: 11 апр 2012, 14:20
Сообщения: 22
Откуда: Санкт-Петербург
Спасибо за ответ! Да все так glMatrixmode(GL_MODELIVIEW); glLoadidentity(); прорисовка glLookAt(..,..,..); и тд я так тоже делал проблема в том что поворот необходимо делать по случайным осям. Задумка получать данные с гироскопа и поворачивать "чертежные виды" по основным вопросов нет, а вот изометрия почему-то как бы перескакивает если вращал одну ось потом перешел на другую и тд вроде все как по учебнику: установка вьюпорта, скиссор, очистка вида, переключение на модельную матрицу, загрузка единичной, прорисовка чего-то там и установка камеры обзора. Я сейчас накидаю с исправлениями если не затруднит посмотрите пожалуйста. Просто наводите мышку на нужный вид и вращаете колесико мышки потом в случайном порядке перемещаетесь то в один вид то в другой и происходит "перескок". Но зато всегда в исходное положение изометрия возвращается при установке ортогональных проекций в исходное положение. Спасибо большое, что зашли на ветку.


Вложения:
3D_rotate_forum.rar [10.56 Кб]
Скачиваний: 95
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: OpenGL - glRotate
СообщениеДобавлено: 02 май 2017, 23:09 
Старожил

Зарегистрирован: 17 дек 2014, 04:38
Сообщения: 683
у меня к сожалению сейчас нет возможности скомпилировать вашу программу(у меня OS X). Но и так возникло пара вопросов:
Код:
inline void __fastcall TForm1::Draw_Axis(void)
// 1) почему inline ?
{
   glColor3ub(0,0,0);
   //линии осей координат 3D
   glBegin(GL_LINES);
    //-----ось - X-------
    glVertex3f(0, 0, 0);
    glVertex3f(30, 0, 0);
    //-----ось - Y-------
    glVertex3f(0, 0, 0);
    glVertex3f(0, 30, 0);
    //-----ось - Z-------
    glVertex3f(0, 0, 0);
    glVertex3f(0, 0, -30);
   glEnd();

   //вывод надписей осей
   glListBase(font_list_base_2d);
    glRasterPos3i(45, 3, 3);
   glCallLists(1, GL_UNSIGNED_BYTE, "X");
   glRasterPos3i(3, 45, 3);
   glCallLists(1, GL_UNSIGNED_BYTE, "Y");
   glRasterPos3i(3, 3, -45);
   glCallLists(1, GL_UNSIGNED_BYTE, "Z");

   //вывод стрелок-конусов осей координат
   glColor3ub(0,206,209);
   //стелка координаты X
   glPushMatrix();  // сохранили матрицу
    glTranslatef(30,0,0);
    glRotatef(90.0,  0,1,0);  // трансформировали ось X
    gluCylinder(quadobj,3,0,10,30,3); //отрисовали цылиндр
   glPopMatrix(); // восстановили матрицу в исходную
   //стелка координаты Y
   glPushMatrix(); // второй цилиндр вы рисуете при том что трансформация по X в исходном состоянии
    glTranslatef(0,30,0);
    glRotatef(270.0,  1,0,0);
    gluCylinder(quadobj,3,0,10,30,3);
   glPopMatrix();
   //стелка координаты Z
   glPushMatrix();
    glTranslatef(0,0,-30);
    glRotatef(180.0,  0,1,0);
    gluCylinder(quadobj,3,0,10,30,3);
   glPopMatrix();
}

Я так понял вы крестик такой трехмерный рисуете ?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: OpenGL - glRotate
СообщениеДобавлено: 02 май 2017, 23:21 
Только пришел

Зарегистрирован: 11 апр 2012, 14:20
Сообщения: 22
Откуда: Санкт-Петербург
Да система координат просто чтобы понятней было когда крутишь-вертишь, инлайн остался от прошлого-позапрошлого варианта не обращайте внимания. Картинку файлом кинул. Постараюсь записать анимацию чтобы понятней было.


Вложения:
axis.jpg
axis.jpg [ 47.54 Кб | Просмотров: 1642 ]
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: OpenGL - glRotate
СообщениеДобавлено: 02 май 2017, 23:38 
Старожил

Зарегистрирован: 17 дек 2014, 04:38
Сообщения: 683
А вот вроде я и нашел ваш глюк.
1) Первое
Код:
void __fastcall TForm1::FormMouseWheelUp(TObject *Sender, TShiftState Shift, TPoint &MousePos, bool &Handled)
{
   switch (okno) {
   case okno_1:    {
                  angle_XY -= 5;
                  break;
               }
   case okno_2:    {
                  angle_YZ -= 5;
                  break;
               }
   case okno_3:    {
                  angle_XZ -= 5;
                  break;
               }
   default:      {break;}
   }

   InvalidateRect(Handle, NULL, false);
}

Это изменения ваших переменных в которых накапливаются изменения
А вот ваша отрисовка
Код:
void __fastcall TForm1::Draw_All(void)
{
   GLfloat Matrix[16];
   glQuaternion q_temp;
   glQuaternion m_qXY;
   glQuaternion m_qYZ;
   glQuaternion m_qXZ;

   glViewport(0, 0, Panel1->Width, Panel1->Height);
   glScissor(0, 0, Panel1->Width, Panel1->Height);
   glClearColor(0, 0, 0, 0);
   glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);


   //-----------------------------------------------------------------
   glViewport(0, (Panel1->Height/2)+1, (Panel1->Width/2), Panel1->Height/2);
   glScissor(0, (Panel1->Height/2)+1, (Panel1->Width/2), Panel1->Height/2);
   glClearColor(0.85, 0.85, 0.85, 0.0);
   glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);

   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity(); // Здесь вы загрузили стек матрицы моделей
       //я бы сюда добавил glPushMatrix();

   gluLookAt(0.0,0.0,1.0,   0.0,0.0,0.0,   0.0,1.0,0.0);

   glRotatef(angle_XY,0,0,1); // здесь происходит трансформация относительно предидущей трансформации, а вы помните что в переменной angle_XY у вас не относительные изменения а абсолютные
   Draw_Axis();
   //-----------------------------------------------------------------


   //-----------------------------------------------------------------
   glViewport((Panel1->Width/2)+1, (Panel1->Height/2)+1, (Panel1->Width/2)-1, (Panel1->Height/2));
   glScissor((Panel1->Width/2)+1, (Panel1->Height/2)+1, (Panel1->Width/2)-1, (Panel1->Height/2));
   glClearColor(0.85, 0.85, 0.85, 0.0);
   glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);

   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity(); // Вы другой стек не грузили, зачем вы один и тот же стек постоянно выбираете ?

   gluLookAt(1.0,0.0,0.0,   0.0,0.0,0.0,   0.0,1.0,0.0);

   glRotatef(angle_YZ,1,0,0);  // здесь то же самое только по другой оси
   Draw_Axis();
   //-----------------------------------------------------------------


   //-----------------------------------------------------------------
   glViewport(0, 0, (Panel1->Width/2), (Panel1->Height/2));
   glScissor(0, 0, (Panel1->Width/2), (Panel1->Height/2));
   glClearColor(0.85, 0.85, 0.85, 0.0);
   glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);

    glMatrixMode(GL_MODELVIEW);
   glLoadIdentity(); // Опять

   gluLookAt(0.0,-1.0,0.0,   0.0,0.0,0.0,   0.0,0.0,1.0);

   glRotatef(angle_XZ,0,1,0); // И снова
   Draw_Axis();
   //-----------------------------------------------------------------


   //-----------------------------------------------------------------
   glViewport((Panel1->Width/2)+1, 0, (Panel1->Width/2)-1, (Panel1->Height/2));
   glScissor((Panel1->Width/2)+1, 0, (Panel1->Width/2)-1, (Panel1->Height/2));
   glClearColor(0.85, 0.85, 0.85, 0.0);
   glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
        // а сюда glPopMatrix();
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity(); // почему не изменяя mode вы все время устанавливаете стек матрицы ?

   glPushMatrix(); // Что самое интересное здесь вы это делаете

   gluLookAt(1.0,-1.0,1.0,   0.0,0.0,0.0,   0.0,1.0,0.0);

   switch (okno)
   {
   case okno_1:   {
                  glRotatef(angle_XY,0,0,1);
                  //   m_qXY.CreateFromAxisAngle(0.0f, 0.0f, 1.0f, angle_XY);
                  //   m_qXY.CreateMatrix(Matrix);
                  break;
               }
   case okno_2:   {
                  glRotatef(angle_YZ,1,0,0);
                  //   m_qYZ.CreateFromAxisAngle(1.0f, 0.0f, 0.0f, angle_YZ);
                  //   m_qYZ.CreateMatrix(Matrix);

                  break;
               }
   case okno_3:   {
                  glRotatef(angle_XZ,0,1,0);
                  //   m_qXZ.CreateFromAxisAngle(0.0f, 1.0f, 0.0f, angle_XZ);
                  //   m_qXZ.CreateMatrix(Matrix);
                  break;
               }
   }


   //   glMultMatrixf(Matrix);

   Draw_Axis();

   glPopMatrix();
   //-----------------------------------------------------------------

   SwapBuffers(ghDC);
}


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: OpenGL - glRotate
СообщениеДобавлено: 02 май 2017, 23:41 
Только пришел

Зарегистрирован: 11 апр 2012, 14:20
Сообщения: 22
Откуда: Санкт-Петербург
https://youtu.be/Jot_oUc8Q84 - ссылка на видео немного колесико на мышке проскакивает, но основной перескок все равно видно...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: OpenGL - glRotate
СообщениеДобавлено: 02 май 2017, 23:55 
Только пришел

Зарегистрирован: 11 апр 2012, 14:20
Сообщения: 22
Откуда: Санкт-Петербург
Спасибо за разъяснения завтра попробую все очень логично объяснили. Должно заработать! Я уж грешным делом кватернионы штудировать стал.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: OpenGL - glRotate
СообщениеДобавлено: 03 май 2017, 00:03 
Старожил

Зарегистрирован: 17 дек 2014, 04:38
Сообщения: 683
В конце в switch я так понимаю вы обрисовываете одну из трех проекций. А перед этим аксонометрию (четвертое окно). Только я не понял зачем вы его обрисовываете 3 раза ?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: OpenGL - glRotate
СообщениеДобавлено: 03 май 2017, 00:19 
Только пришел

Зарегистрирован: 11 апр 2012, 14:20
Сообщения: 22
Откуда: Санкт-Петербург
Show


-сделал вот так, видимо опять что-то не то.... Не понял на счет SWITCH'а?!


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: OpenGL - glRotate
СообщениеДобавлено: 03 май 2017, 00:30 
Старожил

Зарегистрирован: 17 дек 2014, 04:38
Сообщения: 683
ну вот у вас в конце кода оператор switch(okno), внутри него я так понимаю вы определяете матрицы для каждого окна где проекции по осям. А перед этим вы три раза вызываете Draw_Axis(); что вы три раза рисуете ?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: OpenGL - glRotate
СообщениеДобавлено: 03 май 2017, 00:33 
Старожил

Зарегистрирован: 17 дек 2014, 04:38
Сообщения: 683
и если можете откомпилите и запишите на youtube, что получилось после того как вы добавили сохранение матриц


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: OpenGL - glRotate
СообщениеДобавлено: 03 май 2017, 00:52 
Только пришел

Зарегистрирован: 11 апр 2012, 14:20
Сообщения: 22
Откуда: Санкт-Петербург
Первый vieport и scissor выделяет для прорисовки всю панель и закрашивает черным цветом(чтобы черные полоски разделяли панель на 4-ре части), второй - первый экран(верхний левый), третий (верхний правый), четвертый(нижний левый), пятый(нижний правый) везде прорисовываются оси, в 1,2,3 - части экрана перед прорисовкой поворачиваем только в нужной плоскости. При перемещении курсора мышки определяем в каком мы окне(отдельной функцией по событию - Panel1MouseMove), а по событию -
FormPaint уже рисуем то что надо. При этом смотрим в switch на глобальную переменную - (typedef enum{okno_1, okno_2, okno_3, okno_4, forma}ENM_OKNO; ENM_OKNO okno;) . А колесиком просто инкремент/декремент угла идет. Задумка то простая с гироскопа приходят данные(пока данные не известно какие, подозреваю что вектор - угол) мы их визуализируем. Оси потом сместим в уголки зон и добавим какой-нибудь красивый объект.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: OpenGL - glRotate
СообщениеДобавлено: 03 май 2017, 01:06 
Только пришел

Зарегистрирован: 11 апр 2012, 14:20
Сообщения: 22
Откуда: Санкт-Петербург
https://youtu.be/d3xhrTCtQdQ - вот с сохранением матриц


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: OpenGL - glRotate
СообщениеДобавлено: 03 май 2017, 01:25 
Старожил

Зарегистрирован: 17 дек 2014, 04:38
Сообщения: 683
А попробуйте убрать switch(okno); сделайте так
Код:
   glPushMatrix();
   gluLookAt(1.0,-1.0,1.0,   0.0,0.0,0.0,   0.0,1.0,0.0);

/*   switch (okno)
   {
   case okno_1:   {
                  glRotatef(angle_XY,0,0,1);
                  break;
               }
   case okno_2:   {
                  glRotatef(angle_YZ,1,0,0);
                  break;
               }
   case okno_3:   {
                  glRotatef(angle_XZ,0,1,0);
                  break;
               }
   }*/

   glRotatef(angle_XY,0,0,1);
   glRotatef(angle_YZ,1,0,0);
   glRotatef(angle_XZ,0,1,0);

   Draw_Axis();
   glPopMatrix();
   //-----------------------------------------------------------------

   SwapBuffers(ghDC);


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: OpenGL - glRotate
СообщениеДобавлено: 03 май 2017, 01:27 
Старожил

Зарегистрирован: 17 дек 2014, 04:38
Сообщения: 683
Спасибо за видео сохранение матриц оставьте и сделайте так как я написал в предидущем посту


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: OpenGL - glRotate
СообщениеДобавлено: 05 май 2017, 17:37 
Старожил

Зарегистрирован: 17 дек 2014, 04:38
Сообщения: 683
Решилась проблема ? Помогло ?


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 17 ] 


Часовой пояс: UTC + 5 часов


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB