webgl 2.0 学习 绘制系列之gl_VertexID

676 阅读1分钟

一、gl_VertexID

gl_VertexID是一个在OpenGL中是一个内置的变量,每个顶点运行它时它们的gl_VertexID都不一样。我们利用这样的特点,将此作一个索引,得到不同的gl_Position,用以传入下一阶段——栅格化(Rasterize),这样一个三角形就得以显示出来了。

#version 430
//layout(location = 0) in vec4 VERTEX;
uniform mat4 MODEL_MATRIX;
uniform mat4 VIEW_MATRIX;
uniform mat4 PROJECTION_MATRIX;

//out vec4 VERTEX_COLOR;
void main()
{

   const vec4 vertices[3] = vec4[3](
               vec4( 0.25, -0.25, 0.5, 1.0 ),
               vec4( -0.25, -0.25, 0.5, 1.0 ),
               vec4( 0.25, 0.25, 0.5, 1.0 ) );
   gl_Position = PROJECTION_MATRIX * VIEW_MATRIX * MODEL_MATRIX  * vertices[gl_VertexID];;

   //gl_Position = PROJECTION_MATRIX * VIEW_MATRIX * MODEL_MATRIX * VERTEX;
}

二、实践

<!DOCTYPE html>
<!-- Ported from the OpenGL Samples Pack https://github.com/g-truc/ogl-samples/blob/master/tests/gl-320-draw-image-space.cpp -->
<html lang="en">

<head>
    <title>WebGL 2 Samples - draw_image_space</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
    <link rel="stylesheet" href="style.css">
</head>

<body>
    <div id="info">WebGL 2 Samples - draw_image_space</div>

    <!-- WebGL 2 shaders -->
    <script id="vs" type="x-shader/x-vertex">
        #version 300 es
        precision highp float;
        precision highp int;
        
        void main()
        {
            gl_Position = vec4(2.f * float(uint(gl_VertexID) % 2u) - 1.f, 2.f * float(uint(gl_VertexID) / 2u) - 1.f, 0.0, 1.0);
        }
    </script>

    <script id="fs" type="x-shader/x-fragment">
        #version 300 es
        precision highp float;
        precision highp int;

        uniform sampler2D diffuse;

        uniform vec2 u_imageSize;

        out vec4 color;

        void main()
        {
            color = texture(diffuse, vec2(gl_FragCoord.x, u_imageSize.y - gl_FragCoord.y) / u_imageSize);
        }
    </script>

    <script src="utility.js"></script>
    <script>
    (function () {
        'use strict';

        var canvas = document.createElement('canvas');
        canvas.width = Math.min(window.innerWidth, window.innerHeight);
        canvas.height = canvas.width;
        document.body.appendChild(canvas);

        var gl = canvas.getContext( 'webgl2', { antialias: false } );
        var isWebGL2 = !!gl;
        if(!isWebGL2) {
            document.getElementById('info').innerHTML = 'WebGL 2 is not available.  See <a href="https://www.khronos.org/webgl/wiki/Getting_a_WebGL_Implementation">How to get a WebGL 2 implementation</a>';
            return;
        }

        // -- Init program
        var program = createProgram(gl, getShaderSource('vs'), getShaderSource('fs'));
        var diffuseLocation = gl.getUniformLocation(program, 'diffuse');
        var imageSizeLocation = gl.getUniformLocation(program, 'u_imageSize');

        // -- Init VertexArray
        var vertexArray = gl.createVertexArray();
        gl.bindVertexArray(vertexArray);

        gl.bindVertexArray(null);

        loadImage('../assets/img/Di-3d.png', function(image) {
            // -- Init Texture
            var texture = gl.createTexture();
            gl.activeTexture(gl.TEXTURE0);
            gl.bindTexture(gl.TEXTURE_2D, texture);
            gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
            gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);

            // -- Render
            gl.clearColor(0.0, 0.0, 0.0, 1.0);
            gl.clear(gl.COLOR_BUFFER_BIT);

            gl.useProgram(program);
            gl.uniform1i(diffuseLocation, 0);
            gl.uniform2f(imageSizeLocation, canvas.width / 2, canvas.height / 2);
            
            gl.bindVertexArray(vertexArray);

            gl.drawArrays(gl.TRIANGLES, 0, 3);

            // Delete WebGL resources
            gl.deleteTexture(texture);
            gl.deleteProgram(program);
            gl.deleteVertexArray(vertexArray);
        });
    })();
    </script>
    <div id="highlightedLines"  style="display: none">#L23</div>
</body>

</html>

image.png