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

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

Страниц: [1] 2 3   Вниз
  Печать  
Автор Тема: Прорисовка сетки поверх полигонов  (Прочитано 17706 раз)
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« : Июль 31, 2014, 16:55 »

Здравствуйте!
Я заинтересовался вопросом, как поверх нарисованных мною полигонов нарисовать сетку.
При обычном наложении сетки на полигоны возникала, так называемая z-fighting.
В интернете я нашёл функцию glPolygonOffset(-1.0, -1.0). На что указывают её аргументы, так и не смог понять.
В прикрепленном файле имеется две детали. Одна вставлена во вторую. Поверхности, которые не видны, я вычислять не хотел бы (по крайней мере на процессоре), так как мне очень критична скорость. На рисунке видно, как сквозь синюю деталь, обшитую белыми линиями, просачиваются чёрные, принадлежащие красной детали (при поворотах видны иногда и соседние белые, которые за поверхностью).
Данные о вершинах поступают таким образом, что невозможно определить переднюю сторону полигона.
Каким образом можно ликвидировать это неверное наложение?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #1 : Июль 31, 2014, 17:09 »

Поверхности, которые не видны, я вычислять не хотел бы (по крайней мере на процессоре), так как ..
Ну а я просто "не знаю как" (без разницы хотел или нет  Улыбающийся). Делал подобное 2 дня назад - просто второй проход напр glDrawArrays(GL_LINES..), можно толщину линии увеличить.
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #2 : Июль 31, 2014, 17:46 »

У меня проще. Детали идеально соприкасаются по элементам. Вычислить эти элементы и вуаля.
Можно, пожалуйста подробнее, с кодом. Я только успел изучить 5 глав суперкниги и на разбор документации времени нет.
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #3 : Июль 31, 2014, 18:00 »

Сразу не понял сообщения…
Так я второй проход и делаю. Получается то, что на рисунке
Обратите внимание на силуэт красного тела. Его не должно быть. Две вертикальные черные линии на синем теле лишние
Увеличение толщины сделает их только заметнее
« Последнее редактирование: Июль 31, 2014, 18:06 от __Heaven__ » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #4 : Июль 31, 2014, 18:10 »

У меня юзверь выбирает как рисовать (с заливкой, wireframe и др), поэтому данные wireframe хранятся как ребра/линии и просто рисуются вторым проходом. Если Вам нет нужды создавать такие данные (есть только полигоны), то попробуйте вторым проходом напр
Код
C++ (Qt)
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

Сразу не понял сообщения…
Так я второй проход и делаю. Получается то, что на рисунке
Обратите внимание на силуэт красного тела. Его не должно быть. Две вертикальные черные линии на синем теле лишние
Увеличение толщины сделает их только заметнее
Не связывайтесь с glPolygonOffset
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #5 : Июль 31, 2014, 18:25 »

У меня данные хранятся в виде массива координат вершин (xyzxyzxyz)
Если я делаю без полигон офсет, то получаю z конфликт на пересечении линии и поверхности. То есть сетка получается бегающим пунктиром. Меня не устраивает, что линии полностью не прокрашиваются. Позже готов предоставить скрин.
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #6 : Июль 31, 2014, 18:26 »

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

Сообщений: 11445


Просмотр профиля
« Ответ #7 : Июль 31, 2014, 18:53 »

У меня данные хранятся в виде массива координат вершин (xyzxyzxyz)
Если я делаю без полигон офсет, то получаю z конфликт на пересечении линии и поверхности. То есть сетка получается бегающим пунктиром. Меня не устраивает, что линии полностью не прокрашиваются. Позже готов предоставить скрин.
Как выводили "бегающую" сетку - это неясно из Вашего поста, поэтому трудно что-то советовать. Пробуйте glPolygonMode, не устраивает - выводите линиями, их всегда можно получить из полигонов. Проверить оба варианта максимум час, действуйте более конкретно/целеустремленно.   
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #8 : Июль 31, 2014, 19:43 »

Во вложении 3 картинки. Первая это с применением оффсет. Вторая без применения оффсет. Третья - то же, что и вторая, только повернута немного и наклонена.
Без применения оффсета сетка мелькает при повороте, превращаясь в пунктиры, пропадая частично. То есть, идёт борьба между первым проходом полигонов и вторым, с wire.

Мой код, к сожалению остался на работе - выкладываю старый, но, эффект прослеживается такой же:

Код:
void Positioner::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    float* otlData = otlVertexes.data();
    float* formData = formVertexes.data();

    glPushMatrix();

    glRotatef(xRot, 1.0f, 0.0f, 0.0f);
    glRotatef(yRot, 0.0f, 1.0f, 0.0f);
    glRotatef(zRot, 0.0f, 0.0f, 1.0f);

    glTranslatef(-geomCenter[0], -geomCenter[1], -geomCenter[2]);

    glBegin(GL_TRIANGLES);
        if (showCastBtn->isChecked())
        {
            glColor3f(1.0f, 0.0f, 0.0f);
            for (int i = 0; i < otlVertexes.size(); i += 3)
                glVertex3fv(otlData + i);
        }
        if (showMouldBtn->isChecked())
        {
            glColor3f(0.0f, 0.0f, 1.0);
            for (int i = 0; i < formVertexes.size(); i += 3)
                glVertex3fv(formData + i);
        }

    glEnd();

    glColor3f(0.0f, 0.0f, 0.0f);
    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
