思路:引擎作为分包加载 并 自行渲染首屏
支持的引擎版本:2.x
自定义引擎:
由于微信首次创建的是主canvas,后面创建的都是离屏 canvas,所以需要自定义一下引擎,点击编辑器打开文件builtin/adapters/platforms/wechat/wrapper/builtin/Canvas.js:修改下面代码
let first = true
export default function Canvas() {
//const canvas = wx.createCanvas()
const canvas = first ? wx.__first__canvas ? wx.__first__canvas : wx.createCanvas() : wx.createCanvas()
first = false
然后重新构建。
1.引擎分包
修改game.json文件,新增engine文件夹作为分包:
"subpackages": [
{
"name":"engine",
"root":"engine/"
}
]
移动: 除assets、subpackages、game.json、project.config.json四个文件外,其他全部移动到engine文件夹下。
拷贝: 将assets文件夹拷贝到engine,然后删除engine/assets里所有的import、native文件夹和config.json文件,只剩下index.js文件。
引擎分包完成,接下来加载分包和自行渲染首屏。
2.首屏渲染:
根目录新增game.js、first-screen.js、first-screen.png文件
game.js代码:(游戏入口)
// 1.渲染首屏
wx.__first__canvas = wx.createCanvas();
const first_scene = require("./first-screen.js");
first_scene.drawImg("first-screen.png");
let inter = setInterval(() => {
requestAnimationFrame(()=>{
first_scene.drawImg("first-screen.png");
})
}, 1);
// 2.加载引擎分包
function loadEngine(sub_name) {
if (wx.loadSubpackage) {
_load(sub_name).then((result) => {
if (!result) {
loadEngine(sub_name);
}
});
} else {
require(sub_name + '/game.js');
}
}
function _load(sub_name) {
return new Promise((resolve, reject) => {
const t = new Date().getTime();
const loadTask = wx.loadSubpackage({
name: sub_name,
success: function (res) {
clearInterval(inter)
console.log("引擎包加载完毕", new Date().getTime() - t, "ms");
resolve(true);
},
fail: function (res) {
console.log("引擎包加载失败", new Date().getTime() - t, "ms");
resolve(false);
}
});
loadTask.onProgressUpdate(res => {
});
});
}
loadEngine("engine");
first-screen.js代码:(一个简单的 WebGL 渲染图片的代码)
// Vertex shader program
var VSHADER_SOURCE =
'attribute vec4 a_Position;\n' +
'attribute vec2 a_TexCoord;\n' +
'varying vec2 v_TexCoord;\n' +
'void main() {\n' +
' gl_Position = a_Position;\n' +
' v_TexCoord = a_TexCoord;\n' +
'}\n';
// Fragment shader program
var FSHADER_SOURCE =
'#ifdef GL_ES\n' +
'precision mediump float;\n' +
'#endif\n' +
'uniform sampler2D u_Sampler;\n' +
'varying vec2 v_TexCoord;\n' +
'void main() {\n' +
' gl_FragColor = texture2D(u_Sampler, v_TexCoord);\n' +
'}\n';
/**
* Create a program object and make current
* @param gl GL context
* @param vshader a vertex shader program (string)
* @param fshader a fragment shader program (string)
* @return true, if the program object was created and successfully made current
*/
function initShaders(gl, vshader, fshader) {
var program = createProgram(gl, vshader, fshader);
if (!program) {
console.log('Failed to create program');
return false;
}
gl.useProgram(program);
gl.program = program;
return true;
}
/**
* Create the linked program object
* @param gl GL context
* @param vshader a vertex shader program (string)
* @param fshader a fragment shader program (string)
* @return created program object, or null if the creation has failed
*/
function createProgram(gl, vshader, fshader) {
// Create shader object
var vertexShader = loadShader(gl, gl.VERTEX_SHADER, vshader);
var fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fshader);
if (!vertexShader || !fragmentShader) {
return null;
}
// Create a program object
var program = gl.createProgram();
if (!program) {
return null;
}
// Attach the shader objects
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
// Link the program object
gl.linkProgram(program);
// Check the result of linking
var linked = gl.getProgramParameter(program, gl.LINK_STATUS);
if (!linked) {
var error = gl.getProgramInfoLog(program);
console.log('Failed to link program: ' + error);
gl.deleteProgram(program);
gl.deleteShader(fragmentShader);
gl.deleteShader(vertexShader);
return null;
}
return program;
}
/**
* Create a shader object
* @param gl GL context
* @param type the type of the shader object to be created
* @param source shader program (string)
* @return created shader object, or null if the creation has failed.
*/
function loadShader(gl, type, source) {
// Create shader object
var shader = gl.createShader(type);
if (shader == null) {
console.log('unable to create shader');
return null;
}
// Set the shader program
gl.shaderSource(shader, source);
// Compile the shader
gl.compileShader(shader);
// Check the result of compilation
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;
}
function initVertexBuffers(gl, vertices) {
var verticesTexCoords = vertices || new Float32Array([
// Vertex coordinates, texture coordinate
-1, 1, 0.0, 1.0,
-1, -1, 0.0, 0.0,
1, 1, 1.0, 1.0,
1, -1, 1.0, 0.0,
]);
var n = 4; // The number of vertices
// Create the buffer object
var vertexTexCoordBuffer = gl.createBuffer();
if (!vertexTexCoordBuffer) {
console.log('Failed to create the buffer object');
return -1;
}
// Bind the buffer object to target
gl.bindBuffer(gl.ARRAY_BUFFER, vertexTexCoordBuffer);
gl.bufferData(gl.ARRAY_BUFFER, verticesTexCoords, gl.STATIC_DRAW);
var FSIZE = verticesTexCoords.BYTES_PER_ELEMENT;
//Get the storage location of a_Position, assign and enable buffer
var a_Position = gl.getAttribLocation(gl.program, 'a_Position');
if (a_Position < 0) {
console.log('Failed to get the storage location of a_Position');
return -1;
}
gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, FSIZE * 4, 0);
gl.enableVertexAttribArray(a_Position); // Enable the assignment of the buffer object
// Get the storage location of a_TexCoord
var a_TexCoord = gl.getAttribLocation(gl.program, 'a_TexCoord');
if (a_TexCoord < 0) {
console.log('Failed to get the storage location of a_TexCoord');
return -1;
}
// Assign the buffer object to a_TexCoord variable
gl.vertexAttribPointer(a_TexCoord, 2, gl.FLOAT, false, FSIZE * 4, FSIZE * 2);
gl.enableVertexAttribArray(a_TexCoord); // Enable the assignment of the buffer object
return n;
}
function initTextures(gl, n, imgPath) {
var texture = gl.createTexture(); // Create a texture object
if (!texture) {
console.log('Failed to create the texture object');
return false;
}
// Get the storage location of u_Sampler
var u_Sampler = gl.getUniformLocation(gl.program, 'u_Sampler');
if (!u_Sampler) {
console.log('Failed to get the storage location of u_Sampler');
return false;
}
var image = wx.createImage(); // Create the image object
if (!image) {
console.log('Failed to create the image object');
return false;
}
// Register the event handler to be called on loading an image
image.onload = function () { loadTexture(gl, n, texture, u_Sampler, image); };
// Tell the browser to load an image
image.src = imgPath;
return true;
}
function loadTexture(gl, n, texture, u_Sampler, image) {
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1); // Flip the image's y axis
// Enable texture unit0
gl.activeTexture(gl.TEXTURE0);
// Bind the texture object to the target
gl.bindTexture(gl.TEXTURE_2D, texture);
// Set the texture parameters
// gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
// Set the texture image
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, image);
// Set the texture unit 0 to the sampler
gl.uniform1i(u_Sampler, 0);
gl.clear(gl.COLOR_BUFFER_BIT); // Clear <canvas>
gl.drawArrays(gl.TRIANGLE_STRIP, 0, n); // Draw the rectangle
}
function drawImg(imgPath) {
const vertices = new Float32Array([
-1, 1, 0.0, 1.0,
-1, -1, 0.0, 0.0,
1, 1, 1.0, 1.0,
1, -1, 1.0, 0.0,
]);
// Retrieve <canvas> element
// var canvas = document.getElementById('webgl');
// Get the rendering context for WebGL
// var gl = getWebGLContext(canvas);
const gl = wx.__first__canvas.getContext("webgl");
if (!gl) {
console.log('Failed to get the rendering context for WebGL');
return;
}
// Initialize shaders
if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
console.log('Failed to intialize shaders.');
return;
}
// Set the vertex information
var n = initVertexBuffers(gl, vertices);
if (n < 0) {
console.log('Failed to set the vertex information');
return;
}
// Specify the color for clearing <canvas>
gl.clearColor(1.0, 1.0, 1.0, 1.0);
// Set texture
if (!initTextures(gl, n, imgPath)) {
console.log('Failed to intialize the texture.');
return;
}
}
exports.drawImg = drawImg;
first-screen.png图片(随便找一张启动图)
参考图