toy shaders examples opengl-es webgl vertex-shader

opengl-es - shaders - shader gl



¿Es importante llamar a glDisableVertexAttribArray()? (3)

El estado en el que se habilitan las matrices de atributos de vértice puede estar vinculado a un objeto de matriz de vértice (VAO), o ser global.

Si está utilizando VAO, no debe deshabilitar los arreglos de atributos, ya que están encapsulados en el VAO.

Sin embargo, para el estado habilitado de la matriz de atributos de vértice global, debe deshabilitarlos, porque si se dejan habilitados, OpenGL intentará leer desde las matrices, que pueden estar vinculadas a un puntero no válido, que puede bloquear su programa si el puntero es a la dirección del cliente espacio, o genere un error OpenGL si señala fuera de los límites de un objeto de búfer de vértice vinculado.

No estoy del todo claro sobre el alcance de habilitar matrices de atributos de vértice. Tengo varios programas de sombreado diferentes con diferentes números de atributos de vértice. ¿ glEnableVertexAttribArray llamadas glEnableVertexAttribArray son locales a un programa de sombreado, o globales?

En este momento, estoy habilitando matrices de atributos de vértice cuando creo el programa de sombreado, y nunca las deshabilito, y todo parece funcionar, pero parece que se supone que debo habilitarlas / deshabilitarlas justo antes / después de realizar llamadas. ¿Hay un impacto en esto?

(Estoy en WebGL, por casualidad, así que realmente estamos hablando de gl.enableVertexAttribArray y gl.disableVertexAttribArray . gl.disableVertexAttribArray también que el libro naranja, OpenGL Shading Language , es bastante poco informativo sobre estas llamadas).


Para webGL voy a ir con , es importante llamar a gl.disableVertexAttribArray.

Chrome me estaba dando esta advertencia:

WebGL: INVALID_OPERATION: drawElements: attribs not setup correctly

Esto estaba sucediendo cuando el programa cambió a uno utilizando menos del número máximo de atributos. Obviamente, la solución fue deshabilitar los atributos no utilizados antes de dibujar.

Si todos sus programas usan la misma cantidad de atributos, puede que salga con la posibilidad de llamar a gl.enableVertexAttribArray una vez en la inicialización. De lo contrario, tendrá que gestionarlos cuando cambie de programa.


WebGL no es lo mismo que OpenGL.

En WebGL, las matrices habilitadas están permitidas explícitamente siempre que haya un búfer adjunto al atributo y (a) si se usa es lo suficientemente grande como para satisfacer la llamada draw o (b) no se usa.

A diferencia de OpenGL ES 2.0, WebGL no permite matrices del lado del cliente.

Prueba:

var gl = document.querySelector("canvas").getContext("webgl"); var m4 = twgl.m4; var programInfo2Attribs = twgl.createProgramInfo(gl, ["vs-uses-2-attributes", "fs"]); var programInfo1Attrib = twgl.createProgramInfo(gl, ["vs-uses-1-attribute", "fs"]); var arrays2Attribs = { position: [ -1, -1, 0, 1, -1, 0, -1, 1, 0, ], color: [ 1,0,0,1, 1,1,0,1, 0,1,0,1, ], }; var arrays1Attrib = { position: [ -1, -1, 0, 1, -1, 0, -1, 1, 0, -1, 1, 0, 1, -1, 0, 1, 1, 0, ], }; var bufferInfo2Attribs = twgl.createBufferInfoFromArrays(gl, arrays2Attribs); var bufferInfo1Attrib = twgl.createBufferInfoFromArrays(gl, arrays1Attrib); var uniforms = { u_matrix: m4.scale(m4.translation([-0.5, 0, 0]), [0.25, 0.5, 0.5]), }; gl.useProgram(programInfo2Attribs.program); twgl.setBuffersAndAttributes(gl, programInfo2Attribs, bufferInfo2Attribs); twgl.setUniforms(programInfo2Attribs, uniforms); twgl.drawBufferInfo(gl, gl.TRIANGLES, bufferInfo2Attribs); uniforms.u_matrix = m4.scale(m4.translation([0.5, 0, 0]), [0.25, 0.5, 0.5]); gl.useProgram(programInfo1Attrib.program); twgl.setBuffersAndAttributes(gl, programInfo1Attrib, bufferInfo1Attrib); twgl.setUniforms(programInfo1Attrib, uniforms); twgl.drawBufferInfo(gl, gl.TRIANGLES, bufferInfo1Attrib);

canvas { border: 1px solid black; }

<script src="https://twgljs.org/dist/twgl-full.min.js"></script> <script id="vs-uses-2-attributes" type="not-js"> attribute vec4 position; attribute vec4 color; varying vec4 v_color; uniform mat4 u_matrix; void main() { gl_Position = u_matrix * position; v_color = color; } </script> <script id="vs-uses-1-attribute" type="not-js"> attribute vec4 position; varying vec4 v_color; uniform mat4 u_matrix; void main() { gl_Position = u_matrix * position; v_color = vec4(0,1,0,1); } </script> <script id="fs" type="not-js"> precision mediump float; varying vec4 v_color; void main() { gl_FragColor = v_color; } </script> <p> 1st it draws a triangle (3 vertices, 2 attributes)<br/> 2nd it draws a quad (6 vertices, 1 attribute)<br/> It does NOT called gl.disableVertexAttrib so on the second draw call one of the attributes is still enabled. It is pointing to a buffer with only 3 vertices in it even though 6 vertices will be drawn. There are no errors. </p> <canvas></canvas>