Skip to content

Commit

Permalink
Fix rounding error gap in webgl renderer
Browse files Browse the repository at this point in the history
  • Loading branch information
Tyriar committed Aug 28, 2022
1 parent 591f178 commit f7e0f69
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 18 deletions.
2 changes: 1 addition & 1 deletion addons/xterm-addon-webgl/src/GlyphRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ export class GlyphRenderer extends Disposable {
gl.vertexAttribPointer(VertexAttribLocations.UNIT_QUAD, 2, this._gl.FLOAT, false, 0, 0);

// Setup the unit quad element array buffer, this points to indices in
// unitQuadVertuces to allow is to draw 2 triangles from the vertices
// unitQuadVertices to allow is to draw 2 triangles from the vertices
const unitQuadElementIndices = new Uint8Array([0, 1, 3, 0, 2, 3]);
const elementIndicesBuffer = gl.createBuffer();
this.register(toDisposable(() => gl.deleteBuffer(elementIndicesBuffer)));
Expand Down
28 changes: 14 additions & 14 deletions addons/xterm-addon-webgl/src/RectangleRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,11 @@ layout (location = ${VertexAttribLocations.COLOR}) in vec4 a_color;
layout (location = ${VertexAttribLocations.UNIT_QUAD}) in vec2 a_unitquad;
uniform mat4 u_projection;
uniform vec2 u_resolution;
out vec4 v_color;
void main() {
vec2 zeroToOne = (a_position + (a_unitquad * a_size)) / u_resolution;
vec2 zeroToOne = a_position + (a_unitquad * a_size);
gl_Position = u_projection * vec4(zeroToOne, 0.0, 1.0);
v_color = a_color;
}`;
Expand Down Expand Up @@ -75,7 +74,6 @@ export class RectangleRenderer extends Disposable {

private _program: WebGLProgram;
private _vertexArrayObject: IWebGLVertexArrayObject;
private _resolutionLocation: WebGLUniformLocation;
private _attributesBuffer: WebGLBuffer;
private _projectionLocation: WebGLUniformLocation;
private _bgFloat!: Float32Array;
Expand All @@ -99,7 +97,6 @@ export class RectangleRenderer extends Disposable {
this.register(toDisposable(() => gl.deleteProgram(this._program)));

// Uniform locations
this._resolutionLocation = throwIfFalsy(gl.getUniformLocation(this._program, 'u_resolution'));
this._projectionLocation = throwIfFalsy(gl.getUniformLocation(this._program, 'u_projection'));

// Create and set the vertex array object
Expand All @@ -116,7 +113,7 @@ export class RectangleRenderer extends Disposable {
gl.vertexAttribPointer(VertexAttribLocations.UNIT_QUAD, 2, this._gl.FLOAT, false, 0, 0);

// Setup the unit quad element array buffer, this points to indices in
// unitQuadVertuces to allow is to draw 2 triangles from the vertices
// unitQuadVertices to allow is to draw 2 triangles from the vertices
const unitQuadElementIndices = new Uint8Array([0, 1, 3, 0, 2, 3]);
const elementIndicesBuffer = gl.createBuffer();
this.register(toDisposable(() => gl.deleteBuffer(elementIndicesBuffer)));
Expand Down Expand Up @@ -148,7 +145,6 @@ export class RectangleRenderer extends Disposable {
gl.bindVertexArray(this._vertexArrayObject);

gl.uniformMatrix4fv(this._projectionLocation, false, PROJECTION_MATRIX);
gl.uniform2f(this._resolutionLocation, gl.canvas.width, gl.canvas.height);

// Bind attributes buffer and draw
gl.bindBuffer(gl.ARRAY_BUFFER, this._attributesBuffer);
Expand All @@ -165,6 +161,10 @@ export class RectangleRenderer extends Disposable {
this._updateViewportRectangle();
}

public setDimensions(dimensions: IRenderDimensions): void {
this._dimensions = dimensions;
}

private _updateCachedColors(): void {
this._bgFloat = this._colorToFloat32Array(this._colors.background);
}
Expand Down Expand Up @@ -276,21 +276,21 @@ export class RectangleRenderer extends Disposable {
}

private _addRectangle(array: Float32Array, offset: number, x1: number, y1: number, width: number, height: number, r: number, g: number, b: number, a: number): void {
array[offset ] = x1;
array[offset + 1] = y1;
array[offset + 2] = width;
array[offset + 3] = height;
array[offset ] = x1 / this._dimensions.scaledCanvasWidth;
array[offset + 1] = y1 / this._dimensions.scaledCanvasHeight;
array[offset + 2] = width / this._dimensions.scaledCanvasWidth;
array[offset + 3] = height / this._dimensions.scaledCanvasHeight;
array[offset + 4] = r;
array[offset + 5] = g;
array[offset + 6] = b;
array[offset + 7] = a;
}

private _addRectangleFloat(array: Float32Array, offset: number, x1: number, y1: number, width: number, height: number, color: Float32Array): void {
array[offset ] = x1;
array[offset + 1] = y1;
array[offset + 2] = width;
array[offset + 3] = height;
array[offset ] = x1 / this._dimensions.scaledCanvasWidth;
array[offset + 1] = y1 / this._dimensions.scaledCanvasHeight;
array[offset + 2] = width / this._dimensions.scaledCanvasWidth;
array[offset + 3] = height / this._dimensions.scaledCanvasHeight;
array[offset + 4] = color[0];
array[offset + 5] = color[1];
array[offset + 6] = color[2];
Expand Down
7 changes: 4 additions & 3 deletions addons/xterm-addon-webgl/src/WebglRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ export class WebglRenderer extends Disposable implements IRenderer {
this._core.screenElement!.style.width = `${this.dimensions.canvasWidth}px`;
this._core.screenElement!.style.height = `${this.dimensions.canvasHeight}px`;

this._rectangleRenderer.setDimensions(this.dimensions);
this._rectangleRenderer.onResize();
this._glyphRenderer.setDimensions(this.dimensions);
this._glyphRenderer.onResize();
Expand Down Expand Up @@ -622,11 +623,11 @@ export class WebglRenderer extends Disposable implements IRenderer {
}

private _setCanvasDevicePixelDimensions(width: number, height: number): void {
if (this.dimensions.scaledCanvasWidth === width && this.dimensions.scaledCanvasHeight === height) {
if (this._canvas.width === width && this._canvas.height === height) {
return;
}
this.dimensions.scaledCanvasWidth = width;
this.dimensions.scaledCanvasHeight = height;
// While the actual canvas size has changed, keep scaledCanvasWidth/Height as the value before
// the change as it's an exact multiple of the cell sizes.
this._canvas.width = width;
this._canvas.height = height;
this._requestRedrawViewport();
Expand Down

0 comments on commit f7e0f69

Please sign in to comment.