webgl image slider
i am new to webgl and i am trying to make an image slider. for now i just made the ring of image (nothing should slide yet) but it does not work and i dont know why (all i get is black canvas and no errors). i basically took the code from this guide http://learningwebgl.com/blog/?p=507 and altered it:
<html>
<head>
<title>Learning WebGL — 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 开发者_StackOverflow中文版/ 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"><< 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"><< Back to Lesson 5</a><br />
</body>
</html>
the final goal is to be able to make a ring of images that the user will be able to scroll left and write to see them all. Any help will be appreciated.
thanks for the help, palaviv
Your vertices are set so that they form a line instead of a quad (and so nothing shows up).
Change the Y-coord of the second vert to 1.0 and the last vert to -1.0 and you should get something visible. (Well, you also need to call drawScene after all the images are loaded. You could add a drawScene() call to the end of handleLoadedTexture or set up a requestAnimFrame loop or somesuch.)
For debugging drawing probs like this, a fragment shader that draws constant color pixels is very helpful (gl_FragColor = vec4(1.0, 0.0, 1.0, 1.0)), helps you figure out if it's a fragment shader / texture prob or a vertex pipeline prob.
Hope this helps,
Ilmari
精彩评论