Ошибка WebGL useProgram: программа не действительна - PullRequest
0 голосов
/ 31 марта 2020

У меня есть этот код для webgl, и я пытаюсь скомпилировать и использовать эту программу, но когда я делаю gl.useProgram (); я получаю эту ошибку: WebGL: INVALID_OPERATION: useProgram: программа недействительна.

Я не знаю, как решить эту проблему или возникла ошибка в вершинном шейдере или фрагментном шейдере.

    const canvas = document.querySelector("#glCanvas");
    // Initialize the GL context
    const gl = canvas.getContext("webgl");

    // If we don't have a GL context, give up now

    if (!gl) {
        alert('Unable to initialize WebGL. Your browser or machine may not support it.');
        return;
    }
    
  
  // Vertex shader program
    const vsSource = `
    layout (location = 0) in vec4 VertexPosition;
    layout (location = 1) in vec3 VertexNormal;
    layout (location = 2) in vec2 TextureCoord;

    out vec3 Position;
    out vec3 Normal;
    out vec2 TexCoords;

    uniform mat4 uModelViewMatrix;
    uniform mat4 uNormalMatrix;
    uniform mat4 uMVP;

    void main()
    {

        Position = vec3 (uModelViewMatrix * VertexPosition);
        Normal = normalize(uNormalMatrix * VertexNormal);

        TexCoords = TextureCoord;

        gl_Position = uMVP * VertexPosition;
    
    }
  `;


    const fsSource = `
    in vec3 Position;
    in vec3 Normal;
    in vec2 TexCoords;

    layout (location = 0) out vec4 FragColor;

    struct TMaterial {
        sampler2D Diffuse;
        sampler2D Specular;
        float Shininess;
    };
    struct TLight {
        vec3 Position;

        vec3 Ambient;
        vec3 Diffuse;
        vec3 Specular;
    };

    uniform TMaterial Material;
    uniform TLight Light;

    vec3 Phong(){
        vec3 n = normalize(Normal);
        vec3 s = normalize(Light.Position - Position);
        vec3 v = normalize(-Position);
        vec3 r = reflect(-s, n);

        vec3 Ambient = Light.Ambient * vec3(texture(Material.Diffuse, TexCoords));
        vec3 Diffuse = Light.Diffuse * max(dot(s, n), 0.0) * vec(texture(Material.Diffuse, TexCoords));

        vec3 Specular = Light.Specular * pow(max(dot(r, v), 0.0), Material.Shininess) * vec3(texture(Material.Specular, TexCoords));

        return Ambient + Diffuse + Specular;
    }

    void main()
    {
      FragColor = vec3 (Phong(), 0.0);
    }
  `;


    //Crear el programa y linkarlo a los shaders que acabamos de crear
    const vertexShader = gl.createShader(gl.VERTEX_SHADER);
    const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);

    gl.shaderSource(vertexShader, vsSource);
    gl.shaderSource(fragmentShader, fsSource);

    gl.compileShader(vertexShader);
    gl.compileShader(fragmentShader);


    const programLightingMap = gl.createProgram();
    gl.attachShader(programLightingMap, vertexShader);
    gl.attachShader(programLightingMap, fragmentShader);
    gl.linkProgram(programLightingMap);


    gl.useProgram(programLightingMap);
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>WebGL</title>
    <script src="https://cdn.jsdelivr.net/npm/gl-matrix@3.2.1/gl-matrix-min.js"></script>

    <script src="Shader.js"></script>

</head>

<body>
    <h1>WebGL!!</h1>
    <canvas id="glCanvas" width="640" height="480"></canvas>
    <hr>
    <p id="diplayData"></p>
</body>

</html>

РЕДАКТИРОВАТЬ: Я получаю эту ошибку шейдеров:

ERROR: 0:2: 'in' : storage qualifier supported in GLSL ES 3.00 and above only
ERROR: 0:3: 'in' : storage qualifier supported in GLSL ES 3.00 and above only
ERROR: 0:4: 'in' : storage qualifier supported in GLSL ES 3.00 and above only
ERROR: 0:6: 'out' : storage qualifier supported in GLSL ES 3.00 and above only
ERROR: 0:7: 'out' : storage qualifier supported in GLSL ES 3.00 and above only
ERROR: 0:8: 'out' : storage qualifier supported in GLSL ES 3.00 and above only
ERROR: 0:18: '*' : wrong operand types - no operation '*' exists that takes a left-hand operand of type 'uniform highp 4X4 matrix of float' and a right operand of type 'in highp 3-component vector of float' (or there is no acceptable conversion)
ERROR: 0:18: 'normalize' : no matching overloaded function found
ERROR: 0:18: '=' : dimension mismatch
ERROR: 0:18: 'assign' : cannot convert from 'const mediump float' to 'out highp 3-component vector of float'

1 Ответ

0 голосов
/ 31 марта 2020

Ваши ошибки означают, что вы пытаетесь использовать шейдер WebGL2 в WebGL1

'in': квалификатор хранилища поддерживается только в GLSL ES 3.00 и выше

означает вы использовали in, как в

in vec4 position;`

, который действителен только в GLSL ES 3.00 и выше, точно так же, как сказано:

Чтобы сделать Shaer GLSL ES 3.00, первая строка должна быть

#version 300 es

Но если сделать это, вы получите новую ошибку, которая #version 300 es недопустима в WebGL1

У вас есть 2 варианта

  1. Switch в WebGL2.

    Измените ваш getContext вызов, чтобы использовать webgl2 вместо webgl, а затем добавьте #version 300 es в качестве первой строки ваших шейдеров

  2. Перепишите ваши шейдеры использовать GLSL 1.0

    . В этом случае скажите работать с WebGL1.

Кроме того, ваша строка 18 должна быть похожа на

    Normal = normalize(mat3(uNormalMatrix) * VertexNormal);

или

    Normal = normalize((uNormalMatrix * vec4(VertexNormal, 0)).xyz);
...