Skip to content

Commit aafface

Browse files
committed
initial testing of texture support
1 parent 4f618cc commit aafface

File tree

5 files changed

+222
-21
lines changed

5 files changed

+222
-21
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
}

sample.html

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<title>GeoJS QuadFeature with Random Texture</title>
6+
<script src="dist/built/geo.js"></script>
7+
<style>
8+
html, body, #map {
9+
height: 100%;
10+
margin: 0;
11+
overflow: hidden;
12+
}
13+
</style>
14+
</head>
15+
<body>
16+
<div id="map"></div>
17+
<script>
18+
// Define frame size for the texture
19+
const frameWidth = 256;
20+
const frameHeight = 256;
21+
22+
// Function to generate a random texture
23+
function generateRandomTexture(width, height) {
24+
const data = new Uint8Array(width * height * 4); // RGBA
25+
for (let i = 0; i < data.length; i += 4) {
26+
data[i] = Math.floor(Math.random() * 256); // R
27+
data[i + 1] = Math.floor(Math.random() * 256); // G
28+
data[i + 2] = Math.floor(Math.random() * 256); // B
29+
data[i + 3] = 255; // A
30+
}
31+
return {
32+
data,
33+
width,
34+
height
35+
};
36+
}
37+
38+
function randomTextureToImage(texture) {
39+
const { data, width, height } = texture;
40+
41+
// Create a canvas
42+
const canvas = document.createElement('canvas');
43+
canvas.width = width;
44+
canvas.height = height;
45+
46+
// Draw the texture data to the canvas
47+
const ctx = canvas.getContext('2d');
48+
const imageData = ctx.createImageData(width, height);
49+
imageData.data.set(data);
50+
ctx.putImageData(imageData, 0, 0);
51+
52+
// Create an image element from the canvas
53+
const img = new Image();
54+
img.src = canvas.toDataURL(); // Converts canvas to base64 PNG
55+
56+
return img;
57+
}
58+
59+
const randomTexture = generateRandomTexture(frameWidth, frameHeight);
60+
61+
//const image = randomTextureToImage(randomTexture)
62+
// Create the map
63+
const map = geo.map({
64+
node: '#map',
65+
center: { x: -98, y: 39 }, // Rough center of contiguous U.S.
66+
zoom: 3,
67+
baselayer: null
68+
});
69+
70+
// map.createLayer('osm');
71+
const layer = map.createLayer('feature');
72+
const geoCorners = {
73+
ul: { x: -125, y: 50 }, // upper-left (NW)
74+
ur: { x: -66, y: 50 }, // upper-right (NE)
75+
ll: { x: -125, y: 24 }, // lower-left (SW)
76+
lr: { x: -66, y: 24 } // lower-right (SE)
77+
};
78+
79+
// const imageUrl = 'image.jpg';
80+
// const imageObj = new Image();
81+
// imageObj.src = 'image.jpg'
82+
// imageObj.crossOrigin = 'anonymouse'
83+
84+
// Define geo-coordinates where the image should be projected
85+
const corners = {
86+
ul: { x: -105, y: 45 }, // Upper-left
87+
ur: { x: -95, y: 45 }, // Upper-right
88+
ll: { x: -105, y: 35 }, // Lower-left
89+
lr: { x: -95, y: 35 } // Lower-right
90+
};
91+
92+
// Create quad feature using local texture coordinates
93+
layer.createFeature('quad')
94+
.data([{
95+
ul: corners.ul,
96+
lr: corners.lr,
97+
texture: randomTexture,
98+
}])
99+
.draw();
100+
101+
map.draw();
102+
</script>
103+
</body>
104+
</html>

