webgl图像滑块

时间:2011-05-17 10:29:14

标签: javascript web textures webgl

我是webgl的新手,我正在尝试创建一个图像滑块。现在我只是制作了图像的环(没有什么应该滑动)但它不起作用,我不知道为什么(我得到的是黑色帆布,没有错误)。 我基本上从本指南http://learningwebgl.com/blog/?p=507中获取了代码并对其进行了修改:

<html>

<head>
<title>Learning WebGL &mdash; lesson 5</title>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">

<script type="text/javascript" src="glMatrix-0.9.5.min.js"></script>
<script type="text/javascript" src="webgl-utils.js"></script>

<script id="shader-fs" type="x-shader/x-fragment">
#ifdef GL_ES
precision highp float;
#endif

varying vec2 vTextureCoord;

uniform sampler2D uSampler;

void main(void) {
    gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));
}
</script>

<script id="shader-vs" type="x-shader/x-vertex">
attribute vec3 aVertexPosition;
attribute vec2 aTextureCoord;

uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;

varying vec2 vTextureCoord;


void main(void) {
    gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
    vTextureCoord = aTextureCoord;
}
</script>


<script type="text/javascript">

var gl;
var pics_num=5;
var pics_names=["a.jpg","b.jpg","c.jpg","d.jpg","e.jpg"]


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.pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix");
    shaderProgram.mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix");
    shaderProgram.samplerUniform = gl.getUniformLocation(shaderProgram, "uSampler");
}


function handleLoadedTexture(texture) {
    gl.bindTexture(gl.TEXTURE_2D, texture);
    gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture.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, null);
}

function loadTexture(image) {
    var texture=gl.createTexture();
    texture.image=new Image()
    texture.image.onload = function () {
            handleLoadedTexture(texture)
    }
    texture.image.src = image;
    return texture;
}


//var neheTexture;
var Texture_array=new Array();  

function initTexture() {
    for (var i=0;i<pics_num;i=i+1)
    {
        //Texture_array[i] = gl.createTexture();
        //Texture_array[i].image = new Image();
        //Texture_array[i].image.onload = function () {
        //    handleLoadedTexture(Texture_array[i])
        //}

        //Texture_array[i].image.src = pics_names[i];
        Texture_array[i]=loadTexture(pics_names[i]);
    }
}






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 "Invalid popMatrix!";
    }
    mvMatrix = mvMatrixStack.pop();
}


function setMatrixUniforms() {
    gl.uniformMatrix4fv(shaderProgram.pMatrixUniform, false, pMatrix);
    gl.uniformMatrix4fv(shaderProgram.mvMatrixUniform, false, mvMatrix);
}


function degToRad(degrees) {
    return degrees * Math.PI / 180;
}

var VertexPositionBuffer=new Array();
var VertexTextureCoordBuffer=new Array();
var VertexIndexBuffer=new Array();

