Restore old grease pencil code

This commit is contained in:
luboslenco 2019-10-14 21:21:11 +02:00
parent c6d74fc4ea
commit c56fb4bbf1
6 changed files with 376 additions and 5 deletions

View File

@ -0,0 +1,9 @@
#version 450
in vec4 color;
out vec4 fragColor;
void main() {
fragColor = color;
}

View File

@ -0,0 +1,25 @@
{
"contexts": [
{
"name": "grease_pencil",
"depth_write": false,
"compare_mode": "always",
"cull_mode": "none",
"blend_source": "source_alpha",
"blend_destination": "inverse_source_alpha",
"blend_operation": "add",
"alpha_blend_source": "source_alpha",
"alpha_blend_destination": "inverse_source_alpha",
"alpha_blend_operation": "add",
"links": [
{
"name": "VP",
"link": "_viewProjectionMatrix"
}
],
"texture_params": [],
"vertex_shader": "grease_pencil.vert.glsl",
"fragment_shader": "grease_pencil.frag.glsl"
}
]
}

View File

@ -0,0 +1,13 @@
#version 450
in vec3 pos;
in vec4 col;
out vec4 color;
uniform mat4 VP;
void main() {
color = col;
gl_Position = VP * vec4(pos.xyz, 1.0);
}

View File

@ -0,0 +1,178 @@
package armory.data;
import kha.graphics4.VertexBuffer;
import kha.graphics4.IndexBuffer;
import kha.graphics4.Usage;
import kha.graphics4.VertexStructure;
import kha.graphics4.VertexData;
import kha.graphics4.PipelineState;
import kha.graphics4.CompareMode;
import kha.graphics4.CullMode;
import kha.graphics4.ConstantLocation;
import iron.math.Vec4;
import iron.object.Transform;
import iron.data.SceneFormat;
import iron.data.ShaderData;
import iron.data.ShaderData.ShaderContext;
class GreasePencilData extends Data {
public var name:String;
public var raw:TGreasePencilData;
public var layers:Array<GreasePencilLayer>;
public static var shaderData:ShaderData = null;
public static var structure:VertexStructure = null;
public static var usage:Usage;
public static var frameEnd = 0;
static var first = true;
public function new(raw:TGreasePencilData, done:GreasePencilData->Void) {
super();
this.raw = raw;
this.name = raw.name;
if (structure == null) {
structure = new VertexStructure();
structure.add("pos", VertexData.Float3);
structure.add("col", VertexData.Float4);
usage = Usage.StaticUsage;
}
if (first) {
first = false;
var shaderName:Array<String> = raw.shader.split("/");
Data.getShader(shaderName[0], shaderName[1], null, function(b:ShaderData) {
shaderData = b;
makeLayers(done);
});
}
else makeLayers(done);
}
function makeLayers(done:GreasePencilData->Void) {
layers = [];
for (l in raw.layers) {
layers.push(new GreasePencilLayer(l));
}
done(this);
}
public static function parse(name:String, id:String, done:GreasePencilData->Void) {
Data.getSceneRaw(name, function(format:TSceneFormat) {
var raw:TGreasePencilData = Data.getGreasePencilRawByName(format.grease_pencil_datas, id);
if (raw == null) {
trace('Grease pencil data "$id" not found!');
done(null);
}
new GreasePencilData(raw, done);
});
}
public static function getContext(name:String):ShaderContext {
return shaderData.getContext(name);
}
}
class GreasePencilLayer {
public var name:String;
public var frames:Array<GreasePencilFrame>;
public var currentFrame = 0;
public function new(l:TGreasePencilLayer) {
name = l.name;
frames = [];
for (f in l.frames) {
frames.push(new GreasePencilFrame(f));
}
}
}
class GreasePencilFrame {
public var vertexBuffer:VertexBuffer;
public var vertexStrokeBuffer:VertexBuffer;
public var indexBuffer:IndexBuffer;
public var raw:TGreasePencilFrame;
public var numVertices:Int;
public function new(f:TGreasePencilFrame) {
raw = f;
var va = f.vertex_array.values;
var cola = f.col_array.values;
var colfilla = f.colfill_array.values;
var indices = f.index_array.values;
numVertices = Std.int(va.length / 3);
// Fill
vertexBuffer = new VertexBuffer(numVertices, GreasePencilData.structure, GreasePencilData.usage);
var vertices = vertexBuffer.lock();
var di = -1;
for (i in 0...numVertices) {
vertices.set(++di, va[i * 3]); // Positions
vertices.set(++di, va[i * 3 + 1]);
vertices.set(++di, va[i * 3 + 2]);
vertices.set(++di, colfilla[i * 4]); // Fill color
vertices.set(++di, colfilla[i * 4 + 1]);
vertices.set(++di, colfilla[i * 4 + 2]);
vertices.set(++di, colfilla[i * 4 + 3]);
}
vertexBuffer.unlock();
indexBuffer = new IndexBuffer(indices.length, GreasePencilData.usage);
var indicesA = indexBuffer.lock();
for (i in 0...indicesA.length) indicesA[i] = indices[i];
indexBuffer.unlock();
// Stroke
vertexStrokeBuffer = new VertexBuffer(numVertices, GreasePencilData.structure, GreasePencilData.usage);
vertices = vertexStrokeBuffer.lock();
di = -1;
for (i in 0...numVertices) {
vertices.set(++di, va[i * 3]); // Positions
vertices.set(++di, va[i * 3 + 1]);
vertices.set(++di, va[i * 3 + 2]);
vertices.set(++di, cola[i * 4]); // Stroke color
vertices.set(++di, cola[i * 4 + 1]);
vertices.set(++di, cola[i * 4 + 2]);
vertices.set(++di, cola[i * 4 + 3]);
}
vertexStrokeBuffer.unlock();
// Store max frame number of all layers
if (GreasePencilData.frameEnd < raw.frame_number) {
GreasePencilData.frameEnd = raw.frame_number;
}
}
public function delete() {
vertexBuffer.delete();
}
}
typedef TGreasePencilFormat = {
@:optional var grease_pencil_datas:Array<TGreasePencilData>;
@:optional var grease_pencil_ref:String;
}
typedef TGreasePencilData = {
var name:String;
var layers:Array<TGreasePencilLayer>;
var shader:String;
}
typedef TGreasePencilLayer = {
var name:String;
var opacity:Float;
var frames:Array<TGreasePencilFrame>;
}
typedef TGreasePencilFrame = {
var frame_number:Int;
var vertex_array:TVertexArray;
var col_array:TVertexArray;
var colfill_array:TVertexArray;
var index_array:TIndexArray;
var num_stroke_points:Uint32Array;
}

