2017-11-07 5 views
1

Ich bin auf Webglfundamentals Blog-Serie und Lernanimationen. Basierend auf meinem Verständnis, versuche ich this auf eine etwas andere Art zu replizieren, so dass ich keine Abhängigkeit von den Util-Dateien der Blog-Serie habe. Ich bin dieser Fehler nicht in der Lage zu beheben:"Kann Property 'Projektion' von undefined nicht lesen: webgl Fehler in meinem ersten 3D-Geometrie-Programm

Cannot read property 'projection' of undefined 
    at createVertices. 

var gl, 
 
    shaderProgram, 
 
    vertices; 
 

 
initGL(); 
 
createShaders(); 
 
createVertices(); 
 

 
function initGL() { 
 
    var canvas = document.getElementById("canvas"); 
 
    console.log(canvas); 
 
    gl = canvas.getContext("webgl"); 
 
    gl.viewport(0, 0, canvas.width, canvas.height); 
 
    gl.clearColor(1, 1, 1, 1); 
 
} 
 

 
function createShaders() { 
 
    var vertexShader = getShader(gl, "3d-vertex-shader"); 
 
    var fragmentShader = getShader(gl, "3d-fragment-shader"); 
 
    
 
    shaderProgram = gl.createProgram(); 
 
    gl.attachShader(shaderProgram, vertexShader); 
 
    gl.attachShader(shaderProgram, fragmentShader); 
 
    gl.linkProgram(shaderProgram); 
 

 
} 
 

 
function createVertices() { 
 
    vertices = [ 
 
    // left column 
 
      0, 0, 0, 
 
      30, 0, 0, 
 
      0, 150, 0, 
 
      0, 150, 0, 
 
      30, 0, 0, 
 
      30, 150, 0, 
 
    
 
      // top rung 
 
      30, 0, 0, 
 
      100, 0, 0, 
 
      30, 30, 0, 
 
      30, 30, 0, 
 
      100, 0, 0, 
 
      100, 30, 0, 
 
    
 
      // middle rung 
 
      30, 60, 0, 
 
      67, 60, 0, 
 
      30, 90, 0, 
 
      30, 90, 0, 
 
      67, 60, 0, 
 
      67, 90, 0 
 
    ]; 
 
    
 

 
    
 
    //create buffer 
 
    var buffer = gl.createBuffer(); 
 
    gl.bindBuffer(gl.ARRAY_BUFFER, buffer); 
 
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); 
 
    
 
    
 
    function radToDeg(r) { 
 
    return r * 180/Math.PI; 
 
    } 
 

 
    function degToRad(d) { 
 
    return d * Math.PI/180; 
 
    } 
 

 
    var translation = [45, 150, 0]; 
 
    var rotation = [degToRad(40), degToRad(25), degToRad(325)]; 
 
    var scale = [1, 1, 1]; 
 
    var color = [Math.random(), Math.random(), Math.random(), 1]; 
 
    
 
    
 
    
 
    // look up where the vertex data needs to go. 
 
    var positionLocation = gl.getAttribLocation(shaderProgram, "a_position"); 
 

 
    // lookup uniforms 
 
    var colorLocation = gl.getUniformLocation(shaderProgram, "u_color"); 
 
    var matrixLocation = gl.getUniformLocation(shaderProgram, "u_matrix"); 
 
    
 
    
 
    // webglUtils.resizeCanvasToDisplaySize(gl.canvas); 
 

 
    // Tell it to use our program (pair of shaders) 
 
    gl.useProgram(shaderProgram); 
 

 
    // Turn on the attribute 
 
    gl.enableVertexAttribArray(positionLocation); 
 
    
 
    // Create a buffer to put positions in 
 
    var positionBuffer = gl.createBuffer(); 
 
    // Bind it to ARRAY_BUFFER (think of it as ARRAY_BUFFER = positionBuffer) 
 
    gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer); 
 

 
    // Tell the attribute how to get data out of positionBuffer (ARRAY_BUFFER) 
 
    var size = 3;   // 3 components per iteration 
 
    var type = gl.FLOAT; // the data is 32bit floats 
 
    var normalize = false; // don't normalize the data 
 
    var stride = 0;  // 0 = move forward size * sizeof(type) each iteration to get the next position 
 
    var offset = 0;  // start at the beginning of the buffer 
 
    gl.vertexAttribPointer(
 
     positionLocation, size, type, normalize, stride, offset) 
 

 
    // set the color 
 
    gl.uniform4fv(colorLocation, color); 
 

 
    // Compute the matrices 
 
    var matrix = m4.projection(gl.canvas.clientWidth, gl.canvas.clientHeight, 400); 
 
    matrix = m4.translate(matrix, translation[0], translation[1], translation[2]); 
 
    matrix = m4.xRotate(matrix, rotation[0]); 
 
    matrix = m4.yRotate(matrix, rotation[1]); 
 
    matrix = m4.zRotate(matrix, rotation[2]); 
 
    matrix = m4.scale(matrix, scale[0], scale[1], scale[2]); 
 

 
    // Set the matrix. 
 
    gl.uniformMatrix4fv(matrixLocation, false, matrix); 
 

 
    // Draw the geometry. 
 
    var primitiveType = gl.TRIANGLES; 
 
    var offset = 0; 
 
    var count = 18; // 6 triangles in the 'F', 3 points per triangle 
 
    gl.drawArrays(primitiveType, offset, count); 
 
} 
 

 
//m4 
 
