javascript WebGL - 无效的操作 useProgram
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11998781/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
WebGL - Invalid Operation useProgram
提问by cgasser
I'm learning WebGL and am on thistutorial that has to do with lighting. I'm new to JavaScript so I'm not so good at debugging it yet. I keep getting these errors, anyone know why I'm getting them and how to fix it?
我正在学习 WebGL,并且正在学习与照明有关的本教程。我是 JavaScript 的新手,所以我还不太擅长调试它。我不断收到这些错误,有人知道我为什么会收到这些错误以及如何解决吗?
WebGL: INVALID_OPERATION: useProgram: program not valid http://insanergamer.zxq.net/:1
WebGL: INVALID_OPERATION: getAttribLocation: program not linked http://insanergamer.zxq.net/:1
WebGL: INVALID_OPERATION: getUniformLocation: program not linked http://insanergamer.zxq.net/:1
WebGL: too many errors, no more errors will be reported to the console for this context.
index.html
索引.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf 8" />
<link rel="stylesheet" href="main.css">
<script type="text/javascript" language="javascript" src="gl-matrix.js"></script>
<script type="text/javascript" language="javascript" src="webgl-utils.js"></script>
<script type="text/javascript" language="javascript" src="first.js"></script>
<script id="shader-fs" type="x-shader/x-fragment">
precision mediump float;
varying vec2 vTextureCoord;
varying vec3 vLightWeighting;
uniform sampler2D uSampler;
void main(void) {
vec4 textureColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));
gl_FragColor = vec4(textureColor.rgb * vLightWeighting, textureColor.a);
}
</script>
<script id="shader-vs" type="x-shader/x-vertex">
attribute vec3 aVertexPosition;
attribute vec3 aVertexNormal;
attribute vec2 aTextureCoord;
uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;
uniform mat3 uNMatrix;
uniform vec3 uAmbientColor;
uniform vec3 uLightingDirection;
uniform vec3 uDirectionalColor;
uniform bool uUseLighting;
varying vec2 vTextureCoord;
varying vec3 vLightWeighting;
void main(void) {
gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
vTextureCoord = aTextureCoord;
if (!uUseLighting) {
vLightWeighting = vec3(1.0, 1.0, 1.0);
} else {
vec3 transformedNormal = uNMatrix * aVertexNormal;
float directionalLightWeighting = max(dot(transformedNormal, uLightingDirection), 0.0);
vLightWeighting = uAmbientColor + uDirectionalColor * directionalLightWeighting;
}
</script>
</head>
<body onLoad="webGLStart()">
<header>
</header>
<nav>
</nav>
<section>
<h3><a href="todo.html">Link to the TODO page.</a></h3>
<form>
<input type="checkbox" id="lighting"></input>Lighting On/Off<br />
Ambient Lighting Color: Red:<input type="text" id="ambientR"></input> Green:<input type="text" id="ambientG"></input> Blue:<input type="text" id="ambientB"></input> <br />
Light Direction: X:<input type="text" id="lightDirectionX"></input> Y:<input type="text" id="lightDirectionY"></input> Z:<input type="text" id="lightDirectionZ"></input> <br />
Direction Lighting Color: Red:<input type="text" id="directionalR"></input> Green:<input type="text" id="directionalG"></input> Blue:<input type="text" id="directionalB"></input> <br />
</form>
<p>Press 'F' to change Texture quality.</p>
<p>Use Arrow Keys to rotate cube.</p>
<p>Page Up and Page down to zoom in and out.</p>
<canvas canvasProperties="prop" id="canvas1" style="border: none;" width="1280" height="720"></canvas>
<article>
<header>
</header>
<footer>
</footer>
</article>
</section>
<aside>
</aside>
<footer>
</footer>
</body>
first.js
第一个.js
var gl;
function initGL(canvas) {
try {
gl = canvas.getContext("experimental-webgl");
gl.viewportWidth = canvas.width;
gl.viewportHeight = canvas.height;
} catch (e) {
}
if (!gl) {
alert("Could not initialise WebGL, sorry :-(");
}
}
function getShader(gl, id) {
var shaderScript = document.getElementById(id);
if (!shaderScript) {
return null;
}
var str = "";
var k = shaderScript.firstChild;
while (k) {
if (k.nodeType == 3) {
str += k.textContent;
}
k = k.nextSibling;
}
var shader;
if (shaderScript.type == "x-shader/x-fragment") {
shader = gl.createShader(gl.FRAGMENT_SHADER);
} else if (shaderScript.type == "x-shader/x-vertex") {
shader = gl.createShader(gl.VERTEX_SHADER);
} else {
return null;
}
gl.shaderSource(shader, str);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
alert(gl.getShaderInfoLog(shader));
return null;
}
return shader;
}
var shaderProgram;
function initShaders() {
var fragmentShader = getShader(gl, "shader-fs");
var vertexShader = getShader(gl, "shader-vs");
shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
gl.linkProgram(shaderProgram);
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
alert("Could not initialise shaders");
}
gl.useProgram(shaderProgram);
shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);
shaderProgram.textureCoordAttribute = gl.getAttribLocation(shaderProgram, "aTextureCoord");
gl.enableVertexAttribArray(shaderProgram.textureCoordAttribute);
shaderProgram.vertexNormalAttribute = gl.getAttribLocation(shaderProgram, "aVertexNormal");
gl.enableVertexAttribArray(shaderProgram.vertexNormalAttribute);
shaderProgram.pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix");
shaderProgram.mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix");
shaderProgram.nMatrixUniform = gl.getUniformLocation(shaderProgram, "uNMatrix");
shaderProgram.samplerUniform = gl.getUniformLocation(shaderProgram, "uSampler");
shaderProgram.useLightingUniform = gl.getUniformLocation(shaderProgram, "uUseLighting");
shaderProgram.ambientColorUniform = gl.getUniformLocation(shaderProgram, "uAmbientColor");
shaderProgram.lightingDirectionUniform = gl.getUniformLocation(shaderProgram, "uLightingDirection");
shaderProgram.directionalColorUniform = gl.getUniformLocation(shaderProgram, "uDirectionalColor");
}
var cubeTextures = Array();
function initTexture()
{
var cubeImage = new Image();
for(var i=0;i < 3; i++)
{
var texture = gl.createTexture();
texture.image = cubeImage;
cubeTextures.push(texture);
}
cubeImage.onload = function()
{
handleLoadedTexture(cubeTextures);
}
cubeImage.src = "cube.png";
}
function handleLoadedTexture(texture)
{
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
gl.bindTexture(gl.TEXTURE_2D,texture[0]);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture[0].image);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.bindTexture(gl.TEXTURE_2D, texture[1]);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture[1].image);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.bindTexture(gl.TEXTURE_2D, texture[2]);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture[2].image);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_NEAREST);
gl.generateMipmap(gl.TEXTURE_2D);
gl.bindTexture(gl.TEXTURE_2D, null);
}
var mvMatrix = mat4.create();
var mvMatrixStack = []
var pMatrix = mat4.create();
function mvPushMatrix()
{
var copy = mat4.create();
mat4.set(mvMatrix, copy);
mvMatrixStack.push(copy);
}
function mvPopMatrix()
{
if(mvMatrixStack.length == 0)
{
throw "No Matrix to Pop!";
}
mvMatrix = mvMatrixStack.pop();
}
function degToRad(degrees)
{
return degrees * Math.PI / 180;
}
function setMatrixUniforms() {
gl.uniformMatrix4fv(shaderProgram.pMatrixUniform, false, pMatrix);
gl.uniformMatrix4fv(shaderProgram.mvMatrixUniform, false, mvMatrix);
var normalMatrix = mat3.create();
mat4.toInverseMat3(mvMatrix, normalMatrix);
mat3.transpose(normalMatrix);
gl.uniformMatrix3fv(shaderProgram.nMatrixUniform, false, normalMatrix);
}
var cubeVertexPositionBuffer;
var cubeVertexTextureCoordBuffer;
var cubeVertexIndexBuffer;
function initBuffers() {
cubeVertexPositionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer);
vertices = [
// Front face
-1.0, -1.0, 1.0,
1.0, -1.0, 1.0,
1.0, 1.0, 1.0,
-1.0, 1.0, 1.0,
// Back face
-1.0, -1.0, -1.0,
-1.0, 1.0, -1.0,
1.0, 1.0, -1.0,
1.0, -1.0, -1.0,
// Top face
-1.0, 1.0, -1.0,
-1.0, 1.0, 1.0,
1.0, 1.0, 1.0,
1.0, 1.0, -1.0,
// Bottom face
-1.0, -1.0, -1.0,
1.0, -1.0, -1.0,
1.0, -1.0, 1.0,
-1.0, -1.0, 1.0,
// Right face
1.0, -1.0, -1.0,
1.0, 1.0, -1.0,
1.0, 1.0, 1.0,
1.0, -1.0, 1.0,
// Left face
-1.0, -1.0, -1.0,
-1.0, -1.0, 1.0,
-1.0, 1.0, 1.0,
-1.0, 1.0, -1.0,
];
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
cubeVertexPositionBuffer.itemSize = 3;
cubeVertexPositionBuffer.numItems = 24;
cubeVertexNormalBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexNormalBuffer);
var vertexNormals = [
// Front face
0.0, 0.0, 1.0,
0.0, 0.0, 1.0,
0.0, 0.0, 1.0,
0.0, 0.0, 1.0,
// Back face
0.0, 0.0, -1.0,
0.0, 0.0, -1.0,
0.0, 0.0, -1.0,
0.0, 0.0, -1.0,
// Top face
0.0, 1.0, 0.0,
0.0, 1.0, 0.0,
0.0, 1.0, 0.0,
0.0, 1.0, 0.0,
// Bottom face
0.0, -1.0, 0.0,
0.0, -1.0, 0.0,
0.0, -1.0, 0.0,
0.0, -1.0, 0.0,
// Right face
1.0, 0.0, 0.0,
1.0, 0.0, 0.0,
1.0, 0.0, 0.0,
1.0, 0.0, 0.0,
// Left face
-1.0, 0.0, 0.0,
-1.0, 0.0, 0.0,
-1.0, 0.0, 0.0,
-1.0, 0.0, 0.0
];
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertexNormals), gl.STATIC_DRAW);
cubeVertexNormalBuffer.itemSize = 3;
cubeVertexNormalBuffer.numItems = 24;
cubeVertexTextureCoordBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexTextureCoordBuffer);
var textureCoords = [
// Front face
0.0, 0.0,
1.0, 0.0,
1.0, 1.0,
0.0, 1.0,
// Back face
1.0, 0.0,
1.0, 1.0,
0.0, 1.0,
0.0, 0.0,
// Top face
0.0, 1.0,
0.0, 0.0,
1.0, 0.0,
1.0, 1.0,
// Bottom face
1.0, 1.0,
0.0, 1.0,
0.0, 0.0,
1.0, 0.0,
// Right face
1.0, 0.0,
1.0, 1.0,
0.0, 1.0,
0.0, 0.0,
// Left face
0.0, 0.0,
1.0, 0.0,
1.0, 1.0,
0.0, 1.0,
];
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textureCoords), gl.STATIC_DRAW);
cubeVertexTextureCoordBuffer.itemSize = 2;
cubeVertexTextureCoordBuffer.numItems = 24;
cubeVertexIndexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer);
var cubeVertexIndices = [
0, 1, 2, 0, 2, 3, // Front face
4, 5, 6, 4, 6, 7, // Back face
8, 9, 10, 8, 10, 11, // Top face
12, 13, 14, 12, 14, 15, // Bottom face
16, 17, 18, 16, 18, 19, // Right face
20, 21, 22, 20, 22, 23 // Left face
]
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(cubeVertexIndices), gl.STATIC_DRAW);
cubeVertexIndexBuffer.itemSize = 1;
cubeVertexIndexBuffer.numItems = 36;
}
var rCubeX = 0;
var SpeedX = 0;
var rCubeY = 0;
var SpeedY = 0;
var z = -5.0;
var filter = 0;
function drawScene() {
gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
mat4.perspective(45, gl.viewportWidth / gl.viewportHeight, 0.1, 100.0, pMatrix);
mat4.identity(mvMatrix);
mat4.translate(mvMatrix, [0.0, 0.0, z]);
mvPushMatrix();
mat4.rotate(mvMatrix, degToRad(rCubeX), [1, 0, 0]);
mat4.rotate(mvMatrix, degToRad(rCubeY), [0, 1, 0]);
gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer);
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, cubeVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexNormalBuffer);
gl.vertexAttribPointer(shaderProgram.vertexNormalAttribute, cubeVertexNormalBuffer.itemSize, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexTextureCoordBuffer);
gl.vertexAttribPointer(shaderProgram.textureCoordAttribute, cubeVertexTextureCoordBuffer.itemSize, gl.FLOAT, false, 0, 0);
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, cubeTextures[filter]);
gl.uniform1i(shaderProgram.samplerUniform, 0);
var lighting = document.getElementById("lighting").checked;
gl.uniform1i(shaderProgram.useLightingUniform, lighting);
if(lighting)
{
gl.uniform3f(
shaderProgram.ambientColorUniform,
parseFloat(document.getElementById("ambientR").value),
parseFloat(document.getElementById("ambientG").value),
parseFloat(document.getElementById("ambientB").value)
);
}
var lightingDirection = [
parseFloat(document.getElementById("lightDirectionX").value),
parseFloat(document.getElementById("lightDirectionY").value),
parseFloat(document.getElementById("lightDirectionZ").value)
];
var adjustedLD = vec3.create();
vec3.normalize(lightingDirection, adjustedLD);
vec3.scale(adjustedLD, -1);
gl.uniform3fv(shaderProgram.lightingDirectionUniform, adjustedLD);
gl.uniform3f(
shaderProgram.directionalColorUniform,
parseFloat(document.getElementById("directionalR").value),
parseFloat(document.getElementById("directionalG").value),
parseFloat(document.getElementById("directionalB").value)
);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer);
setMatrixUniforms();
gl.drawElements(gl.TRIANGLES, cubeVertexIndexBuffer.numItems, gl.UNSIGNED_SHORT, 0);
mvPopMatrix();
}
var lastTime = 0;
function animate()
{
var timeNow = new Date().getTime();
if(lastTime != 0)
{
var elapsed = timeNow - lastTime;
rCubeX += (SpeedX * elapsed) / 1000.0;
rCubeY += (SpeedY * elapsed) / 1000.0;
}
lastTime = timeNow;
}
var currentlyPressedKeys = {};
function handleKeyDown(event){
currentlyPressedKeys[event.keyCode] = true;
if(String.fromCharCode(event.keyCode) == "F"){
filter += 1;
if(filter == 3){
filter = 0;
}
}
}
function handleKeyUp(event){
currentlyPressedKeys[event.keyCode] = false;
}
function handleKeys()
{
if(currentlyPressedKeys[33])
{
z -= 0.05;
}
if(currentlyPressedKeys[34])
{
z += 0.05;
}
if(currentlyPressedKeys[37])
{
SpeedY --;
} else if (SpeedY < 0){
SpeedY ++;
}
if(currentlyPressedKeys[39])
{
SpeedY ++;
}else if(SpeedY > 0){
SpeedY --;
}
if (currentlyPressedKeys[38]) {
SpeedX --;
} else if(SpeedX < 0){
SpeedX ++;
}
if (currentlyPressedKeys[40]) {
SpeedX ++;
} else if(SpeedX > 0){
SpeedX--;
}
}
function update()
{
requestAnimFrame(update);
handleKeys();
drawScene();
animate();
}
function webGLStart() {
var canvas = document.getElementById("canvas1");
initGL(canvas);
initShaders();
initBuffers();
initTexture();
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.enable(gl.DEPTH_TEST);
document.onkeydown = handleKeyDown;
document.onkeyup = handleKeyUp;
update();
}
采纳答案by Brendan Kenny
The cause in this particular case is that you're missing a closing } at the end of your vertex shader, though that doesn't answer why you aren't seeing a message about why your shader is failing to compile.
在这种特殊情况下,原因是您在顶点着色器的末尾错过了一个结束 },尽管这并不能回答为什么您没有看到有关您的着色器无法编译的消息的原因。
Your error checking code in getShader
actually looks like it should work fine, and you do in fact check and alert the error logs Clutch mentioned when compilation and linking fails.
您的错误检查代码getShader
实际上看起来应该可以正常工作,并且您实际上会检查并提醒编译和链接失败时提到的错误日志 Clutch。
When I copied your code and ran it verbatim, it correctly gave me an error ("unexpected EOF"), so maybe you have javascript alerts turned off? You might consider using console.log
instead of alerting and getting to know the Javascript console in your favorite browser.
当我复制您的代码并逐字运行时,它正确地给了我一个错误(“意外的 EOF”),所以也许您关闭了 javascript 警报?您可能会考虑使用console.log
您最喜欢的浏览器中的 Javascript 控制台来代替警报并了解它。
回答by Cutch
WebGL is giving you a big hint with the console log messages:
WebGL 通过控制台日志消息为您提供了一个重要提示:
WebGL: INVALID_OPERATION: useProgram: program not valid WebGL: INVALID_OPERATION: getAttribLocation: program not linked
WebGL:INVALID_OPERATION:useProgram:程序无效 WebGL:INVALID_OPERATION:getAttribLocation:程序未链接
The program is not linked and therefore can't be used or it's state queried.
该程序未链接,因此无法使用或查询其状态。
Your program does seem to be checking that the shaders compiled correctly and that the program is linked, but that's not the case. There is likely something wrong with your error checking code, hiding the real issue. I always call these two functions on freshly compiled shaders and recently linked programs:
您的程序似乎确实在检查着色器是否正确编译以及程序是否已链接,但事实并非如此。您的错误检查代码可能有问题,隐藏了真正的问题。我总是在新编译的着色器和最近链接的程序上调用这两个函数:
getShaderInfoLog
获取着色器信息日志
getProgramInfoLog
获取程序信息日志
They both return strings and will help you get to the root cause.
它们都返回字符串并将帮助您找到根本原因。
回答by Ivan Bacher
I was also getting these weird errors, but only in Chrome and not in firefox:
我也遇到了这些奇怪的错误,但只在 Chrome 中而不是在 Firefox 中:
WebGL: INVALID_OPERATION: getAttribLocation: program not linked
WebGL: INVALID_OPERATION: getUniformLocation: program not linked
WebGL: INVALID_OPERATION: useProgram: program not valid
WebGL: INVALID_OPERATION: getAttribLocation: program not linked
WebGL: INVALID_OPERATION: getUniformLocation: program not linked
I also noticed that most of the examples on the http://threejs.org/throw errors to (only in chrome). Any by redownloading the source, i was able to get rid of the errors.
我还注意到http://threejs.org/上的大多数示例都会向(仅在 chrome 中)抛出错误。任何通过重新下载源代码,我都能够摆脱错误。
回答by akarve
Use an updated version of three.js, e.g. from this CDN http://cdnjs.com/libraries/three.js. Older versions throw the above errors on valid code.
使用three.js 的更新版本,例如来自此CDN http://cdnjs.com/libraries/three.js。旧版本在有效代码上抛出上述错误。