function initBuffers() {
    for (var i=0;i<pics_num;i=i+1)
    {
        VertexPositionBuffer[i] = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, VertexPositionBuffer[i]);
        vertices = [
             Math.cos(i*((2*Math.PI)/pics_num)), -1.0,  Math.sin(i*((2*Math.PI)/pics_num)),
              Math.cos(i*((2*Math.PI)/pics_num)), -1.0,  Math.sin(i*((2*Math.PI)/pics_num)),
            Math.cos((i+1)*((2*Math.PI)/pics_num)), 1.0, Math.sin((i+1)*((2*Math.PI)/pics_num)),
              Math.cos((i+1)*((2*Math.PI)/pics_num)), 1.0,  Math.sin((i+1)*((2*Math.PI)/pics_num)),

        ];
        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
        VertexPositionBuffer[i].itemSize = 3;
        VertexPositionBuffer[i].numItems = 4;

        VertexTextureCoordBuffer[i] = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER,  VertexTextureCoordBuffer[i] );
        var textureCoords = [
          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);
        VertexTextureCoordBuffer[i].itemSize = 2;
        VertexTextureCoordBuffer[i].numItems = 4;

        VertexIndexBuffer[i] = gl.createBuffer();
        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, VertexIndexBuffer[i]);
        var cubeVertexIndices = [
            0, 1, 2,      0, 2, 3,  
        ];
        gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(cubeVertexIndices), gl.STATIC_DRAW);
        VertexIndexBuffer[i].itemSize = 1;
        VertexIndexBuffer[i].numItems = 6;
    }
}



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, -5.0]);

    for (var i=0;i<pics_num;i=i+1)
    {
        mvPushMatrix();
        gl.bindBuffer(gl.ARRAY_BUFFER, VertexPositionBuffer[i]);
        gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, VertexPositionBuffer[i].itemSize, gl.FLOAT, false, 0, 0);

        gl.bindBuffer(gl.ARRAY_BUFFER, VertexTextureCoordBuffer[i]);
        gl.vertexAttribPointer(shaderProgram.textureCoordAttribute, VertexTextureCoordBuffer[i].itemSize, gl.FLOAT, false, 0, 0);

        gl.activeTexture(gl.TEXTURE0);
        gl.bindTexture(gl.TEXTURE_2D, Texture_array[i]);
        gl.uniform1i(shaderProgram.samplerUniform, 0);

        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, VertexIndexBuffer[i]);
        setMatrixUniforms();
        gl.drawElements(gl.TRIANGLES, VertexIndexBuffer[i].numItems, gl.UNSIGNED_SHORT, 0);
        mvPopMatrix();
    }
}






function webGLStart() {
    var canvas = document.getElementById("lesson05-canvas");
    initGL(canvas);
    initShaders();
    initBuffers();
    initTexture();

    gl.clearColor(0.0, 0.0, 0.0, 1.0);
    gl.enable(gl.DEPTH_TEST);

    drawScene();
}


</script>


</head>


<body onload="webGLStart();">
<a href="http://learningwebgl.com/blog/?p=507">&lt;&lt; Back to Lesson 5</a><br />

<canvas id="lesson05-canvas" style="border: none;" width="500" height="500"></canvas>

<br/>
<a href="http://learningwebgl.com/blog/?p=507">&lt;&lt; Back to Lesson 5</a><br />
</body>

</html>

最终目标是能够创建一个用户可以向左滚动并写入以查看所有图像的图像环。 任何帮助将不胜感激。

感谢您的帮助, palaviv

2 个答案:

答案 0 :(得分:0)

你的顶点被设置为它们形成一条线而不是一个四边形(所以没有任何东西出现)。

将第二个顶点的Y坐标更改为1.0,将最后一个顶点更改为-1.0,您应该看到一些可见的东西。 (好吧,你还需要在加载所有图像后调用drawScene。你可以在handleLoadedTexture的末尾添加一个drawScene()调用,或者设置一个requestAnimFrame循环或者其他东西。)

为了调试这样的绘图probs,绘制恒定颜色像素的片段着色器非常有用(gl_FragColor = vec4(1.0,0.0,1.0,1.0)),可以帮助你弄清楚它是否是片段着色器/纹理概率或者顶点管道问题。

希望这有帮助,

ILMARI

答案 1 :(得分:0)

感谢男人,它真的帮助了我。我为这个愚蠢的错误感到羞愧。 任何方式它现在工作得很好所以我认为不好上传代码,以便任何想要的人都可以使用它。现在我只能出于某种原因加载gif图像,所以如果有人知道为什么它会有所帮助。

固定代码:

<html>

<head>
<title>Learning WebGL &mdash; lesson 5</title>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">

<script type="text/javascript" src="glMatrix-0.9.5.min.js"></script> 
<script type="text/javascript" src="webgl-utils.js"></script>

<script id="shader-fs" type="x-shader/x-fragment">
#ifdef GL_ES
precision highp float;
#endif

