算法
最长回文子串
给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
var longestPalindrome = function(s) {
if(s.length < 2) return s;
var res = '';
var x, y;
for(let i=0; i<s.length; i++){
if(res.length > (s.length - i) * 2 - 1) return res;
var _res = s[i];
if(s[i+1] === s[i]){
x = i;
y = i;
while(s[x] == s[y+1]){
_res += s[x];
++y;
}
}else{
x = y = i;
}
while(--x > -1 && ++y < s.length && s[x] === s[y]){
_res = s[x] + _res + s[y];
}
res = res.length > _res.length ? res : _res;
}
return res;
};
颜色及纹理
多个缓存区共存
var vertexBuffer = this.gl.createBuffer();
var arr = []
this.points.map((item, index) => {
arr.push(item.x);
arr.push(item.y);
arr.push(10 * ++index);
})
var verticesSizes = new Float32Array(arr)
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, vertexBuffer)
this.gl.bufferData(this.gl.ARRAY_BUFFER, verticesSizes, this.gl.STATIC_DRAW);
var FSIZE = verticesSizes.BYTES_PER_ELEMENT;
this.gl.vertexAttribPointer(this.a_Position, 2, this.gl.FLOAT, false, FSIZE * 3, 0);
this.gl.enableVertexAttribArray(this.a_Position);
this.gl.vertexAttribPointer(this.a_PointSize, 1, this.gl.FLOAT, false, FSIZE * 3, FSIZE * 2);
this.gl.enableVertexAttribArray(this.a_PointSize);
this.gl.drawArrays(this.gl.POINTS, 0, this.points.length);
多个数据使用一个缓存区时,就可以用到字段数据的长度间隔和 offse 来表示,FSIZE 是 单个数据长度,FSIZE * 3 是间隔3个数据取一次,FSIZE * 2,是偏移两个数据开始取,前面的 1 参数就是取的数据长度。this.gl.vertexAttribPointer(this.a_PointSize, 1, this.gl.FLOAT, false, FSIZE * 3, FSIZE * 2);
从顶点着色器将数据传入片元着色器
在顶点着色器中声明颜色varying vec4 v_Color;,然后将颜色从顶点着色器传入片元着色器
var VSHADER_SOURCE = `
attribute vec4 a_Position;
attribute float a_PointSize;
attribute vec4 a_Color;
// 将变量通过光栅化插入片元着色器
varying vec4 v_Color;
void main() {
gl_Position = a_Position;
gl_PointSize = a_PointSize;
v_Color = a_Color;
}
`;
var FSHADER_SOURCE = `
precision mediump float;
varying vec4 v_Color;
void main() {
gl_FragColor = v_Color;
}
`;
var gl = canvas.getContext('webgl');
initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)
this.gl = gl;
this.points = [];
this.a_Position = gl.getAttribLocation(gl.program, 'a_Position');
this.a_PointSize = gl.getAttribLocation(gl.program, 'a_PointSize');
this.a_Color = gl.getAttribLocation(gl.program, 'a_Color');
this.gl.clearColor(0.0, 0.0, 0.0, 1.0);
this.gl.clear(this.gl.COLOR_BUFFER_BIT);
var vertexBuffer = this.gl.createBuffer();
var arr = []
this.points.map((item, index) => {
arr.push(item.x);
arr.push(item.y);
arr.push(10 * ++index);
arr.push(item.colorR)
arr.push(item.colorG)
arr.push(item.colorB)
})
var verticesSizes = new Float32Array(arr)
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, vertexBuffer)
this.gl.bufferData(this.gl.ARRAY_BUFFER, verticesSizes, this.gl.STATIC_DRAW);
var FSIZE = verticesSizes.BYTES_PER_ELEMENT;
this.gl.vertexAttribPointer(this.a_Position, 2, this.gl.FLOAT, false, FSIZE * 6, 0);
this.gl.enableVertexAttribArray(this.a_Position);
this.gl.vertexAttribPointer(this.a_PointSize, 1, this.gl.FLOAT, false, FSIZE * 6, FSIZE * 2);
this.gl.enableVertexAttribArray(this.a_PointSize);
this.gl.vertexAttribPointer(this.a_Color, 3, this.gl.FLOAT, false, FSIZE * 6, FSIZE * 3);
this.gl.enableVertexAttribArray(this.a_Color);
this.gl.drawArrays(this.gl.POINTS, 0, this.points.length);
绘制过程
绘制图形是通过缓冲区对象、顶点着色器、图形装配、光栅化、片元着色器。
第一步:执行着色器,将缓存区的数据写入到顶点着色器中,并将坐标点传入储存的装配区中
第二步:装配图形,通过 drawArrays 来确定装配的图形。
第三步:显示在屏幕上的三角形是由片元组成的,所以还需要将图形转化为片元,这个过程被称为光栅化
第四步:对光栅化之后的片元进行逐片着色,最后形成图像