<commit_before>/*******************************************************************************
 #      ____               __          __  _      _____ _       _               #
 #     / __ \              \ \        / / | |    / ____| |     | |              #
 #    | |  | |_ __   ___ _ __ \  /\  / /__| |__ | |  __| | ___ | |__   ___      #
 #    | |  | | '_ \ / _ \ '_ \ \/  \/ / _ \ '_ \| | |_ | |/ _ \| '_ \ / _ \     #
 #    | |__| | |_) |  __/ | | \  /\  /  __/ |_) | |__| | | (_) | |_) |  __/     #
 #     \____/| .__/ \___|_| |_|\/  \/ \___|_.__/ \_____|_|\___/|_.__/ \___|     #
 #           | |                                                                #
 #           |_|                 _____ _____  _  __                             #
 #                              / ____|  __ \| |/ /                             #
 #                             | (___ | |  | | ' /                              #
 #                              \___ \| |  | |  <                               #
 #                              ____) | |__| | . \                              #
 #                             |_____/|_____/|_|\_\                             #
 #                                                                              #
 #                              (c) 2010-2011 by                                #
 #           University of Applied Sciences Northwestern Switzerland            #
 #                     Institute of Geomatics Engineering                       #
 #                           <EMAIL>                            #
 ********************************************************************************
 *     Licensed under MIT License. Read the file LICENSE for more information   *
 *******************************************************************************/

goog.provide('owg.Texture');

goog.require('goog.debug.Logger');
goog.require('owg.MathUtils');
goog.require('owg.Mesh');
goog.require('owg.mat4');

//------------------------------------------------------------------------------
/**
 * @class texture
 * @constructor
 * {@link http://www.openwebglobe.org}
 * @author <NAME> <EMAIL>
 * @param {engine3d} engine
 * @param {boolean=} opt_useAsRenderTarget
 * @param {number=} opt_framebufferWidth
 * @param {number=} opt_framebufferHeight
 */
function Texture(engine, opt_useAsRenderTarget, opt_framebufferWidth, opt_framebufferHeight)
{
   this.engine = engine;   // pointer to the engine
   this.gl = engine.gl;    // pointer to the gl
   this.texture = null;    // the texture
   this.ready = false;     // is true when texture is ready to use
   this.failed = false;    // is true when texture creation / download failed
   this.blitMesh = null;   // optional mesh used for blitting
   this.width = 0;
   this.height = 0; 
   
   this.rttFrameBuffer = null; //used if this texture is used as a render target
   this.usedAsRenderTarget = false;
     
   if(opt_useAsRenderTarget)   // texture is used as render target.
   {       
        this.rttFramebuffer = this.gl.createFramebuffer();
        this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, this.rttFramebuffer);
        this.rttFramebuffer.width = opt_framebufferWidth;
        this.rttFramebuffer.height = opt_framebufferHeight;

        this.texture = this.gl.createTexture();
        this.gl.bindTexture(this.gl.TEXTURE_2D, this.texture);
        
        this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.LINEAR);
        this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR);
        this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE);
        this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE);
     
        this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA, this.rttFramebuffer.width, this.rttFramebuffer.height, 0, this.gl.RGBA, this.gl.UNSIGNED_BYTE, null);

        var renderbuffer = this.gl.createRenderbuffer();
        this.gl.bindRenderbuffer(this.gl.RENDERBUFFER, renderbuffer);
        //this.gl.renderbufferStorage(this.gl.RENDERBUFFER, this.gl.DEPTH_COMPONENT16, this.rttFramebuffer.width, this.rttFramebuffer.height);

        this.gl.framebufferTexture2D(this.gl.FRAMEBUFFER, this.gl.COLOR_ATTACHMENT0, this.gl.TEXTURE_2D, this.texture, 0);
        //this.gl.framebufferRenderbuffer(this.gl.FRAMEBUFFER, this.gl.DEPTH_ATTACHMENT, this.gl.RENDERBUFFER, renderbuffer);

        this.gl.bindTexture(this.gl.TEXTURE_2D, null);
        this.gl.bindRenderbuffer(this.gl.RENDERBUFFER, null);
        this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, null);
        
        this.ready = true;
        this.usedAsRenderTarget = true;
        this.width = opt_framebufferWidth;
        this.height = opt_framebufferHeight;        
   }
}

