Сдам Сам

ПОЛЕЗНОЕ


КАТЕГОРИИ







Наш первый рендеринг в OpenGL





 

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

Void

display(void)

{

glClear(GL_COLOR_BUFFER_BIT);

glBindVertexArray(VAOs[Triangles]);

glDrawArrays(GL_TRIANGLES, 0, NumVertices);

glFlush();

}

 

Мы начинаем рендеринг с очищения кадрового буфера. Это делается командой glClear().

void glClear(GLbitfield mask);

Clears the specified buffers to their current clearing values. The mask

argument is a bitwise logical OR combination of the values listed in

 

Таблица 1.3 Очистка буфера

 

Буфер Именование
Буфер цвета GL_COLOR_BUFFER_BIT
Буфер глубины GL_DEPTH_BUFFER_BIT
Стенсил буфер GL_STENSIL_BUFFER_BIT

 

Мы обсудим стенсил и глубину, а также подробно поговорим про буфер цвета в Главе 4, “Color, Pixles and Framebuffers”.

Возможно вы спросите, как же установить цвет очистки для glClear(). Дефолтный цвет очистки в OpenGL - черный. Настроить другой цвет можно командой glClreaColour().

void glClearColor(GLclampf red, GLclampf green, GLclampf blue,

GLclampf alpha);

Sets the current clear color for use in clearing color buffers in RGBA mode.

(See Chapter 4 for more information on RGBA mode.) The red, green,

blue, and alpha values are clamped if necessary to the range [0, 1]. The

default clear color is (0,0,0,0), which is the RGBA representation of black.

 

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

На примере цвета очистки, предположим вы хотите, чтобы очистка экрана всегда была белой. Вам нужно вызвать glClreaColor(1,1,1,1). Но где делать этот запрос? Конечно можно задать его непосредственно перед glClrear() в display(), но тогда первый запрос будет резервным - OpenGL будет менять цвет с белого на черный каждый последующий раз при очистке. Более логично было бы прописать значение цвета очистки в init(). Таким образом мы можем сократить дополнительные внесения изменений в код программы. Все значения по умолчанию устанавливаются init(). Хотя конечно, ничего плохого в том, чтобы вносить каждый раз временные изменения, но это может замедлить выполнение вашей программы.

 

Попробуйте

Пропишите запрос glClrear() в triangles.cpp.

 

Рисование в OpenGL

 

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

Далее мы вызываем glDrawArrays(), которая собственно и посылает вершинные данные в конвейер OpenGL.

"> void glDrawArrays(GLenum mode, GLint first, GLsizei count);

Constructs a sequence of geometric primitives using the elements from

the currently bound vertex array starting at first and ending at



first + count − 1. mode specifies what kinds of primitives are constructed

and is one of GL_POINTS, GL_LINES, GL_LINE_STRIP, GL_LINE_LOOP,

GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, and

GL_PATCHES.

 

В нашем примере, мы запрашивает рендеринг отдельных треугольников, устанавливая метод рендеринга GL_TRIANGLES, начиная с нулевого байта, как мы указали в glVertexAttribPointer() для буфера, и до числа, указанного в NumVertices (у нас их 6).

Попробуйте

Измените triangles.cpp для визуализации разных типов геометрических примитивов, таких как GL_POINTS или GL_LINES. Могут быть использованы любые из вышеупомянутых примитивов, но некоторые результаты могут оказаться не совсем тем, что вы ожидаете. В случае GL_PATCHES вы не сможете увидеть резуьтат, так как для его отображения требуется мозаичный шейдер, о котором Глава 9.

 

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

void glFlush(void);

Forces previously issued OpenGL commands to begin execution, thus

guaranteeing that they complete in finite time.

 

Продвинутый уровень

В какой-то точке своей карьеры программиста OpenGL вы зададитесь вопросом: “Сколько времени это отняло?”. “Это” может быть временем визуализации объекта, отрисовки полого экрана, или любой другой команды, выполняемой OpenGL. Чтобы делать это точно, вам нужно знать, когда OpenGL заканчивает выполнение команд, которые вы хотите измерить.

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

void glFinish(void);

Forces the completion of all pending OpenGL commands and waits for

their completion.

Прим.: пользуйтесь командой glFinish() только при разработке приложения, а после окончания работы удалите ее из запросов. Хотя она помогает определить скорость выполнения некоторых команд OpenGL, она вредить скорости исполнения вашей программы в целом.

 

Включение и выключение команд в OpenGL

 

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

void glEnable(GLenum capability);

void glDisable(GLenum capability);

glEnable() turns on a capability and glDisable() turns it off. There are

numerous enumerated values that can be passed as parameters to

glEnable() or glDisable(). Examples include GL_DEPTH_TEST for

turning on and off depth testing; GL_BLEND to control blending and

GL_RASTERIZER_DISCARD for advanced rendering control while doing

transform feedback.

 

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

GLboolean glIsEnabled(GLenum capability);

Returns GL_TRUE or GL_FALSE, depending on whether or not the

queried capability is currently activated.

 

 

Основные понятия о шейдерах

 

Цель данной главы.

 

После прочтения этой главы вы сможете:

● Определить, какие различные шейдеры использует OpenGL для создания изображения;

● Создавать и компилировать шейдеры на языке OpenGL Shading Language;

● Перенаправлять данные в шейдеры посредством различных приемов, достуных в программе OpenGL;

● Применять продвинутые возможности GLSL для создания более функциональных шейдеров.

 

Эта глава дает понятие о том, как использовать настраиваемые шейдеры в OpenGL. По ходу главы, мы расскажем о приминение OpenGL Shading Language (GLSL, как его называют), и о том, как шейдеры влияют на ваше приложение в OpenGL.

 

В этой главе вы найдете следующие подразделы:

● “Шейдеры и OpenGL” расскажет о настраиваемых шейдерах в контексте приложений OpenGL;

● “Настраиваемый конвейер OpenGL” детализирует каждую стадию настраиваемого конвейера OpenGL;

● “Обзор OpenGL Shading Language” дает вводную информацию об OpenGL Shading Language;

● “Блоки интерфейса” покажет, как организовать переменные шейдеров с приложением или между стадиями;

● “Компилирование шейдеров” описывает процесс конвертирования GLSL в настраиваемый шейдер программ, которые можно использовать на OpenGL;

● “Подпрограммы шейдоров” описывает метод увеличения эффективности шейдеров, который поможет сделать выбор исполняемых процессов без переписывания всего шейдера;

● “Раздельные объекты шейдинга” детализирует процесс составления элементов из нескольких шейдеров в один, настраиваемый графический конвейер.

 

 

Шейдеры и OpenGL

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

Шейдеры, будь они для OpenGL или любой другой API, обычно пишутся на специализированном языке программирования. OpenGL использует GLSL (OpenGL Shading Language), который появился на версии 2.0 (хотя и был ранее в виде дополнений). Он развивался вместе с OpenGL, обычно обновляясь вместе с каждой новой версией программы. Хотя GLSL это язык программирования, специально созданный для работы с графикой, вы обнаружите, что в нем много сходства с “С”, и даже есть элементы С++.

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

 









Не нашли то, что искали? Воспользуйтесь поиском гугл на сайте:


©2015- 2018 zdamsam.ru Размещенные материалы защищены законодательством РФ.