收藏
回答

sharedCanvas 在主域上屏Canvas绘制失败

框架类型 问题类型 API/组件名称 终端类型 操作系统 微信版本 基础库版本
小游戏 Bug wxAPI 客户端 6.6.6 1.9.93


这里是主域代码

var initShaders = function (gl, vshader, fshader) {
var program = createProgram(gl, vshader, fshader);
if (!program) {
console.log('无法创建程序对象');
return false;
}

gl.useProgram(program);
gl.program = program;

return true;
};


var createProgram = function (gl, vshader, fshader) {
// 创建着色器对象
   var vertexShader = loadShader(gl, gl.VERTEX_SHADER, vshader);
var fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fshader);
if (!vertexShader || !fragmentShader) {
return null;
}

// 创建程序对象
   var program = gl.createProgram();
if (!program) {
return null;
}

// 为程序对象分配顶点着色器和片元着色器
   gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);

// 连接着色器
   gl.linkProgram(program);

// 检查连接
   var linked = gl.getProgramParameter(program, gl.LINK_STATUS);
if (!linked) {
var error = gl.getProgramInfoLog(program);
console.log('无法连接程序对象: ' + error);
gl.deleteProgram(program);
gl.deleteShader(fragmentShader);
gl.deleteShader(vertexShader);
return null;
}
return program;
};

var loadShader = function (gl, type, source) {
// 创建着色器对象
   var shader = gl.createShader(type);
if (shader == null) {
console.log('无法创建着色器');
return null;
}

// 设置着色器源代码
   gl.shaderSource(shader, source);
// 编译着色器
   gl.compileShader(shader);

// 检查着色器的编译状态
   var compiled = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
if (!compiled) {
var error = gl.getShaderInfoLog(shader);
console.log('Failed to compile shader: ' + error);
gl.deleteShader(shader);
return null;
}

return shader;
};


var VSHADER_SOURCE = `
   attribute vec4 a_Position;
   attribute vec2 a_TexCoord;
   varying vec2 v_TexCoord;

   void main(){
      gl_Position = a_Position;
      v_TexCoord = a_TexCoord;
   }`;

var FSHADER_SOURCE = `
   precision mediump float;
   uniform sampler2D u_Sampler;
   varying vec2 v_TexCoord;

   void main(){
      gl_FragColor = texture2D(u_Sampler,v_TexCoord);
   }`;


var main = function() {

var gl = ctx;

if(!initShaders(gl,VSHADER_SOURCE,FSHADER_SOURCE)){
console.log("初始化着色器失败!");
return;
}

//设置顶点的相关信息
 var n = initVertexBuffers(gl);

if(n < 0){
console.log("无法获取到点的数据");
return;
}

//配置纹理
 if(!initTextures(gl,n)){
console.log("无法配置纹理");
}
};


var initVertexBuffers = function (gl) {

var verticesSizes = new Float32Array([
//四个顶点的位置和纹理数据
   -0.5, 0.5, 0.0, 1.0,
-0.5,-0.5, 0.0, 0.0,
0.5, 0.5, 1.0, 1.0,
0.5,-0.5, 1.0, 0.0
 ]);


var n = 4;

var vertexSizeBuffer = gl.createBuffer();
if(!vertexSizeBuffer){
console.log("无法创建缓冲区");
return -1;
}

gl.bindBuffer(gl.ARRAY_BUFFER,vertexSizeBuffer);
gl.bufferData(gl.ARRAY_BUFFER,verticesSizes,gl.STATIC_DRAW);

var a_Position = gl.getAttribLocation(gl.program,"a_Position");

if(a_Position < 0){
console.log("无法获取到存储位置");
return;
}

//获取数组一个值所占的字节数

 var fsize = verticesSizes.BYTES_PER_ELEMENT;

//将顶点坐标的位置赋值

 gl.vertexAttribPointer(a_Position,2,gl.FLOAT,false,fsize*4,0);
gl.enableVertexAttribArray(a_Position);

//将顶点的纹理坐标分配给a_TexCoord并开启它
 var a_TexCoord = gl.getAttribLocation(gl.program,"a_TexCoord");

if(a_TexCoord < 0){
console.log("无法获取到存储位置");
return;
}

//将纹理坐标赋值

 gl.vertexAttribPointer(a_TexCoord,2,gl.FLOAT,false,fsize*4,fsize*2);
gl.enableVertexAttribArray(a_TexCoord);
return n;
};