var m4 = { 
 

 
    projection: function(width, height, depth) { 
 
    // Note: This matrix flips the Y axis so 0 is at the top. 
 
    return [ 
 
     2/width, 0, 0, 0, 
 
     0, -2/height, 0, 0, 
 
     0, 0, 2/depth, 0, 
 
     -1, 1, 0, 1, 
 
    ]; 
 
    }, 
 

 
    multiply: function(a, b) { 
 
    var a00 = a[0 * 4 + 0]; 
 
    var a01 = a[0 * 4 + 1]; 
 
    var a02 = a[0 * 4 + 2]; 
 
    var a03 = a[0 * 4 + 3]; 
 
    var a10 = a[1 * 4 + 0]; 
 
    var a11 = a[1 * 4 + 1]; 
 
    var a12 = a[1 * 4 + 2]; 
 
    var a13 = a[1 * 4 + 3]; 
 
    var a20 = a[2 * 4 + 0]; 
 
    var a21 = a[2 * 4 + 1]; 
 
    var a22 = a[2 * 4 + 2]; 
 
    var a23 = a[2 * 4 + 3]; 
 
    var a30 = a[3 * 4 + 0]; 
 
    var a31 = a[3 * 4 + 1]; 
 
    var a32 = a[3 * 4 + 2]; 
 
    var a33 = a[3 * 4 + 3]; 
 
    var b00 = b[0 * 4 + 0]; 
 
    var b01 = b[0 * 4 + 1]; 
 
    var b02 = b[0 * 4 + 2]; 
 
    var b03 = b[0 * 4 + 3]; 
 
    var b10 = b[1 * 4 + 0]; 
 
    var b11 = b[1 * 4 + 1]; 
 
    var b12 = b[1 * 4 + 2]; 
 
    var b13 = b[1 * 4 + 3]; 
 
    var b20 = b[2 * 4 + 0]; 
 
    var b21 = b[2 * 4 + 1]; 
 
    var b22 = b[2 * 4 + 2]; 
 
    var b23 = b[2 * 4 + 3]; 
 
    var b30 = b[3 * 4 + 0]; 
 
    var b31 = b[3 * 4 + 1]; 
 
    var b32 = b[3 * 4 + 2]; 
 
    var b33 = b[3 * 4 + 3]; 
 
    return [ 
 
     b00 * a00 + b01 * a10 + b02 * a20 + b03 * a30, 
 
     b00 * a01 + b01 * a11 + b02 * a21 + b03 * a31, 
 
     b00 * a02 + b01 * a12 + b02 * a22 + b03 * a32, 
 
     b00 * a03 + b01 * a13 + b02 * a23 + b03 * a33, 
 
     b10 * a00 + b11 * a10 + b12 * a20 + b13 * a30, 
 
     b10 * a01 + b11 * a11 + b12 * a21 + b13 * a31, 
 
     b10 * a02 + b11 * a12 + b12 * a22 + b13 * a32, 
 
     b10 * a03 + b11 * a13 + b12 * a23 + b13 * a33, 
 
     b20 * a00 + b21 * a10 + b22 * a20 + b23 * a30, 
 
     b20 * a01 + b21 * a11 + b22 * a21 + b23 * a31, 
 
     b20 * a02 + b21 * a12 + b22 * a22 + b23 * a32, 
 
     b20 * a03 + b21 * a13 + b22 * a23 + b23 * a33, 
 
     b30 * a00 + b31 * a10 + b32 * a20 + b33 * a30, 
 
     b30 * a01 + b31 * a11 + b32 * a21 + b33 * a31, 
 
     b30 * a02 + b31 * a12 + b32 * a22 + b33 * a32, 
 
     b30 * a03 + b31 * a13 + b32 * a23 + b33 * a33, 
 
    ]; 
 
    }, 
 

 
    translation: function(tx, ty, tz) { 
 
    return [ 
 
     1, 0, 0, 0, 
 
     0, 1, 0, 0, 
 
     0, 0, 1, 0, 
 
     tx, ty, tz, 1, 
 
    ]; 
 
    }, 
 

 
    xRotation: function(angleInRadians) { 
 
    var c = Math.cos(angleInRadians); 
 
    var s = Math.sin(angleInRadians); 
 

 
    return [ 
 
     1, 0, 0, 0, 
 
     0, c, s, 0, 
 
     0, -s, c, 0, 
 
     0, 0, 0, 1, 
 
    ]; 
 
    }, 
 

 
    yRotation: function(angleInRadians) { 
 
    var c = Math.cos(angleInRadians); 
 
    var s = Math.sin(angleInRadians); 
 

 
    return [ 
 
     c, 0, -s, 0, 
 
     0, 1, 0, 0, 
 
     s, 0, c, 0, 
 
     0, 0, 0, 1, 
 
    ]; 
 
    }, 
 

 
    zRotation: function(angleInRadians) { 
 
    var c = Math.cos(angleInRadians); 
 
    var s = Math.sin(angleInRadians); 
 

 
    return [ 
 
     c, s, 0, 0, 
 
     -s, c, 0, 0, 
 
     0, 0, 1, 0, 
 
     0, 0, 0, 1, 
 
    ]; 
 
    }, 
 

 
    scaling: function(sx, sy, sz) { 
 
    return [ 
 
     sx, 0, 0, 0, 
 
     0, sy, 0, 0, 
 
     0, 0, sz, 0, 
 
     0, 0, 0, 1, 
 
    ]; 
 
    }, 
 

 
    translate: function(m, tx, ty, tz) { 
 
    return m4.multiply(m, m4.translation(tx, ty, tz)); 
 
    }, 
 

 
    xRotate: function(m, angleInRadians) { 
 
    return m4.multiply(m, m4.xRotation(angleInRadians)); 
 
    }, 
 

 
    yRotate: function(m, angleInRadians) { 
 
    return m4.multiply(m, m4.yRotation(angleInRadians)); 
 
    }, 
 

 
    zRotate: function(m, angleInRadians) { 
 
    return m4.multiply(m, m4.zRotation(angleInRadians)); 
 
    }, 
 

 
    scale: function(m, sx, sy, sz) { 
 
    return m4.multiply(m, m4.scaling(sx, sy, sz)); 
 
    }, 
 

 
}; 
 
