diff --git a/panorama-viewer.js b/panorama-viewer.js index f1fbbe1..787ff7c 100644 --- a/panorama-viewer.js +++ b/panorama-viewer.js @@ -10,7 +10,7 @@ // The number of parallels, including the poles, dividing the sphere's surface. // Two parallels would make a vertical line segment. if (parallels < 3) { - throw "parallels must be ≥ 3"; + // throw "parallels must be ≥ 3"; } const radius = 1; @@ -18,8 +18,8 @@ const positions = new Float32Array(meridians * parallels * 3); let positionsIdx = 0; for (let p = 0; p < parallels; p++) { - const y = -radius + p * 2 * radius / parallels; - for (let m = 0; m < meridians; m++) { + const y = p * 2 * radius / (parallels - 1) - radius; + for (let m = 0; m <= meridians; m++) { const θ = m * 2 * Math.PI / meridians; const x = Math.sin(θ) * radius; const z = Math.cos(θ) * radius; @@ -58,14 +58,14 @@ const currTextureCoords = [ // Lower triangle - m / meridians, p / parallels, - (m + 1) / meridians, p / parallels, - (m + 1) / meridians, (p + 1) / parallels, + m / meridians, p / (parallels - 1), + (m + 1) / meridians, p / (parallels - 1), + (m + 1) / meridians, (p + 1) / (parallels - 1), // Upper triangle - m / meridians, p / parallels, - (m + 1) / meridians, (p + 1) / parallels, - m / meridians, (p + 1) / parallels, + m / meridians, p / (parallels - 1), + (m + 1) / meridians, (p + 1) / (parallels - 1), + m / meridians, (p + 1) / (parallels - 1), ]; for (const coord of currTextureCoords) { textureCoords[textureCoordsIdx++] = coord; @@ -73,9 +73,13 @@ } } - return { positions, textureCoords, indices }; + return { + positions, textureCoords, indices, + positionStride: 3 * positions.constructor.BYTES_PER_ELEMENT, + textureCoordStride: 2 * textureCoords.constructor.BYTES_PER_ELEMENT, + }; } - console.log(makeCylinder()); + // console.log(makeCylinder()); const initShaderProgram = (gl) => { const vShaderSrc = ` @@ -97,7 +101,12 @@ uniform sampler2D sampler; void main() { - gl_FragColor = texture2D(sampler, vTextureCoord); + if (gl_FrontFacing) { + gl_FragColor = texture2D(sampler, vTextureCoord); + } else { + gl_FragColor = vec4(0.5,0,0,1); + } + } `; @@ -138,18 +147,19 @@ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); }); return texture; }; let viewer = document.getElementById("viewer"); - let gl = viewer.getContext("webgl2"); + let gl = viewer.getContext("webgl"); let program = initShaderProgram(gl); let modelMatrixLocation = gl.getUniformLocation(program, "modelMatrix"); // Set up mouse-panning state machine. let θy = 0; - let θx = 0.25; + let θx = 0; const PanState = Object.freeze({ idle: (event) => { if (event.type === "mousedown") { @@ -184,29 +194,24 @@ viewer.addEventListener("mousemove", runPanState); gl.useProgram(program); - let vertexBuffer = gl.createBuffer(); - let vertices = new Float32Array([ - // x, y, z, u, v - 0, 0, 0, 0, 0, - 1, 0, 0, 1, 0, - 1, 1, 0, 1, 1, - 0, 1, 0, 0, 1, - ]); - const vertexStride = 4 * 5; - const positionOffset = 0; - const textureCoordOffset = 4 * 3; - gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW); + const cylinder = makeCylinder(3, 3); + console.log(cylinder); + + let positionBuffer = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer); + gl.bufferData(gl.ARRAY_BUFFER, cylinder.positions, gl.STATIC_DRAW); const positionLocation = gl.getAttribLocation(program, "position"); + + let textureCoordBuffer = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, textureCoordBuffer); + gl.bufferData(gl.ARRAY_BUFFER, cylinder.textureCoords, gl.STATIC_DRAW); const textureCoordLocation = gl.getAttribLocation(program, "textureCoord"); let indexBuffer = gl.createBuffer(); - let indices = new Uint16Array([ - 0, 1, 2, - 3, 0, 2, - ]); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW); + gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, cylinder.indices, gl.STATIC_DRAW); + + gl.enable(gl.CULL_FACE); // Load texture let image = document.getElementById("image"); @@ -222,14 +227,16 @@ mat4.rotateY(modelMatrix, modelMatrix, θy); gl.uniformMatrix4fv(modelMatrixLocation, false, modelMatrix); - gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer); + gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer); gl.enableVertexAttribArray(positionLocation); - gl.vertexAttribPointer(positionLocation, 3, gl.FLOAT, false, vertexStride, positionOffset); - gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT, 0); + gl.vertexAttribPointer(positionLocation, 3, gl.FLOAT, false, 0, 0); + gl.bindBuffer(gl.ARRAY_BUFFER, textureCoordBuffer); gl.enableVertexAttribArray(textureCoordLocation); - gl.vertexAttribPointer(textureCoordLocation, 2, gl.FLOAT, false, vertexStride, textureCoordOffset); + gl.vertexAttribPointer(textureCoordLocation, 2, gl.FLOAT, false, 0, 0); + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer); + gl.drawElements(gl.TRIANGLES, 12, gl.UNSIGNED_SHORT, 0); requestAnimationFrame(render); };