webgl2 方法解析: getShaderParameter()

164 阅读2分钟

getShaderParameter 是 WebGL2 中的一个方法,用于获取着色器对象的状态信息。以下是关于这个方法的中文详细介绍:

基本用法

gl.getShaderParameter(shader, pname);
  • shader: 要查询的着色器对象(WebGLShader)

  • pname: 指定要查询的参数,可以是以下值之一:

    • gl.SHADER_TYPE: 返回着色器类型(顶点着色器或片段着色器)
    • gl.DELETE_STATUS: 返回布尔值表示着色器是否被标记为删除
    • gl.COMPILE_STATUS: 返回布尔值表示着色器是否编译成功
    • gl.INFO_LOG_LENGTH: 返回信息日志的长度
    • gl.SHADER_SOURCE_LENGTH: 返回着色器源代码的长度

返回值

返回的值取决于查询的参数 pname:

  • 对于 gl.SHADER_TYPE: 返回 gl.VERTEX_SHADERgl.FRAGMENT_SHADER
  • 对于 gl.DELETE_STATUSgl.COMPILE_STATUS: 返回布尔值
  • 对于长度查询: 返回整数值

实际示例

以下是一个完整的示例, 可以直接运行:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>WebGL2 getShaderParameter 示例</title>
    <style>
        body { margin: 0; padding: 20px; font-family: Arial, sans-serif; }
        canvas { border: 1px solid #ccc; display: block; margin: 20px auto; }
        #info { margin: 20px; padding: 10px; background: #f0f0f0; border-radius: 5px; }
        .error { color: red; }
    </style>
</head>
<body>
    <h1>WebGL2 getShaderParameter 示例</h1>
    <div id="info"></div>
    <canvas id="glCanvas" width="400" height="400"></canvas>
​
    <script>
        // 获取DOM元素
        const canvas = document.getElementById('glCanvas');
        const infoDiv = document.getElementById('info');
        
        // 初始化WebGL2上下文
        const gl = canvas.getContext('webgl2');
        if (!gl) {
            infoDiv.innerHTML = '<p class="error">您的浏览器不支持WebGL2</p>';
            throw new Error('WebGL2 not supported');
        }
​
        // 顶点着色器源码
        const vsSource = `#version 300 es
        in vec4 aPosition;
        void main() {
            gl_Position = aPosition;
        }`;
​
        // 片段着色器源码
        const fsSource = `#version 300 es
        precision highp float;
        out vec4 fragColor;
        void main() {
            fragColor = vec4(1.0, 0.5, 0.2, 1.0); // 橙色
        }`;
​
        // 编译着色器函数
        function compileShader(source, type) {
            const shader = gl.createShader(type);
            gl.shaderSource(shader, source);
            gl.compileShader(shader);
            
            // 使用getShaderParameter检查编译状态
            const success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
            if (!success) {
                const log = gl.getShaderInfoLog(shader);
                infoDiv.innerHTML += `<p class="error">${type === gl.VERTEX_SHADER ? '顶点' : '片段'}着色器编译错误: ${log}</p>`;
                gl.deleteShader(shader);
                return null;
            }
            
            // 使用getShaderParameter检查着色器类型
            const shaderType = gl.getShaderParameter(shader, gl.SHADER_TYPE);
            infoDiv.innerHTML += `<p>${type === gl.VERTEX_SHADER ? '顶点' : '片段'}着色器创建成功,类型验证: ${
                shaderType === gl.VERTEX_SHADER ? 'VERTEX_SHADER' : 'FRAGMENT_SHADER'
            }</p>`;
            
            return shader;
        }
​
        // 编译着色器
        const vertexShader = compileShader(vsSource, gl.VERTEX_SHADER);
        const fragmentShader = compileShader(fsSource, gl.FRAGMENT_SHADER);
        
        if (!vertexShader || !fragmentShader) {
            throw new Error('着色器编译失败');
        }
​
        // 创建着色程序
        const program = gl.createProgram();
        gl.attachShader(program, vertexShader);
        gl.attachShader(program, fragmentShader);
        gl.linkProgram(program);
        
        // 检查链接状态
        if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
            const log = gl.getProgramInfoLog(program);
            infoDiv.innerHTML += `<p class="error">程序链接错误: ${log}</p>`;
            throw new Error('程序链接失败');
        }
​
        // 设置顶点数据
        const positionBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
        const positions = [
             0.0,  0.5, 0.0,
            -0.5, -0.5, 0.0,
             0.5, -0.5, 0.0
        ];
        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
​
        // 使用程序
        gl.useProgram(program);
        
        // 获取并启用顶点属性
        const positionAttributeLocation = gl.getAttribLocation(program, 'aPosition');
        gl.enableVertexAttribArray(positionAttributeLocation);
        gl.vertexAttribPointer(positionAttributeLocation, 3, gl.FLOAT, false, 0, 0);
​
        // 清除并绘制
        gl.clearColor(0.0, 0.0, 0.0, 1.0);
        gl.clear(gl.COLOR_BUFFER_BIT);
        gl.drawArrays(gl.TRIANGLES, 0, 3);
​
        infoDiv.innerHTML += '<p>渲染完成!你应该看到一个橙色的三角形。</p>';
    </script>
</body>
</html>

注意事项

  1. 如果着色器对象无效,会生成 INVALID_VALUE 错误
  2. 在开发过程中,检查 COMPILE_STATUS 是调试着色器的重要步骤
  3. 即使编译失败,仍然可以使用 getShaderInfoLog 获取错误信息
  4. 这个方法通常与 getShaderInfoLog 一起使用,用于调试和验证着色器状态。