Rework a bit the webgl helper to allow having several programs
Without this, doing render passes with different programs using one helper instance was not really doable
This commit is contained in:
@@ -540,7 +540,7 @@ class WebGLPointsLayerRenderer extends WebGLLayerRenderer {
|
|||||||
this.previousExtent_ = frameState.extent.slice();
|
this.previousExtent_ = frameState.extent.slice();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.helper.useProgram(this.program_);
|
this.helper.useProgram(this.program_, frameState);
|
||||||
this.helper.prepareDraw(frameState);
|
this.helper.prepareDraw(frameState);
|
||||||
|
|
||||||
// write new data
|
// write new data
|
||||||
@@ -726,7 +726,7 @@ class WebGLPointsLayerRenderer extends WebGLLayerRenderer {
|
|||||||
Math.floor(frameState.size[1] / 2),
|
Math.floor(frameState.size[1] / 2),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
this.helper.useProgram(this.hitProgram_);
|
this.helper.useProgram(this.hitProgram_, frameState);
|
||||||
this.helper.prepareDrawToRenderTarget(
|
this.helper.prepareDrawToRenderTarget(
|
||||||
frameState,
|
frameState,
|
||||||
this.hitRenderTarget_,
|
this.hitRenderTarget_,
|
||||||
|
|||||||
@@ -508,7 +508,7 @@ class WebGLTileLayerRenderer extends WebGLLayerRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.helper.useProgram(this.program_);
|
this.helper.useProgram(this.program_, frameState);
|
||||||
this.helper.prepareDraw(frameState, !blend);
|
this.helper.prepareDraw(frameState, !blend);
|
||||||
|
|
||||||
const zs = Object.keys(tileTexturesByZ)
|
const zs = Object.keys(tileTexturesByZ)
|
||||||
|
|||||||
+25
-25
@@ -49,6 +49,7 @@ export const DefaultUniform = {
|
|||||||
TIME: 'u_time',
|
TIME: 'u_time',
|
||||||
ZOOM: 'u_zoom',
|
ZOOM: 'u_zoom',
|
||||||
RESOLUTION: 'u_resolution',
|
RESOLUTION: 'u_resolution',
|
||||||
|
SIZE_PX: 'u_sizePx',
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -206,11 +207,12 @@ function releaseCanvas(key) {
|
|||||||
* Shaders must be compiled and assembled into a program like so:
|
* Shaders must be compiled and assembled into a program like so:
|
||||||
* ```js
|
* ```js
|
||||||
* // here we simply create two shaders and assemble them in a program which is then used
|
* // here we simply create two shaders and assemble them in a program which is then used
|
||||||
* // for subsequent rendering calls
|
* // for subsequent rendering calls; note how a frameState is required to set up a program,
|
||||||
|
* // as several default uniforms are computed from it (projection matrix, zoom level, etc.)
|
||||||
* const vertexShader = new WebGLVertex(VERTEX_SHADER);
|
* const vertexShader = new WebGLVertex(VERTEX_SHADER);
|
||||||
* const fragmentShader = new WebGLFragment(FRAGMENT_SHADER);
|
* const fragmentShader = new WebGLFragment(FRAGMENT_SHADER);
|
||||||
* const program = this.context.getProgram(fragmentShader, vertexShader);
|
* const program = this.context.getProgram(fragmentShader, vertexShader);
|
||||||
* helper.useProgram(this.program);
|
* helper.useProgram(this.program, frameState);
|
||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
* Uniforms are defined using the `uniforms` option and can either be explicit values or callbacks taking the frame state as argument.
|
* Uniforms are defined using the `uniforms` option and can either be explicit values or callbacks taking the frame state as argument.
|
||||||
@@ -564,8 +566,6 @@ class WebGLHelper extends Disposable {
|
|||||||
canvas.style.width = size[0] + 'px';
|
canvas.style.width = size[0] + 'px';
|
||||||
canvas.style.height = size[1] + 'px';
|
canvas.style.height = size[1] + 'px';
|
||||||
|
|
||||||
gl.useProgram(this.currentProgram_);
|
|
||||||
|
|
||||||
// loop backwards in post processes list
|
// loop backwards in post processes list
|
||||||
for (let i = this.postProcessPasses_.length - 1; i >= 0; i--) {
|
for (let i = this.postProcessPasses_.length - 1; i >= 0; i--) {
|
||||||
this.postProcessPasses_[i].init(frameState);
|
this.postProcessPasses_[i].init(frameState);
|
||||||
@@ -581,10 +581,6 @@ class WebGLHelper extends Disposable {
|
|||||||
gl.ONE,
|
gl.ONE,
|
||||||
opt_disableAlphaBlend ? gl.ZERO : gl.ONE_MINUS_SRC_ALPHA
|
opt_disableAlphaBlend ? gl.ZERO : gl.ONE_MINUS_SRC_ALPHA
|
||||||
);
|
);
|
||||||
|
|
||||||
gl.useProgram(this.currentProgram_);
|
|
||||||
this.applyFrameState(frameState);
|
|
||||||
this.applyUniforms(frameState);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -609,10 +605,6 @@ class WebGLHelper extends Disposable {
|
|||||||
gl.ONE,
|
gl.ONE,
|
||||||
opt_disableAlphaBlend ? gl.ZERO : gl.ONE_MINUS_SRC_ALPHA
|
opt_disableAlphaBlend ? gl.ZERO : gl.ONE_MINUS_SRC_ALPHA
|
||||||
);
|
);
|
||||||
|
|
||||||
gl.useProgram(this.currentProgram_);
|
|
||||||
this.applyFrameState(frameState);
|
|
||||||
this.applyUniforms(frameState);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -709,6 +701,7 @@ class WebGLHelper extends Disposable {
|
|||||||
DefaultUniform.RESOLUTION,
|
DefaultUniform.RESOLUTION,
|
||||||
frameState.viewState.resolution
|
frameState.viewState.resolution
|
||||||
);
|
);
|
||||||
|
this.setUniformFloatVec2(DefaultUniform.SIZE_PX, [size[0], size[1]]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -803,22 +796,20 @@ class WebGLHelper extends Disposable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use a program. If the program is already in use, this will return `false`.
|
* Set up a program for use. The program will be set as the current one. Then, the uniforms used
|
||||||
|
* in the program will be set based on the current frame state and the helper configuration.
|
||||||
* @param {WebGLProgram} program Program.
|
* @param {WebGLProgram} program Program.
|
||||||
* @return {boolean} Changed.
|
* @param {import("../PluggableMap.js").FrameState} frameState Frame state.
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
useProgram(program) {
|
useProgram(program, frameState) {
|
||||||
if (program == this.currentProgram_) {
|
const gl = this.getGL();
|
||||||
return false;
|
gl.useProgram(program);
|
||||||
} else {
|
this.currentProgram_ = program;
|
||||||
const gl = this.getGL();
|
this.uniformLocations_ = {};
|
||||||
gl.useProgram(program);
|
this.attribLocations_ = {};
|
||||||
this.currentProgram_ = program;
|
this.applyFrameState(frameState);
|
||||||
this.uniformLocations_ = {};
|
this.applyUniforms(frameState);
|
||||||
this.attribLocations_ = {};
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -959,6 +950,15 @@ class WebGLHelper extends Disposable {
|
|||||||
this.getGL().uniform1f(this.getUniformLocation(uniform), value);
|
this.getGL().uniform1f(this.getUniformLocation(uniform), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Give a value for a vec2 uniform
|
||||||
|
* @param {string} uniform Uniform name
|
||||||
|
* @param {Array<number>} value Array of length 4.
|
||||||
|
*/
|
||||||
|
setUniformFloatVec2(uniform, value) {
|
||||||
|
this.getGL().uniform2fv(this.getUniformLocation(uniform), value);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Give a value for a vec4 uniform
|
* Give a value for a vec4 uniform
|
||||||
* @param {string} uniform Uniform name
|
* @param {string} uniform Uniform name
|
||||||
|
|||||||
@@ -57,6 +57,15 @@ const INVALID_FRAGMENT_SHADER = `
|
|||||||
gl_FragColor = vec4(oops, 1.0, 1.0, 1.0);
|
gl_FragColor = vec4(oops, 1.0, 1.0, 1.0);
|
||||||
}`;
|
}`;
|
||||||
|
|
||||||
|
const SAMPLE_FRAMESTATE = {
|
||||||
|
size: [100, 150],
|
||||||
|
viewState: {
|
||||||
|
rotation: 0.4,
|
||||||
|
resolution: 2,
|
||||||
|
center: [10, 20],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
describe('ol/webgl/WebGLHelper', function () {
|
describe('ol/webgl/WebGLHelper', function () {
|
||||||
let h;
|
let h;
|
||||||
afterEach(function () {
|
afterEach(function () {
|
||||||
@@ -117,7 +126,10 @@ describe('ol/webgl/WebGLHelper', function () {
|
|||||||
u_test4: createTransform(),
|
u_test4: createTransform(),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
h.useProgram(h.getProgram(FRAGMENT_SHADER, VERTEX_SHADER));
|
h.useProgram(
|
||||||
|
h.getProgram(FRAGMENT_SHADER, VERTEX_SHADER),
|
||||||
|
SAMPLE_FRAMESTATE
|
||||||
|
);
|
||||||
h.prepareDraw({
|
h.prepareDraw({
|
||||||
pixelRatio: 2,
|
pixelRatio: 2,
|
||||||
size: [50, 80],
|
size: [50, 80],
|
||||||
@@ -164,7 +176,7 @@ describe('ol/webgl/WebGLHelper', function () {
|
|||||||
h = new WebGLHelper();
|
h = new WebGLHelper();
|
||||||
|
|
||||||
p = h.getProgram(FRAGMENT_SHADER, VERTEX_SHADER);
|
p = h.getProgram(FRAGMENT_SHADER, VERTEX_SHADER);
|
||||||
h.useProgram(p);
|
h.useProgram(p, SAMPLE_FRAMESTATE);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('has saved the program', function () {
|
it('has saved the program', function () {
|
||||||
@@ -209,34 +221,30 @@ describe('ol/webgl/WebGLHelper', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('#makeProjectionTransform', function () {
|
describe('#makeProjectionTransform', function () {
|
||||||
let frameState;
|
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
h = new WebGLHelper();
|
h = new WebGLHelper();
|
||||||
|
|
||||||
frameState = {
|
|
||||||
size: [100, 150],
|
|
||||||
viewState: {
|
|
||||||
rotation: 0.4,
|
|
||||||
resolution: 2,
|
|
||||||
center: [10, 20],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('gives out the correct transform', function () {
|
it('gives out the correct transform', function () {
|
||||||
const scaleX = 2 / frameState.size[0] / frameState.viewState.resolution;
|
const scaleX =
|
||||||
const scaleY = 2 / frameState.size[1] / frameState.viewState.resolution;
|
2 /
|
||||||
|
SAMPLE_FRAMESTATE.size[0] /
|
||||||
|
SAMPLE_FRAMESTATE.viewState.resolution;
|
||||||
|
const scaleY =
|
||||||
|
2 /
|
||||||
|
SAMPLE_FRAMESTATE.size[1] /
|
||||||
|
SAMPLE_FRAMESTATE.viewState.resolution;
|
||||||
const given = createTransform();
|
const given = createTransform();
|
||||||
const expected = createTransform();
|
const expected = createTransform();
|
||||||
scaleTransform(expected, scaleX, scaleY);
|
scaleTransform(expected, scaleX, scaleY);
|
||||||
rotateTransform(expected, -frameState.viewState.rotation);
|
rotateTransform(expected, -SAMPLE_FRAMESTATE.viewState.rotation);
|
||||||
translateTransform(
|
translateTransform(
|
||||||
expected,
|
expected,
|
||||||
-frameState.viewState.center[0],
|
-SAMPLE_FRAMESTATE.viewState.center[0],
|
||||||
-frameState.viewState.center[1]
|
-SAMPLE_FRAMESTATE.viewState.center[1]
|
||||||
);
|
);
|
||||||
|
|
||||||
h.makeProjectionTransform(frameState, given);
|
h.makeProjectionTransform(SAMPLE_FRAMESTATE, given);
|
||||||
|
|
||||||
expect(given.map((val) => val.toFixed(15))).to.eql(
|
expect(given.map((val) => val.toFixed(15))).to.eql(
|
||||||
expected.map((val) => val.toFixed(15))
|
expected.map((val) => val.toFixed(15))
|
||||||
@@ -377,7 +385,8 @@ describe('ol/webgl/WebGLHelper', function () {
|
|||||||
void main(void) {
|
void main(void) {
|
||||||
gl_Position = vec4(u_test, attr3, 0.0, 1.0);
|
gl_Position = vec4(u_test, attr3, 0.0, 1.0);
|
||||||
}`
|
}`
|
||||||
)
|
),
|
||||||
|
SAMPLE_FRAMESTATE
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user