好像不是没有webgl,有些是有,但是用不了,不知道为什么?,特别奇怪
webgl崩溃也会导致游戏无法使用webgl的
额,不是吧,webgl怎么用toDataURL。有相关资料么
我指的是类似烘培的功能,不是截全屏。
有些是引擎选的自动模式,自动模式下切换到 Canvas 了,其实强制用 WebGL 也问题不大
toDataURL 不就是截全屏幕吗?不然还有哪个 API?
支持今早抛弃过时的技术
1、 WebGL可以使用toDataURL,不过直接使用截出来的是黑屏,要在获取webgl的时候加preserveDrawingBuffer参数(对性能有影响)或者在cc.Director.EVENT_AFTER_DRAW事件中截图。相关链接:
2、 如果要截局部的图,目前可以使用cc.RenderTexture去截某个node及其所有子节点(有点不好用,需要一些hack代码去调整位置,据说2.0会有新的截图组件),然后:
// 以下width, height变量为局部截图的宽高
let rt = cc.RenderTexture.create(width, height, cc.Texture2D.PIXEL_FORMAT_RGBA8888, gl.DEPTH_STENCIL);
...... // 用rt截图
let texture = rt._texture._glID;
let frameBuffer = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
// 每个像素点需要rgba四个值
let data = new Uint8Array(width * height * 4);
gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, data);
// RenderTexture截出来的图是反向的,下面这段代码通过把data数组反向,来把图像反过来。
let halfHeight: number = Math.floor(height / 2);
let bytesPerRow: number = width * 4;
let temp = new Uint8Array(width * 4);
for (let y = 0; y < halfHeight; ++y) {
let topOffset: number = Math.round(y * bytesPerRow);
let bottomOffset = Math.round((height - y - 1) * bytesPerRow);
temp.set(data.subarray(topOffset, topOffset + bytesPerRow));
data.copyWithin(topOffset, bottomOffset, bottomOffset + bytesPerRow);
data.set(temp, bottomOffset);
}
// RenderTexture截出来的图是反向的,上面这段代码通过把data数组反向,来把图像反过来。
gl.deleteFramebuffer(frameBuffer);
// 创建一个2D Canvas来保存截图结果
let canvas = document.createElement('canvas');
canvas.width = width;
canvas.height = height;
let context = canvas.getContext('2d');
let imageData = context.createImageData(width, height);
imageData.data.set(data);
context.putImageData(imageData, 0, 0);
// str即为截图结果
let str = canvas.toDataURL();
能提供一下相关代码吗… 谢谢了
我就是截图的时候截的是个黑的 所以用了canvas
这段代码挂在Canvas上,点击Canvas就能看到效果。
this.node.on(cc.Node.EventType.TOUCH_END, () => {
cc.director.once(cc.Director.EVENT_AFTER_DRAW, () => {
let canvas = document.getElementById('GameCanvas') as HTMLCanvasElement;
let str = canvas.toDataURL();
let img = new Image();
img.onload = () => {
let texture = new cc.Texture2D();
texture.initWithElement(img);
texture.handleLoadedTexture();
let spriteFrame = new cc.SpriteFrame(texture);
let spriteNode = new cc.Node();
let sprite = spriteNode.addComponent(cc.Sprite);
sprite.spriteFrame = spriteFrame;
this.node.addChild(spriteNode);
spriteNode.scale = 0.4;
};
img.src = str;
});
});
多谢
我觉得可以忽略掉canvas了。就算支持了canvas又能怎么样呢?性能太差了,完全没法满足正常的需求。
支持去掉 Canvas
国产好多浏览器不支持webgl或者支持不太好,他们心里没有点逼数吗
在opp浏览器上 首次进来的时候 用webGL会启动报错 退出页面再重新进来就可以
找到了 ·· 是deleteframebuffer的问题 去掉就可以了
cc.director.once(cc.Director.EVENT_AFTER_DRAW, () => {
var target = tar._sgNode;
//设置节点位置否则会在左下角
tar.opos = tar.getPosition();
tar.setPosition(tar.width/2,tar.height/2);
// 以下width, height变量为局部截图的宽高
var width = tar.width;
var height = tar.height;
// 用rt截图
var rt = cc.RenderTexture.create(width,height,cc.Texture2D.PIXEL_FORMAT_RGBA8888, gl.DEPTH_STENCIL);
rt.begin();
rt.beginWithClear(0,0,0,0)
target.visit();
rt.end();
tar.setPosition(tar.opos);
let texture = rt._texture._glID;
let frameBuffer = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
// 每个像素点需要rgba四个值
let data = new Uint8Array(width * height * 4);
gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, data);
// RenderTexture截出来的图是反向的,下面这段代码通过把data数组反向,来把图像反过来。
let halfHeight = Math.floor(height / 2);
let bytesPerRow = width * 4;
let temp = new Uint8Array(width * 4);
for (let y = 0; y < halfHeight; ++y) {
let topOffset = Math.round(y * bytesPerRow);
let bottomOffset = Math.round((height - y - 1) * bytesPerRow);
temp.set(data.subarray(topOffset, topOffset + bytesPerRow));
data.copyWithin(topOffset, bottomOffset, bottomOffset + bytesPerRow);
data.set(temp, bottomOffset);
}
// RenderTexture截出来的图是反向的,上面这段代码通过把data数组反向,来把图像反过来。
//不知道什么原因这行会导致canvas整体被拉伸 但是删除这句话会导致画面固定 = =
//gl.deleteFramebuffer(frameBuffer);
// 创建一个2D Canvas来保存截图结果
let canvas = document.createElement('canvas');
canvas.width = width;
canvas.height = height;
let context = canvas.getContext('2d');
let imageData = context.createImageData(width, height);
imageData.data.set(data);
context.putImageData(imageData, 0, 0);
// str即为截图结果
var str = canvas.toDataURL('image/png');
});
1.9.3目前webgl可用的针对任意节点的截图方法(未完善)
deleteframebuffer后的canvas绘制有问题 输出查看canvas大小和缩放是正常的
如果有大佬有时间希望看看能给个方法不···
请单独发贴,不要挖坟