//    glEnable(GL_POLYGON_OFFSET_LINE);
    glPolygonOffset(-0.5f, -1.0f);
    glBegin(GL_TRIANGLES);
        if (showCastBtn->isChecked())
        {
            for (int i = 0; i < otlVertexes.size(); i += 3)
                glVertex3fv(otlData + i);
        }
        if (showMouldBtn->isChecked())
        {
            glColor3f(1.0f, 1.0f, 1.0f);
            for (int i = 0; i < formVertexes.size(); i += 3)
                glVertex3fv(formData + i);
        }
    glEnd();
    glDisable(GL_POLYGON_OFFSET_LINE);

    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
//    glPolygonOffset(0.0f, 0.0f);


    glPopMatrix();
}

Новый код у меня на том же принципе, вместо перебора вершин в цикле передаю сразу весь массив.
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #9 : Август 01, 2014, 10:45 »

Вот поправленный код:
Код:
void Positioner::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    float* otlData = otlVertexes.data();
    float* formData = formVertexes.data();

    glPushMatrix();

    glRotatef(xRot, 1.0f, 0.0f, 0.0f);
    glRotatef(yRot, 0.0f, 1.0f, 0.0f);
    glRotatef(zRot, 0.0f, 0.0f, 1.0f);

    glTranslatef(-geomCenter[0], -geomCenter[1], -geomCenter[2]);

    if (showCastBtn->isChecked())
    {
        glColor3f(1.0f, 0.0f, 0.0f);
        glEnableClientState(GL_VERTEX_ARRAY);
        glVertexPointer(3, GL_FLOAT, 0, otlData);
        glDrawArrays(GL_TRIANGLES, 0, otlVertexes.size() / 3);

        glEnable(GL_POLYGON_OFFSET_LINE);
        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
        glColor3f(0.0f, 0.0f, 0.0f);
        glDrawArrays(GL_TRIANGLES, 0, otlVertexes.size() / 3);
        glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

        glDisable(GL_POLYGON_OFFSET_LINE);
        glDisableClientState(GL_VERTEX_ARRAY);
    }
    if (showMouldBtn->isChecked())
    {
        glColor3f(0.0f, 0.0f, 1.0f);
        glEnableClientState(GL_VERTEX_ARRAY);
        glVertexPointer(3, GL_FLOAT, 0, formData);
        glDrawArrays(GL_TRIANGLES, 0, formVertexes.size() / 3);

        glEnable(GL_POLYGON_OFFSET_LINE);
        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
        glColor3f(1.0f, 1.0f, 1.0f);
        glDrawArrays(GL_TRIANGLES, 0, formVertexes.size() / 3);
        glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
        glDisableClientState(GL_VERTEX_ARRAY);
        glDisable(GL_POLYGON_OFFSET_LINE);
    }

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

Сообщений: 11445


Просмотр профиля
« Ответ #10 : Август 01, 2014, 11:18 »

__Heaven__, не то чтобы я Вас "понукаю", но вещи должны делаться в нормальном, рабочем темпе. Проверили glPolygonMode, не выходит. Чего ждем? Проверяем вариант с отрисовкой линий (который работает у меня). Хотя бы "на коленке", glBegin(GL_LINES) и.т.д
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #11 : Август 01, 2014, 11:49 »

Igors, не сразу понял ваше предложение.
Не успех... Результат на коленке с использованием линий дает тот же результат z блокировки.
Код:
//        glEnable(GL_POLYGON_OFFSET_LINE);
//        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
//        glColor3f(1.0f, 1.0f, 1.0f);
//        glDrawArrays(GL_TRIANGLES, 0, formVertexes.size() / 3);
//        glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
//        glDisableClientState(GL_VERTEX_ARRAY);
//        glDisable(GL_POLYGON_OFFSET_LINE);
        glColor3f(1.0f, 1.0f, 1.0f);
        float* pEnd = formData + formVertexes.size();
        glBegin(GL_LINES);
        for (;formData < pEnd; formData += 3*3)
        {
            glVertex3fv(formData);
            glVertex3fv(formData+3);

            glVertex3fv(formData);
            glVertex3fv(formData+6);

            glVertex3fv(formData+3);
            glVertex3fv(formData+6);

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

Сообщений: 2130



Просмотр профиля
« Ответ #12 : Август 01, 2014, 12:03 »

Увеличение размера линии тоже не помогло.
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #13 : Август 01, 2014, 14:03 »

Igors, можно посмотреть ваш код?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #14 : Август 02, 2014, 11:31 »

Igors, можно посмотреть ваш код?
Нет возможности выдрать его из большого проекта. Пока не смог добиться у себя ощутимого мерцания. Поэкспериментирую еще - отпишусь
Записан
Страниц: [1] 2 3   Вверх
  Печать  
 
Перейти в:  


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