mirror of
https://github.com/cds-astro/aladin-lite.git
synced 2025-12-31 07:02:45 -08:00
447 lines
14 KiB
HTML
447 lines
14 KiB
HTML
<html>
|
|
|
|
<head>
|
|
<title>Aladin WebGL</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 type="text/javascript" src="healpix.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>
|
|
|
|
|
|
<script type="text/javascript"><!--
|
|
|
|
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");
|
|
}
|
|
|
|
|
|
function handleLoadedTexture(texture) {
|
|
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
|
|
gl.bindTexture(gl.TEXTURE_2D, texture);
|
|
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_MIPMAP_NEAREST);
|
|
gl.generateMipmap(gl.TEXTURE_2D);
|
|
|
|
gl.bindTexture(gl.TEXTURE_2D, null);
|
|
}
|
|
|
|
|
|
var moonTexture;
|
|
var textureImg;
|
|
|
|
function initTexture() {
|
|
moonTexture = gl.createTexture();
|
|
textureImg = new Image();
|
|
textureImg.onload = function () {
|
|
moonTexture.image = scaleImageAsPowerOfTwo(textureImg);
|
|
console.log(moonTexture.image.width);
|
|
console.log(moonTexture.image.height);
|
|
handleLoadedTexture(moonTexture)
|
|
}
|
|
|
|
textureImg.src = "mellinger.jpg";
|
|
}
|
|
|
|
function isPowerOfTwo(x) {
|
|
return (x & (x - 1)) == 0;
|
|
}
|
|
|
|
function nextHighestPowerOfTwo(x) {
|
|
--x;
|
|
for (var i = 1; i < 32; i <<= 1) {
|
|
x = x | x >> i;
|
|
}
|
|
return x + 1;
|
|
}
|
|
|
|
function scaleImageAsPowerOfTwo(image) {
|
|
if (!isPowerOfTwo(image.width) || !isPowerOfTwo(image.height)) {
|
|
// Scale up the texture to the next highest power of two dimensions.
|
|
var canvas = document.createElement("canvas");
|
|
canvas.width = nextHighestPowerOfTwo(image.width);
|
|
canvas.height = nextHighestPowerOfTwo(image.height);
|
|
var ctx = canvas.getContext("2d");
|
|
ctx.drawImage(image, 0, 0, canvas.height, canvas.width);
|
|
image = canvas;
|
|
}
|
|
return image;
|
|
}
|
|
|
|
|
|
|
|
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);
|
|
|
|
var normalMatrix = mat3.create();
|
|
mat4.toInverseMat3(mvMatrix, normalMatrix);
|
|
mat3.transpose(normalMatrix);
|
|
gl.uniformMatrix3fv(shaderProgram.nMatrixUniform, false, normalMatrix);
|
|
}
|
|
|
|
|
|
function degToRad(degrees) {
|
|
return degrees * Math.PI / 180;
|
|
}
|
|
|
|
|
|
var mouseDown = false;
|
|
var lastMouseX = null;
|
|
var lastMouseY = null;
|
|
|
|
var moonRotationMatrix = mat4.create();
|
|
mat4.identity(moonRotationMatrix);
|
|
|
|
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, moonRotationMatrix, moonRotationMatrix);
|
|
|
|
lastMouseX = newX
|
|
lastMouseY = newY;
|
|
}
|
|
|
|
|
|
|
|
var moonVertexPositionBuffer;
|
|
var moonVertexNormalBuffer;
|
|
var moonVertexTextureCoordBuffer;
|
|
var moonVertexIndexBuffer;
|
|
|
|
function initBuffers() {
|
|
var vertexPositionData = [];
|
|
var normalData = [];
|
|
var textureCoordData = [];
|
|
var indexData = [];
|
|
var radius = 2;
|
|
|
|
|
|
// texture has 27 columns (width) and 29 rows (height)
|
|
var nbCol = 27;
|
|
var nbRows = 29;
|
|
// loop over Healpix indexes at NSIDE=8
|
|
for (var ipix=0; ipix<hpxCoo.length; ipix++) {
|
|
// for (var ipix=0; ipix<4; ipix++) {
|
|
//for (var ipix=0; ipix<100; ipix++) {
|
|
|
|
|
|
var rowIdx = Math.floor(ipix/nbCol);
|
|
var colIdx = ipix-rowIdx*nbCol;
|
|
|
|
for (var i=0; i<4; i++) {
|
|
var idx = (i+3)%4;
|
|
var x = hpxCoo[ipix][idx]['x'];
|
|
var y = hpxCoo[ipix][idx]['y'];
|
|
var z = hpxCoo[ipix][idx]['z'];
|
|
|
|
var u = colIdx/nbCol;
|
|
var v = rowIdx/nbRows;
|
|
|
|
if (i==1 || i==2) {
|
|
u += 1/nbCol;
|
|
}
|
|
if (i<2) {
|
|
v += 1/nbRows;
|
|
}
|
|
|
|
v = 1-v;
|
|
|
|
normalData.push(x);
|
|
normalData.push(y);
|
|
normalData.push(z);
|
|
textureCoordData.push(u);
|
|
textureCoordData.push(v);
|
|
vertexPositionData.push(radius * x);
|
|
vertexPositionData.push(radius * y);
|
|
vertexPositionData.push(radius * z);
|
|
|
|
//console.log('x: ' + x);
|
|
//console.log('y: ' + y);
|
|
//console.log('z: ' + z);
|
|
//console.log("u: "+u);
|
|
//console.log("v: "+v);
|
|
}
|
|
//console.log("\n")
|
|
|
|
indexData.push(ipix*4);
|
|
indexData.push(ipix*4+1);
|
|
indexData.push(ipix*4+3);
|
|
|
|
indexData.push(ipix*4+1);
|
|
indexData.push(ipix*4+2);
|
|
indexData.push(ipix*4+3);
|
|
|
|
}
|
|
|
|
|
|
moonVertexNormalBuffer = gl.createBuffer();
|
|
gl.bindBuffer(gl.ARRAY_BUFFER, moonVertexNormalBuffer);
|
|
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(normalData), gl.STATIC_DRAW);
|
|
moonVertexNormalBuffer.itemSize = 3;
|
|
moonVertexNormalBuffer.numItems = normalData.length / 3;
|
|
|
|
moonVertexTextureCoordBuffer = gl.createBuffer();
|
|
gl.bindBuffer(gl.ARRAY_BUFFER, moonVertexTextureCoordBuffer);
|
|
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textureCoordData), gl.STATIC_DRAW);
|
|
moonVertexTextureCoordBuffer.itemSize = 2;
|
|
moonVertexTextureCoordBuffer.numItems = textureCoordData.length / 2;
|
|
|
|
moonVertexPositionBuffer = gl.createBuffer();
|
|
gl.bindBuffer(gl.ARRAY_BUFFER, moonVertexPositionBuffer);
|
|
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertexPositionData), gl.STATIC_DRAW);
|
|
moonVertexPositionBuffer.itemSize = 3;
|
|
moonVertexPositionBuffer.numItems = vertexPositionData.length / 3;
|
|
|
|
moonVertexIndexBuffer = gl.createBuffer();
|
|
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, moonVertexIndexBuffer);
|
|
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indexData), gl.STATIC_DRAW);
|
|
moonVertexIndexBuffer.itemSize = 1;
|
|
moonVertexIndexBuffer.numItems = indexData.length;
|
|
}
|
|
|
|
|
|
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, -6]);
|
|
|
|
mat4.multiply(mvMatrix, moonRotationMatrix);
|
|
|
|
gl.activeTexture(gl.TEXTURE0);
|
|
gl.bindTexture(gl.TEXTURE_2D, moonTexture);
|
|
gl.uniform1i(shaderProgram.samplerUniform, 0);
|
|
|
|
gl.bindBuffer(gl.ARRAY_BUFFER, moonVertexPositionBuffer);
|
|
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, moonVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);
|
|
|
|
gl.bindBuffer(gl.ARRAY_BUFFER, moonVertexTextureCoordBuffer);
|
|
gl.vertexAttribPointer(shaderProgram.textureCoordAttribute, moonVertexTextureCoordBuffer.itemSize, gl.FLOAT, false, 0, 0);
|
|
|
|
gl.bindBuffer(gl.ARRAY_BUFFER, moonVertexNormalBuffer);
|
|
gl.vertexAttribPointer(shaderProgram.vertexNormalAttribute, moonVertexNormalBuffer.itemSize, gl.FLOAT, false, 0, 0);
|
|
|
|
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, moonVertexIndexBuffer);
|
|
setMatrixUniforms();
|
|
gl.drawElements(gl.TRIANGLES, moonVertexIndexBuffer.numItems, gl.UNSIGNED_SHORT, 0);
|
|
}
|
|
|
|
|
|
function tick() {
|
|
requestAnimFrame(tick);
|
|
drawScene();
|
|
}
|
|
|
|
|
|
function webGLStart() {
|
|
var canvas = document.getElementById("lesson11-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;
|
|
|
|
tick();
|
|
}
|
|
|
|
--></script>
|
|
|
|
|
|
</head>
|
|
|
|
|
|
<body onload="webGLStart();">
|
|
|
|
<canvas id="lesson11-canvas" style="border: none;" width="800" height="800"></canvas>
|
|
<br/>
|
|
|
|
</body>
|
|
|
|
</html>
|