В openGL, как вы можете получить элементы для рисования назад? - PullRequest
12 голосов
/ 09 октября 2008

По умолчанию кажется, что объекты нарисованы спереди назад. Я рисую двумерный объект пользовательского интерфейса и хотел бы создать его задом наперед. Например, я мог бы сначала создать белый квадрат, а затем создать чуть меньший черный квадрат поверх него, создав тем самым черную панель с белой рамкой. В этом посте было некоторое обсуждение, и этот порядок описывался как «Алгоритм художника», но в конечном итоге приведенный ими пример просто отображал объекты в обратном порядке, чтобы получить желаемый эффект. Я рассчитываю задом наперед (первые объекты возвращаются назад, последующие объекты рисуются сверху) рендеринга можно добиться с помощью некоторого преобразования (gOrtho?)?

Я также упомяну, что меня не интересует решение с использованием библиотеки-оболочки, такой как GLUT.

Я также обнаружил, что поведение по умолчанию на Mac с использованием Cocoa NSOpenGLView, похоже, отодвигает на задний план, где, как и в Windows, я не могу получить это поведение. Код установки в окнах, которые я использую, таков:

glViewport (0, 0, wd, ht);
glMatrixMode(GL_PROJECTION);           
glLoadIdentity();                      
glOrtho (0.0f, wd, ht, 0.0f, -1.0f, 1.0f);
glMatrixMode(GL_MODELVIEW);             
glLoadIdentity();                       

Ответы [ 6 ]

22 голосов
/ 10 октября 2008

Следующий вызов отключит проверку глубины, в результате чего объекты будут нарисованы в порядке их создания. Это фактически заставит объекты отодвинуться назад.

glDepthFunc(GL_NEVER);      // Ignore depth values (Z) to cause drawing bottom to top

Убедитесь, что вы не называете это:

glEnable (GL_DEPTH_TEST);   // Enables Depth Testing
5 голосов
/ 09 октября 2008

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

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

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

Но если вам действительно нужно сделать это таким образом, тогда вы должны сделать это сами. Сначала отправьте белый квадрат в конвейер рендеринга, запустите рендеринг, а затем отправьте черный квадрат. Если вы сделаете это таким образом и отключите буферизацию глубины, квадраты могут быть копланарными, и вам все равно будет гарантировано, что черный квадрат нарисован поверх белого квадрата.

2 голосов
/ 09 октября 2008

Нарисуйте предметы, за которыми вы хотите находиться, немного позади предметов, за которыми вы хотите быть впереди. То есть фактически измените значение z (при условии, что z перпендикулярен плоскости экрана). Вам не нужно сильно его менять, чтобы предметы рисовать перед собой. И если вы слегка измените значение z, вы не должны заметить значительного смещения от их желаемого положения. Вы даже можете пойти по-настоящему модно и вычислить правильную позицию x, y на основе измененной позиции z, чтобы элемент появился там, где он должен быть.

2 голосов
/ 09 октября 2008

Порядок рисования сложно. Нет простого решения. Алгоритм художника (сортировка объектов по их расстоянию относительно обзора вашей камеры) является наиболее простым, но, как вы обнаружили, он не решает все случаи.

Я бы предложил комбинацию альгроитма и слоев художника. Вы строите слои для определенных элементов в вашей программе. Итак, вы получили фоновый слой, слои объектов, слои спецэффектов и слой GUI.

Используйте алгоритм художника на предметах каждого слоя. В некоторых специальных слоях (например, в вашем слое GUI) сортировка выполняется не по алгоритму художника, а по порядку вызовов. Сначала вы называете этот белый квадрат, чтобы он был нарисован первым.

1 голос
/ 10 октября 2008

Ваш материал будет отрисован в точном порядке, в котором вы вызываете функции glBegin / glEnd. Вы можете получить буферизацию глубины, используя z-буфер, и если ваши 2d-объекты имеют разные значения z, вы можете получить нужный эффект сюда. Единственный способ увидеть поведение, которое вы описываете на Mac, - это если программа рисует вещи в обратном порядке вручную или использует z-буфер для этого. В противном случае OpenGL не имеет никакой функциональности, как вы описали.

0 голосов
/ 10 октября 2008

Как указал AlanKley, способ сделать это - отключить буфер глубины. Алгоритм рисования - это действительно метод преобразования 2D-сканирования, используемый для визуализации полигонов в правильном порядке, когда у вас нет чего-то вроде z-буфера. Но вы не примените его к 3D полигонам. Обычно вы преобразуете и проецируете их (обрабатывает пересечения с другими полигонами), а затем сортируете результирующий список 2D проецируемых полигонов по их проецированной z-координате, а затем рисуете их в обратном z-порядке.

Я всегда думал об алгоритме художника как об альтернативной технике удаления скрытой поверхности, когда вы не можете (или не хотите) использовать z-буфер.

...