Skip to content

Commit

Permalink
feat(point image): add point image
Browse files Browse the repository at this point in the history
  • Loading branch information
lzxue committed Oct 16, 2019
1 parent a995815 commit 89b2513
Show file tree
Hide file tree
Showing 20 changed files with 180 additions and 55 deletions.
2 changes: 1 addition & 1 deletion packages/core/src/inversify.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import getDecorators from 'inversify-inject-decorators';
import { TYPES } from './types';

/** Service interfaces */
import { IIconService} from './services/asset/IIconService';
import { IIconService } from './services/asset/IIconService';
import { ICameraService } from './services/camera/ICameraService';
import { IGlobalConfigService } from './services/config/IConfigService';
import { ICoordinateSystemService } from './services/coordinate/ICoordinateSystemService';
Expand Down
3 changes: 3 additions & 0 deletions packages/core/src/services/asset/IIconService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ export interface IICONMap {
[key: string]: IIconValue;
}
export interface IIconService {
canvasHeight: number;
init(): void;
addImage(id: string, image: IImage): void;
getTexture(): ITexture2D;
getIconMap(): IICONMap;
getCanvas(): HTMLCanvasElement;
}
38 changes: 25 additions & 13 deletions packages/core/src/services/asset/IconService.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { inject, injectable } from 'inversify';
import { TYPES } from '../../types';
import { buildIconMaping } from '../../utils/font_util';
import { gl } from '../renderer/gl';
import { IRendererService } from '../renderer/IRendererService';
import { ITexture2D } from '../renderer/ITexture2D';
import {
IIcon,
Expand All @@ -13,23 +16,24 @@ const MAX_CANVAS_WIDTH = 1024;
const imageSize = 64;
@injectable()
export default class IconService implements IIconService {
public canvasHeight: number;
private textrure: ITexture2D;
private canvas: HTMLCanvasElement;
private iconData: IIcon[];
private iconMap: IICONMap;
private canvasHeigth: number;
private textrure: ITexture2D;
private ctx: CanvasRenderingContext2D;

constructor() {
public init() {
this.iconData = [];
this.iconMap = {};
this.canvas = document.createElement('canvas');
// this.texture =
this.ctx = this.canvas.getContext('2d') as CanvasRenderingContext2D;
}

public async addImage(id: string, image: IImage) {
const imagedata = (await this.loadImage(image)) as HTMLImageElement;
public addImage(id: string, image: IImage) {
let imagedata = new Image();
this.loadImage(image).then((img) => {
imagedata = img as HTMLImageElement;
});
this.iconData.push({
id,
image: imagedata,
Expand All @@ -42,28 +46,35 @@ export default class IconService implements IIconService {
MAX_CANVAS_WIDTH,
);
this.iconMap = mapping;
this.canvasHeigth = canvasHeight;
this.canvasHeight = canvasHeight;
this.updateIconAtlas();
}

public getTexture(): ITexture2D {
throw new Error('Method not implemented.');
return this.textrure;
}

public getIconMap() {
return this.iconMap;
}
public getCanvas() {
return this.canvas;
}

private updateIconAtlas() {
this.canvas.width = MAX_CANVAS_WIDTH;
this.canvas.height = this.canvasHeigth;
this.canvas.height = this.canvasHeight;
Object.keys(this.iconMap).forEach((item: string) => {
const { x, y, image } = this.iconMap[item];
this.ctx.drawImage(image, x, y, imageSize, imageSize);
});
// this.texture.magFilter = THREE.LinearFilter;
// this.texture.minFilter = THREE.LinearFilter;
// this.texture.needsUpdate = true;
// const { createTexture2D } = this.rendererService;
// this.textrure = createTexture2D({
// data: this.canvas,
// width: this.canvas.width,
// height: this.canvasHeight,
// mag: gl.LINEAR,
// });
}

private loadImage(url: IImage) {
Expand All @@ -73,6 +84,7 @@ export default class IconService implements IIconService {
return;
}
const image = new Image();
image.crossOrigin = 'anonymous';
image.onload = () => {
resolve(image);
};
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/services/renderer/ITexture2D.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export interface ITexture2DInitializationOptions {
*/
data?:
| undefined
| HTMLCanvasElement
| HTMLImageElement
| number[]
| number[][]
Expand Down
3 changes: 3 additions & 0 deletions packages/core/src/services/scene/ISceneService.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { IImage } from '../asset/IIconService';
import { ILayer } from '../layer/ILayerService';
import { IMapConfig } from '../map/IMapService';
import { IRenderConfig } from '../renderer/IRendererService';


export interface ISceneService {
init(config: IMapConfig & IRenderConfig): void;
addLayer(layer: ILayer): void;
addImage(id: string, image: IImage): void;
render(): void;
destroy(): void;
}
13 changes: 11 additions & 2 deletions packages/core/src/services/scene/SceneService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { inject, injectable } from 'inversify';
import { AsyncParallelHook, AsyncSeriesHook } from 'tapable';
import { TYPES } from '../../types';
import { createRendererContainer } from '../../utils/dom';
import { IIconService, IImage } from '../asset/IIconService';
import { ICameraService, IViewport } from '../camera/ICameraService';
import { IGlobalConfig, IGlobalConfigService } from '../config/IConfigService';
import { IInteractionService } from '../interaction/IInteractionService';
Expand All @@ -12,7 +13,6 @@ import { IMapCamera, IMapService } from '../map/IMapService';
import { IRendererService } from '../renderer/IRendererService';
import { IShaderModuleService } from '../shader/IShaderModuleService';
import { ISceneService } from './ISceneService';

/**
* will emit `loaded` `resize` `destroy` event
*/
Expand Down Expand Up @@ -45,6 +45,9 @@ export default class Scene extends EventEmitter implements ISceneService {
@inject(TYPES.IShaderModuleService)
private readonly shaderModule: IShaderModuleService;

@inject(TYPES.IIconService)
private readonly iconService: IIconService;

/**
* 是否首次渲染
*/
Expand Down Expand Up @@ -76,6 +79,10 @@ export default class Scene extends EventEmitter implements ISceneService {

public init(globalConfig: IGlobalConfig) {
this.configService.setAndCheckConfig(globalConfig);

// 初始化资源管理 字体,图片
this.iconService.init();

/**
* 初始化底图
*/
Expand Down Expand Up @@ -151,6 +158,9 @@ export default class Scene extends EventEmitter implements ISceneService {
this.interactionService.destroy();
window.removeEventListener('resize', this.handleWindowResized, false);
}
public addImage(id: string, img: IImage) {
this.iconService.addImage(id, img);
}

private handleWindowResized = () => {
this.emit('resize');
Expand All @@ -174,7 +184,6 @@ export default class Scene extends EventEmitter implements ISceneService {
this.render();
}
};

private handleMapCameraChanged = (viewport: IViewport) => {
this.cameraService.update(viewport);
this.render();
Expand Down
1 change: 0 additions & 1 deletion packages/core/src/shaders/lighting.glsl
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// Blinn-Phong model
// apply lighting in vertex shader instead of fragment shader
// @see https://learnopengl.com/Advanced-Lighting/Advanced-Lighting
// TODO: support point light、spot light & sun light
uniform float u_ambient : 1.0;
uniform float u_diffuse : 1.0;
uniform float u_specular : 1.0;
Expand Down
7 changes: 3 additions & 4 deletions packages/layers/src/core/BaseLayer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ export default class BaseLayer implements ILayer {
public styleAttributes: {
[key: string]: Required<ILayerStyleAttribute>;
} = {};
@lazyInject(TYPES.IIconService)
protected readonly iconService: IIconService;

protected layerSource: Source;

Expand All @@ -71,9 +73,6 @@ export default class BaseLayer implements ILayer {
@lazyInject(TYPES.IRendererService)
private readonly rendererService: IRendererService;

@lazyInject(TYPES.IIconService)
private readonly iconService: IIconService;

constructor(initializationOptions: Partial<ILayerInitializationOptions>) {
this.initializationOptions = initializationOptions;
}
Expand Down Expand Up @@ -140,7 +139,7 @@ export default class BaseLayer implements ILayer {
return this;
}
public style(options: ILayerStyleOptions): ILayer {
this.styleOption = options; // TODO: merge 默认同类型
this.styleOption = options;
return this;
}
public render(): ILayer {
Expand Down
3 changes: 1 addition & 2 deletions packages/layers/src/plugins/DataEncodePlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,9 @@ export default class DataEncodePlugin implements ILayerPlugin {
id: record._id,
coordinates: record.coordinates,
};
// TODO: 数据过滤
Object.keys(attributes).forEach((attributeName: string) => {
const attribute = attributes[attributeName];
// const { type } = attribute; // TODO: 支持常量 或变量
// const { type } = attribute;
// if (type === StyleScaleType.CONSTANT) {
// return;
// }
Expand Down
5 changes: 3 additions & 2 deletions packages/layers/src/point/buffers/ImageBuffer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ export default class ImageBuffer extends BaseBuffer {
}
protected buildFeatures() {
const layerData = this.data as IEncodeFeature[];
this.attributes.uv = new Float32Array(this.verticesCount * 2);
layerData.forEach((item: IEncodeFeature, index: number) => {
const { color = [0, 0, 0, 0], size, id, shape, coordinates } = item;
const { x, y } = this.iconMap[shape as string];
const { x, y } = this.iconMap[shape as string] || { x: 0, y: 0 };
const coor = coordinates as Position;
this.attributes.vertices.set([coor[0], coor[1], coor[2] || 0], index * 3);
this.attributes.positions.set(coor, index * 3);
this.attributes.colors.set(color, index * 4);
this.attributes.pickingIds.set([id as number], index);
this.attributes.sizes.set([size as number], index); //
Expand Down
56 changes: 41 additions & 15 deletions packages/layers/src/point/point.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
import {
gl,
IIconService,
IRendererService,
IShaderModuleService,
lazyInject,
TYPES,
} from '@l7/core';
import BaseLayer from '../core/BaseLayer';
import ExtrudeBuffer from './buffers/ExtrudeBuffer';
import ImageBuffer from './buffers/ImageBuffer';
import extrude_frag from './shaders/extrude_frag.glsl';
import extrude_vert from './shaders/extrude_vert.glsl';
import image_frag from './shaders/image_frag.glsl';
import image_vert from './shaders/image_vert.glsl';

export default class PointLayer extends BaseLayer {
public name: string = 'PointLayer';
Expand All @@ -19,6 +23,7 @@ export default class PointLayer extends BaseLayer {
@lazyInject(TYPES.IRendererService)
private readonly renderer: IRendererService;


protected renderModels() {
this.models.forEach((model) =>
model.draw({
Expand All @@ -35,20 +40,28 @@ export default class PointLayer extends BaseLayer {
vs: extrude_vert,
fs: extrude_frag,
});
this.shaderModule.registerModule('pointImage', {
vs: image_vert,
fs: image_frag,
});

this.models = [];
const { vs, fs, uniforms } = this.shaderModule.getModule('point');
const buffer = new ExtrudeBuffer({
data: this.getEncodedData(),
});
buffer.computeVertexNormals('miters', false);
const { vs, fs, uniforms } = this.shaderModule.getModule('pointImage');
// const buffer = new ExtrudeBuffer({
// data: this.getEncodedData(),
// });
// buffer.computeVertexNormals('miters', false);
const {
createAttribute,
createBuffer,
createElements,
createTexture2D,
createModel,
} = this.renderer;

const buffer = new ImageBuffer({
data: this.getEncodedData(),
iconMap: this.iconService.getIconMap(),
});
this.models.push(
createModel({
attributes: {
Expand Down Expand Up @@ -78,27 +91,40 @@ export default class PointLayer extends BaseLayer {
data: buffer.attributes.sizes,
type: gl.FLOAT,
}),
size: 3,
size: 1,
}),
a_shape: createAttribute({
a_uv: createAttribute({
buffer: createBuffer({
data: buffer.attributes.miters,
data: buffer.attributes.uv,
type: gl.FLOAT,
}),
size: 3,
size: 2,
}),
// a_shape: createAttribute({
// buffer: createBuffer({
// data: buffer.attributes.miters,
// type: gl.FLOAT,
// }),
// size: 3,
// }),
},
uniforms: {
...uniforms,
u_opacity: this.styleOption.opacity as number,
u_texture: createTexture2D({
data: this.iconService.getCanvas(),
width: 1024,
height: this.iconService.canvasHeight,
}),
},
fs,
vs,
count: buffer.indexArray.length,
elements: createElements({
data: buffer.indexArray,
type: gl.UNSIGNED_INT,
}),
primitive: gl.POINTS,
count: buffer.verticesCount,
// elements: createElements({
// data: buffer.indexArray,
// type: gl.UNSIGNED_INT,
// }),
}),
);
}
Expand Down
5 changes: 3 additions & 2 deletions packages/layers/src/point/shaders/image_frag.glsl
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
uniform sampler2D u_texture;
varying vec4 v_color;
varying vec2 v_uv;
void main(){
vec2 pos=v_uv+gl_PointCoord / 512.*64.;
pos.y=1.-pos.y;
vec2 pos= v_uv + gl_PointCoord / vec2(1024.,128.)*64.;
pos.y= 1.- pos.y;
vec4 textureColor=texture2D(u_texture,pos);
if(v_color == vec4(0.)){
gl_FragColor= textureColor;
Expand Down
7 changes: 5 additions & 2 deletions packages/layers/src/point/shaders/image_vert.glsl
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
precision highp float;
attribute vec3 a_Position;
attribute vec4 a_color;
attribute vec2 a_uv;
attribute float a_size;
attribute float a_shape;
varying vec4 v_color;
varying vec2 v_uv;
uniform mat4 u_ModelMatrix;
#pragma include "projection"
void main() {
v_color = a_color;
v_uv = a_uv;
vec4 project_pos = project_position(vec4(a_Position, 1.0));
gl_Position = project_common_position_to_clipspace(vec4(project_pos, 1.0));
gl_Position = project_common_position_to_clipspace(vec4(project_pos.xyz, 1.0));
gl_PointSize = a_size;
v_uv = uv;

}
Loading

0 comments on commit 89b2513

Please sign in to comment.