Is it possible to access low-level WebGL from openlayers in the same way simple canvas html5 element can be accessed?
var context = event.glContext;
var gl = context.getGL();
I've tried to adapt the low-level clipping example in openlayers to draw a simple triangle such as the one in WebGL Fundamentals tutorial hooking it to the precompose event but without any luck.
Is this the right event to hook to?
The following code has an openstreetmap tile layer as base and static image with reprojection on top following this example.
The idea was to manipulate the top static image as canvas to test low-level WebGL. But the only thing that happens is that the top layer clips the bottom OSM layer no matter what points I pass to the buffer.
I have a very limited understanding of WebGL, can somebody point me in the right direction?
proj4.defs('EPSG:27700', '+proj=tmerc +lat_0=49 +lon_0=-2 +k=0.9996012717 ' +
'+x_0=400000 +y_0=-100000 +ellps=airy ' +
'+towgs84=446.448,-125.157,542.06,0.15,0.247,0.842,-20.489 ' +
'+units=m +no_defs');
var imageExtent = [0, 0, 700000, 1300000];
var img = new ol.layer.Image({
source: new ol.source.ImageStatic({
url: 'https://upload.wikimedia.org/wikipedia/commons/thumb/1/18/' +
'British_National_Grid.svg/2000px-British_National_Grid.svg.png',
crossOrigin: '',
projection: 'EPSG:27700',
imageExtent: imageExtent
})
});
var myosm = new ol.layer.Tile({
source: new ol.source.OSM()
});
var map = new ol.Map({
//layers: [myosm, img],
layers: [myosm, img],
target: 'map',
renderer: /** @type {Array<ol.renderer.Type>} */ (['webgl', 'canvas']),
view: new ol.View({
center: ol.proj.transform(
ol.extent.getCenter(imageExtent), 'EPSG:27700', 'EPSG:3857'),
zoom: 4
})
});
var vertexShaderSource = document.getElementById("2d-vertex-shader").text;
var fragmentShaderSource = document.getElementById("2d-fragment-shader").text;
img.on('precompose', function(e) {
var context = e.glContext;
var gl = context.getGL();
var program = gl.createProgram();
var vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertexShaderSource);
gl.compileShader(vertexShader);
gl.attachShader(program, vertexShader);
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fragmentShaderSource);
gl.compileShader(fragmentShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
var positionLocation = gl.getAttribLocation(program, 'a_position');
var positions = [
0, 0,
0, 0.5,
0.7, 0,
];
var buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
gl.clearColor(0, 0, 0, 0);
gl.clear(gl.COLOR_BUFFER_BIT);
context.useProgram(program);
gl.enableVertexAttribArray(positionLocation);
gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);
gl.drawArrays(gl.TRIANGLES, 0, 24);
});
<link href="https://openlayers.org/en/v4.6.4/css/ol.css" rel="stylesheet"/>
<script src="https://openlayers.org/en/v4.6.4/build/ol.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.4.4/proj4.js"></script>
<div id="map" class="map"></div>
<div id="no-webgl" class="alert alert-danger" style="display: none">
This example requires a browser that supports <a href="http://get.webgl.org/">WebGL</a>.
</div>
<script id="2d-vertex-shader" type="notjs">
// an attribute will receive data from a buffer
attribute vec4 a_position;
// all shaders have a main function
void main() {
// gl_Position is a special variable a vertex shader
// is responsible for setting
gl_Position = a_position;
}
</script>
<script id="2d-fragment-shader" type="notjs">
// fragment shaders don't have a default precision so we need
// to pick one. mediump is a good default
precision mediump float;
void main() {
// gl_FragColor is a special variable a fragment shader
// is responsible for setting
gl_FragColor = vec4(1, 0, 0.5, 1); // return redish-purple
}
</script>