<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/gl-matrix@3.4.3/gl-matrix-min.js"></script>
</head>
<body>
<canvas id="renderCanvas" width="300" height="300"></canvas>
<script>
// Get the WebGL context
const gl = document.getElementById("renderCanvas").getContext("webgl");
// Create a vertex shader
const vertexShaderSource =
`
attribute vec2 aPosition;
attribute vec2 aTexCoord;
uniform mat4 uMvpMatrix;
varying vec2 vTexCoord;
void main()
{
gl_Position = uMvpMatrix * vec4(aPosition, 0.0, 1.0);
vTexCoord = aTexCoord;
}`;
const vShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vShader, vertexShaderSource);
gl.compileShader(vShader);
// Create a fragment shader
const fragmentShaderSource =
`
precision mediump float;
varying vec2 vTexCoord;
uniform sampler2D uSampler;
void main()
{
gl_FragColor = texture2D(uSampler, vTexCoord);
}`;
const fShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fShader, fragmentShaderSource);
gl.compileShader(fShader);
// Create a shader program
const program = gl.createProgram();
gl.attachShader(program, vShader);
gl.attachShader(program, fShader);
gl.linkProgram(program);
gl.useProgram(program);
// Create a vertex buffer
const vertexPositions = [
-0.5, -0.5,
-0.5, 0.5,
0.5, -0.5,
0.5, 0.5
];
const vertexPosBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexPosBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertexPositions), gl.STATIC_DRAW);
// Setting the position attribute
const aPositionLocation = gl.getAttribLocation(program, "aPosition");
gl.vertexAttribPointer(aPositionLocation, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(aPositionLocation);
// Create a texture coord buffer
const texCoords = [
0, 0,
0, 1,
2, 0,
2, 1
];
const texCoordBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, texCoordBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(texCoords), gl.STATIC_DRAW);
// Setting the texture coordinates attribute
const aTexCoordLocation = gl.getAttribLocation(program, "aTexCoord");
gl.vertexAttribPointer(aTexCoordLocation, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(aTexCoordLocation);
// Set up the camera and projection
const viewMatrix = glMatrix.mat4.create();
glMatrix.mat4.lookAt(viewMatrix, [0, 0, 90], [0, 0, 0], [0, 1, 0]);
const projMatrix = glMatrix.mat4.create();
glMatrix.mat4.ortho(projMatrix, 0, 100, 100, 0, -100, 100);
const projViewMatrix = glMatrix.mat4.create();
glMatrix.mat4.mul(projViewMatrix, projMatrix, viewMatrix);
// Set object size and object position
const modelMatrix = glMatrix.mat4.create();
glMatrix.mat4.translate(modelMatrix, modelMatrix, [50, 50, 1]);
glMatrix.mat4.scale(modelMatrix, modelMatrix, [60, 30, 1]);
// Send mvp matrix to shader
const uMvpMatrixLocation = gl.getUniformLocation(program, "uMvpMatrix");
const mvpMatrix = glMatrix.mat4.create();
glMatrix.mat4.mul(mvpMatrix, projViewMatrix, modelMatrix);
gl.uniformMatrix4fv(uMvpMatrixLocation, false, mvpMatrix);
const image = new Image();
image.onload = () =>
{
const texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, image);
draw();
};
image.crossOrigin = "";
image.src = "./images/smile.png";
// Set a color for background
gl.clearColor(0.2, 0.2, 0.2, 1.0);
function draw()
{
// Clear the background with the selected color
gl.clear(gl.COLOR_BUFFER_BIT);
// Draw an object
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
}
</script>
</body>
</html>