Подтвердить что ты не робот

Возможно ли иметь два контекста WebGL на одной странице?

Я пытаюсь сделать одну и ту же сцену WebGL, используя две холсты бок о бок. Является ли это возможным? Пока мне не повезло.

Идея такова:

  • Загружаю свою геометрию
  • Я установил два контекста gl, один на холст
  • Я вызываю drawElements в первом контексте, передающем мою геометрию
  • Я вызываю drawElements во второй контекст, передающий мою геометрию

Результаты: Только первый вызов выполнен успешно. Второй контекст выполняет gl.clear правильно, но геометрия не отображается.

Что мне не хватает? это ограничение? или ограничение в реализациях Firefox и Safari?

Спасибо,

4b9b3361

Ответ 1

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

Это, безусловно, возможно, но он будет очень интенсивным в памяти (как вы можете себе представить). Лучшим решением было бы создать контекст, который равен 2x вашей ширины, и использовать gl.viewport и gl.scissor для рендеринга на половину из них для каждого вида сцены.

Или сделайте полный холст размера видового экрана и используйте настройки scissor/viewport для соответствия другим элементам html. См. Этот Q & A: Как мы можем отображать те же объекты в двух холстах в webgl?

Ответ 2

Это должно было вызвать ошибку. Как сказал Тоджи, два WebGLContext не могут делиться ресурсами. Однако для этого есть предложение. Проверить здесь. Я подозреваю, что скоро увидим что-то подобное в WebGL.

Ответ 3

Я использую несколько контекстов WebGL на одной странице, назначая один и тот же класс в полотна, которые должны отображать содержимое WebGL, и помещая что-то конкретное в внутренний холст html:

function specific(what) {
    switch (what) {
    case 'front':
        //do something
        break;
    case 'side':
        //do something else
        break;
    }
}

function webGLStart() {
    var canvasArray = document.getElementsByClassName("webGLcanvas");
    for (var index = 0; index < canvasArray.length; ++index) {
        initWebGlContext();
        specific(canvasArray[index].innerHTML);
    }
}

</script>
</head>

<body onload="webGLStart();">
    <canvas class="webGLcanvas">front</canvas>
    <canvas class="webGLcanvas">side</canvas>
</body>

Здесь вы можете найти рабочий пример .

Как объяснялось ранее (Toji и Chris Broadfoot), вам нужно иметь в виду, что вы не можете делиться ресурсами между контекстами WebGL.

edit: код теперь доступен на github.