Как я могу расширить область просмотра в openGL, чтобы правильно обрезать печатный текст?

Я использую этот код для рисования текста в openGL с помощью GLUT:

Код (часть инициализации), который устанавливает мое происхождение (0,0) в верхний левый угол и поддерживает правильную систему координации на основе разрешения экрана:

    glViewport(0, 0, x, y);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0, x, y, 0, -1, 1);
    glMatrixMode(GL_MODELVIEW);

Код (печатная часть):

void drawtext(GLfloat x, GLfloat y, const char* string )
{
    glRasterPos2f(x,y);
    while ( *string != '\0' )
         glutBitmapCharacter(p_glutfont,static_cast<int>(*string++));
}

И все было бы прекрасно, если бы не только тот факт, что когда X и Y начинаются с отрицательных координат (из-за того, что объекты с напечатанным в виде тега текстом частично выходят за пределы поля зрения, то весь текст не рисуется. представим что у меня есть объект с текстовым тегом поверх него, и он входит в вид из левого верхнего угла в точке x = -40, y = 40:

         X axis      window
 axis Y  ----------------------------
        | y=40                       |
 x=-40__|_________                   |
    |Text to print|                  |
    |_____________|                  |
        |                            |
        |                            |
        |____________________________|

Текст не печатается до тех пор, пока он не будет нарисован точно из координаты X => 0. Также этой проблемы не существует, когда текст должен быть обрезан с ПРАВОЙ стороны - тогда он печатается правильно - здесь я понял, что это связано с начальным положением текста.

Мой вопрос: как я могу правильно РАСШИРИТЬ отображение окна просмотра/экрана на:

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

Хотя я провел свое исследование, я не мог в течение 2 дней прийти к какому-либо решению. Я пытался поиграть с glViewport и glOrtho, но ни одно из изменений и подходов, которые я пробовал (например, установка glViewport на -x,-y,x*2,y*2), не помогло - они всегда портят мою систему координации экрана. что важно для сохранения разрешения окна.

PS: я провел дополнительные исследования и наткнулся на эту статью http://www.opengl.org/archives/resources/faq/technical/clipping.htm.

10.070 Как нарисовать примитивы glBitmap() или glDrawPixels(), у которых начальный glRasterPos() находится за пределами левого или нижнего края окна?

Когда положение растра установлено за пределами окна, оно часто находится за пределами объема просмотра и впоследствии помечается как недопустимое. Рендеринг примитивов glBitmap и glDrawPixels не будет происходить с недопустимой позицией растра. Поскольку glBitmap/glDrawPixels создают пиксели вверх и вправо от положения растра, кажется невозможным визуализировать этот тип примитива, обрезанного левым и/или нижним краями окна.

Однако есть часто используемый прием: задайте для положения растра допустимое значение внутри объема просмотра. Затем сделайте следующий вызов:

 glBitmap (0, 0, 0, 0, xMove, yMove, NULL); 

Это говорит OpenGL отображать неактивное растровое изображение, но перемещать текущую растровую позицию на (xMove,yMove). Ваше приложение будет предоставлять значения (xMove,yMove), которые помещают положение растра за пределы объема просмотра. Следуйте этому вызову с помощью glBitmap() или glDrawPixels(), чтобы выполнить желаемый рендеринг.

К сожалению, я не могу применить этот совет в работе, а когда я его использую, текст полностью отсутствует.


person seeoneself    schedule 03.10.2012    source источник


Ответы (1)


здесь я понял, что это связано с начальным положением текста.

Почти. glRasterPos — это команда операции рисования растра, и любая позиция, которую вы в нее введете, проходит через конвейер преобразования. Если точка выходит за пределы обрезаемого объема (не области просмотра!), она отбрасывается, и все дальнейшие операции рисования растра отключаются до тех пор, пока не будет указан новый glRasterPos, который не обрезается.

Простым и рекомендуемым решением было бы вообще не использовать операции рисования растра, потому что они медленные, плохо поддерживаются и были полностью удалены из более поздних версий OpenGL. glutBitmapCharacter использует операции растрового рисования.

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

person datenwolf    schedule 03.10.2012
comment
Это все действительные моменты - я пришел к выводу, что мне может понадобиться использовать другие возможности печати в будущих проектах, но для целей, которые у меня есть прямо сейчас, этого вполне достаточно, поэтому я бы не стал использовать совершенно новый метод рисования текста, ЕСЛИ можно как-то по-другому отобразить этот вид отсечения, о чем, по сути, и был мой вопрос. - person seeoneself; 03.10.2012
comment
Также - как описано здесь: mesa3d.org/brianp/sig97/gotchas.htm - эта проблема с отрисовкой текста в перенасыщении общеизвестна - и одно из решений, которое они предлагают, состоит в том, чтобы по-другому отображать систему координат. К сожалению, я вообще не понимаю их примера :( - person seeoneself; 03.10.2012
comment
@seeoneself: вы не можете обойти отключение растровых операций, если glRasterPos преобразуется за пределы объема клипа. Это неотъемлемое свойство OpenGL. Если вы хотите придерживаться glutBitmapCharacter, то вам, вероятно, лучше всего будет отрендерить текст в промежуточный FBO, а затем нарисовать его в вашей сцене с помощью текстурированного четырехугольника. - person datenwolf; 03.10.2012
comment
Как насчет того обходного пути, который я нашел на OpenGL.org, посмотрите мой вопрос - я добавил к нему PS с объяснением - в основном используя glBitmap(0,0,0,desired_X_outside_clip_volume,desired_Y_outside_clip_volume,NULL); который должен перемещать растерпос в желаемое положение, но не может заставить его работать. - person seeoneself; 03.10.2012
comment
@seeoneself: Идея заключается в следующем: область просмотра, установленная с помощью glViewport, действительно определяет границы границ объема клипа в координатах окна. Определяя пределы области просмотра, выходящие за пределы области окна, вы эффективно перемещаете границы клипа за пределы окна. Однако это расширение области просмотра должно быть дополнено настройкой проекции, чтобы все снова совпадало. В случае, если ваша проекция является ортопроекцией, удваивающей область просмотра, просто передайте экстенты области просмотра в параметры glOrtho слева, справа, снизу, сверху. - person datenwolf; 03.10.2012
comment
@seeoneself: Другой упомянутый трюк состоит в том, чтобы поместить glRasterPos в границы объема клипа и нарисовать нулевое растровое изображение с помощью glBitmap с отрицательным значением для xmove, чтобы переместить текст за пределы области просмотра. - person datenwolf; 03.10.2012
comment
да, я понял этот 1-й метод - с glOrtho и glViewport я просто не могу понять, а другой трюк с простым glBitmap не работает для glutBitmapCharacter. Возможно, я не могу сделать свои мировые координаты, скажем (от -800, -600 до 1600,1200) - и просмотреть координаты (которые будут определять только видимую область), например: от 0,0 до 800,600? - person seeoneself; 03.10.2012