game.js代码如下:
"use strict";
import "webgl-utils.js";
var v = {
text: `
attribute vec2 a_position;
uniform vec2 u_resolution;
void main() {
// convert the rectangle from pixels to 0.0 to 1.0
vec2 zeroToOne = a_position / u_resolution;
// convert from 0->1 to 0->2
vec2 zeroToTwo = zeroToOne * 2.0;
// convert from 0->2 to -1->+1 (clipspace)
vec2 clipSpace = zeroToTwo - 1.0;
gl_Position = vec4(clipSpace * vec2(1, -1), 0, 1);
}`,
type: `x-shader/x-vertex`
};
var f = {
text: `
precision mediump float;
uniform vec4 u_color;
void main() {
gl_FragColor = u_color;
}`,
type: `x-shader/x-fragment`
};
function main() {
// Get A WebGL context
/** @type {HTMLCanvasElement} */
console.log(canvas, "canvas")
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
var gl = canvas.getContext("webgl");
if (!gl) {
return;
}
// setup GLSL program
var program = webglUtils.createProgramFromScripts(gl, [v, f]);
// look up where the vertex data needs to go.
var positionAttributeLocation = gl.getAttribLocation(program, "a_position");
// look up uniform locations
var resolutionUniformLocation = gl.getUniformLocation(program, "u_resolution");
var colorUniformLocation = gl.getUniformLocation(program, "u_color");
// Create a buffer to put three 2d clip space points in
var positionBuffer = gl.createBuffer();
// Bind it to ARRAY_BUFFER (think of it as ARRAY_BUFFER = positionBuffer)
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
const s = webglUtils.resizeCanvasToDisplaySize(canvas);
// Tell WebGL how to convert from clip space to pixels
gl.viewport(0, 0, canvas.width, canvas.height);
console.log(0, 0, canvas.width, canvas.height, s)
// Clear the canvas
gl.clearColor(.2, 0, 0, 0);
gl.clear(gl.COLOR_BUFFER_BIT);
// Tell it to use our program (pair of shaders)
gl.useProgram(program);
// Bind the position buffer.
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
// create the buffer
const indexBuffer = gl.createBuffer();
// make this buffer the current 'ELEMENT_ARRAY_BUFFER'
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
// Fill the current element array buffer with data
const indices = [
0, 1, 2, // first triangle
2, 1, 3, // second triangle
];
gl.bufferData(
gl.ELEMENT_ARRAY_BUFFER,
new Uint16Array(indices),
gl.STATIC_DRAW
);
// code above this line is initialization code
// --------------------------------
// code below this line is rendering code
// Turn on the attribute
gl.enableVertexAttribArray(positionAttributeLocation);
// Tell the attribute how to get data out of positionBuffer (ARRAY_BUFFER)
var size = 2; // 2 components per iteration
var type = gl.FLOAT; // the data is 32bit floats
var normalize = false; // don't normalize the data
var stride = 0; // 0 = move forward size * sizeof(type) each iteration to get the next position
var offset = 0; // start at the beginning of the buffer
gl.vertexAttribPointer(
positionAttributeLocation, size, type, normalize, stride, offset);
// bind the buffer containing the indices
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
// set the resolution
gl.uniform2f(resolutionUniformLocation, canvas.width, canvas.height);
var primitiveType = gl.TRIANGLES;
var offset = 0;
var count = 6;
var indexType = gl.UNSIGNED_SHORT;
function render(now) {
for (var ii = 0; ii < 50; ++ii) {
// Setup a random rectangle
// This will write to positionBuffer because
// its the last thing we bound on the ARRAY_BUFFER
// bind point
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
setRectangle(
gl, randomInt(300), randomInt(300), randomInt(300), randomInt(300));
// Set a random color.
gl.uniform4f(colorUniformLocation, Math.random(), Math.random(), Math.random(), 1);
// Draw the rectangle.
var primitiveType = gl.TRIANGLES;
var offset = 0;
var count = 6;
var indexType = gl.UNSIGNED_SHORT;
gl.drawElements(primitiveType, count, indexType, offset);
}
requestAnimationFrame(render);
}
render();
}
// Returns a random integer from 0 to range - 1.
function randomInt(range) {
return Math.floor(Math.random() * range);
}
// Fill the buffer with the values that define a rectangle.
function setRectangle(gl, x, y, width, height) {
var x1 = x;
var x2 = x + width;
var y1 = y;
var y2 = y + height;
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
x1, y1,
x2, y1,
x1, y2,
x2, y2,
]), gl.STATIC_DRAW);
}
main();
webgl-utils.js代码修改过的部分:
function createShaderFromScript(
gl, scriptId, opt_shaderType, opt_errorCallback) {
let shaderSource = '';
let shaderType;
// const shaderScript = document.getElementById(scriptId);
// if (!shaderScript) {
// throw ('*** Error: unknown script element' + scriptId);
// }
const shaderScript = scriptId;
shaderSource = shaderScript.text;
if (!opt_shaderType) {
if (shaderScript.type === 'x-shader/x-vertex') {
shaderType = gl.VERTEX_SHADER;
} else if (shaderScript.type === 'x-shader/x-fragment') {
shaderType = gl.FRAGMENT_SHADER;
} else if (shaderType !== gl.VERTEX_SHADER && shaderType !== gl.FRAGMENT_SHADER) {
throw ('*** Error: unknown shader type');
}
}
return loadShader(
gl, shaderSource, opt_shaderType ? opt_shaderType : shaderType,
opt_errorCallback);
}
function(root, factory) { // eslint-disable-line
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define([], function() {
return factory.call(root);
});
} else {
// Browser globals
GameGlobal.webglUtils = factory.call(root);
}
}
修复:
function render(now) {
//添加这行代码,修复问题。
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
for (var ii = 0; ii < 50; ++ii) {
// Setup a random rectangle
// This will write to positionBuffer because
// its the last thing we bound on the ARRAY_BUFFER
// bind point
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
setRectangle(
gl, randomInt(300), randomInt(300), randomInt(300), randomInt(300));
// Set a random color.
gl.uniform4f(colorUniformLocation, Math.random(), Math.random(), Math.random(), 1);
// Draw the rectangle.
var primitiveType = gl.TRIANGLES;
var offset = 0;
var count = 6;
var indexType = gl.UNSIGNED_SHORT;
gl.drawElements(primitiveType, count, indexType, offset);
}
requestAnimationFrame(render);
}