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