var initTextures = function (gl,n) {

var texture = gl.createTexture();//创建纹理对象

 if(!texture){
console.log("无法创建纹理对象");
return;
}

//获取u_Sampler的存储位置

 var u_Sampler = gl.getUniformLocation(gl.program,"u_Sampler");

if(u_Sampler < 0){
console.log("无法获取变量的存储位置");
return;
}

//加载sharedCanvas,显示不出来,打开这里测试加载sharedCanvas
 // var openDataContext = wx.getOpenDataContext();
 // var sharedCanvas = openDataContext.canvas;
 // sharedCanvas.width  = 512;
 // sharedCanvas.height = 512;
 // loadTexture(gl,n,texture,u_Sampler, sharedCanvas);


 //直接加载图片可以显示出来
 var image = new Image();
image.onload = function () {
loadTexture(gl,n,texture,u_Sampler,image);
};

image.src = "https://wgld.org/s/sample_014/texture.png";
return true;
};

var loadTexture = function (gl,n,texture,u_Sampler,image) {

//对纹理图像进行y轴反转

 gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL,1);

//开启0号纹理单元

 gl.activeTexture(gl.TEXTURE0);

//向target绑定纹理对象

 gl.bindTexture(gl.TEXTURE_2D,texture);

//配置纹理参数

 gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.LINEAR);

//配置纹理图像

 gl.texImage2D(gl.TEXTURE_2D,0,gl.RGB,gl.RGB,gl.UNSIGNED_BYTE,image);

//将0号纹理传递给着色器

 gl.uniform1i(u_Sampler,0);

//绘制
 gl.clearColor(0.0,1.0,1.0,1.0);

gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLE_STRIP,0,n);

};
//发送消息通知开放数据域,生成sharedCanvas
var openDataContext = wx.getOpenDataContext();
openDataContext.postMessage({
method:'showGroupRank',
pageIndex: 1
 });

setTimeout(main, 500);



以下是开放数据域代码



console.log("开放数据域逻辑加载成功!");

/**
更新用户托管数据
*/
var updateRank = function(data){
wx.setUserCloudStorage({'key':'rank', 'value':data.rank});
};

/**
显示群排行
*/
var showGroupRank = function(data){
var shareCanvas = wx.getSharedCanvas();
var ctx = shareCanvas.getContext("2d");

ctx.fillStyle="#0000ff";
ctx.fillRect(100,300,150,100);

ctx.font="50px Georgia";
ctx.fillText("shareCanvas绘制测试:" + data.pageIndex, 20,200, 400);

console.log("shareCanvas 显示成功!当前shareCanvas,width:" + shareCanvas.width + ";height:" + shareCanvas.height);
};

/**
显示好友排行
*/
var showFriendRank = function(data){

};

wx.onMessage(function(data) {
console.log("收到主域消息"+JSON.stringify(data));

switch (data.method){
case 'updateRank':{
updateRank(data);
break;
}
case 'showGroupRank':{
showGroupRank(data);
break;
}
case 'showFriendRank':{
showFriendRank(data);
break;
}
}

});


最后一次编辑于  2018-03-29
回答关注问题邀请回答
收藏

7 个回答

  • Special
    Special
    2018-03-29

    https://developers.weixin.qq.com/miniprogram/dev/devtools/minicode.html

    2018-03-29
    有用
    回复
  • Special
    Special
    2018-03-29

    wechatide://minicode/jweLzhmG6MYr


    你看下,我改好了

    2018-03-29
    有用
    回复
  • Special
    Special
    2018-03-28

    代码缺少了 data 变量的定义我没有跑起来。


    感觉是 main() 只执行了一次,但 openDataContext 里的逻辑可能会晚于 main 的执行,导致在 main 执行时候没有获取到 sharedCanvas 的画面,你可以尝试下每帧都调一下 main

    2018-03-28
    有用
    回复
  • 许敬
    许敬
    2018-03-29

    谢谢,就是因为我改了canvas的尺寸才导致的清空

    2018-03-29
    有用
    回复
  • 许敬
    许敬
    2018-03-29

    webGL的绘图方式十分的繁琐,官方能否在保证数据安全的前提下,提供更加简单的从开放数据域输出图形的方法?

    2018-03-29
    有用
    回复
  • 许敬
    许敬
    2018-03-29

    我新建了一个测试项目,主域用Canvas2d,按你们的官方文档写,是可以显示的,说明sharedCanvas上是有东西的,再把主域切换到webGL,就显示不出来了,只能显示一个黑框。我直接加载图片是没问题的。

    2018-03-29
    有用
    回复
  • 许敬
    许敬
    2018-03-29

    我又编辑了一下代码,这代码我测试过的,直接加载图片,是可以显示的,如果加载sharedCanvas就显示不出来了,你可以打开测试sharedCanvas的代码测试一下

    2018-03-29
    有用
    回复
登录 后发表内容