forked from LeenkxTeam/LNXSDK
Deinterleaved Vertex Buffer Update
This commit is contained in:
@ -14,6 +14,7 @@ import iron.math.Vec4;
|
||||
import iron.math.Mat4;
|
||||
import iron.data.SceneFormat;
|
||||
import iron.data.MeshData;
|
||||
import iron.data.ShaderData;
|
||||
|
||||
class Geometry {
|
||||
#if lnx_deinterleaved
|
||||
@ -208,7 +209,7 @@ class Geometry {
|
||||
for (v in 0...vertexBuffers.length)
|
||||
if (vertexBuffers[v].name == e.name) {
|
||||
vbs.push(vertexBuffers[v].buffer);
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
if (e.name == "ipos" && instancedVB != null) {
|
||||
vbs.push(instancedVB);
|
||||
@ -264,7 +265,7 @@ class Geometry {
|
||||
for (i in 0...vaLength)
|
||||
vertexBuffers[i] = {
|
||||
name: vertexArrays[i].attrib,
|
||||
buffer: makeDeinterleavedVB(vertexArrays[i].values, vertexArrays[i].attrib, vertexArrays[i].size)
|
||||
buffer: makeDeinterleavedVB(vertexArrays[i])
|
||||
};
|
||||
#else
|
||||
|
||||
@ -295,14 +296,20 @@ class Geometry {
|
||||
}
|
||||
|
||||
#if lnx_deinterleaved
|
||||
function makeDeinterleavedVB(data: ByteArray, name: String, structLength: Int): VertexBuffer {
|
||||
function makeDeinterleavedVB(va: TVertexArray): VertexBuffer {
|
||||
var struct = new VertexStructure();
|
||||
struct.add(name, structLength == 2 ? VertexData.Short2Norm : VertexData.Short4Norm);
|
||||
struct.add(va.attrib, ShaderContext.parseData(va.data));
|
||||
|
||||
var vertexBuffer = new VertexBuffer(Std.int(data.byteLength / 2 / structLength), struct, usage);
|
||||
var vcount = verticesCount(va);
|
||||
var vertexBuffer = new VertexBuffer(vcount, struct, usage);
|
||||
|
||||
var stride = Std.int(struct.byteSize() / 2);
|
||||
var vertices = vertexBuffer.lock();
|
||||
for (i in 0...Std.int(vertices.byteLength / 2)) vertices.setInt16(i * 2, data.getInt16(i * 2));
|
||||
var di = -1;
|
||||
for (i in 0...vcount) {
|
||||
for (o in 0...va.size) vertices.setInt16(++di * 2, va.values[i * va.size + o]);
|
||||
for (o in va.size...stride) vertices.setInt16(++di * 2, 0);
|
||||
}
|
||||
vertexBuffer.unlock();
|
||||
|
||||
return vertexBuffer;
|
||||
|
||||
@ -73,11 +73,11 @@ class MeshBatch {
|
||||
var scontext = b.shader.getContext(context);
|
||||
if (scontext == null) continue;
|
||||
g.setPipeline(scontext.pipeState);
|
||||
// #if lnx_deinterleaved // TODO
|
||||
// g.setVertexBuffers(b.vertexBuffers);
|
||||
// #else
|
||||
#if lnx_deinterleaved
|
||||
g.setVertexBuffers(b.getVertexBuffers(scontext.raw.vertex_elements));
|
||||
#else
|
||||
g.setVertexBuffer(b.getVertexBuffer(scontext.raw.vertex_elements));
|
||||
// #end
|
||||
#end
|
||||
g.setIndexBuffer(b.indexBuffer);
|
||||
|
||||
Uniforms.setContextConstants(g, scontext, bindParams);
|
||||
@ -127,8 +127,12 @@ class Bucket {
|
||||
|
||||
public var batched = false;
|
||||
public var shader: ShaderData;
|
||||
#if lnx_deinterleaved
|
||||
public var vertexBuffers: Array<InterleavedVertexBuffer> = [];
|
||||
#else
|
||||
var vertexBuffer: VertexBuffer;
|
||||
var vertexBufferMap: Map<String, VertexBuffer> = new Map();
|
||||
#end
|
||||
public var indexBuffer: IndexBuffer;
|
||||
public var meshes: Array<MeshObject> = [];
|
||||
|
||||
@ -138,8 +142,12 @@ class Bucket {
|
||||
|
||||
public function remove() {
|
||||
indexBuffer.delete();
|
||||
#if lnx_deinterleaved
|
||||
for (buf in vertexBuffers) buf.buffer.delete();
|
||||
#else
|
||||
// this.vertexBuffer is in the map, so it's also deleted here
|
||||
for (buf in vertexBufferMap) buf.delete();
|
||||
#end
|
||||
meshes = [];
|
||||
}
|
||||
|
||||
@ -151,6 +159,20 @@ class Bucket {
|
||||
meshes.remove(m);
|
||||
}
|
||||
|
||||
#if lnx_deinterleaved
|
||||
public function getVertexBuffers(elems: Array<TVertexElement>): Array<VertexBuffer> {
|
||||
var vbs: Array<VertexBuffer> = [];
|
||||
for (e in elems) {
|
||||
for (v in vertexBuffers) {
|
||||
if (v.name == e.name) {
|
||||
vbs.push(v.buffer);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return vbs;
|
||||
}
|
||||
#else
|
||||
function copyAttribute(attribSize: Int, count: Int, to: ByteArray, toStride: Int, toOffset: Int, from: ByteArray, fromStride: Int, fromOffset: Int) {
|
||||
for (i in 0...count) {
|
||||
for (j in 0...attribSize) {
|
||||
@ -196,6 +218,7 @@ class Bucket {
|
||||
}
|
||||
return vb;
|
||||
}
|
||||
#end
|
||||
|
||||
function vertexCount(g: Geometry, hasUVs: Bool): Int {
|
||||
var vcount = g.getVerticesLength();
|
||||
@ -240,6 +263,50 @@ class Bucket {
|
||||
|
||||
if (mdatas.length == 0) return;
|
||||
|
||||
#if lnx_deinterleaved
|
||||
var attrNames: Array<String> = [];
|
||||
var attrReps = new Map<String, TVertexArray>();
|
||||
for (md in mdatas) {
|
||||
for (va in md.geom.vertexArrays) {
|
||||
if (attrReps.get(va.attrib) == null) {
|
||||
attrReps.set(va.attrib, va);
|
||||
attrNames.push(va.attrib);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (name in attrNames) {
|
||||
var rep = attrReps.get(name);
|
||||
var attrStruct = new VertexStructure();
|
||||
attrStruct.add(name, ShaderContext.parseData(rep.data));
|
||||
var stride = Std.int(attrStruct.byteSize() / 2);
|
||||
var vtotal = 0;
|
||||
for (md in mdatas) vtotal += md.geom.getVerticesCount();
|
||||
var vb = new VertexBuffer(vtotal, attrStruct, Usage.StaticUsage);
|
||||
var vertices = vb.lock();
|
||||
var ai = -1;
|
||||
for (md in mdatas) {
|
||||
var va: TVertexArray = null;
|
||||
for (v in md.geom.vertexArrays) {
|
||||
if (v.attrib == name) {
|
||||
va = v;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (va != null && va.values != null) {
|
||||
var nverts = md.geom.getVerticesCount();
|
||||
for (i in 0...nverts) {
|
||||
for (o in 0...va.size) vertices.setInt16(++ai * 2, va.values[i * va.size + o]);
|
||||
for (o in va.size...stride) vertices.setInt16(++ai * 2, 0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (i in 0...md.geom.getVerticesCount() * stride) vertices.setInt16(++ai * 2, 0);
|
||||
}
|
||||
}
|
||||
vb.unlock();
|
||||
vertexBuffers.push({name: name, buffer: vb});
|
||||
}
|
||||
#else
|
||||
// Pick UVs if present
|
||||
var vs = mdatas[0].geom.struct;
|
||||
for (md in mdatas) if (md.geom.struct.size() > vs.size()) vs = md.geom.struct;
|
||||
|
||||
@ -102,8 +102,9 @@ class ShaderContext {
|
||||
constants = [];
|
||||
textureUnits = [];
|
||||
|
||||
var instStruct: VertexStructure = null;
|
||||
if (instancingType > 0) { // Instancing
|
||||
var instStruct = new VertexStructure();
|
||||
instStruct = new VertexStructure();
|
||||
instStruct.add("ipos", VertexData.Float3);
|
||||
if (instancingType == 2 || instancingType == 4) {
|
||||
instStruct.add("irot", VertexData.Float3);
|
||||
@ -117,11 +118,19 @@ class ShaderContext {
|
||||
this.instanceStride = Std.int(instStruct.byteSize() / 4);
|
||||
|
||||
instStruct.instanced = true;
|
||||
pipeState.inputLayout = [structure, instStruct];
|
||||
}
|
||||
else { // Regular
|
||||
pipeState.inputLayout = [structure];
|
||||
#if lnx_deinterleaved
|
||||
var layouts: Array<VertexStructure> = [];
|
||||
for (e in structure.elements) {
|
||||
var s = new VertexStructure();
|
||||
s.add(e.name, e.data);
|
||||
layouts.push(s);
|
||||
}
|
||||
#else
|
||||
var layouts = [structure];
|
||||
#end
|
||||
if (instStruct != null) layouts.push(instStruct);
|
||||
pipeState.inputLayout = layouts;
|
||||
|
||||
// Depth
|
||||
pipeState.depthWrite = raw.depth_write;
|
||||
|
||||
Reference in New Issue
Block a user