Something went wrong. Try again.
[READ-ONLY] Mirror of https://github.com/excaliburjs/Excalibur. 🎮 Your friendly TypeScript 2D game engine for the web 🗡️ excaliburjs.com
excalibur excaliburjs game-development game-engine game-framework gamedev games html5-canvas typescript
Something went wrong. Try again.
TypeScript
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173import type { Vector } from '../../../math/vector';import { vec } from '../../../math/vector';import type { Color } from '../../../color';import lineVertexSource from './debug-line-vertex.glsl?raw';import lineFragmentSource from './debug-line-fragment.glsl?raw';import type { ExcaliburGraphicsContextWebGL } from '../excalibur-graphics-context-webgl';import type { RendererPlugin } from '../renderer';import { Shader, VertexBuffer, VertexLayout } from '../..';import { GraphicsDiagnostics } from '../../graphics-diagnostics';
export class DebugLineRenderer implements RendererPlugin { public readonly type = 'ex.debug-line'; public priority: number = 0; private _context!: ExcaliburGraphicsContextWebGL; private _gl!: WebGL2RenderingContext; private _shader!: Shader; private _maxLines: number = 10922; private _vertexBuffer!: VertexBuffer; private _layout!: VertexLayout; private _vertexIndex = 0; private _lineCount = 0; initialize(gl: WebGL2RenderingContext, context: ExcaliburGraphicsContextWebGL): void { this._gl = gl; this._context = context; this._shader = new Shader({ graphicsContext: context, vertexSource: lineVertexSource, fragmentSource: lineFragmentSource }); this._shader.compile(); this._shader.use();
this._shader.setUniformMatrix('u_matrix', this._context.ortho);
this._vertexBuffer = new VertexBuffer({ gl, size: 7 * 6 * this._maxLines, // 7 floats per vert, 6 verts per line type: 'dynamic' });
this._layout = new VertexLayout({ gl, vertexBuffer: this._vertexBuffer, shader: this._shader, attributes: [ ['a_position', 2], ['a_color', 4], ['a_lengthSoFar', 1] ] }); }
public dispose() { this._vertexBuffer.dispose(); this._shader.dispose(); this._context = null as any; this._gl = null as any; }
private _startScratch = vec(0, 0); private _endScratch = vec(0, 0); private _lengthSoFar = 0; private _currentlyDashed = false; draw(start: Vector, end: Vector, color: Color, width = 2, dashed: boolean = false): void { // Force a render if the batch is full or we switch form dashed -> not dashed or vice versa if (this._isFull() || this._currentlyDashed !== dashed) { this._currentlyDashed = dashed; this.flush(); }
this._lineCount++;
const transform = this._context.getTransform(); const finalStart = transform.multiply(start, this._startScratch); const finalEnd = transform.multiply(end, this._endScratch);
const dir = finalEnd.sub(finalStart); const dist = finalStart.distance(finalEnd); const normal = dir.normal(); const halfWidth = width / 2;
const vertexBuffer = this._vertexBuffer.bufferData; // Start Bottom Vert vertexBuffer[this._vertexIndex++] = finalStart.x - normal.x * halfWidth; vertexBuffer[this._vertexIndex++] = finalStart.y - normal.y * halfWidth; vertexBuffer[this._vertexIndex++] = color.r / 255; vertexBuffer[this._vertexIndex++] = color.g / 255; vertexBuffer[this._vertexIndex++] = color.b / 255; vertexBuffer[this._vertexIndex++] = color.a; vertexBuffer[this._vertexIndex++] = this._lengthSoFar;
// Start Top Vert vertexBuffer[this._vertexIndex++] = finalStart.x + normal.x * halfWidth; vertexBuffer[this._vertexIndex++] = finalStart.y + normal.y * halfWidth; vertexBuffer[this._vertexIndex++] = color.r / 255; vertexBuffer[this._vertexIndex++] = color.g / 255; vertexBuffer[this._vertexIndex++] = color.b / 255; vertexBuffer[this._vertexIndex++] = color.a; vertexBuffer[this._vertexIndex++] = this._lengthSoFar;
// End Bottom Vert vertexBuffer[this._vertexIndex++] = finalEnd.x - normal.x * halfWidth; vertexBuffer[this._vertexIndex++] = finalEnd.y - normal.y * halfWidth; vertexBuffer[this._vertexIndex++] = color.r / 255; vertexBuffer[this._vertexIndex++] = color.g / 255; vertexBuffer[this._vertexIndex++] = color.b / 255; vertexBuffer[this._vertexIndex++] = color.a; vertexBuffer[this._vertexIndex++] = this._lengthSoFar + dist;
// End Bottom Vert vertexBuffer[this._vertexIndex++] = finalEnd.x - normal.x * halfWidth; vertexBuffer[this._vertexIndex++] = finalEnd.y - normal.y * halfWidth; vertexBuffer[this._vertexIndex++] = color.r / 255; vertexBuffer[this._vertexIndex++] = color.g / 255; vertexBuffer[this._vertexIndex++] = color.b / 255; vertexBuffer[this._vertexIndex++] = color.a; vertexBuffer[this._vertexIndex++] = this._lengthSoFar + dist;
// Start Top Vert vertexBuffer[this._vertexIndex++] = finalStart.x + normal.x * halfWidth; vertexBuffer[this._vertexIndex++] = finalStart.y + normal.y * halfWidth; vertexBuffer[this._vertexIndex++] = color.r / 255; vertexBuffer[this._vertexIndex++] = color.g / 255; vertexBuffer[this._vertexIndex++] = color.b / 255; vertexBuffer[this._vertexIndex++] = color.a; vertexBuffer[this._vertexIndex++] = this._lengthSoFar;
// End Top Vert vertexBuffer[this._vertexIndex++] = finalEnd.x + normal.x * halfWidth; vertexBuffer[this._vertexIndex++] = finalEnd.y + normal.y * halfWidth; vertexBuffer[this._vertexIndex++] = color.r / 255; vertexBuffer[this._vertexIndex++] = color.g / 255; vertexBuffer[this._vertexIndex++] = color.b / 255; vertexBuffer[this._vertexIndex++] = color.a; vertexBuffer[this._vertexIndex++] = this._lengthSoFar + dist; }
private _isFull() { if (this._lineCount >= this._maxLines) { return true; } return false; }
hasPendingDraws(): boolean { return this._lineCount !== 0; }
flush(): void { // nothing to draw early exit if (this._lineCount === 0) { return; }
const gl = this._gl; this._shader.use(); this._layout.use(true);
this._shader.setUniformMatrix('u_matrix', this._context.ortho); this._shader.setUniformBoolean('u_dashed', this._currentlyDashed);
gl.drawArrays(gl.TRIANGLES, 0, this._lineCount * 6); // 6 verts per line
GraphicsDiagnostics.DrawnImagesCount += this._lineCount; GraphicsDiagnostics.DrawCallCount++;
// reset this._vertexIndex = 0; this._lineCount = 0; this._lengthSoFar = 0; }}