//------------------------------------------------------------------------------
/**
 * Loads the Texture image.
 * @param {string} url The url to download the image
 * @param {function()=} opt_callbackready An optional callback called when texture is ready. Has the texture class as param.
 * @param {function(Texture)=} opt_callbackfailed An optional callback called when texture failed. Has the texture class as param.
 * @param {boolean=} opt_flip Flip texture image on load
 */
Texture.prototype.loadTexture = function(url, opt_callbackready, opt_callbackfailed, opt_flip)
{
   // preparations
   this.texture = this.gl.createTexture();
   this.flip = opt_flip;
   var texture=this.texture;
   var curgl = this.gl;
   var thismat = this;
   var cbr = opt_callbackready;
   var cbf = opt_callbackfailed;
   this.texture.image = new Image();
   this.texture.image.onload = function()
   {
      _cbHandleLoadedTexture(curgl, texture, cbr, thismat);
      thismat.ready = true;
   }
   this.texture.image.src = url;
   this.texture.image.onerror = function()
   {
      goog.debug.Logger.getLogger('owg.Texture').warning("***FAILED DOWNLOADING: " + url);
      this.failed = true;
      if (cbf)
      {
         cbf(thismat);
      }
   }
   return this.texture;
}
//------------------------------------------------------------------------------
/**
 * @description Create WebGL texture object once it is available
 * @ignore
 */
function _cbHandleLoadedTexture(gl, textureobject, cb, TextureClass)
{
   // Create texture:
   gl.bindTexture(gl.TEXTURE_2D, textureobject);
   if (TextureClass.flip)
   {
      gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
   }
   gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, textureobject.image);
   gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
   gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
   gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
   gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
   gl.bindTexture(gl.TEXTURE_2D, null);
   
   TextureClass.width = textureobject.image.width;
   TextureClass.height = textureobject.image.height;
   
   if (cb != null)
   {
      cb(TextureClass);
   }
   

}

//------------------------------------------------------------------------------
/**
 * Texture Binding, must be called before mesh.draw() called.
 *
 */
Texture.prototype.Enable = function()
{
   if (this.ready)
   {
      this.gl.activeTexture(this.gl.TEXTURE0);
      this.gl.bindTexture(this.gl.TEXTURE_2D, this.texture);
   }
}
//------------------------------------------------------------------------------
/**
 * Unbinds the texture
 *
 */
Texture.prototype.Disable = function()
{
   if (this.ready)
   {
      this.gl.bindTexture(this.gl.TEXTURE_2D, null);
   }
}
//------------------------------------------------------------------------------
/**
 * Blit Texture: Draw texture on screen
 */
