Сжатие буферов динамически - PullRequest
2 голосов
/ 07 апреля 2019

Я обновляю существующий код WebGl (только с базовыми знаниями о WebGl). В коде есть пара функций для увеличения набора буферов, подобных этому

this.tail = new Float32Array(0);
this.tail_buffer = gl.createBuffer();
this.tail_index = 0;
this.tail_colors = new Float32Array(0);
this.tail_colors_buffer = gl.createBuffer();
var length = 512;   
this.head = new Float32Array(0);
this.head_buffer = gl.createBuffer();
this.tail_length = new Float32Array(0);

/**
 * Update the tail buffer between two indexes.
 * @param {number} a, with a <= b
 * @param {number} b
 */
_update = function(a, b) {
    var gl = this.gl;
    var length = 512;
    var buffer = this.tail.buffer;
    gl.bindBuffer(gl.ARRAY_BUFFER, this.tail_buffer);
    if (a == 0 && b == length - 1) {
        gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.tail);
    } else {
        var sublength = b - a + 1;
        for (var s = 0; s < this.solutions.length; s++)  {
            var offset = s * 3 * length * 4 + 3 * a * 4;
            var view = new Float32Array(buffer, offset, sublength * 3);
            gl.bufferSubData(gl.ARRAY_BUFFER, offset, view);
        }
    }
};

/**
 * Adjust all buffer sizes if needed.
 */
_grow_buffers = function() {
    function next2(x) {
        return Math.pow(2, Math.ceil(Math.log(x) * Math.LOG2E));
    }
    var gl = this.gl;
    var count = next2(some_number);
    var length = 512;
    if (this.tail.length < count * length * 3) {
        var old_tail = this.tail;
        this.tail = new Float32Array(count * length * 3);
        this.tail.set(old_tail);
        gl.bindBuffer(gl.ARRAY_BUFFER, this.tail_buffer);
        gl.bufferData(gl.ARRAY_BUFFER, count * length * 4 * 3, gl.DYNAMIC_DRAW);
        this._update(0, length - 1);
    }
    if (this.tail_length.length < count) {
        var old_tail_length = this.tail_length;
        this.tail_length = new Float32Array(count);
        this.tail_length.set(old_tail_length);
    }
    if (this.tail_colors.length < count * 3) {
        this.tail_colors = new Float32Array(count * 3);
        for (var i = 0; i < this.tail_colors.length; i++) {
            var color = getColor(i);
            this.tail_colors[i * 3 + 0] = color[0];
            this.tail_colors[i * 3 + 1] = color[1];
            this.tail_colors[i * 3 + 2] = color[2];
        }
        gl.bindBuffer(gl.ARRAY_BUFFER, this.tail_colors_buffer);
        gl.bufferData(gl.ARRAY_BUFFER, count * 4 * 3, gl.STATIC_DRAW);
        gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.tail_colors);
    }
    if (this.head.length < count * 3) {
        this.head = new Float32Array(count * 3);
        gl.bindBuffer(gl.ARRAY_BUFFER, this.head_buffer);
        gl.bufferData(gl.ARRAY_BUFFER, count * 3 * 4, gl.DYNAMIC_DRAW);
    }
};

Я хотел бы написать функцию, которая сокращает буферы (вместо того, чтобы увеличивать их, как показано выше). Самый простой способ - использовать функцию, аналогичную функции grow_buffers, но поменять операторы if (с <на>). Я думаю, что я что-то упустил, хотя и это не может освободить все пространство буфера.

Вот некоторые вещи, которые я не понимаю в приведенном выше коде: что делает gl.bufferSubData? В умножении на 3 * 4 я не понимаю 4 (3, вероятно, число цветов)

...