CreateProgram: примеры (JAVASCRIPT)

Использование createProgram в JavaScript и WebGL
Раздел: WebGL, Программы
createProgram: WebGLProgram

Описание функции createProgram

Функция createProgram не является встроенной (native) функцией в стандартном JavaScript (ECMAScript). Она обычно встречается в контексте специфичных библиотек или фреймворков, например, для создания шейдерных программ в WebGL с использованием API WebGLRenderingContext. В рамках WebGL, createProgram() — это метод контекста рендеринга, который создает и возвращает новый пустой WebGLProgram объект. Этот объект служит контейнером для скомпилированных и связанных вместе шейдеров (вершинного и фрагментного).

Синтаксис в контексте WebGL:
const program = gl.createProgram();

Аргументы: Метод не принимает никаких аргументов.

Возвращаемое значение: Новый объект WebGLProgram. Если создание не удалось (например, из-за нехватки памяти), возвращается null.

Когда используется: Функция используется на начальном этапе настройки рендеринга в WebGL. После создания пустой программы к ней с помощью gl.attachShader() прикрепляются скомпилированные шейдеры, затем программа связывается (gl.linkProgram()) и, наконец, используется (gl.useProgram()).

Примеры использования

Пример создания и базовой настройки программы в WebGL.

// Получение контекста WebGL
const canvas = document.getElementById('myCanvas');
const gl = canvas.getContext('webgl');

// 1. Создание пустой программы
const shaderProgram = gl.createProgram();
console.log('Тип созданного объекта:', shaderProgram?.constructor.name);

// 2. Создание и компиляция шейдеров (упрощенный пример)
const vsSource = 'attribute vec4 aPosition; void main() { gl_Position = aPosition; }';
const fsSource = 'void main() { gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); }';

const vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vsSource);
gl.compileShader(vertexShader);

const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fsSource);
gl.compileShader(fragmentShader);

// 3. Прикрепление шейдеров к программе
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);

// 4. Связывание программы
gl.linkProgram(shaderProgram);

// 5. Проверка успешности связывания
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
    console.error('Ошибка линковки:', gl.getProgramInfoLog(shaderProgram));
    gl.deleteProgram(shaderProgram); // Очистка в случае ошибки
}

// 6. Использование программы
if(shaderProgram) {
    gl.useProgram(shaderProgram);
    console.log('Программа создана и используется.');
}
Тип созданного объекта: WebGLProgram
Программа создана и используется.

Похожие функции в JavaScript

В чистом JavaScript прямых аналогов createProgram (в ее WebGL-смысле) нет, так как это низкоуровневая графическая операция. Однако концептуально можно провести параллели:

  • Конструкторы классов: Создание объекта через new MyProgram() аналогично созданию контейнера для данных и логики. Отличие в том, что createProgram — это фабричный метод API, а не конструктор.
  • Фабричные функции: Функции, возвращающие новые объекты с определенной структурой, например, createUser(name). Они похожи на createProgram по принципу работы, но не связаны с графикой.
  • Инкапсуляция модулей: Современные модули ES6 или паттерн «Модуль» могут служить для организации кода, но не для создания графических программ.

Когда что использовать: gl.createProgram() используется исключительно при работе с WebGL API. Для обычной объектно-ориентированной разработки применяются классы и фабричные функции.

Типичные ошибки

  • Использование без контекста WebGL: Вызов createProgram() как обычной функции JavaScript приведет к ошибке.
  • const program = createProgram(); // Ошибка!
    Uncaught ReferenceError: createProgram is not defined
  • Пропуск этапов настройки: Создание программы — только первый шаг. Попытка использовать пустую программу без прикрепления и линковки шейдеров не даст результата или вызовет ошибку.
  • const gl = canvas.getContext('webgl');
    const program = gl.createProgram();
    gl.useProgram(program); // Программа пуста!
    // Рисование не произойдет
  • Игнорирование проверок: Не проверяется статус линковки программы и компиляции шейдеров. Это затрудняет отладку.
  • // Плохо: нет проверки
    const program = gl.createProgram();
    gl.attachShader(program, badShader); // Шейдер может быть не скомпилирован
    gl.linkProgram(program);
    gl.useProgram(program); // Может молча не работать
  • Утечка ресурсов: Неудачные программы и ненужные шейдеры нужно удалять с помощью gl.deleteProgram() и gl.deleteShader().

Изменения в последних версиях

Метод WebGLRenderingContext.createProgram() не претерпевал существенных изменений с момента его появления в WebGL 1.0. Он остается стабильным и обратно совместимым.

