Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/actionscript-3/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Actionscript 3 在GPU模式下使用文本过滤器AIR mobile_Actionscript 3_Apache Flex_Mobile_Air_Gpu - Fatal编程技术网

Actionscript 3 在GPU模式下使用文本过滤器AIR mobile

Actionscript 3 在GPU模式下使用文本过滤器AIR mobile,actionscript-3,apache-flex,mobile,air,gpu,Actionscript 3,Apache Flex,Mobile,Air,Gpu,不幸的是,这些过滤器在GPU模式下无法工作(阴影、光晕)。我正在寻找一个机会来使用这些效果的文字在这种模式。我欢迎任何建议。基本思想是像平常一样应用过滤器,然后将显示对象绘制到位图数据,并将位图添加到舞台。有关示例,请参见 如果您要将此应用于的文本是静态的,那么这应该很容易做到,但是如果您想要应用此动态文本(例如,将经常更改的分数计数器,或用户可编辑的文本),我想这可能会开始变得烦人,但我不知道有任何其他解决方案。正如Astraport提到的,每次使用bitmapData.draw()更新文本时

不幸的是,这些过滤器在GPU模式下无法工作(阴影、光晕)。我正在寻找一个机会来使用这些效果的文字在这种模式。我欢迎任何建议。

基本思想是像平常一样应用过滤器,然后将显示对象绘制到位图数据,并将位图添加到舞台。有关示例,请参见


如果您要将此应用于的文本是静态的,那么这应该很容易做到,但是如果您想要应用此动态文本(例如,将经常更改的分数计数器,或用户可编辑的文本),我想这可能会开始变得烦人,但我不知道有任何其他解决方案。

正如Astraport提到的,每次使用
bitmapData.draw()
更新文本时,都需要将文本字段绘制到bitmapData

如果使用
textField.getBounds
确定所需位图数据的大小,则生成的边界矩形将不包括因过滤器而产生的额外大小(例如,DropShadowFilter根据“距离”和“模糊”在文本框的侧面伸出特定像素)。为了确保在绘制位图时包含过滤器,还需要使用
bitmapData.generateFilterRect()
获得正确大小的rect

代码片段(未经测试,但总体思路):


以下是如何将任何
显示对象
转换为
位图
——用于在AIR GPU mobile
rendermode
中“恢复”过滤效果。这是Pixelthis的解决方案,经过固定、优化和测试:

    // => 'bitmap' must belong to the same parent as 'obj'. 'obj' should be invisible.
    static public function Update(obj:DisplayObject, bitmap:Bitmap):void {
        //trace("CacheToBmp",obj.name);

        // Remember the transform matrix of the text field
        var offset:Matrix = obj.transform.matrix.clone();
        // Get the bounds of just the textfield (does not include filters)
        var bounds:Rectangle = obj.getBounds(obj);
        // Create a bitmapData that is used just to calculate the size of the filters
        var tempBD:BitmapData = new BitmapData( Math.ceil(bounds.width), Math.ceil(bounds.height), false );
        bounds.width = obj.width;
        bounds.height = obj.height;
        // Make a copy of the textField bounds. We'll adjust this with the filters
        var finalBounds:Rectangle = new Rectangle(0,0,bounds.width,bounds.height);

        // Step through each filter in the textField and adjust our bounds to include them all
        var filterBounds:Rectangle;
        for each (var filter:BitmapFilter in obj.filters) {
            filterBounds = tempBD.generateFilterRect( tempBD.rect, filter );
            finalBounds = finalBounds.union(filterBounds);
        }
        finalBounds.offset(bounds.x,bounds.y);
        finalBounds.x = Math.floor(finalBounds.x);
        finalBounds.y = Math.floor(finalBounds.y);
        finalBounds.width = Math.ceil(finalBounds.width);
        finalBounds.height = Math.ceil(finalBounds.height);

        // Now draw the textfield to a new bitmpaData
        var data:BitmapData = new BitmapData( finalBounds.width, finalBounds.height, false, 0 );
        offset.tx = -finalBounds.x;
        offset.ty = -finalBounds.y;
        data.drawWithQuality( obj, offset, obj.transform.colorTransform, obj.blendMode, null, true, StageQuality.HIGH );
        bitmap.bitmapData = data;

        // Position the bitmap in same place as 'obj'
        bitmap.x = obj.transform.matrix.tx + finalBounds.x;
        bitmap.y = obj.transform.matrix.ty + finalBounds.y;
    }

GPU渲染模式限制:不支持过滤器。我看到了这个建议,但它不适合我。我使用动态文本。
    // => 'bitmap' must belong to the same parent as 'obj'. 'obj' should be invisible.
    static public function Update(obj:DisplayObject, bitmap:Bitmap):void {
        //trace("CacheToBmp",obj.name);

        // Remember the transform matrix of the text field
        var offset:Matrix = obj.transform.matrix.clone();
        // Get the bounds of just the textfield (does not include filters)
        var bounds:Rectangle = obj.getBounds(obj);
        // Create a bitmapData that is used just to calculate the size of the filters
        var tempBD:BitmapData = new BitmapData( Math.ceil(bounds.width), Math.ceil(bounds.height), false );
        bounds.width = obj.width;
        bounds.height = obj.height;
        // Make a copy of the textField bounds. We'll adjust this with the filters
        var finalBounds:Rectangle = new Rectangle(0,0,bounds.width,bounds.height);

        // Step through each filter in the textField and adjust our bounds to include them all
        var filterBounds:Rectangle;
        for each (var filter:BitmapFilter in obj.filters) {
            filterBounds = tempBD.generateFilterRect( tempBD.rect, filter );
            finalBounds = finalBounds.union(filterBounds);
        }
        finalBounds.offset(bounds.x,bounds.y);
        finalBounds.x = Math.floor(finalBounds.x);
        finalBounds.y = Math.floor(finalBounds.y);
        finalBounds.width = Math.ceil(finalBounds.width);
        finalBounds.height = Math.ceil(finalBounds.height);

        // Now draw the textfield to a new bitmpaData
        var data:BitmapData = new BitmapData( finalBounds.width, finalBounds.height, false, 0 );
        offset.tx = -finalBounds.x;
        offset.ty = -finalBounds.y;
        data.drawWithQuality( obj, offset, obj.transform.colorTransform, obj.blendMode, null, true, StageQuality.HIGH );
        bitmap.bitmapData = data;

        // Position the bitmap in same place as 'obj'
        bitmap.x = obj.transform.matrix.tx + finalBounds.x;
        bitmap.y = obj.transform.matrix.ty + finalBounds.y;
    }