2013-05-14 3 views
1

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

Он будет использоваться, указав вид и камеру, как этот упрощенный пример:

displayView('#myCanvas1', [0, 5, 2]); 

, который можно было бы назвать несколько раз, чтобы отобразить в нескольких полотнах:

displayView('#myFrontCanvas', [0, 5, 2]); 
displayView('#mySideCanvas', [5, 0, 2]); 

или можно было бы назвать несколько раз на то же холст, чтобы изменить вид:

displayView('#myCanvas', [0, 5, 2]); 
// later 
displayView('#myCanvas', [5, 0, 2]); 
// later 
displayView('.thisCanvasIsActuallyTheSameOneAgain', [5, 0, 0]); 

Каждый раз, когда он вызывается на новом холсте, ему нужно будет настроить буферы, шейдеры и т. Д. Но когда вызывается на ранее используемом холсте, он должен повторно использовать старые буферы и шейдеры. Я не думаю, что можно обмениваться ресурсами между контекстами, поэтому мне нужно дублировать & сами отслеживать их.

Моя мысль состоит в том, чтобы хранить все буферы, шейдеры и т. Д. В массиве каждый раз, когда он вызывается на холсте, а затем искать этот массив в последующих вызовах. Я не могу хранить объекты canvas в массиве, потому что это испортит сбор мусора, поэтому моя проблема XY: могу ли я проверить, принадлежит ли конкретный шейдер, программа или буфер к определенному контексту? Также я исхожу из того, что когда удаляется холст, шейдеры и буферы будут удалены , хотя они все еще упоминаются в массиве?

Как следует из названия, я также открыт для лучшего решения всей проблемы.

ответ

1

Как и в большинстве других объектов JavaScript, вы можете добавить свойство к самому объекту контекста, который будет зависеть до тех пор, пока это делает контекст. Пока вы не используете одно и то же имя, как кто-то другой, это будет работать нормально, поэтому используйте красивое уникальное имя.

Что-то вроде:

function initializeStorage(context) { 
    return { ... }; 
} 

function getStorage(context) { 
    if (!('_DavesLibraryPrivateStorage' in context)) { 
     context._DavesLibraryPrivateStorage = initializeStorage(context); 
    } 
    return context._DavesLibraryPrivateStorage; 
} 

context.useProgram(getStorage(context).program); 

Будущие версии JavaScript, скорее всего, сделать это возможно сделать это в чистом виде с помощью WeakMap (доступен сейчас в Firefox и Chrome за флагом!) Или частного символы, так что просто подумайте об этом временном kludge.

+0

На самом деле не знаю, почему я об этом не думал. Благодаря! – Dave

Смежные вопросы