2016-05-15 16 views
1

Ich versuche gerade, eine einfache Textur mit WebGL zu rendern. Dies ist im Grunde ein Port vom normalen System OpenGL. Es scheint nicht zu funktionieren und ich habe wirklich keine Ahnung, was falsch ist, da es auch sehr schwierig scheint, diese Sache zu debuggen.WebGL: Einfaches Textur-Rendering-Problem ("Zeichnen zu einem Ziel rect kleiner als das Darstellungsfeld rect.")

Ich erhalte eine Fehlermeldung auf Firefox aber: „Fehler: WebGL: drawElements: Zeichnung zu einem Ziel rect kleiner als die Darstellungs rect (Diese Warnung wird nur einmal gegeben werden).“

Das Ansichtsfenster/Projektion Matrix/Positionen scheinen korrekt zu sein, warum bekomme ich diesen Fehler?

<!DOCTYPE html> 
<html> 
<head> 
    <meta charset="utf-8"> 
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 
    <title>Test</title> 
    <style> 
    .canstyle { 
    width: 800px; 
    height: 600px; 
    } 
    </style> 
</head> 
<body> 
    <canvas id="canvas0" class="canstyle"> 
    </canvas> 
    <script type='text/javascript'> 
    var vertexShaderSrc = ` 
      precision mediump float; 

      attribute vec2 aVertexPosition; 
      attribute vec2 aTextureCoord; 

      uniform mat3 projectionMatrix; 

      varying vec2 vTextureCoord; 

      void main() { 
       gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); 
       vTextureCoord = aTextureCoord; 
      } 
    `; 

    var fragmentShaderSrc = ` 

      precision mediump float; 

      varying vec2 vTextureCoord; 

      uniform sampler2D uSampler; 

      void main() { 
      gl_FragColor = texture2D(uSampler, vTextureCoord); 
      } 
    `; 

    var img1 = new Image(); // HTML5 Constructor 
    img1.src = 'bunny.png'; 
    img1.alt = 'alt'; 
    img1.onload = function() { 
    render(); 
    } 

    function render() { 
    var canvas = document.getElementById("canvas0"); 
    var gl = canvas.getContext("webgl", { 
     alpha: false, 
     depth: false, 
     stencil: true, 
     premultipliedAlpha: false 
    }); 

    var funcs = Object.getOwnPropertyNames(gl.__proto__).filter(function(p) { 
     return typeof gl[p] === 'function'; 
    }); 

    function HookFunction(func, callback) { 
     return function() { 
     var res = func.apply(this, arguments); 
     callback(arguments); 
     return res; 
     }; 
    } 

    var endFrame = false; 
    var afterFrame = 8; 
    funcs.forEach(function(funcName) { 
     gl[funcName] = HookFunction(gl[funcName], function(args) { 
     if (endFrame) { 
      if (afterFrame == 0) { 
      return; 
      } 
      afterFrame -= 1; 
     } 
     if (funcName == "drawElements") { 
      endFrame = true; 
     } 
     var KK = []; 
     var dumpArr = []; 
     for (var item in args) { 
      var arg = args[item]; 
      if (arg === null) { 
      KK.push("null"); 
      } else if (arg instanceof ArrayBuffer || arg instanceof Float32Array || arg instanceof Uint8Array || arg instanceof Uint16Array) { 
      dumpArr.push(new Uint8Array(arg.buffer)); 
      } else { 
      KK.push(arg); 
      } 
     } 
     console.log("WebGL Interceptor: ", funcName, "(", KK.join(', '), ")"); 
     if (dumpArr.length) { 
      console.log(dumpArr); 
     } 

     }); 
    }); 

    gl.disable(gl.DEPTH_TEST); 
    gl.disable(gl.CULL_FACE); 
    gl.disable(gl.STENCIL_TEST); 
    gl.enable(gl.BLEND); 
    gl.enable(gl.SCISSOR_TEST); 

    gl.bindFramebuffer(gl.FRAMEBUFFER, null); 

    gl.viewport(0, 0, 800, 600); 
    gl.scissor(0, 0, 800, 600); 

    gl.clearColor(0.06274509803921569, 0.6, 0.7333333333333333, 1); 
    gl.clear(gl.COLOR_BUFFER_BIT); 

    var vertexDataCount = 4; 
    var vertexByteSize = vertexDataCount * 4; 
    var BatchSize = 2000; 

    var totalIndices = BatchSize * 6; 

    var vertices = new ArrayBuffer(BatchSize * vertexByteSize * 4); 
    var indices = new ArrayBuffer(totalIndices * 2); 

    var indicesUint16View = new Uint16Array(indices); 
    var verticesFloat32View = new Float32Array(vertices); 

    var j = 0; 
    for (var i = 0; i < totalIndices; i += 6, j += 4) { 
     indicesUint16View[i + 0] = j + 0; 
     indicesUint16View[i + 1] = j + 1; 
     indicesUint16View[i + 2] = j + 2; 
     indicesUint16View[i + 3] = j + 0; 
     indicesUint16View[i + 4] = j + 2; 
     indicesUint16View[i + 5] = j + 3; 
    } 

    var indexBuffer = gl.createBuffer(); 
    var vertexBuffer = gl.createBuffer(); 

    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer); 
    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indicesUint16View, gl.STATIC_DRAW); 

    gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer); 
    gl.bufferData(gl.ARRAY_BUFFER, verticesFloat32View, gl.DYNAMIC_DRAW); 

    function compileShader(shaderSource, shaderType) { 
     var shader = gl.createShader(shaderType); 
     gl.shaderSource(shader, shaderSource); 
     gl.compileShader(shader); 
     var success = gl.getShaderParameter(shader, gl.COMPILE_STATUS); 
     if (!success) { 
     throw "could not compile shader:" + gl.getShaderInfoLog(shader); 
     } 
     return shader; 
    } 

    function createProgram(vertexShader, fragmentShader) { 
     var program = gl.createProgram(); 
     gl.attachShader(program, vertexShader); 
     gl.attachShader(program, fragmentShader); 
     gl.linkProgram(program); 
     var success = gl.getProgramParameter(program, gl.LINK_STATUS); 
     if (!success) { 
     throw ("program filed to link:" + gl.getProgramInfoLog(program)); 
     } 
     return program; 
    } 

    var vertexShad = compileShader(vertexShaderSrc, gl.VERTEX_SHADER); 
    var fragShad = compileShader(fragmentShaderSrc, gl.FRAGMENT_SHADER); 

    var shaderProg = createProgram(vertexShad, fragShad); 
    gl.useProgram(shaderProg); 

    var vertLoc = gl.getAttribLocation(shaderProg, "aVertexPosition"); 
    var texCoordLoc = gl.getAttribLocation(shaderProg, "aTextureCoord"); 

    gl.enableVertexAttribArray(vertLoc); 
    gl.enableVertexAttribArray(texCoordLoc); 

    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer); 
    gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer); 

    gl.vertexAttribPointer(vertLoc, 2, gl.FLOAT, false, vertexByteSize, 0); 
    gl.vertexAttribPointer(texCoordLoc, 2, gl.FLOAT, false, vertexByteSize, 2 * 4); 


    var currIndex = 0; 
    verticesFloat32View[currIndex++] = 174; // pos 
    verticesFloat32View[currIndex++] = 113; // pos 
    verticesFloat32View[currIndex++] = 0; // UV 
    verticesFloat32View[currIndex++] = 0; // UV 

    verticesFloat32View[currIndex++] = 226; // pos 
    verticesFloat32View[currIndex++] = 113; // pos 
    verticesFloat32View[currIndex++] = 1; // UV 
    verticesFloat32View[currIndex++] = 0; // UV 

    verticesFloat32View[currIndex++] = 226; // pos 
    verticesFloat32View[currIndex++] = 187; // pos 
    verticesFloat32View[currIndex++] = 1; // UV 
    verticesFloat32View[currIndex++] = 1; // UV 

    verticesFloat32View[currIndex++] = 174; // pos 
    verticesFloat32View[currIndex++] = 187; // pos 
    verticesFloat32View[currIndex++] = 0; // UV 
    verticesFloat32View[currIndex++] = 1; // UV 

    gl.bufferSubData(gl.ARRAY_BUFFER, 0, verticesFloat32View); 

    // | 2/Width | 0   | -1 
    // | 0   | 2/Height | -1 
    // | 0   | 0   | 1 
    var rawProjectionMat = new Float32Array([ 
     0.00249999994, 0, 0, 0, -0.00333333341, 0, -1, 1, 1 
    ]); 

    gl.uniformMatrix3fv(gl.getUniformLocation(shaderProg, "projectionMatrix"), false, rawProjectionMat); 

    gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); 
    gl.activeTexture(gl.TEXTURE0); 

    var texture = gl.createTexture(); 
    gl.bindTexture(gl.TEXTURE_2D, texture); 

    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.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); 
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); 

    gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true); 
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img1); 

    gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0); 

    } 
    </script> 
