2015-06-25 2 views
0

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

Затем, почему и как OpenGL использует дробные значения для печати пикселей?

Например, как это возможно: glVertex2f(0.15f, 0.51f);?

+1

Я вижу, что вы отредактировали свой вопрос, чтобы удалить третью координату из вызова. Это фактически не имеет значения - третья координата все еще существует, только в этом случае она по умолчанию равна 0. – vesan

+1

Кажется, что вы даже не пытались прочитать какой-либо учебник или вики на opengl, -1 – lisyarus

+0

@BROY ничего. Я только что объяснил свой нижний план. – lisyarus

ответ

6

Эта команда не отображает пиксели. Он просто определяет местоположение точки в трехмерном пространстве (вы заметите, что есть 3 координаты, а для пикселя на экране вам потребуется только 2). Это отправная точка для конвейера OpenGL. Затем этот момент проходит через множество преобразований, прежде чем он окажется на экране.

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

Я бы посоветовал немного узнать о том, как работают преобразования OpenGL, например here, here или учебник here.

+1

Это правильно, но даже после преобразования все же полезно передавать дробные координаты в растеризатор. Это связано с тем, что даже если пиксели находятся в целочисленных (или целых + 0,5) местоположениях, пиксельные/фрагментарные шейдеры с растеризатором могут использовать [мультисэмплирование] (https://en.wikipedia.org/wiki/Multisample_anti-aliasing) или даже аналитическое покрытие для получения разных результатов в зависимости от частичного охвата примитива над пикселем. – MooseBoys

+0

@MooseBoys Совершенно верно. И это не ограничивается 3D-графикой. Например, [ClearType] (https://en.wikipedia.org/wiki/ClearType) или WPF используют ту же технику. – vesan

2

Вектора вы передаете в OpenGL не видовых позиции, но произвольные числа в некоторых векторном пространстве. Только после цепочки преобразований эти числа отображаются в пиксельные позиции в видовом экране. Со старым конвейером с фиксированной функцией это может быть все, что может быть представлено умножением вектор-матрица.

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

Это совершенно корректный вершинный шейдер OpenGL-2.1, который интерпретирует положение вершин должно находиться в полярных координатах. Обратите внимание, что из-за того, что треугольники и прямые являются прямыми краями, а полярные координаты являются криволинейными, это дает хорошие визуальные результаты только для точек или сильно тесселированных примитивов.

#version 110 

void main() { 
    gl_Position = 
      gl_ModelViewProjectionMatrix 
     * vec4(gl_Vertex.y*vec2(sin(gl_Vertex.x),cos(gl_Vertex.x)) , 0, 1); 
} 

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

0

Для вашего примера, перед тем как glVertex2f (0.15f, 0.51f) появится на экране, будет сделано много преобразований. Создание сложной вещи грубо проще, после перемещения вашей вершины для просмотра места (с использованием положения и направления камеры) магией здесь является (1) матрица проекции и (2) настройка видового экрана.

Внутри OpenGL "экранные координаты" в кубе (-1, -1, -1) - (1, 1, 1),:

http://www.matrix44.net/cms/wp-content/uploads/2011/03/ogl_coord_object_space_cube.png

матрица проекции 'выжимает' The усечение в этом кубе (что вы делаете в вершинном шейдере), предполагая, что у вас есть перспективное преобразование - если проекция ортогональна, проекция - это просто трубка, ограниченная близкими и дальними значениями (и, как в обоих случаях, коэффициенты масштабирования):

http://www.songho.ca/opengl/files/gl_projectionmatrix01.png

EDIT: Может быть, лучший пример здесь:

http://www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices/#The_Projection_matrix

(EDIT: Z-координат используется в качестве значения глубины) Когда фрагменты, наконец, переносили в пиксели на текстуру/фреймбуфера/экран, они умножаются с настройками окна просмотра :

https://www3.ntu.edu.sg/home/ehchua/programming/opengl/images/GL_2DViewportAspectRatio.png

Надеется, что это помогает!

0

Вершина и пиксель - это разные вещи.

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

Вы можете начать здесь ... http://www.glprogramming.com/blue/ch01.html

В частности ...

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

И ...

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

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