View File

@ -0,0 +1,55 @@
package armory.object;
class GreasePencilObject {
static var gpFrame = 0;
public function drawGreasePencil(params:Array<String>, root:Object) {
var gp = Scene.active.greasePencil;
if (gp == null) return;
var g = currentRenderTarget;
var lamp = getLamp(currentLampIndex);
var context = GreasePencilData.getContext(params[0]);
g.setPipeline(context.pipeState);
Uniforms.setConstants(g, context, null, camera, lamp, null);
// Draw layers
for (layer in gp.layers) {
// Next frame
if (layer.frames.length - 1 > layer.currentFrame && gpFrame >= layer.frames[layer.currentFrame + 1].raw.frame_number) {
layer.currentFrame++;
}
var frame = layer.frames[layer.currentFrame];
if (frame.numVertices > 0) {
// Stroke
#if (js && kha_webgl)
// TODO: Construct triangulated lines from points instead
g.setVertexBuffer(frame.vertexStrokeBuffer);
kha.SystemImpl.gl.lineWidth(3);
var start = 0;
for (i in frame.raw.num_stroke_points) {
kha.SystemImpl.gl.drawArrays(js.html.webgl.GL.LINE_STRIP, start, i);
start += i;
}
#end
// Fill
g.setVertexBuffer(frame.vertexBuffer);
g.setIndexBuffer(frame.indexBuffer);
g.drawIndexedVertices();
}
}
gpFrame++;
// Reset timeline
if (gpFrame > GreasePencilData.frameEnd) {
gpFrame = 0;
for (layer in gp.layers) layer.currentFrame = 0;
}
end(g);
}
}

View File