varying vec2 vTextureCoord;

uniform sampler2D uSampler;

void main(void) {
    gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));
    //gl_FragColor = vec4(1.0, 0.0, 1.0, 1.0);
}
</script>

<script id="shader-vs" type="x-shader/x-vertex">
attribute vec3 aVertexPosition;
attribute vec2 aTextureCoord;

uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;

varying vec2 vTextureCoord;


void main(void) {
    gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
    vTextureCoord = aTextureCoord;
}
</script>


<script type="text/javascript">

var gl;
var pics_num;
var pics_names=["nehe.gif","moon.gif","nehe.gif","nehe.gif","nehe.gif","nehe.gif","moon.gif","moon.gif"]
pics_num=pics_names.length;

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.pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix");
    shaderProgram.mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix");
    shaderProgram.samplerUniform = gl.getUniformLocation(shaderProgram, "uSampler");
}


function handleLoadedTexture(texture) {
    gl.bindTexture(gl.TEXTURE_2D, texture);
    gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture.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, null);
}

function loadTexture(image) {
    var texture=gl.createTexture();
    texture.image=new Image()
    texture.image.onload = function () {
            handleLoadedTexture(texture);
            //drawScene();
    }
    texture.image.src = image;
    return texture;
}


//var neheTexture;
var Texture_array=new Array();  

function initTexture() {
    for (var i=0;i<pics_num;i=i+1)
    {
        //Texture_array[i] = gl.createTexture();
        //Texture_array[i].image = new Image();
        //Texture_array[i].image.onload = function () {
        //    handleLoadedTexture(Texture_array[i])
        //}

        //Texture_array[i].image.src = pics_names[i];
        Texture_array[i]=loadTexture(pics_names[i]);
    }
    //gl.clearColor(0.0, 0.0, 0.0, 1.0);
    //gl.enable(gl.DEPTH_TEST);
    //drawScene();

}






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 "Invalid popMatrix!";
    }
    mvMatrix = mvMatrixStack.pop();
}


function setMatrixUniforms() {
    gl.uniformMatrix4fv(shaderProgram.pMatrixUniform, false, pMatrix);
    gl.uniformMatrix4fv(shaderProgram.mvMatrixUniform, false, mvMatrix);
}


function degToRad(degrees) {
    return degrees * Math.PI / 180;
}

var VertexPositionBuffer=new Array();
var VertexTextureCoordBuffer=new Array();
var VertexIndexBuffer=new Array();

function initBuffers() {
    for (var i=0;i<pics_num;i=i+1)
    {
        VertexPositionBuffer[i] = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, VertexPositionBuffer[i]);
        vertices = [
             Math.cos(i*((2*Math.PI)/pics_num)), -0.5,  Math.sin(i*((2*Math.PI)/pics_num)),
              Math.cos(i*((2*Math.PI)/pics_num)), 0.5,  Math.sin(i*((2*Math.PI)/pics_num)),
            Math.cos((i+1)*((2*Math.PI)/pics_num)), 0.5, Math.sin((i+1)*((2*Math.PI)/pics_num)),
              Math.cos((i+1)*((2*Math.PI)/pics_num)), -0.5,  Math.sin((i+1)*((2*Math.PI)/pics_num)),

        ];
        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
        VertexPositionBuffer[i].itemSize = 3;
        VertexPositionBuffer[i].numItems = 4;

        VertexTextureCoordBuffer[i] = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER,  VertexTextureCoordBuffer[i] );
        var textureCoords = [
          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);
        VertexTextureCoordBuffer[i].itemSize = 2;
        VertexTextureCoordBuffer[i].numItems = 4;

        VertexIndexBuffer[i] = gl.createBuffer();
        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, VertexIndexBuffer[i]);
        var cubeVertexIndices = [
            0, 1, 2,      0, 2, 3,  
        ];
        gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(cubeVertexIndices), gl.STATIC_DRAW);
        VertexIndexBuffer[i].itemSize = 1;
        VertexIndexBuffer[i].numItems = 6;
    }
}