Texture.prototype.Blit = function(x,y,z,angle,scalex,scaley,blend, invtexcoord, alpha)
{   
   if (z==null) { z = 0; }
   if (angle==null) {angle = 0;}
   if (scalex==null) {scalex = 1;}
   if (scaley==null) { scaley = 1; }
   if (blend==null)  { blend = false;}
   if (invtexcoord==null) {invtexcoord = false;}
   if (alpha == null) { alpha = 1.0;}
   
   
   if (this.ready)
   {
      
      var w = this.width;
      var h = this.height;
      
      var xr = this.width/2;
      var yr = this.height/2;
      this.engine.PushMatrices();
      this.engine.SetOrtho2D();

      //deg 2 rad<commit_msg>Mark optional parameters to Texture.prototype.Blit as such<commit_after>/*******************************************************************************
 #      ____               __          __  _      _____ _       _               #
 #     / __ \              \ \        / / | |    / ____| |     | |              #
 #    | |  | |_ __   ___ _ __ \  /\  / /__| |__ | |  __| | ___ | |__   ___      #
 #    | |  | | '_ \ / _ \ '_ \ \/  \/ / _ \ '_ \| | |_ | |/ _ \| '_ \ / _ \     #
 #    | |__| | |_) |  __/ | | \  /\  /  __/ |_) | |__| | | (_) | |_) |  __/     #
 #     \____/| .__/ \___|_| |_|\/  \/ \___|_.__/ \_____|_|\___/|_.__/ \___|     #
 #           | |                                                                #
 #           |_|                 _____ _____  _  __                             #
 #                              / ____|  __ \| |/ /                             #
 #                             | (___ | |  | | ' /                              #
 #                              \___ \| |  | |  <                               #
 #                              ____) | |__| | . \                              #
 #                             |_____/|_____/|_|\_\                             #
 #                                                                              #
 #                              (c) 2010-2011 by                                #
 #           University of Applied Sciences Northwestern Switzerland            #
 #                     Institute of Geomatics Engineering                       #
 #                           <EMAIL>                            #
 ********************************************************************************
 *     Licensed under MIT License. Read the file LICENSE for more information   *
 *******************************************************************************/

goog.provide('owg.Texture');

goog.require('goog.debug.Logger');
goog.require('owg.MathUtils');
goog.require('owg.Mesh');
goog.require('owg.mat4');

//------------------------------------------------------------------------------
/**
 * @class texture
 * @constructor
 * {@link http://www.openwebglobe.org}
 * @author <NAME> <EMAIL>
 * @param {engine3d} engine
 * @param {boolean=} opt_useAsRenderTarget
 * @param {number=} opt_framebufferWidth
 * @param {number=} opt_framebufferHeight
 */
function Texture(engine, opt_useAsRenderTarget, opt_framebufferWidth, opt_framebufferHeight)
{
   this.engine = engine;   // pointer to the engine
   this.gl = engine.gl;    // pointer to the gl
   this.texture = null;    // the texture
   this.ready = false;     // is true when texture is ready to use
   this.failed = false;    // is true when texture creation / download failed
   this.blitMesh = null;   // optional mesh used for blitting
   this.width = 0;
   this.height = 0; 
   
   this.rttFrameBuffer = null; //used if this texture is used as a render target
   this.usedAsRenderTarget = false;
     
   if(opt_useAsRenderTarget)   // texture is used as render target.
   {       
        this.rttFramebuffer = this.gl.createFramebuffer();
        this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, this.rttFramebuffer);
        this.rttFramebuffer.width = opt_framebufferWidth;
        this.rttFramebuffer.height = opt_framebufferHeight;

        this.texture = this.gl.createTexture();
        this.gl.bindTexture(this.gl.TEXTURE_2D, this.texture);
        
        this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.LINEAR);
        this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR);
        this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE);
        this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE);
     
        this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA, this.rttFramebuffer.width, this.rttFramebuffer.height, 0, this.gl.RGBA, this.gl.UNSIGNED_BYTE, null);

        var renderbuffer = this.gl.createRenderbuffer();
        this.gl.bindRenderbuffer(this.gl.RENDERBUFFER, renderbuffer);
        //this.gl.renderbufferStorage(this.gl.RENDERBUFFER, this.gl.DEPTH_COMPONENT16, this.rttFramebuffer.width, this.rttFramebuffer.height);

        this.gl.framebufferTexture2D(this.gl.FRAMEBUFFER, this.gl.COLOR_ATTACHMENT0, this.gl.TEXTURE_2D, this.texture, 0);
        //this.gl.framebufferRenderbuffer(this.gl.FRAMEBUFFER, this.gl.DEPTH_ATTACHMENT, this.gl.RENDERBUFFER, renderbuffer);

        this.gl.bindTexture(this.gl.TEXTURE_2D, null);
        this.gl.bindRenderbuffer(this.gl.RENDERBUFFER, null);
        this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, null);
        
        this.ready = true;
        this.usedAsRenderTarget = true;
        this.width = opt_framebufferWidth;
        this.height = opt_framebufferHeight;        
   }
}

