webgl readpixels is always returning 0,0,0,0

Google网上论坛

You can grab data from a canvas by simply doing:

var pixels = new Uint8Array(gl.drawingBufferWidth * gl.drawingBufferHeight * 4);

gl.readPixels(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight, gl.RGBA, gl.UNSIGNED_BYTE, pixels);

console.log(pixels); 

If the canvas has been created with preserveDrawingBuffer: true, you'll get values back.

The problem here -I think- is that you're trying to read from a canvas that is not yours, and it hasn't been created with that flag.

It doesn't matter if you try to getContext again on that canvas, you can't change it.

So a solution would be to make getContext to always set preserveDrawing to true.

Try this (even though I don't endorse doing this, ever! just for education purposes:)

<!doctype html>

<html>

<head>

<meta charset="utf-8">

<meta http-equiv="X-UA-Compatible" content="IE=edge">

<meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">

<title>Map</title>

<link rel="stylesheet" href="http://cache.amap.com/lbs/static/main1119.css"/>

<script>

var getContext = HTMLCanvasElement.prototype.getContext;

HTMLCanvasElement.prototype.getContext = function(){

if( arguments[ 1 ] ) arguments[ 1 ].preserveDrawingBuffer = true;

var context = getContext.apply( this, arguments );

return context;

}

</script>

<script src="http://cache.amap.com/lbs/static/es5.min.js"></script>

<script src="http://webapi.amap.com/maps?v=1.3&key=123"></script>

<script type="text/javascript" src="http://cache.amap.com/lbs/static/addToolbar.js"></script>

</head>

<body>

<div id="container"></div>

<script>

var map = new AMap.Map('container', {

resizeEnable: true,

zoom:11,

center: [116.397421, 39.80923]

});

map.on('moveend', function() {

var canvas = document.getElementsByClassName("amap-layer")[0];

var gl = canvas.getContext("webgl");

var pixels = new Uint8Array(gl.drawingBufferWidth * gl.drawingBufferHeight * 4);

gl.readPixels(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight, gl.RGBA, gl.UNSIGNED_BYTE, pixels);

console.log(pixels);

});

</script>

</body>

This basically forces all getContext to use preserveDrawingBuffer to true. Since it runs before the AMap code, the library will create its WebGL rendering contexts with that flag set, and you'll be able to read it at a later point.

StackOverflow user

You don't need preserveDrawingBuffer: true to call readPixels. What you need is to call readPixels before exiting the current event.

The spec says if you call any function that affects the canvas (gl.clear, gl.drawXXX) then the browser will clear the canvas after the next composite operation. When that composite operation happens is up to the browser. It could be after it processes several mouse events or keyboard events or click events. The order is undefined. What is defined is that it won't do it until the current event exits so

render
read

 

Show code snippet

works where as

render
setTimeout(read, 1000);  // some other event

does not work

Show code snippet

Note that since it's the composite operation (the browser actually drawing the canvas on the page with the rest of the HTML) that triggers the clear, if the canvas is not on the page then it's not composited and won't be cleared.

In other words the case that didn't work above does work here

Show code snippet

Now, if you want to call readPixels in some other event, like when the user clicks an element, then you have at least 2 options

  1. Set preserveDrawingBuffer: true

  2. Render again in your event

    screenshotElement.addEventListener('click', event => {
      render();  
      gl.readPixels(...);
    });
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值