2014-02-18 3 views
3

В настоящее время я работаю над 2D-графикой, и, насколько я могу судить, каждая вершина в конечном итоге обрабатывается как 4D-точка в однородном пространстве. Поэтому я говорю себе: какая пустая трата ресурсов! Я понимаю, что аппаратное обеспечение в основном предназначено для обработки 3D-сцен и, как таковое, может быть жестко запрограммировано на 4d-линейную алгебру. Тем не менее, есть ли способ написать шейдеры (или включить набор параметров), чтобы в жесткой памяти использовались только оригинальные 2d-координаты? Я знаю, что можно было встроить две матрицы 2x2 в матрицу 4x4, но переменная gl_Position, являющаяся vec4, кажется, заканчивает здесь трек. Я не ищу какого-то «обходного» взлома вроде этого, а скорее канонического способа сделать OpenGL, как определенный режим/состояние.Открывает ли OpenGL3 + определенное состояние для рендеринга 2D-графики?

Мне не удалось найти образец кода или даже просто упомянуть об этом факте в сети, поэтому я собираю его просто невозможно/не желательно, например, по соображениям производительности. Это так?

+1

Waaaaiitt ... Вы работаете над 2D-графикой, которая по существу использует меньше ресурсов. Это очень похоже на преждевременную оптимизацию. И я думаю, что ответ будет «нет» в любом случае из-за того, как создается растеризатор. –

+0

@Bartek Я думаю, что это все еще правильный вопрос. Даже в традиционном 3D-приложении вы делаете некоторые вещи, такие как HUD, которые полностью 2D, поэтому стоит обсудить наиболее эффективный способ сделать это в OpenGL. –

+0

@NathanMonteleone Не стоит обсуждать это, если а) это не настоящая проблема. Б) предлагаемое решение улучшило бы его с помощью такой крошечной разницы. –

ответ

0

Все кредиты принадлежат Andon M. Coleman, который отлично ответил на этот вопрос в виде комментария. Я просто цитирую его здесь для завершения:

«Абсолютно нет. Аппарат сам/был разработан вокруг 4-компонентных данных и инструкций в течение многих лет. Современные графические процессоры являются скалярными, и они должны рассматривать push для GPGPU (но более старые NV GPU pre-GeForce 8xxx имеют чисто векторный ALU). Теперь, что касается атрибутов вершин, вы получаете 16 слотов размера (float * 4) для хранения. Это означает, что вы используете атрибут вершины vec2 или vec4, он фактически ведет себя как vec4. Это можно увидеть, если вы когда-либо пишете vec4 и предоставляете достаточно данных для двух компонентов - GL автоматически назначает Z = 0.0 и W = 1.0.

Кроме того, вы не сможете реализовать обрезку в 2D-пространстве с помощью 2D-координат. Вам нужны однородные координаты для создания координат НДЦ. Вам нужно будет использовать координаты оконного пространства, которые вы не можете сделать из вершинного шейдера. После завершения шейдерного шейдера GL будет выполнять отсечение, разделение перспективы и отображение видового экрана, чтобы добраться до оконного пространства. Но координаты оконного пространства все еще 4D (компонент Z может не вносить вклад в местоположение в пространстве окна, но это влияет на тесты фрагмента). »

1

Современные графические процессоры на самом деле являются скалярными архитектурами. В GLSL вы можете писать и более короткие векторы. vec2 является вполне допустимым типом, и вы можете создавать массивы вершин только с 2 скалярных элементов в векторе, как определено параметром glVertexAttribPointer

Как комментировал Anon М. Coleman size, OpenGL будет внутренне выполнить vec4(v, [0, [0]], 1) конструкцию для любых данных, передаваемых в качестве атрибута вершины размерности < 4.

В вершинном шейдере вы должны назначить vec4 на gl_Position. Но вы можете тривиальным расширить vec2 к vec4:

vec2 v2; 
gl_Position = vec4(v2, 0, 1); 

Да, gl_Position выход всегда должен быть vec4, в связи с тем, OpenGL определяет операции в усеченном пространстве. Но это вовсе не узкое место.

+0

GL уже делает это автоматически, если вы объявляете атрибут вершины как 'vec4' в GLSL, а затем используете' glVertexAttribPointer (...) 'с 'size' = 2 (z = ** 0.0 **, w = ** 1.0 **). Поскольку атрибут vertex 'vec2' занимает столько слотов, сколько' vec4' (1), вы можете эффективно обрабатывать любой атрибут, меньший, чем 'vec4', как если бы это был' vec4', просто объявив его таким образом в шейдере. Вы не сохраните какую-либо память, изменив объявление только в шейдере, но вы, безусловно, можете сэкономить память, используя буфер вершин с двумя компонентами и позволяя GL раскрыть недостающие компоненты для вас. –

+0

@ AndonM.Coleman: Я добавлю это. Но мое первоначальное намерение состояло в том, чтобы показать, как vec2 будет правильно назначен gl_Position. – datenwolf

+0

@ datenwolf: спасибо за ваш ответ. но я боюсь, что это не отвечает на мой вопрос. На самом деле я знал, как расширить vec2-> vec4 (хотя я проигнорировал, что это было сделано автоматически), мой вопрос состоял в том, имеет ли стандартное (и аппаратное обеспечение) выделенный режим для 2D. –

Смежные вопросы