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

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

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

Пока пишу функцию для цилиндра, гляньте на фукцию, которая строит плоскость (я поработал над ней):
Код:
float center[3] = {0, 0, 0};
drPlane (center, 50, 50, 10, 10);

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

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

            }
        }
    glEnd();
}
жду ваших замечаний, пока жду работаю над построением цилиндра...
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


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

Пока пишу функцию для цилиндра, гляньте на фукцию, которая строит плоскость (я поработал над ней):
Ну вот, другое дело. Но еще надо работать

1) Функция не изменяет center, значит он должен быть объявлен как const float center[3]

2) Хотя это и проблемы вызывающего, numU(V) не могут быть меньше 1, функция должна это пресекать

3) centSpaceU(V), StartPLeft (Right) - зачем плодить переменные? Лучше так
Код:
float offset[3] = { center[0] - sizeU / 2, center[1] - sizeV / 2, center[2] };

4) Ошибка в счетчиках циклов: они должны изменяться до numU(V) - 1

5) Если мне не изменяет память, Вы писали о своей лени. Ваш код говорит обратное - Вы прибавляете смещения 12 раз. Ленивый программист должен написать примерно так
Код:
inline void OutVertex( float x, float y, float z, const float offset[3] )
{
  glVertex3f(x + offset[0], y + offset[1], z + offset[2]);
}
« Последнее редактирование: Ноябрь 09, 2009, 14:10 от Igors » Записан
taifun
Гость
« Ответ #17 : Ноябрь 09, 2009, 14:45 »

доработал:

Код:
void VMMutomo::drawPlane (const float center[3], float sizePU, float sizePV, int numU, int numV){
    float sRectU = sizePU/numU;
    float sRectV = sizePV/numV;
    float startPoint[3] = { center[0] - sizePU / 2, center[1] - sizePV / 2, center[2] };

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

            }
        }
    glEnd();
}

относительно пункта 4, если делать так как вы говорите, то у меня получится на одну точку меньше по Х и по Y соответственно получится всего 9 полигонов, а не 10. А вот насчет 5 пункта что-то я вообще не понял, где это применить?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


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

относительно пункта 4, если делать так как вы говорите, то у меня получится на одну точку меньше по Х и по Y соответственно получится всего 9 полигонов, а не 10. А вот насчет 5 пункта что-то я вообще не понял, где это применить?
Относительно пункта 4 я был неправ Улыбающийся Насчет пункта 5 - ну не знаю как объяснить словами

Код:
#define PI    3.141592f
#define PI2  (PI * 2.0f)

inline void OutVertex( float x, float y, float z, const float scale[3], const float center[3] )
{
  glVertex3f(x * scale[0] + center[0], y * scale]1] + center[1], z * scale[2] + center[2]);
}

void VMMutomo::drawPlane ( const float center[3], float sizePU, float sizePV, int numU, int numV )
{
  if (numU < 1) numU = 1;
  if (numV < 1) numV = 1;

  float u = -0.5f, v = -0.5f;
  float du = 1.0f / numU;
  float dv = 1.0f / numV;
  float scale[3] = { sizePU, sizePV, 1.0f };

  glBegin(GL_QUADS);
  for(int j = 0; j < numV; ++j, v += dv) {
    for(int i = 0; i < numU; ++i, u += du) {
     OutVertex(u,        v,        0.0f, scale, center);
     OutVertex(u + du, v,        0.0f, scale, center);
     OutVertex(u + du, v + dv, 0.0f, scale, center);
     OutVertex(u,        v + dv, 0.0f, scale, center);
    }
  }
  glEnd();
}

