слайдер изображений webgl - PullRequest
1 голос
/ 17 мая 2011

Я новичок в 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 голосов
/ 19 мая 2011

спасибо, мужик, это действительно помогло мне.мне стыдно за эту глупую ошибку.Во всяком случае, теперь это работает довольно хорошо, поэтому я подумал, что не могу загрузить код, чтобы любой желающий мог его использовать.сейчас я могу загружать изображения 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 и измените имена картинок в массиве pics_names в строке 46.

0 голосов
/ 18 мая 2011

Ваши вершины установлены так, что они образуют линию вместо четырехугольника (и поэтому ничего не отображается).

Измените Y-координату второго вершины на 1,0, а последний вершина на -1,0 иВы должны получить что-то видимое.(Ну, вам также нужно вызывать drawScene после загрузки всех изображений. Вы можете добавить вызов drawScene () в конец handleLoadedTexture или настроить цикл requestAnimFrame или что-нибудь подобное.)

Для отладки графических проб, таких какэтот фрагментный шейдер, который рисует постоянные цветные пиксели, очень полезен (gl_FragColor = vec4 (1.0, 0.0, 1.0, 1.0)), помогает выяснить, является ли это фрагментным шейдером / текстурой или вершинным конвейером.

Надеюсь, это поможет,

Илмари

...