</body> 
</html> 

EDIT: ich folgendes Bild verwende: https://raw.githubusercontent.com/pixijs/examples/gh-pages/_assets/bunny.png

+0

https://stackoverflow.com/questions/13441843/webgl-everything-is-blurry-despite-using-same-code – lled

Antwort

2

Ich bin nur das Problem zu erraten nicht, wo haben Sie die Größe Ihres Canvas-Element Inhalt eingestellt.

Die Anzahl der tatsächlichen Pixel im Canvas-Element beträgt standardmäßig 300x150. Sie können mit

<canvas width="800" height="600"></canvas> 

dass in HTML gesetzt oder Sie es in JavaScript mit

someCanvasElement.width = 800; 
someCanvasElement.height = 600; 

Firefox kann eingestellt werden, warnt, dass Sie das Ansichtsfenster auf 800x600 eingestellt, aber es ist größer als Ihre Leinwand (300x150), die ist sehr ungewöhnlich und die Warnung sollte Ihnen helfen, das Problem zu bemerken.

FYI: gl.viewport macht nur 2 Dinge. Sie legt die Konvertierung vom Clip-Bereich zum Bildschirmbereich (oder in diesem Fall zum Canvas-Bereich) fest und legt den Clipping-Bereich für Vertices fest. "Clipping-Scheitelpunkte" bedeutet, dass Pixel nicht abgeschnitten werden, sodass das Zeichnen eines gl_PointSize = 10.0 Punktes am Rand der Viewport-Einstellung außerhalb der Viewport-Einstellung erfolgt.

Verwenden Sie zum Scheren von Pixeln den Scheren-Test. Ich sehe, dass Sie einen Scheren-Test durchführen, aber da Sie anscheinend an den Rand der Leinwand zeichnen möchten, müssen Sie die Schere überhaupt nicht einrichten.

+0

Was passiert, wenn ich mehrere Leinwand auf einer Seite habe und jeder nur ein Abschnitt ist, wie kann ich repariere das dann? – majidarif

+1

Mehrere Leinwände ist wahrscheinlich keine gute Idee. Der Browser begrenzt die Anzahl, die Sie haben können, und Sie können keine Ressourcen (Texturen, Puffer) über alle Leinwände hinweg teilen. Stattdessen [http://stackoverflow.com/questions/30608723/is-it-possible-to-enable-unbounded-number-of-renderer-in-three-js/30633132#30633132] oder ähnlich [ dies] (http://twgljs.org/examples/itemlist.html) – gman

+0

der 2. Link sollte gut für meine Verwendung funktionieren, weil jede Leinwand tatsächlich eine Tabellenzelle für mich ist. – majidarif