void VMMutomo::drawCylinder( const float center[3], float height, float radius, int numU, int numV )
{
  if (numU < 1) numU = 1;
  if (numV < 1) numV = 1;

  float u = -0.5f, v = -0.5f;
  float du = 1.0f / numU;
  float dv = 1.0f / numV;
  float scale[3] = { radius, height, radius };

  glBegin(GL_QUADS);
  for(int j = 0; j < numV; ++j, v += dv) {
    for(int i = 0; i < numU; ++i, u += du) {
     float angle1 = u * PI2 + PI * 1.5f;
     float x1 = cos(angle1);
     float z1 = sin(angle1);

     float angle2 = (u + du) * PI2 + PI * 1.5f;
     float x2 = cos(angle2);
     float z2 = sin(angle2);

     OutVertex(x1, v,        z1, scale, center);
     OutVertex(x2, v,        z2, scale, center);
     OutVertex(x2, v + dv, z2, scale, center);
     OutVertex(x1, v + dv, z1, scale, center);
    }
  }
  glEnd();
}
Записан
taifun
Гость
« Ответ #19 : Ноябрь 09, 2009, 16:48 »

да по написанию получается короче, но я пока не буду так делать, мне для понимания так проще. вот написал и для цилиндра:
Код:
void VMMutomo::drawPlane (const float center[3], float sizePU, float sizePV, int numU, int numV){
    if (numU < 1) numU = 1;
    if (numV < 1) numV = 1;
    float sRectU = sizePU/numU;
    float sRectV = sizePV/numV;
    float startPoint[3] = { center[0] - sizePU / 2, center[1] - sizePV / 2, center[2] };

    glBegin(GL_QUADS);
        for(int v = 0; v < numV; v++){
            for(int u = 0; u < numU; u++){
                glVertex3f(startPoint[0] + sRectU*u,     startPoint[1] + sRectV*v,     startPoint[2]);
                glVertex3f(startPoint[0] + sRectU*(u+1), startPoint[1] + sRectV*v,     startPoint[2]);
                glVertex3f(startPoint[0] + sRectU*(u+1), startPoint[1] + sRectV*(v+1), startPoint[2]);
                glVertex3f(startPoint[0] + sRectU*u,     startPoint[1] + sRectV*(v+1), startPoint[2]);
            }
        }
    glEnd();
}

void VMMutomo::drawCylinder (const float center[3], float longCyl, float radius, int numU, int numV){
    if (numU < 1) numU = 1;
    if (numV < 1) numV = 1;
    float angle = 0;
    float x, z;
    float sRectV = longCyl/numU;
    float startPoint[3] = { center[0] - radius, center[1] - longCyl / 2, center[2] };
  
    glBegin(GL_QUADS);
        for(int v = 0; v < numV; v++){
            for(int u = 0; u < numU; u++){
                angle = float (u) / numU * PI * 2 - PI / 2;
                x = center[0] + cos(angle) * radius;
                z = center[2] + sin(angle) * radius;

                float angle1 = float (u+1) / numU * PI * 2 - PI / 2;
                float x1 = center[0] + cos(angle) * radius;
                float z1 = center[2] + sin(angle) * radius;

                glVertex3f(x,     startPoint[1] + sRectV*v,     z);
                glVertex3f(x1,    startPoint[1] + sRectV*v,     z1);
                glVertex3f(x1,    startPoint[1] + sRectV*(v+1), z1);
                glVertex3f(x,     startPoint[1] + sRectV*(v+1), z);

            }
        }
    glEnd();
}
все бы хорошо, да вот только почему-то получилось, что строятся линии только длиной longCyl, а те которые образую кольца не видно


Вставил Вашу функцию все прекрасно работает, буду разбираться завтра утром что сделал не так, а если не справлюсь, тогда потребуется ваша помощь - я напишу. А так вообще по коду есть замечания?
« Последнее редактирование: Ноябрь 09, 2009, 17:04 от taifun » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


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

все бы хорошо, да вот только почему-то получилось, что строятся линии только длиной longCyl, а те которые образую кольца не видно
Ну так надо angle1 использовать когда он вычислен - а Вы снова заряжаете angle.
Код:
angle = float (u) / numU * PI * 2 - PI / 2;          // неверно
angle = float (u) / (numU - 1) * PI * 2 + PI / 2;  // правильно
Смысл: полный поворот (который будут делать все вертексы последние по "u") = PI * 2 (полная окружность). Первые (по "u") вертексы должны быть повернуты на PI / 2 (шов сзади). Пока текстуры нет - шва не видно.

