Skip to content

Commit df207d0

Browse files
committed
feat: raw texture support
1 parent 4f618cc commit df207d0

File tree

5 files changed

+268
-29
lines changed

5 files changed

+268
-29
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,5 +183,5 @@
183183
"webgl",
184184
"svg"
185185
],
186-
"main": "geo.lean.js"
186+
"main": "dist/built/geo.lean.js"
187187
}

src/quadFeature.js

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,20 @@ var quadFeature = function (arg) {
434434
}
435435
img = imgFunc.call(m_this, d, i);
436436
vid = img ? null : vidFunc.call(m_this, d, i);
437-
if (img) {
437+
438+
// Check for texture data (Uint8Array with width/height) - WebGL only
439+
if (d.texture && d.texture.data && d.texture.width && d.texture.height) {
440+
// Create a custom image object for vgl.texture
441+
var textureImage = {
442+
width: d.texture.width,
443+
height: d.texture.height,
444+
type: d.texture.type || 'RGBA',
445+
data: d.texture.data
446+
};
447+
quad.imageTexture = textureImage; // Store as imageTexture for WebGL
448+
imgQuads.push(quad);
449+
quadinfo.imgquad = quad;
450+
} else if (img) {
438451
quadinfo.imageEntry = img;
439452
/* Handle image quads */
440453
image = m_this._objectListGet(m_images, img);
@@ -773,7 +786,9 @@ quadFeature.capabilities = {
773786
/* support for canvas elements as content in image quads */
774787
canvas: 'quad.canvas',
775788
/* support for parallelogram video quads */
776-
video: 'quad.video'
789+
video: 'quad.video',
790+
/* support for raw texture data */
791+
texture: 'quad.texture'
777792
};
778793

779794
inherit(quadFeature, feature);

src/vgl/texture.js

Lines changed: 60 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ vgl.texture = function () {
3030
this.m_nearestPixel = false;
3131

3232
this.m_image = null;
33+
this.m_texture = null;
3334

3435
var m_setupTimestamp = timestamp(),
3536
m_that = this;
@@ -72,13 +73,19 @@ vgl.texture = function () {
7273
this.updateDimensions();
7374
this.computeInternalFormatUsingImage();
7475

75-
// console.log('m_internalFormat ' + this.m_internalFormat);
76-
// console.log('m_pixelFormat ' + this.m_pixelFormat);
77-
// console.log('m_pixelDataType ' + this.m_pixelDataType);
78-
7976
// FOR now support only 2D textures
8077
renderState.m_context.texImage2D(vgl.GL.TEXTURE_2D, 0, this.m_internalFormat,
8178
this.m_pixelFormat, this.m_pixelDataType, this.m_image);
79+
} else if (this.m_texture !== null) {
80+
// Custom texture data object
81+
renderState.m_context.pixelStorei(vgl.GL.UNPACK_ALIGNMENT, 1);
82+
renderState.m_context.pixelStorei(vgl.GL.UNPACK_FLIP_Y_WEBGL, true);
83+
84+
this.updateDimensions();
85+
this.computeInternalFormatUsingImage();
86+
renderState.m_context.texImage2D(vgl.GL.TEXTURE_2D, 0, this.m_internalFormat,
87+
this.m_texture.width, this.m_texture.height, 0,
88+
this.m_pixelFormat, this.m_pixelDataType, this.m_texture.data);
8289
} else {
8390
renderState.m_context.texImage2D(vgl.GL.TEXTURE_2D, 0, this.m_internalFormat,
8491
this.m_width, this.m_height, 0, this.m_pixelFormat, this.m_pixelDataType, null);
@@ -121,6 +128,15 @@ vgl.texture = function () {
121128
return this.m_image;
122129
};
123130

131+
/**
132+
* Get image used by the texture.
133+
*
134+
* @returns {vgl.image}
135+
*/
136+
this.texture = function () {
137+
return this.m_texture;
138+
};
139+
124140
/**
125141
* Set image for the texture.
126142
*
@@ -138,6 +154,36 @@ vgl.texture = function () {
138154
return false;
139155
};
140156

157+
/**
158+
* Set Raw Texture data using Uint8Array
159+
*
160+
* @param {object} texture texture object to load.
161+
* type: 'RGB' | 'RGBA' | 'Luminance' | 'LuminanceAlpha'.
162+
* texture: Uint8Array representing the format based on the type
163+
* width: width of the texture
164+
* height: height of the texture
165+
* @returns {boolean}
166+
*/
167+
this.setTexture = function (texture) {
168+
if (texture !== null) {
169+
this.m_texture = texture;
170+
if (texture.type === 'Luminance') {
171+
this.m_internalFormat = vgl.GL.LUMINANCE;
172+
this.m_pixelFormat = vgl.GL.LUMINANCE;
173+
} else if (texture.type === 'LuminanceAlpha') {
174+
this.m_internalFormat = vgl.GL.LUMINANCE_ALPHA;
175+
this.m_pixelFormat = vgl.GL.LUMINANCE_ALPHA;
176+
} else {
177+
this.m_internalFormat = vgl.GL.RGBA;
178+
this.m_pixelFormat = vgl.GL.RGBA;
179+
}
180+
this.updateDimensions();
181+
this.modified();
182+
return true;
183+
}
184+
185+
return false;
186+
};
141187
/**
142188
* Get nearest pixel flag for the texture.
143189
*
@@ -214,9 +260,11 @@ vgl.texture = function () {
214260
// };
215261

216262
// TODO Fix this
217-
this.m_internalFormat = vgl.GL.RGBA;
218-
this.m_pixelFormat = vgl.GL.RGBA;
219-
this.m_pixelDataType = vgl.GL.UNSIGNED_BYTE;
263+
if (!this.m_internalFormat || !this.m_pixelFormat || !this.m_pixelDataType) {
264+
this.m_internalFormat = vgl.GL.RGBA;
265+
this.m_pixelFormat = vgl.GL.RGBA;
266+
this.m_pixelDataType = vgl.GL.UNSIGNED_BYTE;
267+
}
220268
};
221269

222270
/**
@@ -228,6 +276,11 @@ vgl.texture = function () {
228276
this.m_height = this.m_image.height;
229277
this.m_depth = 0; // Only 2D images are supported now
230278
}
279+
if (this.m_texture !== null) {
280+
this.m_width = this.m_texture.width;
281+
this.m_height = this.m_texture.height;
282+
this.m_depth = 0; // Only 2D images are supported now
283+
}
231284
};
232285

233286
/**

src/webgl/quadFeature.js

Lines changed: 58 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -275,25 +275,48 @@ var webgl_quadFeature = function (arg) {
275275
var texture;
276276

277277
$.each(m_quads.imgQuads, function (idx, quad) {
278-
if (!quad.image) {
278+
if (!quad.image && !quad.imageTexture) {
279279
return;
280280
}
281-
if (quad.image._texture) {
282-
quad.texture = quad.image._texture;
283-
} else {
284-
texture = new vgl.texture();
285-
texture.setImage(quad.image);
286-
let nearestPixel = m_this.nearestPixel();
287-
if (nearestPixel !== undefined) {
288-
if (nearestPixel !== true && util.isNonNullFinite(nearestPixel)) {
289-
const curZoom = m_this.layer().map().zoom();
290-
nearestPixel = curZoom >= nearestPixel;
281+
282+
// Handle custom imageTexture (from texture property)
283+
if (quad.imageTexture) {
284+
if (quad.imageTexture._texture) {
285+
quad.texture = quad.imageTexture._texture;
286+
} else {
287+
texture = new vgl.texture();
288+
texture.setTexture(quad.imageTexture);
289+
let nearestPixel = m_this.nearestPixel();
290+
if (nearestPixel !== undefined) {
291+
if (nearestPixel !== true && util.isNonNullFinite(nearestPixel)) {
292+
const curZoom = m_this.layer().map().zoom();
293+
nearestPixel = curZoom >= nearestPixel;
294+
}
291295
}
296+
if (nearestPixel) {
297+
texture.setNearestPixel(true);
298+
}
299+
quad.texture = quad.imageTexture._texture = texture;
292300
}
293-
if (nearestPixel) {
294-
texture.setNearestPixel(true);
301+
} else if (quad.image) {
302+
// Handle regular image
303+
if (quad.image._texture) {
304+
quad.texture = quad.image._texture;
305+
} else {
306+
texture = new vgl.texture();
307+
texture.setImage(quad.image);
308+
let nearestPixel = m_this.nearestPixel();
309+
if (nearestPixel !== undefined) {
310+
if (nearestPixel !== true && util.isNonNullFinite(nearestPixel)) {
311+
const curZoom = m_this.layer().map().zoom();
312+
nearestPixel = curZoom >= nearestPixel;
313+
}
314+
}
315+
if (nearestPixel) {
316+
texture.setNearestPixel(true);
317+
}
318+
quad.texture = quad.image._texture = texture;
295319
}
296-
quad.texture = quad.image._texture = texture;
297320
}
298321
});
299322
};
@@ -382,7 +405,7 @@ var webgl_quadFeature = function (arg) {
382405
nearestPixel = curZoom >= nearestPixel;
383406
}
384407
m_quads.imgQuads.forEach((quad) => {
385-
if (quad.image && quad.texture && quad.texture.nearestPixel() !== nearestPixel && quad.texture.textureHandle()) {
408+
if ((quad.image || quad.imageTexture) && quad.texture && quad.texture.nearestPixel() !== nearestPixel && quad.texture.textureHandle()) {
386409
/* This could just be
387410
* quad.texture.setNearestPixel(nearestPixel);
388411
* but that needlessly redecodes the image. Instead, just change the
@@ -404,18 +427,25 @@ var webgl_quadFeature = function (arg) {
404427
}
405428
context.bindBuffer(context.ARRAY_BUFFER, m_glBuffers.imgQuadsPosition);
406429
$.each(m_quads.imgQuads, function (idx, quad) {
407-
if (!quad.image) {
430+
if (!quad.image && !quad.imageTexture) {
408431
return;
409432
}
410433
quad.texture.bind(renderState);
411434
// only check if the context is out of memory when using modestly large
412435
// textures. The check is slow.
413-
if (quad.image.width * quad.image.height > _memoryCheckLargestTested) {
436+
if (quad.image && quad.image.width * quad.image.height > _memoryCheckLargestTested) {
414437
_memoryCheckLargestTested = quad.image.width * quad.image.height;
415438
if (context.getError() === context.OUT_OF_MEMORY) {
416439
console.log('Insufficient GPU memory for texture');
417440
}
418441
}
442+
if (quad.imageTexture && quad.imageTexture.width * quad.imageTexture.height > _memoryCheckLargestTested) {
443+
_memoryCheckLargestTested = quad.imageTexture.width * quad.imageTexture.height;
444+
if (context.getError() === context.OUT_OF_MEMORY) {
445+
console.log('Insufficient GPU memory for texture');
446+
}
447+
}
448+
419449
if (quad.opacity !== opacity) {
420450
opacity = quad.opacity;
421451
context.uniform1fv(renderState.m_material.shaderProgram()
@@ -432,8 +462,14 @@ var webgl_quadFeature = function (arg) {
432462
context.uniform2fv(renderState.m_material.shaderProgram()
433463
.uniformLocation('crop'), new Float32Array([crop.x === undefined ? 1 : crop.x, crop.y === undefined ? 1 : crop.y]));
434464
}
435-
w = quad.image.width;
436-
h = quad.image.height;
465+
if (quad.image) {
466+
w = quad.image.width;
467+
h = quad.image.height;
468+
}
469+
if (quad.imageTexture) {
470+
w = quad.imageTexture.width;
471+
h = quad.imageTexture.height;
472+
}
437473
quadcropsrc = quad.crop || {left: 0, top: 0, right: w, bottom: h};
438474
if (!cropsrc || quadcropsrc.left !== cropsrc.left || quadcropsrc.top !== cropsrc.top || quadcropsrc.right !== cropsrc.right || quadcropsrc.bottom !== cropsrc.bottom || quadw !== w || quadh !== h) {
439475
cropsrc = quadcropsrc;
@@ -496,6 +532,9 @@ var webgl_quadFeature = function (arg) {
496532
delete quad.texture;
497533
delete quad.image._texture;
498534
}
535+
if (quad.imageTexture) {
536+
delete quad.imageTexture._texture;
537+
}
499538
});
500539
m_this._updateTextures();
501540
}

0 commit comments

Comments
 (0)