В WebGL 2.0 (WebGL2RenderingContext) метод также присутствует и работает идентично, но добавляется возможность создавать программы, использующие новые возможности шейдеров версии GLSL ES 3.00. Сам процесс создания программы через createProgram() не меняется.

Стандарты ECMAScript (сам JavaScript) не влияют на этот метод, так как он является частью API браузера, а не языка.

Расширенные примеры

Пример 1: Создание нескольких программ для разных эффектов. Можно переключаться между программами для отрисовки разными шейдерами.

Пример javascript
const gl = canvas.getContext('webgl');

// Программа для красного цвета
const redProgram = initProgram(gl, redVertexShaderSrc, redFragmentShaderSrc);
// Программа для текстурирования
const textureProgram = initProgram(gl, texVertexShaderSrc, texFragmentShaderSrc);

function render() {
    // Очистка холста красной программой
    gl.useProgram(redProgram);
    gl.drawArrays(gl.TRIANGLES, 0, 3);

    // Рисование поверх текстурированным объектом
    gl.useProgram(textureProgram);
    gl.drawArrays(gl.TRIANGLES, 3, 3);
}

// Вспомогательная функция инициализации программы
function initProgram(gl, vsSource, fsSource) {
    const program = gl.createProgram();
    // ... (стандартные шаги компиляции, аттача, линковки)
    return program;
}

Пример 2: Удаление и повторное создание программы для "горячей" перезагрузки шейдеров. Полезно при разработке шейдеров.

Пример javascript
let currentProgram = null;

function reloadShaders(newVSSource, newFSSource) {
    const gl = getGLContext();
    // Удаляем старую программу, если она есть
    if (currentProgram) {
        gl.deleteProgram(currentProgram);
    }
    // Создаем новую программу с новыми шейдерами
    currentProgram = gl.createProgram();
    // ... компиляция и линковка с newVSSource и newFSSource
    gl.useProgram(currentProgram);
    console.log('Шейдеры перезагружены.');
}

Пример 3: Абстракция над createProgram в классе. Инкапсуляция логики создания программы для удобства.

Пример javascript
class ShaderProgram {
    constructor(gl, vertexSrc, fragmentSrc) {
        this.gl = gl;
        this.program = gl.createProgram(); // Ключевой вызов
        if (!this.program) throw new Error('Не удалось создать программу');

        this.compileAndLink(vertexSrc, fragmentSrc);
    }

    compileAndLink(vs, fs) {
        // ... логика компиляции шейдеров, аттача и линковки
        const gl = this.gl;
        gl.linkProgram(this.program);
        if (!gl.getProgramParameter(this.program, gl.LINK_STATUS)) {
            const error = gl.getProgramInfoLog(this.program);
            gl.deleteProgram(this.program);
            throw new Error(`Ошибка линковки: ${error}`);
        }
    }

    use() {
        this.gl.useProgram(this.program);
    }
}

// Использование
const myShader = new ShaderProgram(gl, vertexCode, fragmentCode);
myShader.use();

Альтернативы в других языках

В других языках и графических API существуют аналогичные концепции создания шейдерных программ.

C++ с OpenGL: Используются функции glCreateProgram(), glAttachShader(), glLinkProgram(). Синтаксис очень похож на WebGL, так как WebGL является его производным для веба.

// Пример на C++/OpenGL
GLuint programID = glCreateProgram(); // Аналог createProgram()
glAttachShader(programID, vertexShaderID);
glAttachShader(programID, fragmentShaderID);
glLinkProgram(programID);
// Проверка статуса...
// Использование программы
glUseProgram(programID);

Python с PyOpenGL: Синтаксис также зеркалирует OpenGL.

# Пример на Python (PyOpenGL)
from OpenGL.GL import *
program = glCreateProgram()  # Создание программы
glAttachShader(program, vertex_shader)
glAttachShader(program, fragment_shader)
glLinkProgram(program)
# Проверка...
glUseProgram(program)

PHP: Прямого аналога в стандартной библиотеке нет, так как PHP не используется для низкоуровневой графики. Однако для генерации WebGL-кода на стороне сервера можно создавать строки с JavaScript-кодом, содержащим вызов createProgram().

Основное отличие: Вне контекста графических API (OpenGL, WebGL, Vulkan) прямой аналогии функции не существует, потому что ее цель специфична.

JS createProgram function comments

En
CreateProgram Creates a WebGLProgram object