А так вообще по коду есть замечания?
Улыбающийся Наложите текстуру и будет понятно почему выгодно иметь u, v в диапазоне [-0.5f; +0.5f]
Записан
taifun
Гость
« Ответ #21 : Ноябрь 10, 2009, 11:07 »

текстуры пока еще не научился накладывать, буду учиться ...
переписал (показывает нормально), замечания есть?

Код:
void VMMutomo::drawCylinder (const float center[3], float longCyl, float radius, int numU, int numV){
    if (numU < 1) numU = 1;
    if (numV < 1) numV = 1;   

    float u1 = -0.5f, v1 = -0.5f;
    float du = 1.0f / numU;
    float dv = 1.0f / numV;
    float startPoint[3] = { center[0] - radius, center[1], center[2] };

    glBegin(GL_QUADS);
        for(int v = 0; v < numV; v++, v1+=dv){
            for(int u = 0; u < numU; u++, u1+=du){

                float angle1 = u1 * PI2 + PI * 1.5f;
                float x1 = center[0] + cos(angle1) * radius;
                float z1 = center[2] + sin(angle1) * radius;

                float angle2 = (u1 + du) * PI2 + PI * 1.5f;
                float x2 = center[0] + cos(angle2) * radius;
                float z2 = center[2] + sin(angle2) * radius;

                glVertex3f(x1,     startPoint[1] + longCyl*v1,     z1);
                glVertex3f(x2,     startPoint[1] + longCyl*v1,     z2);
                glVertex3f(x2,     startPoint[1] + longCyl*(v1+dv), z2);
                glVertex3f(x1,     startPoint[1] + longCyl*(v1+dv), z1);

            }
        }
    glEnd();

    glPushMatrix();
        glTranslated(0.0, longCyl/2, 0.0);
        glRotated(90.0,1.0,0.0,0.0);
        gluDisk(quadratic,0.0f,radius,numU,numV);

        glTranslated(0.0, 0.0, longCyl);
        gluDisk(quadratic,0.0f,radius,numU,numV);
    glPopMatrix();
}

приделал торцевые стороны, жду Ваших замечаний.
« Последнее редактирование: Ноябрь 10, 2009, 12:28 от taifun » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


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

текстуры пока еще не научился накладывать, буду учиться ...
"Не все сразу" - разумный подход. Но с др. стороны такие легкие и приятные вещи как наложение текстуры имеет смысл задействовать сразу. Вам нужно будет вызвать glTexCoord2f(u,v) перед glVertex3fv.  Как активировать текстуру - наберите в хелпе glBindTexture, оттуда Вы легко найдете еще 2-3 функции которые Вам понадобятся. За день с нуля можно разобраться.

переписал (показывает нормально), замечания есть?
Если мы смотрим только эту функцию (drawCylinder) - то все хорошо. А теперь посмотрим 2 функции: drawPlane и drawCylinder. Бросается в глаза что они отличаются очень немногим. Если Вы будете строить сферу - опять кусок кода будет сдублирован - и так каждый раз для новой модели. Такое программирование методом copy/paste никогда не было уважаемым делом, а по-простому говоря "так делать западло". Если Вам пришлось так копировать (хотя бы 1 раз) то у Вас возникли вещи которые надо обобщить. Для этого и придуманы наследование, виртуальные функции и.т.п. Хотя можно сделать и в стиле чистого "С". Но в любом случае это делать надо.

приделал торцевые стороны, жду Ваших замечаний.
Не используйте стандартных функций если Вы хотите научиться строить сами.
Записан
taifun
Гость
« Ответ #23 : Ноябрь 10, 2009, 14:19 »

1. С текстурами разберусь на неделе.
2. Я думаю сейчас напишу еще функцию для окружности, сферы и пойму что можно быдет вынести и как модернезировать код.
3.  Улыбающийся это я просто хотел посмотреть как будет смотрется. Никак не могу сообразить как вычислять координаты вершин полигона для окружности  Непонимающий
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


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

