Add uniform for lights

This commit is contained in:
schmelczerandras 2020-07-25 16:20:27 +02:00
parent e6782a9a98
commit d336bee1ba
14 changed files with 218 additions and 116 deletions

View file

@ -28,6 +28,10 @@ export abstract class GameObject extends Typed implements CommandReceiver {
this.commandExecutors[commandType.name] = handler;
}
public reactsToCommand<T extends Command>(commandType: new () => T): boolean {
return this.commandExecutors.hasOwnProperty(commandType.name);
}
public sendCommand(command: Command) {
const commandType = command.constructor.name;

View file

@ -5,19 +5,16 @@ import { MoveToCommand } from '../../commands/types/move-to';
import { StepCommand } from '../../commands/types/step';
import { SwipeCommand } from '../../commands/types/swipe';
import { GameObject } from '../game-object';
import { ObjectContainer } from '../object-container';
import { Camera } from './camera';
export class Character extends GameObject {
private keysDown: Set<string> = new Set();
private camera = new Camera();
private static speed = 0.5;
constructor(objects: ObjectContainer) {
constructor(private camera: Camera) {
super();
objects.addObject(this.camera);
this.addCommandExecutor(StepCommand, this.stepHandler.bind(this));
this.addCommandExecutor(KeyDownCommand, (c) => this.keysDown.add(c.key));
this.addCommandExecutor(KeyUpCommand, (c) => this.keysDown.delete(c.key));

View file

@ -0,0 +1,25 @@
import { vec2, vec3 } from 'gl-matrix';
import { DrawCommand } from '../../commands/types/draw';
import { GameObject } from '../game-object';
export class CircleLight extends GameObject {
constructor(
private center: vec2,
private radius: number,
private value: vec3
) {
super();
this.addCommandExecutor(DrawCommand, this.draw.bind(this));
}
private draw(c: DrawCommand) {
if (c.drawer.isOnScreen(this.center)) {
c.drawer.appendToUniformList('lights', {
center: this.center,
radius: this.radius,
value: this.value,
});
}
}
}

View file

@ -0,0 +1,30 @@
import { vec2, vec3 } from 'gl-matrix';
import { CursorMoveCommand } from '../../commands/types/cursor-move-command';
import { DrawCommand } from '../../commands/types/draw';
import { GameObject } from '../game-object';
export class CursorLight extends GameObject {
private mousePosition = vec2.create();
constructor(private radius: number, private value: vec3) {
super();
this.addCommandExecutor(DrawCommand, this.draw.bind(this));
this.addCommandExecutor(CursorMoveCommand, this.setPosition.bind(this));
}
private draw(c: DrawCommand) {
const center = c.drawer.screenUvToWorldCoordinate(this.mousePosition);
if (c.drawer.isOnScreen(center)) {
c.drawer.appendToUniformList('lights', {
center,
radius: this.radius,
value: this.value,
});
}
}
private setPosition(c: CursorMoveCommand) {
this.mousePosition = c.position;
}
}

View file

@ -1,55 +0,0 @@
import { vec2 } from 'gl-matrix';
import { DrawCommand } from '../../commands/types/draw';
import { GameObject } from '../game-object';
export interface Line {
start: vec2;
end: vec2;
radiusFrom: number;
radiusTo: number;
}
export class Dungeon extends GameObject {
private lines: Array<Line> = [];
constructor() {
super();
this.addCommandExecutor(DrawCommand, this.draw.bind(this));
let previousRadius = 350;
let previousEnd = vec2.create();
for (let i = 0; i < 500000; i += 500) {
const height = previousEnd.y + (Math.random() - 0.5) * 2000;
const currentEnd = vec2.fromValues(i, height);
const currentToRadius = Math.random() * 300 + 150;
this.lines.push({
start: previousEnd,
end: currentEnd,
radiusFrom: previousRadius,
radiusTo: currentToRadius,
});
previousEnd = currentEnd;
previousRadius = currentToRadius;
}
}
private draw(c: DrawCommand) {
const lines: Array<vec2> = [];
const radii: Array<number> = [];
for (let line of this.lines) {
if (c.drawer.isOnScreen(line.start) || c.drawer.isOnScreen(line.end)) {
lines.push(line.start);
lines.push(line.end);
radii.push(line.radiusFrom);
radii.push(line.radiusTo);
}
}
c.drawer.giveUniforms({ lines, radii });
}
}

View file

@ -0,0 +1,25 @@
import { vec2 } from 'gl-matrix';
import { DrawCommand } from '../../commands/types/draw';
import { GameObject } from '../game-object';
export interface Line {}
export class Tunnel extends GameObject {
constructor(
private from: vec2,
private to: vec2,
private radiusFrom: number,
private radiusTo: number
) {
super();
this.addCommandExecutor(DrawCommand, this.draw.bind(this));
}
private draw(c: DrawCommand) {
if (c.drawer.isOnScreen(this.from) || c.drawer.isOnScreen(this.to)) {
c.drawer.appendToUniformList('lines', this.from, this.to);
c.drawer.appendToUniformList('radii', this.radiusFrom, this.radiusTo);
}
}
}

View file

@ -0,0 +1,12 @@
import { vec3 } from 'gl-matrix';
import { ObjectContainer } from '../object-container';
import { Camera } from '../types/camera';
import { Character } from '../types/character';
import { CursorLight } from '../types/cursor-light';
export const createCharacter = (objects: ObjectContainer) => {
const camera = new Camera();
objects.addObject(camera);
objects.addObject(new Character(camera));
objects.addObject(new CursorLight(40, vec3.fromValues(0.67, 0.67, 0.33)));
};

View file

@ -0,0 +1,37 @@
import { vec2, vec3 } from 'gl-matrix';
import { ObjectContainer } from '../object-container';
import { CircleLight } from '../types/circle-light';
import { Tunnel } from '../types/tunnel';
export const createDungeon = (objects: ObjectContainer) => {
let previousRadius = 350;
let previousEnd = vec2.create();
for (let i = 0; i < 500000; i += 500) {
const deltaHeight = (Math.random() - 0.5) * 2000;
const height = previousEnd.y + deltaHeight;
const currentEnd = vec2.fromValues(i, height);
const currentToRadius = Math.random() * 300 + 150;
objects.addObject(
new Tunnel(previousEnd, currentEnd, previousRadius, currentToRadius)
);
if (deltaHeight > 0) {
objects.addObject(
new CircleLight(
currentEnd,
Math.random() * 20 + 30,
vec3.scale(
vec3.create(),
vec3.normalize(vec3.create(), vec3.random(vec3.create())),
Math.random() * 0.5 + 0.5
)
)
);
}
previousEnd = currentEnd;
previousRadius = currentToRadius;
}
};