-
Notifications
You must be signed in to change notification settings - Fork 822
Description
Problem Description
Texture from Camera
cannot be displayed twice using Starling. Only one image with such texture will be displayed.
There is no such issue with videos.
So you cannot output camera view in multiple Images
.
Tested with Starling 2.7 and latest source code. Tested with multiple AIR versions, even with latest AIR 51.1.3.10. Tested with Windows and Android with multiple OS versions, devices, architectures and different applications.
The same issue with in all cases.
It works fine with Windows/macOS.
Didn't tested with Linux/macOS/iOS/tvOS.
Didn't tested with pure Stage3D
.
Steps to Reproduce
Try to display camera view output twice via Images
. Launch attached sample. It will get access to camera, create 2 textures for the same camera and try to display it via Images
.
Application example with sources attached.
starling_videotexture_camera_twice_bug.zip
package {
import flash.desktop.NativeApplication;
import flash.desktop.SystemIdleMode;
import flash.display.Sprite;
import flash.events.Event;
import flash.media.Camera;
import flash.events.PermissionEvent;
import flash.permissions.PermissionManager;
import flash.permissions.PermissionStatus;
import flash.utils.setTimeout;
import starling.display.Image;
import starling.core.Starling;
import starling.display.DisplayObjectContainer;
public class StarlingVideoTextureCameraTwiceBug extends Sprite {
private var cameraObject1;
public function StarlingVideoTextureCameraTwiceBug() {
NativeApplication.nativeApplication.systemIdleMode = SystemIdleMode.KEEP_AWAKE;
addEventListener(Event.ADDED_TO_STAGE, addedToStage);
}
private function addedToStage(e:Event):void {
removeEventListener(Event.ADDED_TO_STAGE, addedToStage);
var cameraPermissionManager:PermissionManager = Camera.permissionManager;
if (cameraPermissionManager.permissionStatus != PermissionStatus.GRANTED){
Camera.permissionManager.addEventListener(PermissionEvent.PERMISSION_STATUS, permissionChanged);
Camera.permissionManager.requestPermission();
} else {
startCamera();
}
}
private function permissionChanged(e:PermissionEvent):void {
trace("permissionChanged", Camera.permissionManager.permissionStatus);
startCamera();
}
private function startCamera():void {
StarlingManager.instance.addEventListener(Event.COMPLETE, instance_complete);
StarlingManager.instance.init(stage);
stage.color = 0xFF55FF;
}
private function instance_complete(e:Event):void {
const name:String = Camera.names[0];
const camera:Camera = Camera.getCamera();
trace("name:", name, "camera:", camera);
cameraObject1 = new CameraObject(camera, 0);//Camera view output at left
new CameraObject(camera, 320);//Camera view output at right
//For workaround instead of line above please use commented block below:
/*
setTimeout(function():void {
var image2:Image = new Image(cameraObject1.cameraTexture);
image2.width = 320;
image2.height = 240;
image2.x = 320;
(Starling.current.root as DisplayObjectContainer).addChild(image2);
}, 2000);
*/
}
}
}
import flash.media.Camera;
import starling.core.Starling;
import starling.display.DisplayObjectContainer;
import starling.display.Image;
import starling.textures.Texture;
class CameraObject {
private var _camera:Camera;
private var _x:Number = 0;
private var _cameraImage:Image;
internal var cameraTexture:Texture;
public function CameraObject(camera:Camera, x:Number) {
_camera = camera;
_x = x;
try {
trace("camera init");
cameraTexture = Texture.fromCamera(_camera, Starling.current.contentScaleFactor, onTextureComplete);
return;
} catch (e:Error) {
trace(e.getStackTrace());
}
}
/**
* On Starling Texture complete
*/
private function onTextureComplete(t:Texture):void {
//This listener not called for second texture
trace("texture complete");
_cameraImage = new Image(cameraTexture);
_cameraImage.width = 320;
_cameraImage.height = 240;
_cameraImage.x = _x;
(Starling.current.root as DisplayObjectContainer).addChild(_cameraImage);
}
}
Actual Result:
Only one camera view output will be displayed:
Expected Result:
Both camera views output will be displayed:
Known Workarounds
Create second Image
with the same camera texture after few seconds (mentioned in example above). But it's dirty hack I think.
Also if timeout will not be enough (500 milliseconds for example) - you will get exception:
Error: Error #3605: Sampler 0 binds an invalid texture.
at flash.display3D::Context3D/drawTriangles()
at starling.rendering::Effect/render()[starling_videotexture_camera_twice_bug\starling\rendering\Effect.as:236]
at starling.display::MeshBatch/render()[starling_videotexture_camera_twice_bug\starling\display\MeshBatch.as:254]
at starling.rendering::Painter/drawBatch()[starling_videotexture_camera_twice_bug\starling\rendering\Painter.as:709]
at BatchProcessor/finishBatch()[starling_videotexture_camera_twice_bug\starling\rendering\BatchProcessor.as:119]
at BatchProcessor/finishFrame()[starling_videotexture_camera_twice_bug\starling\rendering\BatchProcessor.as:126]
at starling.rendering::Painter/finishFrame()[starling_videotexture_camera_twice_bug\starling\rendering\Painter.as:592]
at starling.core::Starling/render()[starling_videotexture_camera_twice_bug\starling\core\Starling.as:468]
at starling.core::Starling/nextFrame()[starling_videotexture_camera_twice_bug\starling\core\Starling.as:410]
at starling.core::Starling/onEnterFrame()[starling_videotexture_camera_twice_bug\starling\core\Starling.as:644]