четверг, 13 октября 2016 г.

Минимальный набор команд OpenGL для работы с вершинным шейдером

Каждая более менее простая программа 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);

Это некая абстрактная схема, выраженная в виде инструкций на языке Си. На "человеческом" языке этот алгоритм можно описать так:

  1. Создаем пустую программу с идентификатором programID;
  2. Создаем массив вершин;
  3. Задаем исходники шейдера вершин;
  4. Компилируем их;
  5. Смотрим, есть ли ошибки компиляции, и обрабатываем их;
  6. Повторяем шаги 2-5 для других массивов;
  7. Привязываем все скомпиллированные шейдеры к программе programID;
  8. Компонуем ее;
  9. Смотрим, есть ли ошибки компоновки, и обрабатываем их;
  10. Вытираем шейдеры; Все готово для команд рисования;
  11. Указываем, что будем пользоваться программой с индентификатором programID; Я так понял, что таких "программ" может быть несколько в одном приложении и мы можем переключаться между ними;
  12. "Привязываем" массив вершин;
  13. glDrawArrays - рисуем;
  14. "Отвязываем" массив вершин;
  15. При выходе из приложения явно вытираем массивы вершин и "программы";

Комментариев нет: