<commit_before>// Copyright 2019-2020, University of Colorado Boulder

/**
 * WebGL drawable for Sprites.
 *
 * @author <NAME> <<EMAIL>>
 */

import Vector2 from '../../../../dot/js/Vector2.js';
import inherit from '../../../../phet-core/js/inherit.js';
import Poolable from '../../../../phet-core/js/Poolable.js';
import scenery from '../../scenery.js';
import ShaderProgram from '../../util/ShaderProgram.js';
import SpriteSheet from '../../util/SpriteSheet.js';
import Renderer from '../Renderer.js';
import WebGLSelfDrawable from '../WebGLSelfDrawable.js';

// constants
const COMPONENTS = 5; // { X Y U V A }
const FLOAT_QUANTITY = COMPONENTS * 6; // 6 vertices

// scratch values - corner vertices in the relative transform root coordinate space
const upperLeft = new Vector2( 0, 0 );
const lowerLeft = new Vector2( 0, 0 );
const upperRight = new Vector2( 0, 0 );
const lowerRight = new Vector2( 0, 0 );

/**
 * A generated WebGLSelfDrawable whose purpose will be drawing our Sprites. One of these drawables will be created
 * for each displayed instance of a Sprites.
 * @constructor
 *
 * @param {number} renderer - Renderer bitmask, see Renderer's documentation for more details.
 * @param {Instance} instance
 */
function SpritesWebGLDrawable( renderer, instance ) {
  // @private {function}
  this.contextChangeListener = this.onWebGLContextChange.bind( this );

  // @private {SpriteSheet}
  this.spriteSheet = new SpriteSheet( true );

  // @private {Object} - Maps {number} SpriteImage.id => {Bounds2} UV bounds
  this.spriteImageUVMap = {};

  // @private {Float32Array}
  this.vertexArray = new Float32Array( 128 * FLOAT_QUANTITY );

  // @private {Float32Array}
  this.transformMatrixArray = new Float32Array( 9 );

  this.initializeWebGLSelfDrawable( renderer, instance );

  // @private {function}
  this.spriteChangeListener = this.onSpriteChange.bind( this );

  this.node._sprites.forEach( sprite => {
    sprite.imageProperty.lazyLink( this.spriteChangeListener );
    this.addSpriteImage( sprite.imageProperty.value );
  } );
}

scenery.register( 'SpritesWebGLDrawable', SpritesWebGLDrawable );

inherit( WebGLSelfDrawable, SpritesWebGLDrawable, {
  // What type of WebGL renderer/processor should be used. TODO: doc
  webglRenderer: Renderer.webglCustom,

  /**
   * Adds a SpriteImage to our SpriteSheet.<commit_msg>add issue number for TODO, https://github.com/phetsims/natural-selection/issues/116<commit_after>// Copyright 2019-2020, University of Colorado Boulder

/**
 * WebGL drawable for Sprites.
 *
 * @author <NAME> <<EMAIL>>
 */

import Vector2 from '../../../../dot/js/Vector2.js';
import inherit from '../../../../phet-core/js/inherit.js';
import Poolable from '../../../../phet-core/js/Poolable.js';
import scenery from '../../scenery.js';
import ShaderProgram from '../../util/ShaderProgram.js';
import SpriteSheet from '../../util/SpriteSheet.js';
import Renderer from '../Renderer.js';
import WebGLSelfDrawable from '../WebGLSelfDrawable.js';

// constants
const COMPONENTS = 5; // { X Y U V A }
const FLOAT_QUANTITY = COMPONENTS * 6; // 6 vertices

// scratch values - corner vertices in the relative transform root coordinate space
const upperLeft = new Vector2( 0, 0 );
const lowerLeft = new Vector2( 0, 0 );
const upperRight = new Vector2( 0, 0 );
const lowerRight = new Vector2( 0, 0 );

/**
 * A generated WebGLSelfDrawable whose purpose will be drawing our Sprites. One of these drawables will be created
 * for each displayed instance of a Sprites.
 * @constructor
 *
 * @param {number} renderer - Renderer bitmask, see Renderer's documentation for more details.
 * @param {Instance} instance
 */
function SpritesWebGLDrawable( renderer, instance ) {
  // @private {function}
  this.contextChangeListener = this.onWebGLContextChange.bind( this );

  // @private {SpriteSheet}
  this.spriteSheet = new SpriteSheet( true );

  // @private {Object} - Maps {number} SpriteImage.id => {Bounds2} UV bounds
  this.spriteImageUVMap = {};

  // @private {Float32Array}
  this.vertexArray = new Float32Array( 128 * FLOAT_QUANTITY );

  // @private {Float32Array}
  this.transformMatrixArray = new Float32Array( 9 );

  this.initializeWebGLSelfDrawable( renderer, instance );

  // @private {function}
  this.spriteChangeListener = this.onSpriteChange.bind( this );

  this.node._sprites.forEach( sprite => {
    sprite.imageProperty.lazyLink( this.spriteChangeListener );
    this.addSpriteImage( sprite.imageProperty.value );
  } );
}

scenery.register( 'SpritesWebGLDrawable', SpritesWebGLDrawable );

inherit( WebGLSelfDrawable, SpritesWebGLDrawable, {
  // What type of WebGL renderer/processor should be used. TODO https://github.com/phetsims/natural-selection/issues/116 doc
  webglRenderer: Renderer.webglCustom,

  /**
   * Adds a SpriteImage to our SpriteSheet.
{'fraction_non_alphanumeric': 0.1343035343035343, 'fraction_numerical': 0.01704781704781705, 'mean_word_length': 3.7870646766169154, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 13, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2002074', 'n_tokens_mistral': 1514, 'n_tokens_neox': 1457, 'n_words': 425}