//------------------------------------------------------------------------------
/**
 * Loads the Texture image.
 * @param {string} url The url to download the image
 * @param {function()=} opt_callbackready An optional callback called when texture is ready. Has the texture class as param.
 * @param {function(Texture)=} opt_callbackfailed An optional callback called when texture failed. Has the texture class as param.
 * @param {boolean=} opt_flip Flip texture image on load
 */
Texture.prototype.loadTexture = function(url, opt_callbackready, opt_callbackfailed, opt_flip)
{
   // preparations
   this.texture = this.gl.createTexture();
   this.flip = opt_flip;
   var texture=this.texture;
   var curgl = this.gl;
   var thismat = this;
   var cbr = opt_callbackready;
   var cbf = opt_callbackfailed;
   this.texture.image = new Image();
   this.texture.image.onload = function()
   {
      _cbHandleLoadedTexture(curgl, texture, cbr, thismat);
      thismat.ready = true;
   }
   this.texture.image.src = url;
   this.texture.image.onerror = function()
   {
      goog.debug.Logger.getLogger('owg.Texture').warning("***FAILED DOWNLOADING: " + url);
      this.failed = true;
      if (cbf)
      {
         cbf(thismat);
      }
   }
   return this.texture;
}
//------------------------------------------------------------------------------
/**
 * @description Create WebGL texture object once it is available
 * @ignore
 */
function _cbHandleLoadedTexture(gl, textureobject, cb, TextureClass)
{
   // Create texture:
   gl.bindTexture(gl.TEXTURE_2D, textureobject);
   if (TextureClass.flip)
   {
      gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
   }
   gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, textureobject.image);
   gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
   gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
   gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
   gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
   gl.bindTexture(gl.TEXTURE_2D, null);
   
   TextureClass.width = textureobject.image.width;
   TextureClass.height = textureobject.image.height;
   
   if (cb != null)
   {
      cb(TextureClass);
   }
   

}

//------------------------------------------------------------------------------
/**
 * Texture Binding, must be called before mesh.draw() called.
 *
 */
Texture.prototype.Enable = function()
{
   if (this.ready)
   {
      this.gl.activeTexture(this.gl.TEXTURE0);
      this.gl.bindTexture(this.gl.TEXTURE_2D, this.texture);
   }
}
//------------------------------------------------------------------------------
/**
 * Unbinds the texture
 *
 */
Texture.prototype.Disable = function()
{
   if (this.ready)
   {
      this.gl.bindTexture(this.gl.TEXTURE_2D, null);
   }
}
//------------------------------------------------------------------------------
/**
 * Blit Texture: Draw texture on screen
 * @param {number} x
 * @param {number} y
 * @param {number=} opt_z
 * @param {number=} opt_angle
 * @param {number=} opt_scalex
 * @param {number=} opt_scaley
 * @param {boolean=} opt_blend
 * @param {boolean=} opt_invtexcoord
 * @param {number=} opt_alpha
 */
Texture.prototype.Blit = function(x, y, opt_z, opt_angle, opt_scalex, opt_scaley, opt_blend, opt_invtexcoord, opt_alpha)
{   
   /** @type {number} */
   var z = goog.isNull(opt_z) ? 0 : z;
   var angle = goog.isNull(opt_angle) ? 0 : angle;
   var scalex = goog.isNull(opt_scalex) ? 1 : scalex;
   var scaley = goog.isNull(opt_scaley) ? 1 : scaley;
   var blend = goog.isNull(opt_blend) ? false : blend;
   var invtexcoord = goog.isNull(opt_invtexcoord) ? false : invtexcoord;
   var alpha = goog.isNull(opt_alpha) ? 1.0 : alpha;
   
   if (this.ready)
   {
      
      var w = this.width;
      var h = this.height;
      
      var xr = this.width/2;
      var yr = this.height/2;
      this.engine.PushMatrices();
      this.engine.SetOrtho2D();

      //deg 2 rad
{'fraction_non_alphanumeric': 0.20068640567738932, 'fraction_numerical': 0.005816997266011285, 'mean_word_length': 1.786385737439222, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 40, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2449534', 'n_tokens_mistral': 5335, 'n_tokens_neox': 5146, 'n_words': 894}