2016-12-06 14 views
0

私はWin2D-Example-Galleryから取ったマンデルブローセットを描画して少し微調整したいと思います。Win2D:CanvasVirtualControlの正しい使い方

は、最初に私はCanvasAnimatedControlCreateResources方法 - 内部のマンデルブロを生成するために、すべての私のコードを持っていたが、原因私はシェーダ(HLSLまたはPixelShaderEffect)とCanvasVirtualControl使用してそれを行うようになったパフォーマンスの問題へ:

public PixelShaderEffect _effectMandel; 
CanvasVirtualImageSource _sdrc; 

public async Task CreateResources(CanvasVirtualControl sender) 
{ 
    _sdrc = new CanvasVirtualImageSource(sender, new Size(_width, _height)); 
    var arr = await FileHelper.ReadAllBytes("Shaders/Mandelbrot.bin"); 
    if (arr != null) 
    { 
     _effectMandel = new PixelShaderEffect(arr); 

     using (CanvasDrawingSession drawingSession = sender.CreateDrawingSession(new Rect(0,0,_width,_height))) 
     { 
      drawingSession.DrawImage(_effectMandel); 
     } 
    } 
} 

私はアプリケーションを実行すると、私が使用してセクションにSystem.Runtime.InteropServices.COMException権利を取得し、「App.gics」ファイルは私に言って開きます:

Debugger runs into this

は、私が使用するシェーダコードはこれです:これはなぜ起こるかあなたが知っている場合

// Copyright (c) Microsoft Corporation. All rights reserved. 
// 
// Licensed under the MIT License. See LICENSE.txt in the project root for license information. 


// This shader has no input textures. 
// It generates a mandelbrot fractal. 

#define D2D_INPUT_COUNT 0 
#define D2D_REQUIRES_SCENE_POSITION 

#include "d2d1effecthelpers.hlsli" 


float scale; 
float2 translate; 

static const float4 tapOffsetsX = float4(-0.25, 0.25, -0.25, 0.25); 
static const float4 tapOffsetsY = float4(-0.25, -0.25, 0.25, 0.25); 

static const int iterations = 100; 


D2D_PS_ENTRY(main) 
{ 
    float2 pos = D2DGetScenePosition().xy; 

    // Improve visual quality by supersampling inside the pixel shader, evaluating four separate 
    // versions of the fractal in parallel, each at a slightly different position offset. 
    // The x, y, z, and w components of these float4s contain the four simultaneous computations. 
    float4 c_r = (pos.x + tapOffsetsX) * scale + translate.x; 
    float4 c_i = (pos.y + tapOffsetsY) * scale + translate.y; 

    float4 value_r = 0; 
    float4 value_i = 0; 

    // Evalulate the Mandelbrot fractal. 
    for (int i = 0; i < iterations; i++) 
    { 
     float4 new_r = value_r * value_r - value_i * value_i + c_r; 
     float4 new_i = value_r * value_i * 2 + c_i; 

     value_r = new_r; 
     value_i = new_i; 
    } 

    // Adjust our four parallel results to range 0:1. 
    float4 distanceSquared = value_r * value_r + value_i * value_i; 

    float4 vectorResult = isfinite(distanceSquared) ? saturate(1 - distanceSquared) : 0; 

    // Resolve the supersampling to produce a single scalar result. 
    float result = dot(vectorResult, 0.25); 

    if (result < 1.0/256) 
     return 0; 
    else 
     return float4(result, result, result, 1); 
} 

、お答えください。ありがとう!

+0

おそらく、ロードしたファイルがコンパイルされたFXシェーダーではないからでしょうか? http://stackoverflow.com/questions/1938514/pixel-shader-effect-examples –

+0

@BerinLoritsch私の質問が更新され、Microsoftのシェーダコードが提供されました。ここで提供されている例はhttps://microsoft.github.io/Win2D/html/M_Microsoft_Graphics_Canvas_Effects_PixelShaderEffect__ctor.htmですが、動作しませんでした。 – Manticore

+0

シェイダーコードを書いて以来、しばらくしていました。私が持っていた最大の問題は、バイナリが私が期待していたものであることを確認することでした。私は、コンパイルされたシェーダコードが32/64bitに敏感だとは思わない。また、すべてのオブジェクトファイルを消去してください( '.g.i.cs'ファイルは生成されたソースファイルです)。 Visual Studioも再起動する必要があります。 –

答えて

1

定期的にキャンバスを無効にして60fpsを得るためにタイマーを設定する必要がありました。 は、私は別のは、Microsoftの例に見て、最終的にはこのコードを使用して、それを働いていた:

DispatcherTimer timer; 
internal void Regions_Invalidated(CanvasVirtualControl sender, CanvasRegionsInvalidatedEventArgs args) 
{ 
    // Configure the Mandelbrot effect to position and scale its output. 
    float baseScale = 0.005f; 
    float scale = (baseScale * 96/sender.Dpi)/(helper._modifiers[1]/1000f); 
    var controlSize = baseScale * sender.Size.ToVector2() * scale; 
    Vector2 translate = (baseScale * sender.Size.ToVector2() * new Vector2(-0.5f,-0f)); 

    _effectMandel.Properties["scale"] = scale; 
    _effectMandel.Properties["translate"] = (Microsoft.Graphics.Canvas.Numerics.Vector2)translate; 
#endif 

    // Draw the effect to whatever regions of the CanvasVirtualControl have been invalidated. 
    foreach (var region in args.InvalidatedRegions) 
    { 
     using (var drawingSession = sender.CreateDrawingSession(region)) 
     { 
      drawingSession.DrawImage(_effectMandel); 
     } 
    } 

    // start timer for fps 
    this.timer = new DispatcherTimer(); 
    int fps = 60; 
    this.timer.Interval = new TimeSpan(0, 0, 0, 0, 100/fps); 
    this.timer.Tick += timer_Tick; 
    this.timer.Start(); 
} 

private void timer_Tick(object sender, object e) 
{ 
    this.timer.Stop(); 
    _canvas.Invalidate(); 
} 

・ホープこれは誰かに便利です。