uploadTexture method

void uploadTexture(
  1. Map<String, dynamic> textureProperties,
  2. Texture texture,
  3. int slot
)

Implementation

void uploadTexture(Map<String, dynamic> textureProperties, Texture texture, int slot) {
  dynamic textureType = WebGL.TEXTURE_2D;

  if (texture is DataArrayTexture) textureType = WebGL.TEXTURE_2D_ARRAY;
  if (texture is Data3DTexture) textureType = WebGL.TEXTURE_3D;

  final forceUpload = initTexture(textureProperties, texture);
  final source = texture.source;

  state.activeTexture(WebGL.TEXTURE0 + slot);
  state.bindTexture(textureType, textureProperties["__webglTexture"]);

  if (source.version != source.currentVersion || forceUpload) {

    _gl.pixelStorei(WebGL.UNPACK_ALIGNMENT, texture.unpackAlignment);
    if (kIsWeb) {
      _gl.pixelStorei(WebGL.UNPACK_FLIP_Y_WEBGL, texture.flipY ? 1 : 0);
      _gl.pixelStorei(WebGL.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha ? 1 : 0);
      _gl.pixelStorei(WebGL.UNPACK_COLORSPACE_CONVERSION_WEBGL, WebGL.NONE);
    }

    dynamic image = texture.image;//resizeImage(texture.image, needsPowerOfTwo, false, maxTextureSize);
    image = verifyColorSpace(texture, image);

    final int glFormat = utils.convert(texture.format, texture.colorSpace);
    int glType = utils.convert(texture.type);
    int glInternalFormat = getInternalFormat(texture.internalFormat, glFormat, glType, texture.colorSpace, texture is VideoTexture);

    setTextureParameters(textureType, texture);

    dynamic mipmap;
    final mipmaps = texture.mipmaps;

    final useTexStorage = (isWebGL2 && texture is! VideoTexture);
    final allocateMemory = (textureProperties["__version"] == null) || (forceUpload == true);
    final dataReady = source.dataReady;
    final levels = getMipLevels(texture, image);

    if (texture is DepthTexture) {
				glInternalFormat = getInternalDepthFormat( texture.format == DepthStencilFormat, texture.type );
				if ( allocateMemory ) {
					if ( useTexStorage ) {
						state.texStorage2D( WebGL.TEXTURE_2D, 1, glInternalFormat, image.width, image.height );
					} else {
						state.texImage2D( WebGL.TEXTURE_2D, 0, glInternalFormat, image.width, image.height, 0, glFormat, glType, null );
					}
				}
    }
    else if (texture is DataTexture) {
      // use manually created mipmaps if available
      // if there are no manual mipmaps
      // set 0 level mipmap and then use GL to generate other mipmap levels

      if (mipmaps.isNotEmpty) {
        if (useTexStorage && allocateMemory) {
          state.texStorage2D(WebGL.TEXTURE_2D, levels, glInternalFormat, mipmaps[0].width, mipmaps[0].height);
        }

        for (int i = 0, il = mipmaps.length; i < il; i++) {
          mipmap = mipmaps[i];
          if (useTexStorage && dataReady) {
            state.texSubImage2D(WebGL.TEXTURE_2D, i, 0, 0, mipmap.width, mipmap.height, glFormat, glType, mipmap.data);
          }
          else {
            state.texImage2D(WebGL.TEXTURE_2D, i, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data);
          }
        }

        texture.generateMipmaps = false;
      }
      else {

        if (useTexStorage) {
          if (allocateMemory) {
            state.texStorage2D(WebGL.TEXTURE_2D, levels, glInternalFormat, image.width.toInt(), image.height.toInt());
          }
						if ( dataReady ) {
							updateTexture( texture, image, glFormat, glType );
						}
        }
        else {
          state.texImage2D(WebGL.TEXTURE_2D, 0, glInternalFormat, image.width, image.height, 0, glFormat, glType, image.data);
        }
      }
    }
    else if (texture is CompressedTexture) {
				if ( texture is CompressedArrayTexture ) {
					if ( useTexStorage && allocateMemory ) {
						state.texStorage3D( WebGL.TEXTURE_2D_ARRAY, levels, glInternalFormat, mipmaps[ 0 ].width, mipmaps[ 0 ].height, image.depth );
					}

					for ( int i = 0, il = mipmaps.length; i < il; i ++ ) {
						mipmap = mipmaps[ i ];
						if ( texture.format != RGBAFormat ) {
							if ( glFormat > 0 ) {
								if ( useTexStorage && dataReady) {
                if ( texture.layerUpdates.isNotEmpty ) {
                  final layerByteLength = TextureUtils.getByteLength( mipmap.width, mipmap.height, texture.format, texture.type );
                  for ( final layerIndex in texture.layerUpdates ) {
                    final layerData = mipmap.data.subarray(
                      layerIndex * layerByteLength / mipmap.data.BYTES_PER_ELEMENT,
                      ( layerIndex + 1 ) * layerByteLength / mipmap.data.BYTES_PER_ELEMENT
                    );
                    state.compressedTexSubImage3D( WebGL.TEXTURE_2D_ARRAY, i, 0, 0, layerIndex, mipmap.width, mipmap.height, 1, glFormat, layerData );
                  }
                  texture.clearLayerUpdates();
                } else {
                  state.compressedTexSubImage3D( WebGL.TEXTURE_2D_ARRAY, i, 0, 0, 0, mipmap.width, mipmap.height, image.depth, glFormat, mipmap.data );
                }
								} else {
									state.compressedTexImage3D( WebGL.TEXTURE_2D_ARRAY, i, glInternalFormat, mipmap.width, mipmap.height, image.depth, 0, mipmap.data);//, 0, 0 );
								}
							} else {
								console.warning( 'THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()' );
							}
						} else {
							if ( useTexStorage && dataReady) {
								state.texSubImage3D( WebGL.TEXTURE_2D_ARRAY, i, 0, 0, 0, mipmap.width, mipmap.height, image.depth, glFormat, glType, mipmap.data );
							} else {
								state.texImage3D( WebGL.TEXTURE_2D_ARRAY, i, glInternalFormat, mipmap.width, mipmap.height, image.depth, 0, glFormat, glType, mipmap.data );
							}
						}
					}
				} else {
					if ( useTexStorage && allocateMemory ) {
						state.texStorage2D( WebGL.TEXTURE_2D, levels, glInternalFormat, mipmaps[ 0 ].width, mipmaps[ 0 ].height );
					}

					for (int i = 0, il = mipmaps.length; i < il; i ++ ) {
						mipmap = mipmaps[ i ];

						if ( texture.format != RGBAFormat ) {
							if ( glFormat > 0 ) {
								if ( useTexStorage && dataReady) {
									state.compressedTexSubImage2D( WebGL.TEXTURE_2D, i, 0, 0, mipmap.width, mipmap.height, glFormat, mipmap.data );
								} else {
									state.compressedTexImage2D( WebGL.TEXTURE_2D, i, glInternalFormat, mipmap.width, mipmap.height, 0, mipmap.data );
								}
							} else {
								console.warning( 'THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()' );
							}
						} else {
							if ( useTexStorage && dataReady) {
								state.texSubImage2D( WebGL.TEXTURE_2D, i, 0, 0, mipmap.width, mipmap.height, glFormat, glType, mipmap.data );
							} else {
								state.texImage2D( WebGL.TEXTURE_2D, i, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );
							}
						}
					}
				}
    }
    else if (texture is DataArrayTexture) {
      if (useTexStorage) {
        if (allocateMemory) {
          state.texStorage3D(WebGL.TEXTURE_2D_ARRAY, levels, glInternalFormat, image.width, image.height, image.depth);
        }
        if(dataReady){
          if ( texture.layerUpdates.isNotEmpty ) {
            final layerByteLength = TextureUtils.getByteLength( image.width, image.height, texture.format, texture.type );
            for ( final layerIndex in texture.layerUpdates ) {
              final layerData = image.data.subarray(
                layerIndex * layerByteLength / image.data.BYTES_PER_ELEMENT,
                ( layerIndex + 1 ) * layerByteLength / image.data.BYTES_PER_ELEMENT
              );
              state.texSubImage3D( WebGL.TEXTURE_2D_ARRAY, 0, 0, 0, layerIndex, image.width, image.height, 1, glFormat, glType, layerData );
            }

            texture.clearLayerUpdates();
          }
          else {
            state.texSubImage3D( WebGL.TEXTURE_2D_ARRAY, 0, 0, 0, 0, image.width, image.height, image.depth, glFormat, glType, image.data );
          }
        }
      } else {
        state.texImage3D(WebGL.TEXTURE_2D_ARRAY, 0, glInternalFormat, image.width, image.height, image.depth, 0,
            glFormat, glType, image.data);
      }
    }
    else if (texture is Data3DTexture) {
      if (useTexStorage) {
        if (allocateMemory) {
          state.texStorage3D(WebGL.TEXTURE_3D, levels, glInternalFormat, image.width, image.height, image.depth);
        }
        if(dataReady){
          state.texSubImage3D(WebGL.TEXTURE_3D, 0, 0, 0, 0, image.width, image.height, image.depth, glFormat, glType, image.data);
        }
      } else {
        state.texImage3D(WebGL.TEXTURE_3D, 0, glInternalFormat, image.width, image.height, image.depth, 0, glFormat,glType, image.data);
      }
    }
    else if (texture is FramebufferTexture) {
      if (allocateMemory) {
        if (useTexStorage) {
          state.texStorage2D(WebGL.TEXTURE_2D, levels, glInternalFormat, image.width, image.height);
        } else{
          int width = image.width, height = image.height;

          for (int i = 0; i < levels; i++) {
            state.texImage2D(WebGL.TEXTURE_2D, i, glInternalFormat, width, height, 0, glFormat, glType, null);

            width >>= 1;
            height >>= 1;
          }
        }
      }
    }
    else {
      // regular Texture (image, video, canvas)

      // use manually created mipmaps if available
      // if there are no manual mipmaps
      // set 0 level mipmap and then use GL to generate other mipmap levels

      if (mipmaps.isNotEmpty) {
        if (useTexStorage && allocateMemory) {
          state.texStorage2D(WebGL.TEXTURE_2D, levels, glInternalFormat, mipmaps[0].width, mipmaps[0].height);
        }

        for (int i = 0, il = mipmaps.length; i < il; i++) {
          mipmap = mipmaps[i];
          if (useTexStorage && dataReady) {
            state.texSubImage2DIf(WebGL.TEXTURE_2D, i, 0, 0, glFormat, glType, mipmap);
          }
          else {
            state.texImage2DIf(WebGL.TEXTURE_2D, i, glInternalFormat, glFormat, glType, mipmap);
          }
        }

        texture.generateMipmaps = false;
      }
      else {
        if (useTexStorage) {
          if (allocateMemory) {
            state.texStorage2D(WebGL.TEXTURE_2D, levels, glInternalFormat, image.width.toInt(), image.height.toInt());
          }
          if(dataReady){
            state.texSubImage2DIf(WebGL.TEXTURE_2D, 0, 0, 0, glFormat, glType, image);
          }
        }
        else {
          state.texImage2DIf(WebGL.TEXTURE_2D, 0, glInternalFormat, glFormat, glType, image);
        }
      }
    }

    if (textureNeedsGenerateMipmaps(texture)) {
      generateMipmap(textureType);
    }

    source.currentVersion = source.version;

    if (texture.onUpdate != null) texture.onUpdate!(texture);
  }

  textureProperties["__version"] = texture.version;
}