Skip to content

Commit

Permalink
fixed load mesh (cocos#5084)
Browse files Browse the repository at this point in the history
* fixed load mesh
* refine VertexBuffer and IndexBuffer
  • Loading branch information
2youyou2 authored Aug 6, 2019
1 parent 5e63d7b commit bc3b257
Show file tree
Hide file tree
Showing 6 changed files with 130 additions and 87 deletions.
7 changes: 6 additions & 1 deletion cocos2d/core/3d/skeleton/CCSkinnedMeshRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,12 @@ let SkinnedMeshRenderer = cc.Class({
let texture = this._jointsTexture || new cc.Texture2D();
texture.initWithData(this._jointsData, pixelFormat, width, height);
this._jointsTexture = texture;
this._jointsTextureOptions = {format: cc.Texture2D.PixelFormat.RGBA32F, width: texture.width, height: texture.height, images:[]}
this._jointsTextureOptions = {
format: pixelFormat,
width: texture.width,
height: texture.height,
images:[]
};

customProperties.setProperty('cc_jointsTexture', texture.getImpl(), enums.PARAM_TEXTURE_2D);
customProperties.setProperty('cc_jointsTextureSize', new Float32Array([width, height]), enums.PARAM_FLOAT2);
Expand Down
54 changes: 30 additions & 24 deletions cocos2d/core/mesh/CCMesh.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,13 +117,14 @@ let Mesh = cc.Class({

// ib
let ibrange = primitive.data;
let ibData = new Uint16Array(this._buffer, ibrange.offset, ibrange.length / 2);
let ibData = new Uint8Array(this._buffer, ibrange.offset, ibrange.length);

// vb
let vertexBundle = this._vertexBundles[primitive.vertexBundleIndices[0]];
let vbRange = vertexBundle.data;
let gfxVFmt = new gfx.VertexFormat(vertexBundle.formats);
let vbData = new Float32Array(this._buffer, vbRange.offset, vbRange.length / 4);
// Mesh binary may have several data format, must use Uint8Array to store data.
let vbData = new Uint8Array(this._buffer, vbRange.offset, vbRange.length);

let canBatch = this._canVertexFormatBatch(gfxVFmt);

Expand All @@ -142,16 +143,14 @@ let Mesh = cc.Class({
renderer.device,
gfxVFmt,
gfx.USAGE_STATIC,
vbData,
vertexBundle.verticesCount
vbData
);

let ibBuffer = new gfx.IndexBuffer(
renderer.device,
primitive.indexUnit,
gfx.USAGE_STATIC,
ibData,
ibData.length
ibData
);

// create sub meshes
Expand Down Expand Up @@ -181,7 +180,7 @@ let Mesh = cc.Class({
init (vertexFormat, vertexCount, dynamic) {
this.clear();

let data = new Float32Array(vertexFormat._bytes * vertexCount / 4);
let data = new Uint8Array(vertexFormat._bytes * vertexCount);
let meshData = new MeshData();
meshData.vData = data;
meshData.vfm = vertexFormat;
Expand All @@ -194,7 +193,6 @@ let Mesh = cc.Class({
vertexFormat,
dynamic ? gfx.USAGE_DYNAMIC : gfx.USAGE_STATIC,
data,
vertexCount
);

meshData.vb = vb;
Expand Down Expand Up @@ -227,13 +225,17 @@ let Mesh = cc.Class({
let elNum = el.num;
let data;
let bytes = 4;
if (name === gfx.ATTR_COLOR && !isFlatMode) {
data = subData.uintVData;
if (!data) {
data = subData.uintVData = new Uint32Array(subData.vData.buffer, 0, subData.vData.length);
if (name === gfx.ATTR_COLOR) {
if (!isFlatMode) {
data = subData.getVData(Uint32Array);
}
} else {
data = subData.vData;
else {
data = subData.getVData();
bytes = 1;
}
}
else {
data = subData.getVData(Float32Array);
}

let stride = el.stride / bytes;
Expand Down Expand Up @@ -277,34 +279,42 @@ let Mesh = cc.Class({
* !#zh
* 设置子网格索引。
* @method setIndices
* @param {[Number]|Uint16Array} indices - the sub mesh indices.
* @param {[Number]|Uint16Array|Uint8Array} indices - the sub mesh indices.
* @param {Number} [index] - sub mesh index.
* @param {Boolean} [dynamic] - whether or not to use dynamic buffer.
*/
setIndices (indices, index, dynamic) {
index = index || 0;

let data = new Uint16Array(indices);
let iData = indices;
if (indices instanceof Uint16Array) {
iData = new Uint8Array(indices.buffer, indices.byteOffset, indices.byteLength);
}
else if (Array.isArray(indices)) {
iData = new Uint16Array(indices);
iData = new Uint8Array(iData.buffer, iData.byteOffset, iData.byteLength);
}

let usage = dynamic ? gfx.USAGE_DYNAMIC : gfx.USAGE_STATIC;

let subData = this._subDatas[index];
if (!subData.ib) {
subData.iData = data;
subData.iData = iData;
if (!(CC_JSB && CC_NATIVERENDERER)) {
let buffer = new gfx.IndexBuffer(
renderer.device,
gfx.INDEX_FMT_UINT16,
usage,
data,
data.length
iData,
iData.byteLength / gfx.IndexBuffer.BYTES_PER_INDEX[gfx.INDEX_FMT_UINT16]
);

subData.ib = buffer;
this._subMeshes[index] = new InputAssembler(subData.vb, buffer);
}
}
else {
subData.iData = data;
subData.iData = iData;
subData.iDirty = true;
}
},
Expand Down Expand Up @@ -376,16 +386,12 @@ let Mesh = cc.Class({

if (subData.vDirty) {
let buffer = subData.vb, data = subData.vData;
buffer._numVertices = data.byteLength / buffer._format._bytes;
buffer._bytes = data.byteLength;
buffer.update(0, data);
subData.vDirty = false;
}

if (subData.iDirty) {
let buffer = subData.ib, data = subData.iData;
buffer._numIndices = data.length;
buffer._bytes = data.byteLength;
buffer.update(0, data);
subData.iDirty = false;
}
Expand Down
34 changes: 31 additions & 3 deletions cocos2d/core/mesh/mesh-data.js
Original file line number Diff line number Diff line change
Expand Up @@ -126,14 +126,42 @@ export let Primitive = cc.Class({
});

export function MeshData () {
this.vData = null;
this.uintVData = null;
this.iData = null;
this.vData = null; // Uint8Array;
this.float32VData = null;
this.uint32VData = null;
this.iData = null; // Uint8Array;
this.uint16IData = null;
this.vfm = null;
this.offset = 0;

this.vb = null;
this.ib = null;
this.vDirty = false;
this.iDirty = false;
}

MeshData.prototype.getVData = function (format) {
if (format === Float32Array) {
if (!this.float32VData) {
this.float32VData = new Float32Array(this.vData.buffer, this.vData.byteOffset, this.vData.byteLength / 4);
}
return this.float32VData;
}
else if (format === Uint32Array) {
if (!this.uint32VData) {
this.uint32VData = new Uint32Array(this.vData.buffer, this.vData.byteOffset, this.vData.byteLength / 4);
}
return this.uint32VData;
}
return this.vData;
}

MeshData.prototype.getIData = function (format) {
if (format === Uint16Array) {
if (!this.uint16IData) {
this.uint16IData = new Uint16Array(this.vData.buffer, this.vData.byteOffset, this.vData.byteLength / 4);
}
return this.uint16IData;
}
return this.iData;
}
6 changes: 0 additions & 6 deletions cocos2d/core/renderer/webgl/mesh-buffer.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,6 @@ let MeshBuffer = cc.Class({
0
);
this._vbArr[offset] = this._vb;
this._vb._bytes = this._vData.byteLength;

this._ib = new gfx.IndexBuffer(
this._batcher._device,
Expand All @@ -129,7 +128,6 @@ let MeshBuffer = cc.Class({
0
);
this._ibArr[offset] = this._ib;
this._ib._bytes = this._iData.byteLength;
}
},

Expand Down Expand Up @@ -209,8 +207,6 @@ let MeshBuffer = cc.Class({
newData[i] = oldVData[i];
}
}

this._vb._bytes = this._vData.byteLength;
},

_reallocIData (copyOldData) {
Expand All @@ -224,8 +220,6 @@ let MeshBuffer = cc.Class({
iData[i] = oldIData[i];
}
}

this._ib._bytes = this._iData.byteLength;
},

reset () {
Expand Down
67 changes: 36 additions & 31 deletions cocos2d/renderer/gfx/index-buffer.js
Original file line number Diff line number Diff line change
@@ -1,30 +1,28 @@
import { enums } from './enums';

const BYTES_PER_INDEX = {
[enums.INDEX_FMT_UINT8]: 1,
[enums.INDEX_FMT_UINT16]: 2,
[enums.INDEX_FMT_UINT32]: 4,
}

class IndexBuffer {
/**
* @constructor
* @param {Device} device
* @param {INDEX_FMT_*} format
* @param {USAGE_*} usage
* @param {ArrayBuffer | Uint8Array} data
* @param {Number} numIndices
*/
constructor(device, format, usage, data, numIndices) {
constructor(device, format, usage, data) {
this._device = device;
this._format = format;
this._usage = usage;
this._numIndices = numIndices;
this._bytesPerIndex = 0;

// calculate bytes
if (format === enums.INDEX_FMT_UINT8) {
this._bytesPerIndex = 1;
} else if (format === enums.INDEX_FMT_UINT16) {
this._bytesPerIndex = 2;
} else if (format === enums.INDEX_FMT_UINT32) {
this._bytesPerIndex = 4;
}
this._bytes = this._bytesPerIndex * numIndices;
this._bytesPerIndex = BYTES_PER_INDEX[format];
this._bytes = data.byteLength;
this._numIndices = this._bytes / this._bytesPerIndex;

this._needExpandDataStore = true;

// update
this._glID = device._gl.createBuffer();
Expand Down Expand Up @@ -52,37 +50,42 @@ class IndexBuffer {

/**
* @method update
* @param {Number} offset
* @param {Number} byteOffset
* @param {ArrayBuffer} data
*/
update(offset, data) {
update(byteOffset, data) {
if (this._glID === -1) {
console.error('The buffer is destroyed');
return;
}

if (data && data.byteLength + offset > this._bytes) {
console.error('Failed to update data, bytes exceed.');
return;
if (data.byteLength === 0) return;

// Need to create new buffer object when bytes exceed
if (byteOffset + data.byteLength > this._bytes) {
if (byteOffset) {
// Lost data between [0, byteOffset] which is need for new buffer
console.error('Failed to update data, bytes exceed.');
return;
}
else {
this._needExpandDataStore = true;
this._bytes = byteOffset + data.byteLength;
this._numIndices = this._bytes / this._bytesPerIndex;
}
}

/** @type{WebGLRenderingContext} */
let gl = this._device._gl;
let glUsage = this._usage;

gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._glID);
if (!data) {
if (this._bytes) {
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this._bytes, glUsage);
} else {
console.warn('bufferData should not submit 0 bytes data');
}
} else {
if (offset) {
gl.bufferSubData(gl.ELEMENT_ARRAY_BUFFER, offset, data);
} else {
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, data, glUsage);
}
if (this._needExpandDataStore) {
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, data, glUsage);
this._needExpandDataStore = false;
}
else {
gl.bufferSubData(gl.ELEMENT_ARRAY_BUFFER, byteOffset, data);
}
this._device._restoreIndexBuffer();
}
Expand All @@ -96,4 +99,6 @@ class IndexBuffer {
}
}

IndexBuffer.BYTES_PER_INDEX = BYTES_PER_INDEX;

export default IndexBuffer;
Loading

0 comments on commit bc3b257

Please sign in to comment.