Russian Qt Forum
Ноябрь 25, 2024, 01:38 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2 3   Вниз
  Печать  
Автор Тема: QT + OpenGL  (Прочитано 34639 раз)
taifun
Гость
« : Октябрь 29, 2009, 15:29 »

взял пример OpenGL "Hello GL" запустил все нормально, знак QT вращается все красиво.
вставляю в
Код:
paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();
    glTranslated(0.0, 0.0, -10.0);
    glRotated(xRot / 16.0, 1.0, 0.0, 0.0);
    glRotated(yRot / 16.0, 0.0, 1.0, 0.0);
    glRotated(zRot / 16.0, 0.0, 0.0, 1.0);
    glCallList(object);

    glutSolidTeapot (1);
}

ругается, на glutSolidTeapot (1);                          error: `glutSolidTeapot' was not declared in this scope
библиотеку что ли добавить нужно какую-то, вообще хочу попробывать какой-нибудь 3Д объект нарисовать, сферу, цилиндр как сделать?
Записан
ecspertiza
Супер
******
Offline Offline

Сообщений: 1053


С уважением, мастер конфетного цеха!


Просмотр профиля
« Ответ #1 : Октябрь 29, 2009, 15:37 »

Ну да GLUT это отдельная либа, ее нужно сначала скачать будет, а чтобы рисовать цилиндр там сферы покури мануал по OpenGL, скачай книжечку "Qt профессиональное программирование на С++" там в 23-ей главе очень хорошо описано как работать Qt+OpenGL Подмигивающий
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #2 : Октябрь 29, 2009, 15:43 »

вообще хочу попробывать какой-нибудь 3Д объект нарисовать, сферу, цилиндр как сделать?
Сделайте сначала плоскость 10х10 (из 100 полигонов).  А затем сфера и цилиндр легко получаются из плоскости Улыбающийся
Записан
taifun
Гость
« Ответ #3 : Октябрь 29, 2009, 16:03 »

не хотелось бы через плоскости, хотелось бы что бы написал glutSolidTeapot (1) или auxSolidSphere( 1 ) и готово
 или через плоскости лучше, можете объяснить как лучше и быстрее будет отрисовывать? не даром я зашел где новички задают вопросы  Подмигивающий спасибо!
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #4 : Октябрь 29, 2009, 16:52 »

не хотелось бы через плоскости, хотелось бы что бы написал glutSolidTeapot (1) или auxSolidSphere( 1 ) и готово
 или через плоскости лучше, можете объяснить как лучше и быстрее будет отрисовывать? не даром я зашел где новички задают вопросы  Подмигивающий спасибо!
Просто на готовых шейпах далеко не уехать - их набор ограничен. Ну поиграетесь Вы с чайником (teapot) и что с того? А вот если Вы научитесь создавать/вычислять полигоны и вертексы - тогда многое можно и самому создать. и для загрузки 3D моделей из файлов все готово. Начните с создания 1 полигона в плоскости XY. Просто изменив учебный пример (не забивайте голову умными книгами)

Код:
glBegin(GL_QUADS);
glVertex3f(0, 0, 0);
glVertex3f(10, 0, 0);
glVertex3f(10, 10, 0);
glVertex3f(0, 10, 0);
glEnd();
Затем создайте в цикле 100 полигонов (mesh 10x10). Ну а там уже до цилиндра рукой подать Улыбающийся

Записан
taifun
Гость
« Ответ #5 : Ноябрь 06, 2009, 11:19 »

Я просто ленивый, потому и не хотел сам писать. Но сейчас почитал поразбирался, понял что вы правы и если я научусь работать с полигонами, то это даст мне большие возможности, Спасибо за совет!

Вот у меня еще вопрос
void VMMutomo::paintGL()
Код:
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glLoadIdentity();
    glTranslated(0.0, 0.0, -10.0);
    glRotated(xRot / 16.0, 1.0, 0.0, 0.0);
    glRotated(yRot / 16.0, 0.0, 1.0, 0.0);
    glRotated(zRot / 16.0, 0.0, 0.0, 1.0);
    //glCallList(object);

    glEnable(GL_DEPTH_TEST);
    //qglColor(trolltechGreen);
    qglColor(Qt::white);
    //glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);

    gluQuadricDrawStyle(quadratic, GLU_FILL);
    gluQuadricNormals(quadratic, GLU_SMOOTH);

    glTranslatef(0.0f,0.0f,0.0f);                               // Центр цилиндра
    gluCylinder(quadratic,0.05f,0.05f,0.9f,32,5);       // Рисуем наш цилиндр

/*
    //glTranslated(0.0, 0.0, 0.7);
    qglColor(Qt::black);
    gluSphere(quadratic,0.1f,32,32);                       // Рисуем сферу
*/

//******************* рисуем оси координат ******************
    glBegin(GL_LINES);
        glColor3f(0.0, 0.0, 1.0);       //ось Х
        glVertex3d(0.0, 0.0, 0.0);
        glVertex3d(0.25, 0.0, 0.0);

        glColor3f(0.0, 1.0, 0.0);       //ось Y
        glVertex3d(0.0, 0.0, 0.0);
        glVertex3d(0.0, 0.25, 0.0);

        glColor3f(1.0, 0.0, 0.0);       //ось Y
        glVertex3d(0.0, 0.0, 0.0);
        glVertex3d(0.0, 0.0, 0.25);
    glEnd();
//************************************************************
}

этот цилиндр рисуется но видна передняя стенка, "задняя" видимая часть почему-то отрезается, хотя должна быть видимой по идеи. Когда делаю отображаю цилиндр линиями gluQuadricDrawStyle(quadratic, GLU_FILL); то эта часть видна - отображается все верно. В чем проблема?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #6 : Ноябрь 06, 2009, 11:42 »

и если я научусь работать с полигонами, то это даст мне большие возможности
Хорошие слова, но они не подтверждаются приведенным фрагментом Вашего кода где никаких полигонов Вы не создаете, а вместо этого нашли функцию которая это делает (gluCylinder). Конечно, дело Ваше как изучать, но толку от использования готового немного. Например, понадобится согнутый цилиндр и что будете делать? "Нет могу, нет такой функции" Улыбающийся

этот цилиндр рисуется но видна передняя стенка, "задняя" видимая часть почему-то отрезается, хотя должна быть видимой по идеи. Когда делаю отображаю цилиндр линиями gluQuadricDrawStyle(quadratic, GLU_FILL); то эта часть видна - отображается все верно. В чем проблема?
Посмотрите GL_CULL_FACE и GL_CULL_FACE_MODE и установите нужный.
И вместо "отображаю цилиндр линиями" грамотно говорить "рисую wireframe" Улыбающийся
Записан
taifun
Гость
« Ответ #7 : Ноябрь 06, 2009, 11:51 »

Учту замечания. А вы можете посоветовать книгу или интернет ресурс, где есть материал как работать с полигонами, примеры. А то пока особо в этом нарправление не разбирался, вот понял что сферу можно треугольниками построить, квадратами же не получится, ведь так?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #8 : Ноябрь 06, 2009, 12:23 »

Учту замечания. А вы можете посоветовать книгу или интернет ресурс, где есть материал как работать с полигонами, примеры. А то пока особо в этом нарправление не разбирался,
Книг много, но OGL сам очень развесистый поэтому вероятно Вы просто "утонете в информации" без толку. Для того чтобы начать строить простые 3D объекты - Вы уже все знаете, нужно строить Улыбающийся Используя, по мере надобности, хотя бы тот же OGL help из вижуал студии.

вот понял что сферу можно треугольниками построить, квадратами же не получится, ведь так?
Получится, правда будут quads у которых 2 вертекса совпадают. Это не смертельно хотя в некоторых случаях могут быть проблемы. Вообще quads или triangles не проблема: если у Вас есть 4 вертекса - Вы всегда можете отдать OGL либо 1 quad или 2 triangles (и здесь же проверить корректность quad'a).

Сфера получается из плоскости 2-мя деформациями bend. Цилиндр - одной деформацией bend. Сделайте плоскость, потом поговорим Улыбающийся
Записан
taifun
Гость
« Ответ #9 : Ноябрь 06, 2009, 12:58 »

плоскость вот так я нарисовал:

Код:
for(int i=0; i<10; i++){
        for(int k=0; k<10; k++){
            glBegin(GL_QUADS);
                glVertex3d(0.0, 0.0, 0.0);
                glVertex3d(2*k, 0.0, 0.0);
                glVertex3d(2*k, 2*i, 0.0);
                glVertex3d(0.0, 2*i, 0.0);
            glEnd();
        }
}

правда размеры не те которые Вы сказали, но я думаю это не суть важно, главное принцип понять, ведь так?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #10 : Ноябрь 06, 2009, 13:55 »

плоскость вот так я нарисовал:

Код:
for(int i=0; i<10; i++){
        for(int k=0; k<10; k++){
            glBegin(GL_QUADS);
                glVertex3d(0.0, 0.0, 0.0);
                glVertex3d(2*k, 0.0, 0.0);
                glVertex3d(2*k, 2*i, 0.0);
                glVertex3d(0.0, 2*i, 0.0);
            glEnd();
        }
}

правда размеры не те которые Вы сказали, но я думаю это не суть важно, главное принцип понять, ведь так?
Так, но плоскость Вы нарисовали неправильно Улыбающийся
1) glBegin и glEnd надо вынести за все циклы, ведь вы заряжаете сразу серию полигонов а не по чайной ложке.
2) как же первый вертекс может быть одинаков для всех полигонов? Он у них разный
3) (Необязательно но желательно), вместо (k,j) используйте имена (u, v) - они в 3D имеют именно тот смысл который здесь нужен
4) что это за огрызок кода? Сделайте порядочную функцию, например такую

Код:
void DrawPlaneOGL( const float center[3], float sizeU, float sizeV, float resolutionU, float resolutionV )
{
 ...
}
Записан
taifun
Гость
« Ответ #11 : Ноябрь 06, 2009, 16:09 »

А вот так лучше уже?

Код:
float center[3] = {-5, -5, 0};
drPlane (center, 5, 5, 10, 10);

//***************************************
void VMMutomo::drPlane (float center[3], float sizeU, float sizeV, float longU, float longV){
    glBegin(GL_QUADS);
        for(int u = 0; u < longU; u++){
            for(int v = 0; v < longV; v++){
                glVertex3d(center[0] + sizeV*v,     center[1] + sizeU*u,     center[2] + 0.0);
                glVertex3d(center[0] + sizeV*(v+1), center[1] + sizeU*u,     center[2] + 0.0);
                glVertex3d(center[0] + sizeV*(v+1), center[1] + sizeU*(u+1), center[2] + 0.0);
                glVertex3d(center[0] + sizeV*v,     center[1] + sizeU*(u+1), center[2] + 0.0);

            }
        }
    glEnd();
}

и сразу бы хотел узнать есть ли такая переменная типа glPoint3D(x, y, z), из которой можно вытащить потом  координату Х glPoint.X?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #12 : Ноябрь 06, 2009, 17:10 »

А вот так лучше уже?
Лучше, но надо шлифовать

1) "u" обычно ассоциируется с осью/координатой "x", лучше этого придерживаться. Также легче/интуитивнее строить по строкам, а не по столбцам

2) Если это "center" то он должен центру и соответствовать. А у Вас это левый верхний угол. Также sizeU(V) это размер всей плоскости вдоль оси X(Y), вызывающему неинтересно рассчитывать размер полигона, это должно быть в самой функции.

3) Если параметры float то и вызывайте glVertex3f (и добавляйте 0.0f)

4) Можно задать resolution в числе шагов вдоль X(Y), как у Вас, ничего плохого здесь нет. Но тогда эти параметры должны быть типа int

и сразу бы хотел узнать есть ли такая переменная типа glPoint3D(x, y, z), из которой можно вытащить потом  координату Х glPoint.X?
Сам не видел, но много раз слышал про дельфи-программиста который радостно воскликнул "Я нашел компоненту чтобы сравнить 2 числа!!!"  Улыбающийся

То же и здесь - надо писать свой конкретный класс вместо того чтобы искать нечто, которое еще и подойдет кое-как. Например

Код:
struct Vec3D {
// avoid constructor

  void xyz( float _x = 0.0f, float _y = 0.0f, float _z = 0.0f ) { x = _x; y = _y; z = _z; }

  Vec3D & operator += ( const Vec3D & t )   { ... }
  Vec3D & operator *= ( float t )                 { ... }
  ...
  friend Vec3D operator + ( const Vec3D & t1,  const Vec3D & t2 )  { .. }
  friend Vec3D operator - ( const Vec3D & t1,  const Vec3D & t2 )  { .. }
  ...

// data
  float x, y, z;
};
Записан
taifun
Гость
« Ответ #13 : Ноябрь 09, 2009, 09:52 »

С классом для трехмерной точки понятно.
Вот подправил код:
Код:
    float center[3] = {0, 0, 0};
    drPlane (center, 50, 50, 10, 10);

void VMMutomo::drPlane (float center[3], float sizePU, float sizePV, float numU, float numV){
    float sRectU = sizePU/numU;
    float sRectV = sizePV/numV;
    float centSpaceU = sizePU/2;
    float centSpaceV = sizePV/2;
    center[0] -= centSpaceU;
    center[1] -= centSpaceV;

    glBegin(GL_QUADS);
        for(int v = 0; v < numV; v++){
            for(int u = 0; u < numU; u++){
                glVertex3d(center[0] + sRectU*u,     center[1] + sRectV*v,     center[2] + 0.0);
                glVertex3d(center[0] + sRectU*(u+1), center[1] + sRectV*v,     center[2] + 0.0);
                glVertex3d(center[0] + sRectU*(u+1), center[1] + sRectV*(v+1), center[2] + 0.0);
                glVertex3d(center[0] + sRectU*u,     center[1] + sRectV*(v+1), center[2] + 0.0);

            }
        }
    glEnd();
}
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #14 : Ноябрь 09, 2009, 10:57 »

Ладно, цилиндр. Для каждого вертекса координата Y вычисляется точно так же как и для плоскости. Как вычислить X и Z ?
Посмотрим на цилиндр сверху - видим окружность. Значит

Код:
x = center[0] + cos(angle) * radius;
z = center[2] + sin(angle) * radius;
Где взять angle? Цилиндр - это плоскость свернутая в трубочку. "Шов" (там где 2 свернутых края сходятся) на 12 часов, разворот против часовой стрелки. Значит, для каждого вертекса

Код:
angle = float (u) / numU * PI * 2 - PI / 2;

Примечание: вычисления становятся короче/удобнее если u, v меняются в диапазоне [-0.5f; +0.5f]

Вот подправил код:
Очень плохо подправили. Предыдущие замечания проигнорировали, центр хотя и добавили но с какой стати функция его модифицирует? Так что о сфере и др. вещах поговорим когда у Вас все будет чисто и аккуратно.
« Последнее редактирование: Ноябрь 09, 2009, 11:23 от Igors » Записан
Страниц: [1] 2 3   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.06 секунд. Запросов: 23.