var mouseDown = false;
var lastMouseX = null;
var lastMouseY = null;

var RotationMatrix = mat4.create();
mat4.identity(RotationMatrix);

function handleMouseDown(event) {
    mouseDown = true;
    lastMouseX = event.clientX;
    lastMouseY = event.clientY;
}

function handleMouseUp(event) {
    mouseDown = false;
}

function handleMouseMove(event) {
    if (!mouseDown) {
      return;
    }
    var newX = event.clientX;
    var newY = event.clientY;

    var deltaX = newX - lastMouseX;
    var newRotationMatrix = mat4.create();
    mat4.identity(newRotationMatrix);
    mat4.rotate(newRotationMatrix, degToRad(deltaX / 5), [0, 1, 0]);

    var deltaY = newY - lastMouseY;
    mat4.rotate(newRotationMatrix, degToRad(deltaY / 5), [1, 0, 0]);

    mat4.multiply(newRotationMatrix, RotationMatrix, RotationMatrix);

    lastMouseX = newX
    lastMouseY = newY;
}


var MoveMatrix = mat4.create();
mat4.identity(MoveMatrix);

function handleMouseWheel(event) {
    mat4.translate(MoveMatrix, [0.0, 0.0, event.wheelDelta/120]);
}    

function drawScene() {
    gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

    mat4.perspective(30, gl.viewportWidth / gl.viewportHeight, 0.1, 100.0, pMatrix);

    mat4.identity(mvMatrix);

    mat4.translate(mvMatrix, [0.0, 0.0, -5.0]);

    mat4.multiply(mvMatrix, MoveMatrix);
    mat4.multiply(mvMatrix, RotationMatrix);


    for (var i=0;i<pics_num;i=i+1)
    {
        //mvPushMatrix();
        gl.bindBuffer(gl.ARRAY_BUFFER, VertexPositionBuffer[i]);
        gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, VertexPositionBuffer[i].itemSize, gl.FLOAT, false, 0, 0);

        gl.bindBuffer(gl.ARRAY_BUFFER, VertexTextureCoordBuffer[i]);
        gl.vertexAttribPointer(shaderProgram.textureCoordAttribute, VertexTextureCoordBuffer[i].itemSize, gl.FLOAT, false, 0, 0);

        gl.activeTexture(gl.TEXTURE0);
        gl.bindTexture(gl.TEXTURE_2D, Texture_array[i]);
        gl.uniform1i(shaderProgram.samplerUniform, 0);

        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, VertexIndexBuffer[i]);
        setMatrixUniforms();
        gl.drawElements(gl.TRIANGLES, VertexIndexBuffer[i].numItems, gl.UNSIGNED_SHORT, 0);
        //mvPopMatrix();
    }
}





function tick() {
    requestAnimFrame(tick);
    drawScene();
}




function webGLStart() {
    var canvas = document.getElementById("lesson05-canvas");
    initGL(canvas);
    initShaders();
    initBuffers();
    initTexture();


    gl.clearColor(0.0, 0.0, 0.0, 1.0);
    gl.enable(gl.DEPTH_TEST);

    canvas.onmousedown = handleMouseDown;
    document.onmouseup = handleMouseUp;
    document.onmousemove = handleMouseMove;
    document.onmousewheel = handleMouseWheel;
    tick();
}


</script>


</head>


<body onload="webGLStart();">
<a href="http://learningwebgl.com/blog/?p=507">&lt;&lt; Back to Lesson 5</a><br />

<canvas id="lesson05-canvas" style="border: none;" width="500" height="500"></canvas>

<br/>
<a href="http://learningwebgl.com/blog/?p=507">&lt;&lt; Back to Lesson 5</a><br />
</body>

</html>

您需要做的就是下载glMatrix-0.9.5.min.js,webgl-utils.js并更改第46行中pics_names数组中图片的名称。