Source: LayerImage.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
import { Layer } from './Layer.js'
import { Raster } from './Raster.js'
import { Shader } from './Shader.js'

/**
 * @typedef {Object} LayerImageOptions
 * @property {string} url - URL of the image to display (required)
 * @property {string|Layout} [layout='image'] - Layout format for image display
 * @property {string} [format='vec4'] - Image data format for WebGL processing
 * @property {string} [type='image'] - Must be 'image' when using Layer factory
 * @extends LayerOptions
 */

/**
 * LayerImage provides fundamental image rendering capabilities in OpenLIME.
 * It serves as both a standalone layer for basic image display and a foundation
 * for more complex image-based layers.
 * 
 * Features:
 * - Single image rendering
 * - WebGL-based display
 * - Automatic format handling
 * - Layout system integration
 * - Shader-based processing
 * 
 * Technical Details:
 * - Uses WebGL textures for image data
 * - Supports various color formats (vec3, vec4)
 * - Integrates with OpenLIME layout system
 * - Manages raster data automatically
 * - Provides standard RGB shader by default
 * 
 * @extends Layer
 * 
 * @example
 * ```javascript
 * // Direct instantiation
 * const imageLayer = new OpenLIME.LayerImage({
 *   url: 'image.jpg',
 *   layout: 'image',
 *   format: 'vec4'
 * });
 * viewer.addLayer('main', imageLayer);
 * 
 * // Using Layer factory
 * const factoryLayer = new OpenLIME.Layer({
 *   type: 'image',
 *   url: 'image.jpg',
 *   layout: 'image'
 * });
 * viewer.addLayer('factory', factoryLayer);
 * ```
 */
class LayerImage extends Layer {
    /**
     * Creates a new LayerImage instance
     * @param {LayerImageOptions} options - Configuration options
     * @throws {Error} If rasters options is not empty (should be auto-configured)
     * @throws {Error} If no URL is provided and layout has no URLs
     */
    constructor(options) {
        super(options);

        if (Object.keys(this.rasters).length != 0)
            throw "Rasters options should be empty!";

        if (this.url)
            this.layout.setUrls([this.url]);
        else if (this.layout.urls.length == 0)
            throw "Missing options.url parameter";

        const rasterFormat = this.format != null ? this.format : 'vec4';
        let raster = new Raster({ format: rasterFormat }); //FIXME select format for GEO stuff

        this.rasters.push(raster);


        let shader = new Shader({
            'label': 'Rgb',
            'samplers': [{ id: 0, name: 'source', type: rasterFormat }]
        });

        this.shaders = { 'standard': shader };
        this.setShader('standard');
    }
}

/**
 * Register this layer type with the Layer factory
 * @type {Function}
 * @private
 */
Layer.prototype.types['image'] = (options) => { return new LayerImage(options); }

export { LayerImage }