2014-03-12 3 views
4

Я создаю свою первую игру (карточную игру) с THREE.js для Firefox и Chrome, и в настоящее время я застрял в прерывистой ошибке, которая делает некоторые из моих текстур невидимыми.Reusing Geometry вызывает прерывистую ошибку текстуры THREE.JS

Мой объект с этим сообщением - понять, почему это происходит, поэтому я могу работать над решением. Я буду добавлять свои вопросы в конце сообщения.

Это случается с большей частотой, когда я переключаю вкладки браузера перед загрузкой сцены.

Я уже проверил свой код, чтобы проверить, устанавливал ли новые материалы уже загруженные сетки в сцене, и это было не так.

Я использую зеркальные карты с карточками из фольги, и я безуспешно пытался найти соответствующие решения в Stack Overflow. Я также попытался удалить зеркальные карты.

Я также читал об установке флагов обновления для материалов, добавляемых после того, как объект находится в сцене, и он тоже не работает.

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

Ошибка:

256 [.WebGLRenderingContext]GL ERROR :GL_INVALID_OPERATION : glDrawElements: attempt to access out of range vertices in attribute 0 
WebGL: too many errors, no more errors will be reported to the console for this context. 

Объектные карты шаги создания: 1 - Создание базовой геометрии на нагрузке игры 2 - Повторное использование его для всех создаваемых

Base Создание геометрии карты (манипуляция вершина/лицо, чтобы создать черно-серо-черный градиент для границ с VertexColors: THREE.VertexColors):

(function createGeometry() { 
DBZCCG.Card.backTexture = THREE.ImageUtils.loadTexture(
    "images/DBZCCG/back.jpg"); 

DBZCCG.Card.cubeGeo = 
    new THREE.CubeGeometry(
     DBZCCG.Card.cardWidth, 
     DBZCCG.Card.cardHeight, 
     DBZCCG.Card.cardDepth 
    ); 

/* Vertex and face alterations */ 
var cube = DBZCCG.Card.cubeGeo; 
var vertices = cube.vertices; 
var faces = cube.faces; 

vertices.push(vertices[7].clone()); 
vertices.push(vertices[5].clone()); 
vertices.push(vertices[0].clone()); 
vertices.push(vertices[2].clone()); 

vertices[5].color = vertices[0].color = vertices[2].color = vertices[7].color 
     = new THREE.Color(0x777777); 

vertices[5].z = vertices[0].z = vertices[2].z = vertices[7].z = 0; 

faces[8].a = 9; 
faces[8].b = 8; 
faces[8].c = 10; 

faces[9].a = 8; 
faces[9].b = 11; 
faces[9].c = 10; 

faces.push(new THREE.Face3(9, 5, 7)); 
faces.push(new THREE.Face3(9, 7, 8)); 

faces.push(new THREE.Face3(0, 10, 2)); 
faces.push(new THREE.Face3(10, 11, 2)); 

faces.push(new THREE.Face3(8, 7, 2)); 
faces.push(new THREE.Face3(8, 2, 11)); 

faces.push(new THREE.Face3(5, 9, 0)); 
faces.push(new THREE.Face3(0, 9, 10)); 

for (var i = 0; i < faces.length; i++) { 
    if (vertices[faces[i].a].color === undefined) { 
     faces[i].vertexColors[0] = new THREE.Color(0x000000); 
    } else { 
     faces[i].vertexColors[0] = vertices[faces[i].a].color; 
    } 

    if (vertices[faces[i].b].color === undefined) { 
     faces[i].vertexColors[1] = new THREE.Color(0x000000); 
    } else { 
     faces[i].vertexColors[1] = vertices[faces[i].b].color; 
    } 

    if (vertices[faces[i].c].color === undefined) { 
     faces[i].vertexColors[2] = new THREE.Color(0x000000); 
    } else { 
     faces[i].vertexColors[2] = vertices[faces[i].c].color; 
    } 
} 

})(); 

А вот функция для создания карты:

function createCard(texturePath) { 
     var card = new THREE.Object3D(); 
     DBZCCG.loadCounter++; 
     var frontTexture = texturePath ? 
      THREE.ImageUtils.loadTexture(texturePath, 
      THREE.UVMapping, 
      DBZCCG.incrementLoad) 
      : null; 
     DBZCCG.loadCounter++; 
     var specularMap = 
      THREE.ImageUtils.loadTexture(
       'images/DBZCCG/saiyan/specularmap.jpg', 
       THREE.UVMapping, DBZCCG.incrementLoad); 

     var cardCoverBackMaterials = []; 
     for (var i = 0; i < 4; i++) { 
      cardCoverBackMaterials.push(new THREE.MeshBasicMaterial(
        { 
         transparent: true, 
         emissive: 0xFFFFFF, 
         vertexColors: THREE.VertexColors 
        })); // sides 
     } 

     cardCoverBackMaterials[4] = new THREE.MeshBasicMaterial(
       { 
        transparent: true, 
        emissive: 0xFFFFFF, 
        map: DBZCCG.Card.backTexture 
       }); // back 

     cardCoverBackMaterials[5] = new THREE.MeshBasicMaterial(
      { 
       transparent: true, 
       reflectivity: dataObject.foil ? 
        dataObject.foil.reflectivity : 1, 
       specularMap: specularMap, 
       envMap: dataObject.foil ? dataObject.foil.texture : null, 
       emissive: 0xFFFFFF, 
       map: frontTexture 
      }); // front 

     for (var i = 0; i < 4; i++) { 
      cardCoverBackMaterials.push(
       new THREE.MeshBasicMaterial({ 
        transparent: true, 
        emissive: 0xFFFFFF 
      })); // sides 
     } 

     var cube = new THREE.Mesh(
      DBZCCG.Card.cubeGeo, 
      new THREE.MeshFaceMaterial(cardCoverBackMaterials)); 

     card.add(cube); 

     return card; 
    } 

