Настройка буферных объектов в управляющей программе. Сначала создайте член класса int vaoHandle для хранения дескриптора объекта массива вершин. Дальнейший код можно поместить в функцию InitShaders(). Сначала создаем массивы в которых будут содержаться параметры вершин: float[] positionData = { -0.8f, -0.8f, 0.0f, 0.8f, -0.8f, 0.0f, 0.0f, 0.8f, 0.0f }; float[] colorData = { 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f }; glGenBuffers создаёт два буферных объекта. Дескрипторы сохраняются в массиве для последующего использования. int[] vboHandlers = new int[2]; GL.GenBuffers(2, vboHandlers); Каждый буферный объект связывается с точкой привязки GL_ARRAY_BUFFER (BufferTarget.ArrayBuffer) вызовом glBindBuffer. Все возможные точки привязки содержатся в перечислении BufferTarget. GL.BindBuffer(BufferTarget.ArrayBuffer, vboHandlers[0]); Для заполнения массивов данными вызывается функция glBufferData. glBufferData выделяет память под данные. Третий параметр подсказывает библиотеке OpenGL как будут использоваться данные, чтобы она могла решить как лучше организовать управление внутренним буфером. Имя параметра составлено из двух частей, первая может быть: STATIC, DYNAMIC или STREAM, а вторая может быть DRAW, READ или COPY. _STATIC_ данные будут записаны один раз, и использованы многократно, используется для данных, которые задаются один раз при инициализации. _DYNAMIC_ данные будут использованы много раз, прежде чем поменяются. _STREAM_ данные будут меняться каждый фрейм или одни данные будут отрисованы всего несколько раз. _DRAW данные изменяются управляющей программой и используются как источник данных для отрисовки. _READ данные будут читаться из памяти OpenGL по запросу, следует использовать для буферных объектов пикселей и других буферов, которые будут использоваться для получения информации из OpenGL. _COPY данные используются для отрисовки и для чтения из OpenGL, приложение будет использовать OpenGL для генерации данных, которые будут помещены в буфер, который затем будет использоваться в качестве источника для последующих операций рисования. GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(sizeof(float) * positionData.Length), positionData, BufferUsageHint.StaticDraw); GL.BindBuffer(BufferTarget.ArrayBuffer, vboHandlers[1]); GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(sizeof(float) * colorData.Length), colorData, BufferUsageHint.StaticDraw); После настройки буферных объектов их нужно объединить в объект массива вершин (vertex array object, VAO). VAO содержит информацию о связях между данными в буферах и входными атрибутами вершин. glGenVertexArray() создаёт объект VAO и возвращает его дескриптор. vaoHandle = GL.GenVertexArray(); GL.BindVertexArray(vaoHandle); Активация атрибутов вершин с индексами 1 и 0: GL.EnableVertexAttribArray(0); GL.EnableVertexAttribArray(1); Снова связываем буферный объект с целевой точкой привязки, а потом устанавливается связь между буферными объектами и индексами атрибутов. Первый аргумент – это индекс атрибута, второй – число компонент на каждую вершину (от 1 до 4), четвёртый – логическое значение, определяющее необходимость нормализации данных (необходимость отображения целочисленных значений со знаком в диапазон [-1,1] и целочисленных значений без знака в диапазон [0,1]). Пятый аргумент – это шаг, смещение в байтах между соседними атрибутами. Последний аргумент – смещение в байтах первого атрибута в буфере относительно начала этого буфера, на тот случай если в буфере перед первым элементом записаны дополнительные данные. Настройка объекта VBO – однократная операция. GL.BindBuffer(BufferTarget.ArrayBuffer, vboHandlers[0]); GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, 0, 0); GL.BindBuffer(BufferTarget.ArrayBuffer, vboHandlers[1]); GL.VertexAttribPointer(1, 3, VertexAttribPointerType.Float, false, 0, 0); В функцию Draw добавьте следующие инструкции: GL.UseProgram(BasicProgramID); GL.DrawArrays(PrimitiveType.Triangles, 0, 3); openGlControl.SwapBuffers(); GL.UseProgram(0); glUseProgram() делает активной шейдерную программу BasicProgramID, всё, что будет отрисовано до вызова следующей glUseProgram() будет отрисовано с помощью этой шейдерной программы. glDrawBuffers() запускает отрисовку буферов, выполняя обход всех активных атрибутов и передавая данные по конвейеру в вершинный шейдер. Первый аргумент определяет режим отображения, во втором указывается первый активный индекс, в третьем – число вершин для отображения. Запускаем, получаем треугольник:  Ссылки: 1. Вольф Д. OpenGL 4. Язык шейдеров. Книга рецептов / пер. с англ. А.Н.Киселева. – М.: ДМК Пресс, 2015. – 368 с. |