Предупреждение WebGL: drawArraysInstanced: TEXTURE_2D в блоке 0 является неполным: размеры `level_base` не являются положительными - PullRequest
0 голосов
/ 26 апреля 2020

Я пытаюсь использовать текстуру на webgl.

код для импорта этого изображения:

var image = new Image();  // Create the image object
image.onload = loadTexture(gl, n, texture, u_Sampler, image);
image.crossOrigin = "";
image.src = 'beacon.png';

function loadTexture(gl, n, texture, u_Sampler, image) {
  gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1); // Flip the image's y axis
  gl.activeTexture(gl.TEXTURE0);
  gl.bindTexture(gl.TEXTURE_2D, texture);
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, image);
  gl.uniform1i(u_Sampler, 0);
  gl.clear(gl.COLOR_BUFFER_BIT);   // Clear <canvas>
  gl.drawArrays(gl.TRIANGLE_STRIP, 0, n); // Draw the rectangle
}

включая строку image.crossOrigin = "" останавливает ошибку CORS от отображается в firefox (но не в chrome?), но firefox выдает три других предупреждения, когда страница пытается загрузить:

unreachable code after return statement

^ это происходит, даже когда все операторы return удаляются из программа.

Exceeded 16 live WebGL contexts for this principal, losing the least recently used one.

и

WebGL warning: drawArraysInstanced: TEXTURE_2D at unit 0 is incomplete: The dimensions of `level_base` are not all positive.

текстура не загружается, холст выглядит как черный квадрат

1 Ответ

0 голосов
/ 27 апреля 2020

Обычно вам нужно запустить сервер для изображений в WebGL .

Если ваше изображение находится в том же домене, то вам следует , а не установить crossDomain. Если он находится в другом домене, то вам следует, хотя серверу все еще нужно дать разрешение на использование изображения. См. this

В противном случае есть несколько проблем с кодом

  1. На самом деле это не установка обратного вызова при загрузке изображения

    эта строка

    image.onload = loadTexture(gl, n, texture, u_Sampler, image);
    

    функционально эквивалентна

    const result = loadTexture(gl, n, texture, u_Sampler, image);
    image.onload = result;
    

    Строка должна выглядеть примерно так, чтобы loadTexture вызывался после загрузки изображения, а не до

    image.onload = () => loadTexture(gl, n, texture, u_Sampler, image);
    
  2. Возможно, вам потребуется установить обтекание на CLAMP_TO_EDGE

    // these two lines needed in WebGL1 but not WebGL2 if the image is not
    // power of 2 in both dimension
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
    

    В вашем заголовке предлагается использовать WebGL2, указав drawAraysInstanced, но опубликованный вами код не использует его, и вы не пометить

const vs = `
void main() {
  gl_Position = vec4(0, 0, 0, 1);
  gl_PointSize = 100.0;
}
`;

const fs = `
precision mediump float;
uniform sampler2D u_Sampler;
void main() {
  gl_FragColor = texture2D(u_Sampler, gl_PointCoord.xy);
}
`;

const gl = document.querySelector('canvas').getContext('webgl');
const prg = twgl.createProgram(gl, [vs, fs]);
const u_Sampler = gl.getUniformLocation(prg, 'u_Sampler');

gl.useProgram(prg);

const texture = gl.createTexture();
const n = 4;

var image = new Image();  // Create the image object
image.onload = () => loadTexture(gl, n, texture, u_Sampler, image);
image.crossOrigin = "";
image.src = 'https://i.imgur.com/ZKMnXce.png';

function loadTexture(gl, n, texture, u_Sampler, image) {
  gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1); // Flip the image's y axis
  gl.activeTexture(gl.TEXTURE0);
  gl.bindTexture(gl.TEXTURE_2D, texture);
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
// these two lines needed in WebGL1 but not WebGL2
// if the image is not power-of-2 in both dimensions
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
  gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, image);
  gl.uniform1i(u_Sampler, 0);
  gl.clear(gl.COLOR_BUFFER_BIT);   // Clear <canvas>
  //gl.drawArrays(gl.TRIANGLE_STRIP, 0, n); // Draw the rectangle
  gl.drawArrays(gl.POINTS, 0, 1);
}
<script src="https://twgljs.org/dist/4.x/twgl.min.js"></script>
<canvas></canvas>

Что касается других предупреждений.

недоступный код после оператора возврата

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

function foo() {
  return;
  console.log('here');
}

сгенерирует это предупреждение

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

This возможно ошибка в Firefox, хотя, если код плохой (например, если он создает холсты и контексты в al oop), то для этого предупреждения есть несколько git случаев. В общем, перезагрузка страницы происходит 17 раз, как при веб-разработке. Надеюсь, Firefox исправит это, поэтому будет отображаться предупреждение только тогда, когда git.

...