tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

gluDrawUtil.js (18220B)


      1 /*-------------------------------------------------------------------------
      2 * drawElements Quality Program OpenGL ES Utilities
      3 * ------------------------------------------------
      4 *
      5 * Copyright 2014 The Android Open Source Project
      6 *
      7 * Licensed under the Apache License, Version 2.0 (the "License");
      8 * you may not use this file except in compliance with the License.
      9 * You may obtain a copy of the License at
     10 *
     11 *      http://www.apache.org/licenses/LICENSE-2.0
     12 *
     13 * Unless required by applicable law or agreed to in writing, software
     14 * distributed under the License is distributed on an "AS IS" BASIS,
     15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     16 * See the License for the specific language governing permissions and
     17 * limitations under the License.
     18 *
     19 */
     20 
     21 'use strict';
     22 goog.provide('framework.opengl.gluDrawUtil');
     23 goog.require('framework.opengl.gluShaderProgram');
     24 
     25 goog.scope(function() {
     26 
     27 var gluDrawUtil = framework.opengl.gluDrawUtil;
     28 var gluShaderProgram = framework.opengl.gluShaderProgram;
     29 
     30 /**
     31 * Description of a vertex array binding
     32 * @constructor
     33 * @param {number} type GL gluDrawUtil.Type of data
     34 * @param {(number|undefined)} location Binding location
     35 * @param {number} components Number of components per vertex
     36 * @param {number} elements Number of elements in the array
     37 * @param {Array<number>} data Source data
     38 * @param {number=} stride
     39 * @param {number=} offset
     40 */
     41 gluDrawUtil.VertexArrayBinding = function(type, location, components, elements, data, stride, offset) {
     42    this.type = type;
     43    this.location = location === undefined ? -1 : location;
     44    this.components = components;
     45    this.elements = elements;
     46    this.data = data;
     47    /** @type {?string} */ this.name = null;
     48    this.stride = stride || 0;
     49    this.offset = offset || 0;
     50 };
     51 
     52 /**
     53 * Description of a vertex array binding
     54 * @param {gluDrawUtil.BindingPoint} binding
     55 * @param {gluDrawUtil.VertexArrayPointer} pointer
     56 * @param {number=} dataType GL Data Type
     57 * @return {gluDrawUtil.VertexArrayBinding}
     58 */
     59 gluDrawUtil.vabFromBindingPointAndArrayPointer = function(binding, pointer, dataType) {
     60    var type = dataType === undefined ? gl.FLOAT : dataType;
     61    var location = binding.location;
     62    var components = pointer.numComponents;
     63    var elements = pointer.numElements;
     64    var data = pointer.data;
     65    var vaBinding = new gluDrawUtil.VertexArrayBinding(type, location, components, elements, data);
     66    vaBinding.componentType = pointer.componentType;
     67    vaBinding.name = binding.name;
     68    vaBinding.convert = pointer.convert;
     69    vaBinding.stride = pointer.stride;
     70    return vaBinding;
     71 };
     72 
     73 /**
     74 * ! Lower named bindings to locations and eliminate bindings that are not used by program.
     75 * @param {WebGL2RenderingContext} gl WebGL context
     76 * @param {WebGLProgram} program
     77 * @param {Array} inputArray - Array with the named binding locations
     78 * @param {Array=} outputArray - Array with the lowered locations
     79 * @return {Array} outputArray
     80 */
     81 gluDrawUtil.namedBindingsToProgramLocations = function(gl, program, inputArray, outputArray) {
     82    outputArray = outputArray || [];
     83 
     84    for (var i = 0; i < inputArray.length; i++) {
     85        var cur = inputArray[i];
     86        if (cur.name) {
     87            //assert(binding.location >= 0);
     88            var location = gl.getAttribLocation(program, cur.name);
     89            if (location >= 0) {
     90                if (cur.location >= 0)
     91                    location += cur.location;
     92                // Add binding.location as an offset to accomodate matrices.
     93                outputArray.push(new gluDrawUtil.VertexArrayBinding(cur.type, location, cur.components, cur.elements, cur.data, cur.stride, cur.offset));
     94            }
     95        } else {
     96            outputArray.push(cur);
     97        }
     98    }
     99 
    100    return outputArray;
    101 };
    102 
    103 /**
    104 * Creates vertex buffer, binds it and draws elements
    105 * @param {WebGL2RenderingContext} gl WebGL context
    106 * @param {WebGLProgram} program ID, vertexProgramID
    107 * @param {Array<gluDrawUtil.VertexArrayBinding>} vertexArrays
    108 * @param {gluDrawUtil.PrimitiveList} primitives to gluDrawUtil.draw
    109 * @param { {beforeDrawCall:function(), afterDrawCall:function()}=} callback
    110 */
    111 gluDrawUtil.draw = function(gl, program, vertexArrays, primitives, callback) {
    112    /** TODO: finish implementation */
    113    /** @type {Array<WebGLBuffer>} */ var objects = [];
    114 
    115    // Lower bindings to locations
    116    vertexArrays = gluDrawUtil.namedBindingsToProgramLocations(gl, program, vertexArrays);
    117 
    118    for (var i = 0; i < vertexArrays.length; i++) {
    119        /** @type {WebGLBuffer} */ var buffer = gluDrawUtil.vertexBuffer(gl, vertexArrays[i]);
    120        objects.push(buffer);
    121    }
    122 
    123    if (primitives.indices) {
    124        /** @type {WebGLBuffer} */ var elemBuffer = gluDrawUtil.indexBuffer(gl, primitives);
    125        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, elemBuffer);
    126 
    127        if (callback)
    128            callback.beforeDrawCall();
    129 
    130        gluDrawUtil.drawIndexed(gl, primitives, 0);
    131 
    132        if (callback)
    133            callback.afterDrawCall();
    134 
    135        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
    136    } else {
    137        if (callback)
    138            callback.beforeDrawCall();
    139 
    140        gl.drawArrays(gluDrawUtil.getPrimitiveGLType(gl, primitives.type), 0, primitives.numElements);
    141 
    142        if (callback)
    143            callback.afterDrawCall();
    144    }
    145 
    146  assertMsgOptions(gl.getError() === gl.NO_ERROR, 'drawArrays', false, true);
    147    for (var i = 0; i < vertexArrays.length; i++) {
    148        gl.disableVertexAttribArray(vertexArrays[i].location);
    149    }
    150  gl.bindBuffer(gl.ARRAY_BUFFER, null);
    151 };
    152 
    153 /**
    154 * Creates vertex buffer, binds it and draws elements
    155 * @param {WebGL2RenderingContext} gl WebGL context
    156 * @param {gluDrawUtil.PrimitiveList} primitives Primitives to gluDrawUtil.draw
    157 * @param {number} offset
    158 */
    159 gluDrawUtil.drawIndexed = function(gl, primitives, offset) {
    160 /** @type {number} */ var mode = gluDrawUtil.getPrimitiveGLType(gl, primitives.type);
    161    /** TODO: C++ implementation supports different index types, we use only int16.
    162        Could it cause any issues?
    163 
    164        deUint32 indexGLType = getIndexGLType(primitives.indexType);
    165    */
    166 
    167    gl.drawElements(mode, primitives.indices.length, gl.UNSIGNED_SHORT, offset);
    168 };
    169 
    170 /**
    171 * Enums for primitive types
    172 * @enum
    173 */
    174 gluDrawUtil.primitiveType = {
    175    TRIANGLES: 0,
    176    TRIANGLE_STRIP: 1,
    177    TRIANGLE_FAN: 2,
    178 
    179    LINES: 3,
    180    LINE_STRIP: 4,
    181    LINE_LOOP: 5,
    182 
    183    POINTS: 6,
    184 
    185    PATCHES: 7
    186 };
    187 
    188 /**
    189 * get GL type from primitive type
    190 * @param {WebGL2RenderingContext} gl WebGL context
    191 * @param {gluDrawUtil.primitiveType} type gluDrawUtil.primitiveType
    192 * @return {number} GL primitive type
    193 */
    194 gluDrawUtil.getPrimitiveGLType = function(gl, type) {
    195    switch (type) {
    196        case gluDrawUtil.primitiveType.TRIANGLES: return gl.TRIANGLES;
    197        case gluDrawUtil.primitiveType.TRIANGLE_STRIP: return gl.TRIANGLE_STRIP;
    198        case gluDrawUtil.primitiveType.TRIANGLE_FAN: return gl.TRIANGLE_FAN;
    199        case gluDrawUtil.primitiveType.LINES: return gl.LINES;
    200        case gluDrawUtil.primitiveType.LINE_STRIP: return gl.LINE_STRIP;
    201        case gluDrawUtil.primitiveType.LINE_LOOP: return gl.LINE_LOOP;
    202        case gluDrawUtil.primitiveType.POINTS: return gl.POINTS;
    203 //        case gluDrawUtil.primitiveType.PATCHES: return gl.PATCHES;
    204        default:
    205            throw new Error('Unknown primitive type ' + type);
    206    }
    207 };
    208 
    209 /**
    210 * Calls gluDrawUtil.newPrimitiveListFromIndices() to create primitive list for Points
    211 * @param {number} numElements
    212 */
    213 gluDrawUtil.pointsFromElements = function(numElements) {
    214    return new gluDrawUtil.PrimitiveList(gluDrawUtil.primitiveType.POINTS, numElements);
    215 };
    216 
    217 /**
    218 * Calls gluDrawUtil.newPrimitiveListFromIndices() to create primitive list for Triangles
    219 * @param {Array<number>} indices
    220 */
    221 gluDrawUtil.triangles = function(indices) {
    222    return gluDrawUtil.newPrimitiveListFromIndices(gluDrawUtil.primitiveType.TRIANGLES, indices);
    223 };
    224 
    225 /**
    226 * Calls gluDrawUtil.newPrimitiveListFromIndices() to create primitive list for Patches
    227 * @param {Array<number>} indices
    228 */
    229 gluDrawUtil.patches = function(indices) {
    230    return gluDrawUtil.newPrimitiveListFromIndices(gluDrawUtil.primitiveType.PATCHES, indices);
    231 };
    232 
    233 /**
    234 * Creates primitive list for Triangles or Patches, depending on type
    235 * @param {gluDrawUtil.primitiveType} type gluDrawUtil.primitiveType
    236 * @param {number} numElements
    237 * @constructor
    238 */
    239 gluDrawUtil.PrimitiveList = function(type, numElements) {
    240    this.type = type;
    241    this.indices = 0;
    242    this.numElements = numElements;
    243 };
    244 
    245 /**
    246 * @param {gluDrawUtil.primitiveType} type
    247 * @param {Array<number>} indices
    248 * @return {gluDrawUtil.PrimitiveList}
    249 */
    250 gluDrawUtil.newPrimitiveListFromIndices = function(type, indices) {
    251    /** @type {gluDrawUtil.PrimitiveList} */ var primitiveList = new gluDrawUtil.PrimitiveList(type, 0);
    252    primitiveList.indices = indices;
    253    return primitiveList;
    254 };
    255 
    256 /**
    257 * Create Element Array Buffer
    258 * @param {WebGL2RenderingContext} gl WebGL context
    259 * @param {gluDrawUtil.PrimitiveList} primitives to construct the buffer from
    260 * @return {WebGLBuffer} indexObject buffer with elements
    261 */
    262 gluDrawUtil.indexBuffer = function(gl, primitives) {
    263    /** @type {WebGLBuffer} */ var indexObject = gl.createBuffer();
    264    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexObject);
    265    assertMsgOptions(gl.getError() === gl.NO_ERROR, 'bindBuffer', false, true);
    266    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(primitives.indices), gl.STATIC_DRAW);
    267    assertMsgOptions(gl.getError() === gl.NO_ERROR, 'bufferData', false, true);
    268    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
    269    return indexObject;
    270 };
    271 
    272 /**
    273 * Create Array Buffer
    274 * @param {WebGL2RenderingContext} gl WebGL context
    275 * @param {gluDrawUtil.VertexArrayBinding} vertexArray primitives, Array buffer descriptor
    276 * @return {WebGLBuffer} buffer of vertices
    277 */
    278 gluDrawUtil.vertexBuffer = function(gl, vertexArray) {
    279    /** @type {goog.TypedArray} */ var typedArray;
    280    switch (vertexArray.type) {
    281        case gl.BYTE: typedArray = new Int8Array(vertexArray.data); break;
    282        case gl.UNSIGNED_BYTE: typedArray = new Uint8Array(vertexArray.data); break;
    283        case gl.SHORT: typedArray = new Int16Array(vertexArray.data); break;
    284        case gl.UNSIGNED_SHORT: typedArray = new Uint16Array(vertexArray.data); break;
    285        case gl.INT: typedArray = new Int32Array(vertexArray.data); break;
    286        case gl.UNSIGNED_INT: typedArray = new Uint32Array(vertexArray.data); break;
    287        default: typedArray = new Float32Array(vertexArray.data); break;
    288    }
    289 
    290    /** @type {WebGLBuffer} */ var buffer = gl.createBuffer();
    291    gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
    292    assertMsgOptions(gl.getError() === gl.NO_ERROR, 'bindBuffer', false, true);
    293    gl.bufferData(gl.ARRAY_BUFFER, typedArray, gl.STATIC_DRAW);
    294    assertMsgOptions(gl.getError() === gl.NO_ERROR, 'bufferData', false, true);
    295    gl.enableVertexAttribArray(vertexArray.location);
    296    assertMsgOptions(gl.getError() === gl.NO_ERROR, 'enableVertexAttribArray', false, true);
    297    if (vertexArray.type === gl.FLOAT) {
    298        gl.vertexAttribPointer(vertexArray.location, vertexArray.components, vertexArray.type, false, vertexArray.stride, vertexArray.offset);
    299    } else {
    300        gl.vertexAttribIPointer(vertexArray.location, vertexArray.components, vertexArray.type, vertexArray.stride, vertexArray.offset);
    301    }
    302    assertMsgOptions(gl.getError() === gl.NO_ERROR, 'vertexAttribPointer', false, true);
    303    return buffer;
    304 };
    305 
    306 /**
    307 * @param {Array<number>} rgba
    308 * @constructor
    309 */
    310 gluDrawUtil.Pixel = function(rgba) {
    311    this.rgba = rgba;
    312 };
    313 
    314 gluDrawUtil.Pixel.prototype.getRed = function() {
    315    return this.rgba[0];
    316 };
    317 gluDrawUtil.Pixel.prototype.getGreen = function() {
    318    return this.rgba[1];
    319 };
    320 gluDrawUtil.Pixel.prototype.getBlue = function() {
    321    return this.rgba[2];
    322 };
    323 gluDrawUtil.Pixel.prototype.getAlpha = function() {
    324    return this.rgba[3];
    325 };
    326 gluDrawUtil.Pixel.prototype.equals = function(otherPixel) {
    327    return this.rgba[0] == otherPixel.rgba[0] &&
    328           this.rgba[1] == otherPixel.rgba[1] &&
    329           this.rgba[2] == otherPixel.rgba[2] &&
    330           this.rgba[3] == otherPixel.rgba[3];
    331 };
    332 
    333 /**
    334 * @constructor
    335 */
    336 gluDrawUtil.Surface = function() {
    337 };
    338 
    339 gluDrawUtil.Surface.prototype.readSurface = function(gl, x, y, width, height) {
    340    this.buffer = new Uint8Array(width * height * 4);
    341    gl.readPixels(x, y, width, height, gl.RGBA, gl.UNSIGNED_BYTE, this.buffer);
    342    this.x = x;
    343    this.y = y;
    344    this.width = width;
    345    this.height = height;
    346    return this.buffer;
    347 };
    348 
    349 gluDrawUtil.Surface.prototype.getPixel = function(x, y) {
    350    /** @type {number} */ var base = (x + y * this.width) * 4;
    351    /** @type {Array<number>} */
    352    var rgba = [
    353        this.buffer[base],
    354        this.buffer[base + 1],
    355        this.buffer[base + 2],
    356        this.buffer[base + 3]
    357        ];
    358    return new gluDrawUtil.Pixel(rgba);
    359 };
    360 
    361 gluDrawUtil.Surface.prototype.getPixelUintRGB8 = function(x, y) {
    362    /** @type {number} */ var base = (x + y * this.width) * 4;
    363    /** @type {number} */
    364    return (this.buffer[base] << 16) +
    365        (this.buffer[base + 1] << 8) +
    366        this.buffer[base + 2];
    367 };
    368 
    369 /**
    370 * @enum
    371 */
    372 gluDrawUtil.VertexComponentType = {
    373    // Standard types: all conversion types apply.
    374    VTX_COMP_UNSIGNED_INT8: 0,
    375    VTX_COMP_UNSIGNED_INT16: 1,
    376    VTX_COMP_UNSIGNED_INT32: 2,
    377    VTX_COMP_SIGNED_INT8: 3,
    378    VTX_COMP_SIGNED_INT16: 4,
    379    VTX_COMP_SIGNED_INT32: 5,
    380 
    381    // Special types: only CONVERT_NONE is allowed.
    382    VTX_COMP_FIXED: 6,
    383    VTX_COMP_HALF_FLOAT: 7,
    384    VTX_COMP_FLOAT: 8
    385 };
    386 
    387 /**
    388 * @enum
    389 */
    390 gluDrawUtil.VertexComponentConversion = {
    391    VTX_COMP_CONVERT_NONE: 0, //!< No conversion: integer types, or floating-point values.
    392    VTX_COMP_CONVERT_NORMALIZE_TO_FLOAT: 1, //!< Normalize integers to range [0,1] or [-1,1] depending on type.
    393    VTX_COMP_CONVERT_CAST_TO_FLOAT: 2 //!< Convert to floating-point directly.
    394 };
    395 
    396 /**
    397 * gluDrawUtil.VertexArrayPointer
    398 * @constructor
    399 * @param {gluDrawUtil.VertexComponentType} componentType_
    400 * @param {gluDrawUtil.VertexComponentConversion} convert_
    401 * @param {number} numComponents_
    402 * @param {number} numElements_
    403 * @param {number} stride_
    404 * @const @param {Array<number>} data_
    405 */
    406 gluDrawUtil.VertexArrayPointer = function(componentType_, convert_, numComponents_, numElements_, stride_, data_) {
    407    this.componentType = componentType_;
    408    this.convert = convert_;
    409    this.numComponents = numComponents_;
    410    this.numElements = numElements_;
    411    this.stride = stride_;
    412    this.data = data_;
    413 };
    414 
    415 /**
    416 * gluDrawUtil.BindingPoint
    417 * @constructor
    418 * @param {string} name
    419 * @param {number} location
    420 * @param {number=} offset
    421 */
    422 gluDrawUtil.BindingPoint = function(name, location, offset) {
    423    /** @type {string} */ this.name = name;
    424    /** @type {number} */ this.location = location;
    425    /** @type {number} */ this.offset = offset || 0;
    426 };
    427 
    428 /**
    429 * bindingPointFromLocation
    430 * @param {number} location
    431 * return {gluDrawUtil.BindingPoint}
    432 */
    433 gluDrawUtil.bindingPointFromLocation = function(location) {
    434    return new gluDrawUtil.BindingPoint('', location);
    435 };
    436 
    437 /**
    438 * bindingPointFromName
    439 * @param {string} name
    440 * @param {number=} location
    441 * return {gluDrawUtil.BindingPoint}
    442 */
    443 gluDrawUtil.bindingPointFromName = function(name, location) {
    444    location = location === undefined ? -1 : location;
    445    return new gluDrawUtil.BindingPoint(name, location);
    446 };
    447 
    448 /**
    449 * @param {string} name
    450 * @param {number} numComponents
    451 * @param {number} numElements
    452 * @param {number} stride
    453 * @param {Array<number>} data
    454 * @return {gluDrawUtil.VertexArrayBinding}
    455 */
    456 gluDrawUtil.newInt32VertexArrayBinding = function(name, numComponents, numElements, stride, data) {
    457    var bindingPoint = gluDrawUtil.bindingPointFromName(name);
    458    var arrayPointer = new gluDrawUtil.VertexArrayPointer(gluDrawUtil.VertexComponentType.VTX_COMP_SIGNED_INT32,
    459        gluDrawUtil.VertexComponentConversion.VTX_COMP_CONVERT_NONE, numComponents, numElements, stride, data);
    460    return gluDrawUtil.vabFromBindingPointAndArrayPointer(bindingPoint, arrayPointer, gl.INT);
    461 };
    462 
    463 /**
    464 * @param {string} name
    465 * @param {number} numComponents
    466 * @param {number} numElements
    467 * @param {number} stride
    468 * @param {Array<number>} data
    469 * @return {gluDrawUtil.VertexArrayBinding}
    470 */
    471 gluDrawUtil.newUint32VertexArrayBinding = function(name, numComponents, numElements, stride, data) {
    472    var bindingPoint = gluDrawUtil.bindingPointFromName(name);
    473    var arrayPointer = new gluDrawUtil.VertexArrayPointer(gluDrawUtil.VertexComponentType.VTX_COMP_UNSIGNED_INT32,
    474        gluDrawUtil.VertexComponentConversion.VTX_COMP_CONVERT_NONE, numComponents, numElements, stride, data);
    475    return gluDrawUtil.vabFromBindingPointAndArrayPointer(bindingPoint, arrayPointer, gl.UNSIGNED_INT);
    476 };
    477 
    478 /**
    479 * @param {string} name
    480 * @param {number} numComponents
    481 * @param {number} numElements
    482 * @param {number} stride
    483 * @param {Array<number>} data
    484 * @return {gluDrawUtil.VertexArrayBinding}
    485 */
    486 gluDrawUtil.newFloatVertexArrayBinding = function(name, numComponents, numElements, stride, data) {
    487    var bindingPoint = gluDrawUtil.bindingPointFromName(name);
    488    var arrayPointer = new gluDrawUtil.VertexArrayPointer(gluDrawUtil.VertexComponentType.VTX_COMP_FLOAT,
    489        gluDrawUtil.VertexComponentConversion.VTX_COMP_CONVERT_NONE, numComponents, numElements, stride, data);
    490    return gluDrawUtil.vabFromBindingPointAndArrayPointer(bindingPoint, arrayPointer);
    491 };
    492 
    493 /**
    494 * @param {string} name
    495 * @param {number} column
    496 * @param {number} rows
    497 * @param {number} numElements
    498 * @param {number} stride
    499 * @param {Array<number>} data
    500 * @return {gluDrawUtil.VertexArrayBinding}
    501 */
    502 gluDrawUtil.newFloatColumnVertexArrayBinding = function(name, column, rows, numElements, stride, data) {
    503    var bindingPoint = gluDrawUtil.bindingPointFromName(name);
    504    bindingPoint.location = column;
    505    var arrayPointer = new gluDrawUtil.VertexArrayPointer(gluDrawUtil.VertexComponentType.VTX_COMP_FLOAT,
    506        gluDrawUtil.VertexComponentConversion.VTX_COMP_CONVERT_NONE, rows, numElements, stride, data);
    507    return gluDrawUtil.vabFromBindingPointAndArrayPointer(bindingPoint, arrayPointer);
    508 };
    509 
    510 });