// m4 ends 
 

 

 
    /* 
 
    * https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Tutorial/Adding_2D_content_to_a_WebGL_context 
 
    */ 
 
    function getShader(gl, id) { 
 
    var shaderScript, theSource, currentChild, shader; 
 

 
    shaderScript = document.getElementById(id); 
 

 
    if (!shaderScript) { 
 
     return null; 
 
    } 
 

 
    theSource = ""; 
 
    currentChild = shaderScript.firstChild; 
 

 
    while (currentChild) { 
 
     if (currentChild.nodeType == currentChild.TEXT_NODE) { 
 
     theSource += currentChild.textContent; 
 
     } 
 

 
     currentChild = currentChild.nextSibling; 
 
    } 
 
    if (shaderScript.type == "x-shader/x-fragment") { 
 
     shader = gl.createShader(gl.FRAGMENT_SHADER); 
 
    } else if (shaderScript.type == "x-shader/x-vertex") { 
 
     shader = gl.createShader(gl.VERTEX_SHADER); 
 
    } else { 
 
     // Unknown shader type 
 
     return null; 
 
    } 
 
    gl.shaderSource(shader, theSource); 
 

 
// Compile the shader program 
 
    gl.compileShader(shader); 
 

 
// See if it compiled successfully 
 
    if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { 
 
     alert("An error occurred compiling the shaders: " + gl.getShaderInfoLog(shader)); 
 
     return null; 
 
    } 
 

 
    return shader; 
 
    }
<canvas id="canvas"></canvas> 
 

 

 
<!-- vertex shader --> 
 
<script id="3d-vertex-shader" type="x-shader/x-vertex"> 
 
attribute vec4 a_position; 
 

 
uniform mat4 u_matrix; 
 

 
void main() { 
 
    // Multiply the position by the matrix. 
 
    gl_Position = u_matrix * a_position; 
 
} 
 
</script> 
 