Никак не могу сообразить как вычислять координаты вершин полигона для окружности  Непонимающий
Улыбающийся

x = cos(angle) * radius;
y = sin(angle) * radius;

Это параметрическое (параметр angle) уравнение окружности в плоскости XY
Записан
taifun
Гость
« Ответ #25 : Ноябрь 10, 2009, 16:34 »

что-то здесь совсем туго  Обеспокоенный
Код:
void VMMutomo::drawCircle (const float center[3],  float radius, int numU, int numV){
    if (numU < 1) numU = 1;
    if (numV < 1) numV = 1;

    float u1 = -0.5f, v1 = -0.5f;
    float du = 1.0f / numU;
    float dv = 1.0f / numV;
    float startPoint[3] = { center[0] - radius, center[1], center[2] };

    glBegin(GL_QUADS);
        for(int v = 0; v < numV; v++, v1+=dv){
            for(int u = 0; u < numU; u++, u1+=du){

                float angle1 = u1 * PI2 + PI * 1.5f;
                float x1 = center[0] + cos(angle1) * u1;
                float y1 = center[1] + sin(angle1) * v1;

                float angle2 = (u1 + du) * PI2 + PI * 1.5f;
                float x2 = center[0] + cos(angle2) * (u1+du);
                float y2 = center[1] + sin(angle2) * (v1+dv);

                glVertex3f(x1, y1, center[3]);
                glVertex3f(x2, y1, center[3]);
                glVertex3f(x2, y2, center[3]);
                glVertex3f(x1, y2, center[3]);

            }
        }
    glEnd();
}

а вот угол высчитываем angle1 = u1 * PI2 + PI * 1.5f что это за формула такая
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


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

что-то здесь совсем туго  Обеспокоенный
- Для массива из 3 элементов последним будет center[2]

- Что вы собрались строить: окружность (она не имеет площади) или диск (с дыркой или без)?

- В любом случае где радиус(ы) ?

а вот угол высчитываем angle1 = u1 * PI2 + PI * 1.5f что это за формула такая
Формулы не запоминаются а выводятся. На листе бумаги нарисуйте оси X и Y. Нарисуйте круг с центром в (0, 0). Поставьте на круге 8 жирных точек (вертексы в виде сверху). Точка (-1, 0) (9 часов) первая она соответствует u = -0.5f. Обходим круг против часовой стрелки и попадаем  в ту же точку. Значит для каждой точки угол = u * PI2. Добавляем 1.5 * PI. Изменилось только что мы начинаем с точки (0, 1) (12 часов)

В общем, дело творческое и надо включать пространственное представление Улыбающийся
Записан
taifun
Гость
« Ответ #27 : Ноябрь 10, 2009, 17:22 »

center[3] - который раз уже наступаю на эти грабли и ошибку не показывает в этом месте даже

так диск с нулевым внутренним радиусом - это же и есть окружность или я не правильно понимаю? лучше бы диск делать, а там задав у него нулевой внутренний радиус, получим торцевую сторону цилиндра.

ща добегу до дома и буду рисовать.
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


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

диск - это диск. У него есть поверхность. У окружности поверхности нет, есть только внешняя линия.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


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

center[3] - который раз уже наступаю на эти грабли и ошибку не показывает в этом месте даже
В С/С++ указатель и массив - одно и то же, ничего показывать оно не должно. Не хотите один раз написать класс Vec3D - мучайтесь

так диск с нулевым внутренним радиусом - это же и есть окружность или я не правильно понимаю? лучше бы диск делать, а там задав у него нулевой внутренний радиус, получим торцевую сторону цилиндра.
Здесь используется геометрия времен Евклида и Пифагора, поэтому выдумывать новые термины совсем ни к чему. Окружность, диск, сфера, шар - все это разные вещи.

ща добегу до дома и буду рисовать.
Улыбающийся
« Последнее редактирование: Ноябрь 10, 2009, 18:14 от Igors » Записан
Страниц: 1 [2] 3   Вверх
  Печать  
 
Перейти в:  


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