Вопросы:

1 - Есть ли что-нибудь, что я могу сделать, чтобы попытаться решить эту проблему?

2 - Связано ли это с изображением сцены перед тем, как объекты были добавлены в сцену?

3 - Связано ли это с изображением сцены перед загрузкой текстур?

4 - Для Q2 и Q3 я попытался добавить проверку нагрузки с интервалами окна. Время от времени я получаю ошибку.

5 - Есть ли возможность поймать ошибку webgl и отобразить все снова? Это хороший вариант?

TL/DR; В моем коде произошла прерывистая ошибка WebGL при загрузке. Я использую THREE.js.

Спасибо

three.js R66

EDIT: Я добавляю два скриншота, один с ошибкой и один со всем нормальным.

Error

One reload later, everything is normal


EDIT Устранив:

В основном я использовал ту же геометрию для всех объектов карты на сцене.

Я только что изменил:

var cube = new THREE.Mesh(DBZCCG.Card.cubeGeo, 
new THREE.MeshFaceMaterial(cardCoverBackMaterials)); 

В:

var cube = new THREE.Mesh(DBZCCG.Card.cubeGeo.clone(), 
new THREE.MeshFaceMaterial(cardCoverBackMaterials)); 

Я не должен быть повторно использовать ту же геометрию?

Я до сих пор не понимаю, почему это заставило ошибку уйти, и мне хотелось бы объяснить, почему она решила ошибку (и, возможно, почему она ее вызывала).

Когда я сделал 50-строчный код, пытающийся воспроизвести ошибку, я повторно использовал геометрию, и ошибка так и не произошла. Я также использовал ту же функцию для создания объекта, который вызвал проблемы.

+0

Можете ли вы создать программу на 50 строк, которая демонстрирует проблему? – WestLangley

+0

Я создал программу на 50 строк, выполнив те же самые шаги, которые я выделил в своем вопросе, но 50-строчная программа вообще не создала ошибку. Я мог бы предоставить скриншоты, показывающие вывод рабочей версии и когда произойдет ошибка. Однако, если это превращается в «help-me-debug-my-program», я понимаю, что на меня ничего не может ответить, и я удалю свой вопрос. – hawaii

+0

Буду рад помочь вам, если смогу. Попробуйте воспроизвести проблему с помощью простого примера. Вы добавляете текстуру во время выполнения, когда раньше не было текстуры? – WestLangley

ответ

2

Я бы попытался использовать обратные вызовы с событием onLoad, чтобы контролировать время и выполнение вашего кода. Например изменить

DBZCCG.Card.backTexture = THREE.ImageUtils.loadTexture(
    "images/DBZCCG/back.jpg"); 

в

DBZCCG.Card.backTexture = THREE.ImageUtils.loadTexture(
    "images/DBZCCG/back.jpg", new THREE.UVMapping(), function() { ... }); 

Используйте функции обратного вызова, чтобы обеспечить загрузку завершен до перехода.

Эй, извините за задержку, я немного не зашел в стек. Я думаю, здесь проблема в том, что вы пытались применить несколько текстур к одной и той же геометрии. Я бы подумал, что они должны просто перегнать друг друга, но я думаю, нет. Клонирование геометрии позволило применить каждую текстуру к собственному объекту. Или, по крайней мере, это мое занятие.

+0

Уже изменил это. Я добавил обратный вызов onLoad, который подсчитывает текстуры, которые я пытаюсь добавить в игру, и у меня есть window.interval, прежде чем проверять, достигнуто ли ожидаемое количество текстур. Только после этого я продвигаюсь, чтобы сделать игру. Кроме того, я добавил вызов console.log в обратном вызове onError. Ничего лишнего не появилось в консоли с функцией onError при возникновении ошибки. Сейчас я пытаюсь изменить код. Я перестраиваю сцену с нуля, и она не обнаружила никаких ошибок. Попытка снять сцену со всех элементов, кроме ошибок, сопровождаемых ошибками. – hawaii

+0

Ошибка сохраняется. Мои попытки решить это были минимизация css и js, а также кэширование текстур вместо создания новых. – hawaii

+0

Я смог решить эту проблему, но теперь мне нужно понять, почему это произошло. – hawaii

1

Я сделал то, что сделало ошибку, которая никогда не повторится.

Я редактирую свой вопрос, так как я хочу понять, почему это произошло.

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