Каждая более менее простая программа OpenGL традиционно состоит из трех стандартных частей: инициализирующая, отвечающая на сообщения об изменении размеров сцены, собственно рисующая, деинициализирующая. Поэтому далее приведенные инструкции расположены в порядке их использования и разделены на эти соответствующие части.
Список переменных, которые понадобятся:
Glint programID = 0;
GLuint vaoID = 0;
char[] source = "the code1";//коды шейдеров
char[] source = "the code2";
Glint logLength = 0;
GLint compiled = 0;
GLint linked = 0;
Список команд в инициализирующей части:
programID = glCreateProgram();
glGenVertexArrays(1, &vaoID);
vs = glCreateShader(GLenum(GL_VERTEX_SHADER));
glShaderSource(vs, 1, &source, nil);
glCompileShader(vs);
//Работа с логами и кодами возврата компиляции шейдера
glGetShaderiv(vs, GLbitfield(GL_COMPILE_STATUS), &compiled);
glGetShaderiv(vs, GLenum(GL_INFO_LOG_LENGTH), &logLength);
glGetShaderInfoLog(vs, GLsizei(logLength), &logLength, cLog);
free(cLog);
fs = glCreateShader(GLenum(GL_FRAGMENT_SHADER));
glShaderSource(fs, 1, &fssptr, nil);
glCompileShader(fs);
//Здесь надо повторить обработку кода возврата компиляции и лог
glAttachShader(programID, vs);
glAttachShader(programID, fs);
glLinkProgram(programID);
//Работа с логами и кодами возврата линковки шейдера
glGetProgramiv(programID, UInt32(GL_LINK_STATUS), &linked);
glGetProgramiv(programID, UInt32(GL_INFO_LOG_LENGTH), &logLength);
glGetProgramInfoLog(programID, GLsizei(logLength), &logLength, cLog);
glDeleteShader(vs);
glDeleteShader(fs);
Список команд в рисующей части:
glClear(GLbitfield(GL_COLOR_BUFFER_BIT));
glUseProgram(programID);
glBindVertexArray(vaoID);
//glPointSize(40); и т.п.
glDrawArrays(GLenum(GL_POINTS), 0, 1);
glBindVertexArray(0);
glFlush();
По завершении работы необходимо освободить ресурсы:
glDeleteVertexArrays(1, &vaoID);
glDeleteProgram(programID);
Это некая абстрактная схема, выраженная в виде инструкций на языке Си. На "человеческом" языке этот алгоритм можно описать так:
- Создаем пустую программу с идентификатором programID;
- Создаем массив вершин;
- Задаем исходники шейдера вершин;
- Компилируем их;
- Смотрим, есть ли ошибки компиляции, и обрабатываем их;
- Повторяем шаги 2-5 для других массивов;
- Привязываем все скомпиллированные шейдеры к программе programID;
- Компонуем ее;
- Смотрим, есть ли ошибки компоновки, и обрабатываем их;
- Вытираем шейдеры; Все готово для команд рисования;
- Указываем, что будем пользоваться программой с индентификатором programID; Я так понял, что таких "программ" может быть несколько в одном приложении и мы можем переключаться между ними;
- "Привязываем" массив вершин;
- glDrawArrays - рисуем;
- "Отвязываем" массив вершин;
- При выходе из приложения явно вытираем массивы вершин и "программы";