src/quadFeature.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +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+
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+
data: d.texture.data
445+
};
446+
quad.imageTexture = textureImage; // Store as imageTexture for WebGL
447+
imgQuads.push(quad);
448+
quadinfo.imgquad = quad;
449+
}
450+
437451
if (img) {
438452
quadinfo.imageEntry = img;
439453
/* Handle image quads */

src/vgl/texture.js

Lines changed: 39 additions & 1 deletion
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;
@@ -64,7 +65,7 @@ vgl.texture = function () {
6465
vgl.GL.TEXTURE_WRAP_S, vgl.GL.CLAMP_TO_EDGE);
6566
renderState.m_context.texParameteri(vgl.GL.TEXTURE_2D,
6667
vgl.GL.TEXTURE_WRAP_T, vgl.GL.CLAMP_TO_EDGE);
67-
68+
console.log('Inside the setup vgl function');
6869
if (this.m_image !== null) {
6970
renderState.m_context.pixelStorei(vgl.GL.UNPACK_ALIGNMENT, 1);
7071
renderState.m_context.pixelStorei(vgl.GL.UNPACK_FLIP_Y_WEBGL, true);
@@ -77,8 +78,21 @@ vgl.texture = function () {
7778
// console.log('m_pixelDataType ' + this.m_pixelDataType);
7879

7980
// FOR now support only 2D textures
81+
console.log(this.m_image);
8082
renderState.m_context.texImage2D(vgl.GL.TEXTURE_2D, 0, this.m_internalFormat,
8183
this.m_pixelFormat, this.m_pixelDataType, this.m_image);
84+
} else if (this.m_texture !== null) {
85+
// Custom texture data object
86+
console.log('Rendering custom Texture with size ' + this.m_texture.width + 'and ' + this.m_texture.height);
87+
console.log(this.m_texture.data);
88+
renderState.m_context.pixelStorei(vgl.GL.UNPACK_ALIGNMENT, 1);
89+
renderState.m_context.pixelStorei(vgl.GL.UNPACK_FLIP_Y_WEBGL, true);
90+
91+
this.updateDimensions();
92+
this.computeInternalFormatUsingImage();
93+
renderState.m_context.texImage2D(vgl.GL.TEXTURE_2D, 0, this.m_internalFormat,
94+
this.m_texture.width, this.m_texture.height, 0,
95+
this.m_pixelFormat, this.m_pixelDataType, this.m_texture.data);
8296
} else {
8397
renderState.m_context.texImage2D(vgl.GL.TEXTURE_2D, 0, this.m_internalFormat,
8498
this.m_width, this.m_height, 0, this.m_pixelFormat, this.m_pixelDataType, null);
@@ -121,6 +135,15 @@ vgl.texture = function () {
121135
return this.m_image;
122136
};
123137

138+
/**
139+
* Get image used by the texture.
140+
*
141+
* @returns {vgl.image}
142+
*/
143+
this.texture = function () {
144+
return this.m_texture;
145+
};
146+
124147
/**
125148
* Set image for the texture.
126149
*
@@ -138,6 +161,16 @@ vgl.texture = function () {
138161
return false;
139162
};
140163

164+
this.setTexture = function (texture) {
165+
if (texture !== null) {
166+
this.m_texture = texture;
167+
this.updateDimensions();
168+
this.modified();
169+
return true;
170+
}
171+
172+
return false;
173+
};
141174
/**
142175
* Get nearest pixel flag for the texture.
143176
*
@@ -228,6 +261,11 @@ vgl.texture = function () {
228261
this.m_height = this.m_image.height;
229262
this.m_depth = 0; // Only 2D images are supported now
230263
}
264+
if (this.m_texture !== null) {
265+
this.m_width = this.m_texture.width;
266+
this.m_height = this.m_texture.height;
267+
this.m_depth = 0; // Only 2D images are supported now
268+
}
231269
};
232270

233271
/**

src/webgl/quadFeature.js

Lines changed: 64 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -275,25 +275,51 @@ 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+
console.log('Texture already has a vgl _texture');
287+
} else {
288+
console.log('Updating Texture by creating new VGL');
289+
texture = new vgl.texture();
290+
texture.setTexture(quad.imageTexture);
291+
let nearestPixel = m_this.nearestPixel();
292+
if (nearestPixel !== undefined) {
293+
if (nearestPixel !== true && util.isNonNullFinite(nearestPixel)) {
294+
const curZoom = m_this.layer().map().zoom();
295+
nearestPixel = curZoom >= nearestPixel;
296+
}
291297
}
298+
if (nearestPixel) {
299+
texture.setNearestPixel(true);
300+
}
301+
quad.texture = quad.imageTexture._texture = texture;
292302
}
293-
if (nearestPixel) {
294-
texture.setNearestPixel(true);
303+
} else if (quad.image) {
304+
// Handle regular image
305+
if (quad.image._texture) {
306+
quad.texture = quad.image._texture;
307+
} else {
308+
texture = new vgl.texture();
309+
console.log('Setting Quad Image');
310+
texture.setImage(quad.image);
311+
let nearestPixel = m_this.nearestPixel();
312+
if (nearestPixel !== undefined) {
313+
if (nearestPixel !== true && util.isNonNullFinite(nearestPixel)) {
314+
const curZoom = m_this.layer().map().zoom();
315+
nearestPixel = curZoom >= nearestPixel;
316+
}
317+
}
318+
if (nearestPixel) {
319+
texture.setNearestPixel(true);
320+
}
321+
quad.texture = quad.image._texture = texture;
295322
}
296-
quad.texture = quad.image._texture = texture;
297323
}
298324
});
299325
};
@@ -382,7 +408,10 @@ var webgl_quadFeature = function (arg) {
382408
nearestPixel = curZoom >= nearestPixel;
383409
}
384410
m_quads.imgQuads.forEach((quad) => {
385-
if (quad.image && quad.texture && quad.texture.nearestPixel() !== nearestPixel && quad.texture.textureHandle()) {
411+
console.log(nearestPixel);
412+
console.log(quad.texture.nearestPixel());
413+
console.log(quad.texture.textureHandle());
414+
if ((quad.image || quad.imageTexture) && quad.texture && quad.texture.nearestPixel() !== nearestPixel && quad.texture.textureHandle()) {
386415
/* This could just be
387416
* quad.texture.setNearestPixel(nearestPixel);
388417
* but that needlessly redecodes the image. Instead, just change the
@@ -404,18 +433,25 @@ var webgl_quadFeature = function (arg) {
404433
}
405434
context.bindBuffer(context.ARRAY_BUFFER, m_glBuffers.imgQuadsPosition);
406435
$.each(m_quads.imgQuads, function (idx, quad) {
407-
if (!quad.image) {
436+
if (!quad.image && !quad.imageTexture) {
408437
return;
409438
}
410439
quad.texture.bind(renderState);
411440
// only check if the context is out of memory when using modestly large
412441
// textures. The check is slow.
413-
if (quad.image.width * quad.image.height > _memoryCheckLargestTested) {
442+
if (quad.image && quad.image.width * quad.image.height > _memoryCheckLargestTested) {
414443
_memoryCheckLargestTested = quad.image.width * quad.image.height;
415444
if (context.getError() === context.OUT_OF_MEMORY) {
416445
console.log('Insufficient GPU memory for texture');
417446
}
418447
}
448+
if (quad.imageTexture && quad.imageTexture.width * quad.imageTexture.height > _memoryCheckLargestTested) {
449+
_memoryCheckLargestTested = quad.imageTexture.width * quad.imageTexture.height;
450+
if (context.getError() === context.OUT_OF_MEMORY) {
451+
console.log('Insufficient GPU memory for texture');
452+
}
453+
}
454+
419455
if (quad.opacity !== opacity) {
420456
opacity = quad.opacity;
421457
context.uniform1fv(renderState.m_material.shaderProgram()
@@ -432,8 +468,14 @@ var webgl_quadFeature = function (arg) {
432468
context.uniform2fv(renderState.m_material.shaderProgram()
433469
.uniformLocation('crop'), new Float32Array([crop.x === undefined ? 1 : crop.x, crop.y === undefined ? 1 : crop.y]));
434470
}
435-
w = quad.image.width;
436-
h = quad.image.height;
471+
if (quad.image) {
472+
w = quad.image.width;
473+
h = quad.image.height;
474+
}
475+
if (quad.imageTexture) {
476+
w = quad.imageTexture.width;
477+
h = quad.imageTexture.height;
478+
}
437479
quadcropsrc = quad.crop || {left: 0, top: 0, right: w, bottom: h};
438480
if (!cropsrc || quadcropsrc.left !== cropsrc.left || quadcropsrc.top !== cropsrc.top || quadcropsrc.right !== cropsrc.right || quadcropsrc.bottom !== cropsrc.bottom || quadw !== w || quadh !== h) {
439481
cropsrc = quadcropsrc;
@@ -496,6 +538,9 @@ var webgl_quadFeature = function (arg) {
496538
delete quad.texture;
497539
delete quad.image._texture;
498540
}
541+
if (quad.imageTexture) {
542+
delete quad.imageTexture._texture;
543+
}
499544
});
500545
m_this._updateTextures();
501546
}

0 commit comments

Comments
 (0)