Capture output as render result.

This commit is contained in:
Lubos Lenco 2016-11-12 18:30:39 +01:00
parent fc73ed9c75
commit a2667d8dca
7 changed files with 104 additions and 3 deletions

View file

@ -21,6 +21,12 @@ class EditorSpace extends Trait {
static var first = true;
#if js
static var patchTime = 0.0;
static var lastMtime:Dynamic;
static var lastSize:Dynamic;
#end
public function new() {
super();
@ -38,6 +44,10 @@ class EditorSpace extends Trait {
if (first) {
first = false;
kha.input.Keyboard.get().notify(onKeyDown, onKeyUp);
#if js
electronRenderCapture();
#end
}
}
@ -103,4 +113,61 @@ class EditorSpace extends Trait {
// moveX = moveY = moveZ = false;
// }
}
#if (js) // && sys_webgl)
public static function getRenderResult():js.html.Uint8Array {
var gl = kha.SystemImpl.gl;
var w = gl.drawingBufferWidth;
var h = gl.drawingBufferHeight;
var pixels = new js.html.Uint8Array(w * h * 4);
gl.readPixels(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight, js.html.webgl.GL.RGBA, js.html.webgl.GL.UNSIGNED_BYTE, pixels);
return pixels;
// var bytes = haxe.io.Bytes.ofData(pixels.buffer);
// var pngdata = armory.trait.internal.png.Tools.buildRGB(w, h, bytes);
// var output = new haxe.io.BytesOutput();
// var writer = new armory.trait.internal.png.Writer(output);
// writer.write(pngdata);
// return output.getBytes();
}
#end
#if js
function electronRenderCapture() {
var electron = untyped __js__('window && window.process && window.process.versions["electron"]');
if (electron) {
untyped __js__('var fs = require("fs");');
App.notifyOnUpdate(function() {
patchTime += iron.system.Time.delta;
if (patchTime > 0.2) {
patchTime = 0;
var repatch = false;
untyped __js__('
if (fs.existsSync(__dirname + "/" + "render.msg")) {
{0} = true;
fs.unlinkSync(__dirname + "/" + "render.msg");
}'
, repatch);
if (repatch) {
var pixels = getRenderResult();
untyped __js__('
fs.writeFileSync(__dirname + "/render.bin", new Buffer({0}));
', pixels);
var w = kha.SystemImpl.gl.drawingBufferWidth;
var h = kha.SystemImpl.gl.drawingBufferHeight;
trace("__arm|render" + "|" + w + "|" + h);
}
// Compare mtime and size of file
// untyped __js__('fs.stat(__dirname + "/" + {0} + ".arm", function(err, stats) {', Scene.active.raw.name);
// untyped __js__(' if ({0} > stats.mtime || {0} < stats.mtime || {1} !== stats.size) { if ({0} !== undefined) { {2} = true; } {0} = stats.mtime; {1} = stats.size; }', lastMtime, lastSize, repatch);
// if (repatch) {
// }
// untyped __js__('});');
}
});
}
}
#end
}

View file

@ -1,5 +1,6 @@
# Translating operators from/to Armory player
import bpy
import numpy
import armutils
try:
import barmory
@ -30,6 +31,13 @@ def parse_operator(text):
bpy.context.object.select = False
bpy.context.scene.objects[cmd[2]].select = True
bpy.context.scene.objects.active = bpy.context.scene.objects[cmd[2]]
elif cmd[1] == 'render':
data = numpy.fromfile(armutils.get_fp() + '/build/html5/render.bin', dtype=numpy.uint8)
data = data.astype(float)
data = numpy.divide(data, 255)
image = bpy.data.images.new("Render Result", width=int(cmd[2]), height=int(cmd[3]))
image.pixels = data
return
def send_operator(op):
# Try to translate operator directly to armory

View file

@ -102,7 +102,7 @@ def on_scene_update_post(context):
if len(ops) > 0:
last_operator = ops[-1]
# No attribute when using multiple widnows?
# No attribute when using multiple windows?
if hasattr(bpy.context, 'edit_object'):
edit_obj = bpy.context.edit_object
if edit_obj != None and edit_obj.is_updated_data:

View file

@ -1,6 +1,7 @@
import props_ui
import space_armory
import armutils
import bridge
progress = 100.0
tag_redraw = False
@ -13,6 +14,13 @@ def clear():
def format_text(text):
return (text[:80] + '..') if len(text) > 80 else text # Limit str size
def electron_trace(text):
txt = text.split(' ', 1)
if len(txt) > 1 and txt[1].startswith('__arm'):
bridge.parse_operator(text)
else:
print_info(text)
def print_info(text):
global tag_redraw
print(text)

View file

@ -270,7 +270,7 @@ def watch_play():
msg = str(line).split('"', 1) # Extract message
if len(msg) > 1:
trace = msg[1].rsplit('"', 1)[0]
log.print_info(trace)
log.electron_trace(trace)
line = b''
else:
line += char
@ -461,3 +461,7 @@ def publish_project():
threading.Timer(0.1, watch_compile, ['publish']).start()
bpy.data.worlds['Arm'].arm_minimize = minimize
assets.invalidate_enabled = True
def get_render_result():
with open(armutils.get_fp() + '/build/html5/render.msg', 'w') as f:
pass

View file

@ -453,6 +453,7 @@ class ArmoryPlayPanel(bpy.types.Panel):
layout.prop(wrd, 'arm_play_live_patch')
if wrd.arm_play_live_patch:
layout.prop(wrd, 'arm_play_auto_build')
layout.operator("arm.render", icon="RENDER_STILL")
layout.operator("arm.help")
class ArmoryBuildPanel(bpy.types.Panel):
@ -670,6 +671,18 @@ class ArmoryPublishButton(bpy.types.Operator):
self.report({'INFO'}, 'Publishing project, check console for details.')
return{'FINISHED'}
class ArmoryRenderButton(bpy.types.Operator):
'''Capture Armory output as render result'''
bl_idname = 'arm.render'
bl_label = 'Render'
def execute(self, context):
if state.playproc == None:
self.report({"ERROR"}, "Run Armory player in window first")
return {"CANCELLED"}
make.get_render_result()
return{'FINISHED'}
# Play button in 3D View panel
def draw_view3d_header(self, context):
layout = self.layout

View file

@ -130,7 +130,8 @@ class Main {
f.write("""
iron.Scene.setActive(projectScene, function(object:iron.object.Object) {""")
if armutils.with_chromium() and in_viewport and is_play:
# if armutils.with_chromium() and in_viewport and is_play:
if is_play:
f.write("""
object.addTrait(new armory.trait.internal.EditorSpace());""")
f.write("""