diff --git a/README.md b/README.md index 9b03c06..898c656 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,7 @@ Tarek Sherif writes a really helpful [WebGL 2 Examples](https://github.com/tsher |[fbo_rtt_draw_buffers](http://webglsamples.org/WebGL2Samples/#fbo_rtt_draw_buffers)|:white_check_mark:|TODO|:white_check_mark:|TODO| |[fbo_rtt_texture_array](http://webglsamples.org/WebGL2Samples/#fbo_rtt_texture_array)|:white_check_mark:|:white_check_mark:|:white_check_mark:|:white_check_mark:| |[fbo_rtt_depth_texture](http://webglsamples.org/WebGL2Samples/#fbo_rtt_depth_texture)|:white_check_mark:|TODO|:white_check_mark:|TODO| +|[fbo_read_pixels](http://webglsamples.org/WebGL2Samples/#fbo_read_pixels)|:white_check_mark:|TODO|:white_check_mark:|TODO| |[fbo_blit](http://webglsamples.org/WebGL2Samples/#fbo_blit)|:white_check_mark:|:white_check_mark:|:white_check_mark:|:white_check_mark:| |[fbo_multisample](http://webglsamples.org/WebGL2Samples/#fbo_multisample)|:white_check_mark:|:white_check_mark:|:white_check_mark:|:white_check_mark:| |[fbo_new_blend_equation](http://webglsamples.org/WebGL2Samples/#fbo_new_blend_equation)|:white_check_mark:|:white_check_mark:|:white_check_mark:|:white_check_mark:| diff --git a/index.html b/index.html index 9b0b67f..87d4d67 100644 --- a/index.html +++ b/index.html @@ -205,7 +205,8 @@

WebGL 2.0 Samples

"fbo_new_blend_equation", "fbo_rtt_draw_buffers", "fbo_rtt_texture_array", - "fbo_rtt_depth_texture" + "fbo_rtt_depth_texture", + "fbo_read_pixels" ], "Sampler": [ "sampler_object", diff --git a/samples/draw_image_space.html b/samples/draw_image_space.html index 3eae98a..80460d3 100644 --- a/samples/draw_image_space.html +++ b/samples/draw_image_space.html @@ -37,7 +37,7 @@ void main() { - color = texture(diffuse, vec2(gl_FragCoord.x, 1.0 - gl_FragCoord.y) / u_imageSize); + color = texture(diffuse, vec2(gl_FragCoord.x, u_imageSize.y - gl_FragCoord.y) / u_imageSize); } diff --git a/samples/fbo_read_pixels.html b/samples/fbo_read_pixels.html new file mode 100644 index 0000000..9c6919e --- /dev/null +++ b/samples/fbo_read_pixels.html @@ -0,0 +1,344 @@ + + + + + + WebGL 2 Samples - fbo_read_pixels + + + + + + + +
WebGL 2 Samples - fbo_read_pixels
+

+ This sample demonstrates rendering to texture in a frame buffer using a texture array. And readpixels from this frame buffer. The data read is printed in the console. +

+ + + + + + + + + + + + + + + diff --git a/samples/fbo_rtt_texture_array.html b/samples/fbo_rtt_texture_array.html index 8d303ad..b3b496a 100644 --- a/samples/fbo_rtt_texture_array.html +++ b/samples/fbo_rtt_texture_array.html @@ -13,7 +13,7 @@
WebGL 2 Samples - fbo_rtt_texture_array

- This sample demonstrates rendering to texture in a frame buffer using a texture array. And readpixels from this frame buffer. + This sample demonstrates rendering to texture in a frame buffer using a texture array.

- + diff --git a/samples/glsl_flat_smooth_interpolators.html b/samples/glsl_flat_smooth_interpolators.html index 1ba4035..d07e2a1 100644 --- a/samples/glsl_flat_smooth_interpolators.html +++ b/samples/glsl_flat_smooth_interpolators.html @@ -260,7 +260,7 @@ // -- Render loop (function render() { gl.clearColor(0.0, 0.0, 0.0, 1.0); - gl.clear(gl.COLOR_BUFFER_BIT); + gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); mat4.rotateY(modelView, modelView, rotatationSpeedY); diff --git a/samples/query_occlusion.html b/samples/query_occlusion.html index 0260735..8346198 100644 --- a/samples/query_occlusion.html +++ b/samples/query_occlusion.html @@ -21,11 +21,11 @@ precision highp float; precision highp int; - layout(location = POSITION_LOCATION) in vec2 pos; + layout(location = POSITION_LOCATION) in vec3 pos; void main() { - gl_Position = vec4(pos,0.0,1.0); + gl_Position = vec4(pos, 1.0); } @@ -38,7 +38,7 @@ void main() { - color = vec4(1.0,0.5,0.0,1.0); + color = vec4(1.0, 0.5, 0.0, 1.0); } @@ -64,12 +64,17 @@ // -- Init Program var program = createProgram(gl, getShaderSource('vs'), getShaderSource('fs')); gl.useProgram(program); + gl.enable(gl.DEPTH_TEST); // -- Init Buffer var vertices = new Float32Array([ - -0.3, -0.5, - 0.3, -0.5, - 0.0, 0.5 + -0.3, -0.5, 0.0, + 0.3, -0.5, 0.0, + 0.0, 0.5, 0.0, + + -0.3, -0.5, 0.5, + 0.3, -0.5, 0.5, + 0.0, 0.5, 0.5 ]); var vertexPosBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, vertexPosBuffer); @@ -81,7 +86,7 @@ var vertexPosLocation = 0; // set with GLSL layout qualifier gl.enableVertexAttribArray(vertexPosLocation); - gl.vertexAttribPointer(vertexPosLocation, 2, gl.FLOAT, false, 0, 0); + gl.vertexAttribPointer(vertexPosLocation, 3, gl.FLOAT, false, 0, 0); gl.bindVertexArray(null); @@ -90,12 +95,14 @@ // -- Render gl.clearColor(0.0, 0.0, 0.0, 1.0); - gl.clear(gl.COLOR_BUFFER_BIT); + gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); gl.bindVertexArray(vertexArray); + gl.drawArrays(gl.TRIANGLES, 0, 3); + gl.beginQuery(gl.ANY_SAMPLES_PASSED, query); - gl.drawArraysInstanced(gl.TRIANGLES, 0, 3, 2); + gl.drawArrays(gl.TRIANGLES, 3, 3); gl.endQuery(gl.ANY_SAMPLES_PASSED); (function tick() { @@ -117,6 +124,6 @@ gl.deleteVertexArray(vertexArray); })(); - + diff --git a/samples/texture_srgb.html b/samples/texture_srgb.html index f02e3f0..7faa630 100644 --- a/samples/texture_srgb.html +++ b/samples/texture_srgb.html @@ -17,7 +17,7 @@
This is useful since because then we could work with the filtering math in linear space, then convert back to sRGB space for the color output.
- The output below is applied to a Guassian blur filter. + The output below is applied to a Gaussian blur filter.

diff --git a/samples/transform_feedback_instanced.html b/samples/transform_feedback_instanced.html index 07aae2a..7d291b4 100644 --- a/samples/transform_feedback_instanced.html +++ b/samples/transform_feedback_instanced.html @@ -213,6 +213,9 @@ var vertexArrays = [gl.createVertexArray(), gl.createVertexArray()]; + // Transform feedback objects track output buffer state + var transformFeedbacks = [gl.createTransformFeedback(), gl.createTransformFeedback()]; + var vertexBuffers = new Array(vertexArrays.length); for (var va = 0; va < vertexArrays.length; ++va) { @@ -227,7 +230,7 @@ vertexBuffers[va][ROTATION_LOCATION] = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffers[va][ROTATION_LOCATION]); - gl.bufferData(gl.ARRAY_BUFFER, instanceOffsets, gl.STREAM_COPY); + gl.bufferData(gl.ARRAY_BUFFER, instanceRotations, gl.STREAM_COPY); gl.vertexAttribPointer(ROTATION_LOCATION, 1, gl.FLOAT, false, 0, 0); gl.enableVertexAttribArray(ROTATION_LOCATION); @@ -245,10 +248,15 @@ gl.vertexAttribDivisor(COLOR_LOCATION, 1); // attribute used once per instance gl.bindVertexArray(null); - } + gl.bindBuffer(gl.ARRAY_BUFFER, null); + + // Set up output + gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, transformFeedbacks[va]); + gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, vertexBuffers[va][OFFSET_LOCATION]); + gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 1, vertexBuffers[va][ROTATION_LOCATION]); - // -- Init TransformFeedback - var transformFeedback = gl.createTransformFeedback(); + gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null); + } render(); @@ -295,27 +303,28 @@ function transform() { var programTransform = programs[PROGRAM_TRANSFORM]; + var destinationIdx = (currentSourceIdx + 1) % 2; // Toggle source and destination VBO - var sourceVBO = vertexBuffers[currentSourceIdx]; var sourceVAO = vertexArrays[currentSourceIdx]; - var destinationVBO = vertexBuffers[(currentSourceIdx + 1) % 2]; - - gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, transformFeedback); + var destinationTransformFeedback = transformFeedbacks[destinationIdx]; gl.useProgram(programTransform); gl.bindVertexArray(sourceVAO); + gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, destinationTransformFeedback); + + // NOTE: The following two lines shouldn't be necessary, but are required to work in ANGLE + // due to a bug in its handling of transform feedback objects. + // https://bugs.chromium.org/p/angleproject/issues/detail?id=2051 + gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, vertexBuffers[destinationIdx][OFFSET_LOCATION]); + gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 1, vertexBuffers[destinationIdx][ROTATION_LOCATION]); // Attributes per-vertex when doing transform feedback needs setting to 0 when doing transform feedback gl.vertexAttribDivisor(OFFSET_LOCATION, 0); gl.vertexAttribDivisor(ROTATION_LOCATION, 0); - // Set transform feedback buffer - gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, OFFSET_LOCATION, destinationVBO[OFFSET_LOCATION]); - gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, ROTATION_LOCATION, destinationVBO[ROTATION_LOCATION]); - // Turn off rasterization - we are not drawing gl.enable(gl.RASTERIZER_DISCARD); @@ -328,8 +337,8 @@ gl.disable(gl.RASTERIZER_DISCARD); gl.useProgram(null); gl.bindBuffer(gl.ARRAY_BUFFER, null); - gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, null); gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null); + gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, null); // Ping pong the buffers currentSourceIdx = (currentSourceIdx + 1) % 2; @@ -369,7 +378,6 @@ // If you have a long-running page, and need to delete WebGL resources, use: // - // gl.deleteTransformFeedback(transformFeedback); // gl.deleteProgram(programs[PROGRAM_TRANSFORM]); // gl.deleteProgram(programs[PROGRAM_DRAW]); // for (var i = 0; i < 2; ++i) { @@ -379,9 +387,11 @@ // } // gl.deleteVertexArray(vertexArrays[PROGRAM_TRANSFORM]); // gl.deleteVertexArray(vertexArrays[PROGRAM_DRAW]); + // gl.deleteTransformFeedback(transformFeedbacks[0]); + // gl.deleteTransformFeedback(transformFeedbacks[1]); })(); - + diff --git a/samples/transform_feedback_interleaved.html b/samples/transform_feedback_interleaved.html index 07bc7b9..bc83729 100644 --- a/samples/transform_feedback_interleaved.html +++ b/samples/transform_feedback_interleaved.html @@ -172,6 +172,14 @@ gl.bufferData(gl.ARRAY_BUFFER, SIZE_V4C4 * VERTEX_COUNT, gl.STATIC_COPY); gl.bindBuffer(gl.ARRAY_BUFFER, null); + // -- Init TransformFeedback: Track output buffer + var transformFeedback = gl.createTransformFeedback(); + + gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, transformFeedback); + gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, buffers[PROGRAM_FEEDBACK]); + gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null); + gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, null); + // -- Init Vertex Array var vertexArrays = [gl.createVertexArray(), gl.createVertexArray()]; gl.bindVertexArray(vertexArrays[PROGRAM_TRANSFORM]); @@ -191,14 +199,11 @@ gl.bindBuffer(gl.ARRAY_BUFFER, buffers[PROGRAM_FEEDBACK]); gl.vertexAttribPointer(vertexPosLocationFeedback, 4, gl.FLOAT, false, SIZE_V4C4, 0); gl.vertexAttribPointer(vertexColorLocationFeedback, 4, gl.FLOAT, false, SIZE_V4C4, SIZE_V4C4 / 2); - gl.bindBuffer(gl.ARRAY_BUFFER, null); gl.enableVertexAttribArray(vertexPosLocationFeedback); gl.enableVertexAttribArray(vertexColorLocationFeedback); + gl.bindBuffer(gl.ARRAY_BUFFER, null); gl.bindVertexArray(null); - - // -- Init TransformFeedback - var transformFeedback = gl.createTransformFeedback(); // -- Render gl.clearColor(0.0, 0.0, 0.0, 1.0); @@ -208,8 +213,6 @@ // Disable rasterization, vertices processing only gl.enable(gl.RASTERIZER_DISCARD); - gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, transformFeedback); - gl.useProgram(programs[PROGRAM_TRANSFORM]); var matrix = new Float32Array([ 0.5, 0.0, 0.0, 0.0, @@ -219,15 +222,15 @@ ]); gl.uniformMatrix4fv(mvpLocation, false, matrix); - gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, buffers[PROGRAM_FEEDBACK]); gl.bindVertexArray(vertexArrays[PROGRAM_TRANSFORM]); + gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, transformFeedback); gl.beginTransformFeedback(gl.TRIANGLES); gl.drawArraysInstanced(gl.TRIANGLES, 0, VERTEX_COUNT, 1); gl.endTransformFeedback(); + gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null); gl.disable(gl.RASTERIZER_DISCARD); - gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, null); // Second draw, reuse captured attributes gl.useProgram(programs[PROGRAM_FEEDBACK]); diff --git a/samples/transform_feedback_separated.html b/samples/transform_feedback_separated.html index 6faf4b0..6ded664 100644 --- a/samples/transform_feedback_separated.html +++ b/samples/transform_feedback_separated.html @@ -186,7 +186,7 @@ gl.bufferData(gl.ARRAY_BUFFER, positions.length * Float32Array.BYTES_PER_ELEMENT, gl.STATIC_COPY); gl.bindBuffer(gl.ARRAY_BUFFER, null); - // -- Init Vertex Array + // -- Init Transform Vertex Array var vertexArrays = [gl.createVertexArray(), gl.createVertexArray()]; gl.bindVertexArray(vertexArrays[PROGRAM_TRANSFORM]); @@ -198,6 +198,16 @@ gl.bindVertexArray(null); + // -- Init TransformFeedback + var transformFeedback = gl.createTransformFeedback(); + gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, transformFeedback); + gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, buffers[BufferType.POSITION]); + gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 1, buffers[BufferType.COLOR]); + gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null); + gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, null); + gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 1, null); + + // -- Init Feedback Vertex Array gl.bindVertexArray(vertexArrays[PROGRAM_FEEDBACK]); var vertexPosLocationFeedback = 0; // set with GLSL layout qualifier @@ -213,9 +223,6 @@ gl.bindBuffer(gl.ARRAY_BUFFER, null); gl.bindVertexArray(null); - // -- Init TransformFeedback - var transformFeedback = gl.createTransformFeedback(); - // -- Render gl.clearColor(0.0, 0.0, 0.0, 1.0); @@ -225,7 +232,6 @@ // Disable rasterization, vertices processing only gl.enable(gl.RASTERIZER_DISCARD); - gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, transformFeedback); gl.useProgram(programs[PROGRAM_TRANSFORM]); var matrix = new Float32Array([ @@ -236,17 +242,15 @@ ]); gl.uniformMatrix4fv(mvpLocation, false, matrix); - gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, buffers[BufferType.POSITION]); - gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 1, buffers[BufferType.COLOR]); gl.bindVertexArray(vertexArrays[PROGRAM_TRANSFORM]); + gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, transformFeedback); gl.beginTransformFeedback(gl.TRIANGLES); gl.drawArraysInstanced(gl.TRIANGLES, 0, VERTEX_COUNT, 1); gl.endTransformFeedback(); + gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null); gl.disable(gl.RASTERIZER_DISCARD); - gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, null); - gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 1, null); // Second draw, reuse captured attributes gl.useProgram(programs[PROGRAM_FEEDBACK]); @@ -265,7 +269,7 @@ gl.deleteVertexArray(vertexArrays[PROGRAM_FEEDBACK]); })(); - + diff --git a/samples/transform_feedback_separated_2.html b/samples/transform_feedback_separated_2.html index 483dbeb..860d594 100644 --- a/samples/transform_feedback_separated_2.html +++ b/samples/transform_feedback_separated_2.html @@ -149,11 +149,15 @@ // -- Init Vertex Arrays and Buffers var particleVAOs = [gl.createVertexArray(), gl.createVertexArray()]; + // Transform feedback objects track output buffer state + var particleTransformFeedbacks = [gl.createTransformFeedback(), gl.createTransformFeedback()]; + var particleVBOs = new Array(particleVAOs.length); for (var i = 0; i < particleVAOs.length; ++i) { particleVBOs[i] = new Array(NUM_LOCATIONS); + // Set up input gl.bindVertexArray(particleVAOs[i]); particleVBOs[i][POSITION_LOCATION] = gl.createBuffer(); @@ -185,6 +189,16 @@ gl.bufferData(gl.ARRAY_BUFFER, particleIDs, gl.STATIC_READ); gl.vertexAttribPointer(ID_LOCATION, 1, gl.FLOAT, false, 0, 0); gl.enableVertexAttribArray(ID_LOCATION); + + gl.bindBuffer(gl.ARRAY_BUFFER, null); + + // Set up output + gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, particleTransformFeedbacks[i]); + gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, particleVBOs[i][POSITION_LOCATION]); + gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 1, particleVBOs[i][VELOCITY_LOCATION]); + gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 2, particleVBOs[i][SPAWNTIME_LOCATION]); + gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 3, particleVBOs[i][LIFETIME_LOCATION]); + } function initProgram() { @@ -237,13 +251,10 @@ gl.enable(gl.BLEND); gl.blendFunc(gl.SRC_ALPHA, gl.ONE); - // -- Init TransformFeedback - var transformFeedback = gl.createTransformFeedback(); - gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, transformFeedback); - function render() { var time = Date.now() - appStartTime; + var destinationIdx = (currentSourceIdx + 1) % 2; // Set the viewport gl.viewport(0, 0, canvas.width, canvas.height - 10); @@ -254,15 +265,18 @@ // Toggle source and destination VBO var sourceVAO = particleVAOs[currentSourceIdx]; - var destinationVBO = particleVBOs[(currentSourceIdx + 1) % 2]; + var destinationTransformFeedback = particleTransformFeedbacks[destinationIdx]; gl.bindVertexArray(sourceVAO); + gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, destinationTransformFeedback); - // Set transform feedback buffer - gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, destinationVBO[POSITION_LOCATION]); - gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 1, destinationVBO[VELOCITY_LOCATION]); - gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 2, destinationVBO[SPAWNTIME_LOCATION]); - gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 3, destinationVBO[LIFETIME_LOCATION]); + // NOTE: The following four lines shouldn't be necessary, but are required to work in ANGLE + // due to a bug in its handling of transform feedback objects. + // https://bugs.chromium.org/p/angleproject/issues/detail?id=2051 + gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, particleVBOs[destinationIdx][POSITION_LOCATION]); + gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 1, particleVBOs[destinationIdx][VELOCITY_LOCATION]); + gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 2, particleVBOs[destinationIdx][SPAWNTIME_LOCATION]); + gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 3, particleVBOs[destinationIdx][LIFETIME_LOCATION]); // Set uniforms gl.uniform1f(drawTimeLocation, time); @@ -282,17 +296,17 @@ // If you have a long-running page, and need to delete WebGL resources, use: // - // gl.deleteTransformFeedback(transformFeedback); // gl.deleteProgram(program); // for (var i = 0; i < particleVAOs.length; ++i) { - // gl.deleteVertexArray(i); + // gl.deleteVertexArray(particleVAOs[i]); + // gl.deleteTransformFeedback(particleTransformFeedbacks[i]); // for (var j = 0; j < NUM_LOCATIONS; ++j) { // gl.deleteBuffer(particleVBOs[i][j]); // } // } })(); - +