<!-- fragment shader --> 
 
<script id="3d-fragment-shader" type="x-shader/x-fragment"> 
 
precision mediump float; 
 

 
uniform vec4 u_color; 
 

 
void main() { 
 
    gl_FragColor = u_color; 
 
} 
 
</script> 
 
<!-- 
 
for most samples webgl-utils only provides shader compiling/linking and 
 
canvas resizing because why clutter the examples with code that's the same in every sample. 
 
See http://webglfundamentals.org/webgl/lessons/webgl-boilerplate.html 
 
and http://webglfundamentals.org/webgl/lessons/webgl-resizing-the-canvas.html 
 
for webgl-utils, m3, m4, and webgl-lessons-ui. 
 
--> 
 
<script src="https://webglfundamentals.org/webgl/resources/webgl-utils.js"></script> 
 
<script src="https://webglfundamentals.org/webgl/resources/webgl-lessons-ui.js"></script> 
 
<script src="https://webglfundamentals.org/webgl/resources/webgl-lessons-helper.js"></script>

Meine Version des Stiftes ist here.

Es wäre toll, wenn mir jemand diesen Fehler beheben helfen könnte.

+1

Der Code, den Sie oben nicht den Fehler, den Sie – gman

+0

@gman erwähnt bekommen hat geschrieben in Ordnung ich über ein paar Dinge verwirrt bin hier. der Code-Link hat genau den Code wie oben eingefügt - aber ich sehe diesen Fehler in der Konsole, während er hier ausgeführt wird. Ich habe Hilfe beim Identifizieren meines Codepenfehlers bekommen - ich habe Puffer zweimal definiert, der beim Entfernen den Code ausführt. Mein zweiter Zweifel ist, warum wird das Ansichtsfenster abgeschnitten? Ich habe die gleiche Logik wie das Tutorial verwendet - also sollte der Kontext der gleiche sein? – novembersky

+1

Der Code ist auf Ihrem Codepen nicht identisch. Sie haben mehr Code, den Sie oben hinzugefügt haben. Es ist nicht klar, auf welches Tutorial Sie verweisen. Der Link in Ihrer Frage führt zu einem leeren Codepen. Sie müssen wahrscheinlich auf "Speichern" klicken. Angenommen, es war [dieses Beispiel] (https://codepen.io/anon/pen/vWyGZp), dann sind einige andere Unterschiede zu Ihrem Beispiel, dass Sie das CSS nicht einbezogen haben und die Funktion 'webglUtils.resizeCanvasToDisplaySize (gl.canvas); 'das ist [hier beschrieben] (https://webglfundamentals.org/webgl/lessons/webgl-resizing-the-canvas.html), wenn Sie Ihre eigenen schreiben möchten. – gman

Antwort

0

Die Fehlermeldung

Cannot read property 'projection' of undefined at createVertices.

bedeutet, dass projection nicht definiert ist, wenn Sie versuchen, es zu benutzen. Dies liegt daran, dass m4.projection später im Skript definiert wird.

Um dieses Problem zu lösen, sollten Sie die Deklarationen am Anfang des Skripts und die Funktionsaufrufe am Ende tun.
Bewegen Sie den folgenden Code an dem sehr und des Skripts:

initGL(); 
createShaders(); 
createVertices(); 


Wenn Sie dies tun, werden Sie den nächsten Fehler:

GL ERROR :GL_INVALID_OPERATION : glDrawArrays: attempt to access out of range vertices in attribute 0

Dies liegt daran, wenn Sie

nennen
gl.drawArrays(primitiveType, offset, count); 

die derzeit boud ARRAY_BUFFER ist positionBuffer, die leer ist. Ich nehme an, Sie wollten buffer binden.
Entfernen Sie die folgenden Zeilen dieses Problem zu lösen:

var positionBuffer = gl.createBuffer(); 
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer); 
+0

danke @ rabbid76, das hat den Fehler beseitigt, aber ich sehe eine Warnung: '[.Offscreen-For-WebGL-0x7fabe8cc6400] GL-FEHLER: GL_INVALID_OPERATION: glDrawArrays: versucht, im Attribut 0' auf außerhalb des Bereichs liegende Scheitelpunkte zuzugreifen. . Auch das Bild erscheint noch nicht – novembersky

+0

@ witty2017 Ich erweiterte meine Antwort – Rabbid76

+0

Vielen Dank @ Rabbid76, zum Hinweis auf die wiederholte Definition! Ich bin noch nicht vertraut mit allen wichtigen Funktionen. – novembersky

Verwandte Themen