@ -1062,7 +1062,7 @@ class ArmoryExporter:
cdata[i3 ] = col[0]
cdata[i3 + 1] = col[1]
cdata[i3 + 2] = col[2]
mats = exportMesh.materials
poly_map = []
for i in range(max(len(mats), 1)):
@ -1071,14 +1071,14 @@ class ArmoryExporter:
poly_map[poly.material_index].append(poly)
o['index_arrays'] = []
# map polygon indices to triangle loops
tri_loops = {}
for loop in exportMesh.loop_triangles:
if loop.polygon_index not in tri_loops:
tri_loops[loop.polygon_index] = []
tri_loops[loop.polygon_index].append(loop)
for index, polys in enumerate(poly_map):
tris = 0
for poly in polys:
@ -1736,6 +1736,17 @@ class ArmoryExporter:
self.post_export_world(w, o)
self.output['world_datas'].append(o)
def export_grease_pencils(self):
for gpRef in bpy.data.grease_pencils:
fp = self.get_meshes_file_path('greasepencil_' + gpRef.name)
assets.add(fp)
self.output['grease_pencil_ref'] = 'greasepencil_' + gpRef.name + '/' + gpRef.name
assets.add_shader_pass('grease_pencil')
gpo = self.post_export_grease_pencil(gpRef)
gp_obj = {}
gp_obj['grease_pencil_datas'] = [gpo]
arm.utils.write_arm(fp, gp_obj)
def is_compress(self):
return ArmoryExporter.compress_enabled
@ -1971,6 +1982,7 @@ class ArmoryExporter:
self.export_particle_systems()
self.output['world_datas'] = []
self.export_worlds()
self.export_grease_pencils()
self.export_tilesheets()
if self.scene.world is not None:
@ -2246,7 +2258,7 @@ class ArmoryExporter:
col_mask = ''
for b in bobject.arm_rb_collision_filter_mask:
col_mask = ('1' if b else '0') + col_mask
x['parameters'] = [str(shape), str(body_mass), str(rb.friction), str(rb.restitution), str(int(col_group, 2)), str(int(col_mask, 2)) ]
lx = bobject.arm_rb_linear_factor[0]
ly = bobject.arm_rb_linear_factor[1]
@ -2423,7 +2435,7 @@ class ArmoryExporter:
bobject_eval = bobject.evaluated_get(self.depsgraph) if apply_modifiers else bobject
exportMesh = bobject_eval.to_mesh()
with open(nav_filepath, 'w') as f:
for v in exportMesh.vertices:
f.write("v %.4f " % (v.co[0] * bobject_eval.scale.x))
@ -2585,6 +2597,85 @@ class ArmoryExporter:
po['strength'] = strength
o['probe'] = po
def post_export_grease_pencil(self, gp):
o = {}
o['name'] = gp.name
o['layers'] = []
for layer in gp.layers:
o['layers'].append(self.export_grease_pencil_layer(layer))
o['shader'] = 'grease_pencil/grease_pencil'
return o
def export_grease_pencil_layer(self, layer):
lo = {}
lo['name'] = layer.info
lo['opacity'] = layer.opacity
lo['frames'] = []
for frame in layer.frames:
if frame.frame_number > self.scene.frame_end:
break
lo['frames'].append(self.export_grease_pencil_frame(frame))
return lo
def export_grease_pencil_frame(self, frame):
va = []
cola = []
colfilla = []
indices = []
num_stroke_points = []
index_offset = 0
for stroke in frame.strokes:
for point in stroke.points:
va.append(point.co[0])
va.append(point.co[1])
va.append(point.co[2])
# TODO: store index to color pallete only, this is wasteful
if stroke.color != None:
cola.append(stroke.color.color[0])
cola.append(stroke.color.color[1])
cola.append(stroke.color.color[2])
cola.append(stroke.color.alpha)
colfilla.append(stroke.color.fill_color[0])
colfilla.append(stroke.color.fill_color[1])
colfilla.append(stroke.color.fill_color[2])
colfilla.append(stroke.color.fill_alpha)
else:
cola.append(0.0)
cola.append(0.0)
cola.append(0.0)
cola.append(0.0)
colfilla.append(0.0)
colfilla.append(0.0)
colfilla.append(0.0)
colfilla.append(0.0)
for triangle in stroke.triangles:
indices.append(triangle.v1 + index_offset)
indices.append(triangle.v2 + index_offset)
indices.append(triangle.v3 + index_offset)
num_stroke_points.append(len(stroke.points))
index_offset += len(stroke.points)
fo = {}
# TODO: merge into array of vertex arrays
fo['vertex_array'] = {}
fo['vertex_array']['attrib'] = 'pos'
fo['vertex_array']['size'] = 3
fo['vertex_array']['values'] = va
fo['col_array'] = {}
fo['col_array']['attrib'] = 'col'
fo['col_array']['size'] = 4
fo['col_array']['values'] = cola
fo['colfill_array'] = {}
fo['colfill_array']['attrib'] = 'colfill'
fo['colfill_array']['size'] = 4
fo['colfill_array']['values'] = colfilla
fo['index_array'] = {}
fo['index_array']['material'] = 0
fo['index_array']['size'] = 3
fo['index_array']['values'] = indices
fo['num_stroke_points'] = num_stroke_points
fo['frame_number'] = frame.frame_number
return fo
# https://blender.stackexchange.com/questions/70629
def mod_equal(self, mod1, mod2):
return all([getattr(mod1, prop, True) == getattr(mod2, prop, False) for prop in mod1.bl_rna.properties.keys()])