uploadCubeTexture method

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

Implementation

void uploadCubeTexture(Map<String, dynamic> textureProperties, Texture texture, int slot) {
  if (texture.image.length != 6) return;

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

  state.activeTexture(WebGL.TEXTURE0 + slot);
  state.bindTexture(WebGL.TEXTURE_CUBE_MAP, 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);
    }

    final isCompressed = (texture.isCompressedTexture || texture is CompressedTexture);
    final isDataTexture = (texture.image[0] != null && texture is DataTexture);
    final isCubeTexture = (texture.image[0] != null && texture is CubeTexture);

    final cubeImage = [];

    for (int i = 0; i < 6; i++) {
      if (!isCompressed && !isDataTexture) {
        cubeImage.add(texture.image[i]);
      }
      else {
        cubeImage.add(isDataTexture ? texture.image[i].image : texture.image[i]);
      }

      cubeImage[i] = verifyColorSpace(texture, cubeImage[i]);
    }

    final image = cubeImage[0],
        supportsMips = isPowerOfTwo(image) || isWebGL2,
        glFormat = utils.convert(texture.format, texture.encoding),
        glType = utils.convert(texture.type),
        glInternalFormat = getInternalFormat(texture.internalFormat, glFormat, glType, texture.encoding);

    final useTexStorage = (isWebGL2 && texture is! VideoTexture);
    final allocateMemory = (textureProperties['__version'] == null);
    int levels = getMipLevels(texture, image, supportsMips);

    setTextureParameters(WebGL.TEXTURE_CUBE_MAP, texture, supportsMips);

    dynamic mipmaps;

    if (isCompressed) {
      if (useTexStorage && allocateMemory) {
        state.texStorage2D(WebGL.TEXTURE_CUBE_MAP, levels, glInternalFormat, image.width, image.height);
      }

      for (int i = 0; i < 6; i++) {
        mipmaps = cubeImage[i].mipmaps;

        for (int j = 0; j < mipmaps.length; j++) {
          final mipmap = mipmaps[j];

          if (texture.format != RGBAFormat) {
            if (glFormat != null) {
              if (useTexStorage) {
                state.compressedTexSubImage2D(WebGL.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, 0, 0, mipmap.width, mipmap.height, glFormat, mipmap.data);
              } else {
                state.compressedTexImage2D(WebGL.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glInternalFormat, mipmap.width, mipmap.height, 0, mipmap.data);
              }
            } else {
              console.warning('WebGLRenderer: Attempt to load unsupported compressed texture format in .setTextureCube()');
            }
          } else {
            if (useTexStorage) {
              state.texSubImage2D(WebGL.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, 0, 0, mipmap.width, mipmap.height, glFormat,
                  glType, mipmap.data);
            } else {
              state.texImage2D(WebGL.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glInternalFormat, mipmap.width, mipmap.height,
                  0, glFormat, glType, mipmap.data);
            }
          }
        }
      }
    }
    else {
      mipmaps = texture.mipmaps;

      if (useTexStorage && allocateMemory) {
        // TODO: Uniformly handle mipmap definitions
        // Normal textures and compressed cube textures define base level + mips with their mipmap array
        // Uncompressed cube textures use their mipmap array only for mips (no base level)

        if (mipmaps.length > 0) levels++;

        state.texStorage2D(WebGL.TEXTURE_CUBE_MAP, levels, glInternalFormat, cubeImage[0].width, cubeImage[0].height);
      }

      for (int i = 0; i < 6; i++) {
        if (isDataTexture || isCubeTexture) {
          if (useTexStorage) {
            if(kIsWeb){
              state.texSubImage2DNoSize(WebGL.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 0, 0, glFormat, glType, cubeImage[i].data);
            }
            else{
              state.texSubImage2D(WebGL.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 0, 0, cubeImage[i].width, cubeImage[i].height, glFormat, glType, cubeImage[i].data);
            }
          }
          else {
            if(kIsWeb){
              state.texImage2DNoSize(WebGL.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, glFormat, glType, cubeImage[i].data);
            }
            else{
              state.texImage2D(WebGL.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, cubeImage[i].width,cubeImage[i].height, 0, glFormat, glType, cubeImage[i].data);
            }
          }

          for (int j = 0; j < mipmaps.length; j++) {
            final mipmap = mipmaps[j];
            final mipmapImage = mipmap.image[i].image;

            if (useTexStorage) {
              state.texSubImage2D(WebGL.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, 0, 0, mipmapImage.width,
                  mipmapImage.height, glFormat, glType, mipmapImage.data);
            } else {
              state.texImage2D(WebGL.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, glInternalFormat, mipmapImage.width,
                  mipmapImage.height, 0, glFormat, glType, mipmapImage.data);
            }
          }
        }
        else {
          if (useTexStorage) {
            state.texSubImage2DIf(WebGL.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 0, 0, glFormat, glType, cubeImage[i]);
          } else {
            state.texImage2DIf(
                WebGL.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, glFormat, glType, cubeImage[i]);
          }

          for (int j = 0; j < mipmaps.length; j++) {
            final mipmap = mipmaps[j];

            if (useTexStorage) {
              state.texSubImage2DIf(
                  WebGL.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, 0, 0, glFormat, glType, mipmap.image[i]);
            } else {
              state.texImage2DIf(
                  WebGL.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, glInternalFormat, glFormat, glType, mipmap.image[i]);
            }
          }
        }
      }
    }

    if (textureNeedsGenerateMipmaps(texture, supportsMips)) {
      // We assume images for cube map have the same size.
      generateMipmap(WebGL.TEXTURE_CUBE_MAP);
    }

    source.currentVersion = source.version;

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

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