WebGL

博客分类: 江河计划

WebGL

算法

最长回文子串

给定一个字符串 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 来确定装配的图形。

第三步:显示在屏幕上的三角形是由片元组成的,所以还需要将图形转化为片元,这个过程被称为光栅化

第四步:对光栅化之后的片元进行逐片着色,最后形成图像