glColor фактически не меняет цвет OpenGL

У меня особенно неприятная проблема. В некоторых ситуациях вызовы glColor игнорируются, в результате чего объекты отображаются с неправильным цветом.

Проект Qt, демонстрирующий эту проблему, можно найти здесь.

Когда вы запускаете программу, все, что вы видите на экране, — это два прямоугольных объекта, рассматриваемых под углом. Объект слева визуализируется вызовом glCallList(boxModel1);, а объект справа визуализируется вызовом glCallList(boxModel2);. Два списка отображения создаются методами с очевидными названиями.

И для boxModel1, и для boxModel2 я использую один список отображения под названием squareModel для рендеринга сторон коробок. Я делаю это, потому что, хотя квадратная модель в этом случае тривиальна, squareModel в моей реальной программе намного сложнее, с измененными нормалями и т. д.

Проблема как-то связана с методом createManyRectangles. При вызове с достаточно маленьким номером (у меня 2715) цвета отображаются нормально: синий квадратик и красный квадратик. Когда число высокое (для меня 2716), цвета игнорируются, и оба поля отображаются белыми.

Кто-нибудь может пролить свет на то, что здесь происходит?


person Elliott    schedule 29.11.2011    source источник


Ответы (3)


Попробуйте запустить свою программу с помощью glIntercept. Это позволяет вам записывать каждый вызов OpenGL. Сравните результат, который вы получите между 2715 и 2716 числами прямоугольников. Если есть какие-либо различия, это должно привести вас в правильном направлении.

редактировать

Поскольку ваши фактические вызовы OpenGL выглядят нормально, это может быть проблема с драйвером, как вы упомянули. Вы можете попробовать разные среды (видеокарта, компьютер и т. Д.), Поскольку, как указал тотем, он не сталкивался с вашей проблемой. Возможно, вы могли бы дать некоторую информацию о вашей среде?

Попробуйте визуализировать свои прямоугольники без списков отображения, чтобы увидеть, поможет ли это. Там, где вы использовали бы glCallList, вместо этого повторите последовательность вызовов OpenGL. Если это решит проблему, вы узнаете, что существует проблема с управлением списками отображения в вашем приложении или в драйвере.

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

person bernie    schedule 02.12.2011
comment
Я запустил его. Вот результат для 2715: ссылка. Вот результат для 2716: ссылка. обратите внимание, что я вырезал большую часть многих вызовов прямоугольников, чтобы сэкономить место, но я вырезал только те части, которые были идентичными. Единственными отличиями являются адреса памяти при настройке контекста, адреса памяти при подкачке буферов и добавление одного вызова glColor и четырех вызовов glVertex. Другими словами, нет никаких различий, которых можно было бы ожидать. Как мне это интерпретировать? Ошибка драйвера? - person Elliott; 04.12.2011
comment
Я просмотрел ваш вывод и, к сожалению, вы правы... Я не вижу ничего плохого в последовательности вызовов OpenGL. - person bernie; 05.12.2011
comment
В качестве временного компромисса я смог решить проблему, удалив квадратный список отображения. Вместо этого это просто метод, который создает квадрат, и этот метод вызывается в тех местах, где должен был быть вызван список отображения. В долгосрочной перспективе я обязательно посмотрю на vbos. спасибо за вашу помощь с программой glintercept, которая довольно быстро сузила возможные причины. - person Elliott; 05.12.2011

Весь рендеринг выполняется через списки отображения, но проблема возникает как при указании цвета в списке отображения, так и при указании цвета непосредственно перед вызовом списка отображения.

Списки отображения не автономны. Они не восстанавливают состояние OpenGL после его изменения. Если DL изменяет состояние OpenGL, то это будет состояние OpenGL после выполнения DL.

Вы просто не опубликовали достаточно кода, чтобы окончательно сказать что-либо; это просто наиболее вероятное объяснение. Пока вы не опубликуете воспроизводимый случай, нет реального способа помочь.

person Nicol Bolas    schedule 29.11.2011
comment
Я не понимаю, как это помогает. Никогда не бывает так, чтобы я явно не указывал цвет, который хочу для каждого примитива, либо в списке отображения, либо прямо перед ним. Моя проблема в том, что я вызываю glColor, а уже в следующей строке кода цвет OpenGL не изменился. - person Elliott; 29.11.2011
comment
@Elliott: Вы не опубликовали код, который мог бы воспроизвести проблему. Так что все, что я должен продолжать, это то, что вы говорите. Наиболее вероятным объяснением, помимо ошибки драйвера, является то, что ваш список отображения изменил состояние до того, как вы прочитали его обратно с помощью glGetFloatv. Вы проверяете ошибки OpenGL? - person Nicol Bolas; 29.11.2011
comment
Я обновил свои драйверы, и это все еще происходит. Ошибок OpenGL нет. Что касается списка отображения, меняющего цвет, вызов getFloatv находится в строке сразу после вызова glColor4f, поэтому ничто не может его изменить. Я понимаю, что очень-очень сложно просто установить исправление, не видя кода. Я работаю над воспроизводимой версией, но это довольно большая программа. - person Elliott; 30.11.2011
comment
Я добавил воспроизводимый проект. Надеюсь, это должно помочь. - person Elliott; 02.12.2011
comment
Скачал и скомпилировал данный проект. makeManyRectangles(100000) ; не выдает ошибочное отображение... - person azf; 03.12.2011

У меня была аналогичная проблема, когда я нарисовал много точек с разными цветами, а затем синий каркасный куб. (Я использовал GLUT для своего проекта.)

Изначально мой код выглядел так:

glBegin(GL_POINTS);

    for(int i=0;i<N;i++)
     {
      glColor3f(R[i],G[i],B[i]);
      glVertex3f(X[i],Y[i],Z[i]);
     }

glEnd();
glColor3f(0.0f, 0.0f, 1.0f);
glutWireCube(2.0f);

Однако это привело к мерцающему кубу, который постоянно менял свой цвет от кадра к кадру на какие-то непредсказуемые цвета, как будто последний glColor3f просто игнорируется.

Решение: я поместил glColor3f для куба перед glEnd().

glBegin(GL_POINTS);

    for(int i=0;i<N;i++)
     {
      glColor3f(R[i],G[i],B[i]);
      glVertex3f(X[i],Y[i],Z[i]);
     }

glColor3f(0.0f, 0.0f, 1.0f);    // <= Changed only the position of this line
glEnd();
glutWireCube(2.0f);

Я не знаю, ПОЧЕМУ, но это решило мою проблему. Теперь я получаю синий каркасный куб, и glColor3f больше не игнорируется...

ваше здоровье,

Дэйвид

person David Muelheims    schedule 17.08.2012
comment
Кажется, что такого рода вещи должны быть ожидаемы. После этого я провел много исследований, и оказалось, что весь конвейер с фиксированными функциями (т. е. вызов glBegin, glVertex и т. д.) устарел, и большинство графических карт больше не поддерживают его даже на аппаратном уровне, а программное обеспечение реализации, вероятно, имеют гораздо более низкий приоритет с точки зрения времени разработки. - person Elliott; 19.08.2012