Restore old grease pencil code
This commit is contained in:
parent
c6d74fc4ea
commit
c56fb4bbf1
9
Shaders/grease_pencil/grease_pencil.frag.glsl
Normal file
9
Shaders/grease_pencil/grease_pencil.frag.glsl
Normal file
|
@ -0,0 +1,9 @@
|
|||
#version 450
|
||||
|
||||
in vec4 color;
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
void main() {
|
||||
fragColor = color;
|
||||
}
|
25
Shaders/grease_pencil/grease_pencil.json
Normal file
25
Shaders/grease_pencil/grease_pencil.json
Normal 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"
|
||||
}
|
||||
]
|
||||
}
|
13
Shaders/grease_pencil/grease_pencil.vert.glsl
Normal file
13
Shaders/grease_pencil/grease_pencil.vert.glsl
Normal 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);
|
||||
}
|
178
Sources/armory/data/GreasePencilData.hx
Normal file
178
Sources/armory/data/GreasePencilData.hx
Normal 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;
|
||||
}
|
55
Sources/armory/object/GreasePencilObject.hx
Normal file
55
Sources/armory/object/GreasePencilObject.hx
Normal 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);
|
||||
}
|
||||
}
|
|
@ -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:
|
||||
|
@ -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()])
|
||||
|
|
Loading…
Reference in a new issue