忍者ブログ

Memeplexes

プログラミング、3DCGとその他いろいろについて

かんたんXNA HLSL編 その4 フロー制御文

このページは古いです
最新版はこちら

HLSLにも他の多くのC言語ベースの言語と同じように、
フロー制御文があります。

つまりifやfor, while, doとかのことです。
あらためて説明の必要はないとは思いますが、一応見ておきましょう。
(なんせ人間原理的な意味でこの記事を見ている方はフロー制御をほかの言語で知っているはずですからね)

まず、msdnを見ると、
if, for, while, switch, do, break, continueと、
一通りそろっているようです。(以下msdnより)

[Attribute] if ( Conditional )
{
    Statement Block
}

[Attribute] for ( Initializer; Conditional; Iterator )
{
    Statement Block;
}

[Attribute] while ( Conditional )
{
    Statement Block;
}

[Attribute] switch ( Selector
{
    case 0 :
        { Statement Block; }
    break;
    case 1 :
        { Statement Block; }
    break;
    case n :
        { Statement Block; }
    break;
    default :
        { Statement Block; }
    break;
}

do 
{
    Statement Block;
} while( Conditional )

break;

continue;


おなじみの文です。
・・・・・・と思ったら[Attribute]とかいう変なのがありますね・・・。
どうやらこれはコンパイルの方法を指定する、C#の一部の属性のようなものらしいです。
でも省略可能なので普通のC言語系のフロー制御と同じように使うことができます。
というかこの[Attribute]はVisual C#で試してみるとエラーが出てコンパイルできません

さて、そしてswitchでもコンパイルエラーが出ます
・・・・・・さらにどうやらbreakとcontinueも使えません
これはおそらくXNAの内部で使っているDirectXのバージョンによるものなのでしょう。
XNAはDirectX9を使っていますが、最新はDirectX10です。
XNAがDirectX10を使う予定はまだないそうなので、しばらくはswitchとかはあきらめたほうがいいでしょう。

つまり、実際に使えるのはif, for, while, doだけのようです。
でも、これだけでもフロー制御をするには十分です。
気を取り直していきましょう。

MyGame.cs
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;


public class MyGame : Game
{
    GraphicsDeviceManager graphics;
    ContentManager content;

    Effect effect;
    VertexPositionColor[] vertices = {
            new VertexPositionColor(new Vector3(0, 1, 0), Color.White),
            new VertexPositionColor(new Vector3(1, 0, 0), Color.Blue),
            new VertexPositionColor(new Vector3(-1, 0, 0), Color.Red)
        };


    public MyGame()
    {
        graphics = new GraphicsDeviceManager(this);
        content = new ContentManager(Services);
    }

    protected override void LoadGraphicsContent(bool loadAllContent)
    {
        if (loadAllContent)
        {
            effect = content.Load<Effect>("MyEffect");

            graphics.GraphicsDevice.VertexDeclaration = new VertexDeclaration(
                graphics.GraphicsDevice,
                VertexPositionColor.VertexElements
                );
        }
    }

    protected override void UnloadGraphicsContent(bool unloadAllContent)
    {
        if (unloadAllContent) { content.Unload(); }
    }

    protected override void Draw(GameTime gameTime)
    {
        graphics.GraphicsDevice.Clear(Color.CornflowerBlue);

        effect.Begin();

        foreach (EffectPass pass in effect.CurrentTechnique.Passes)
        {
            pass.Begin();

            graphics.GraphicsDevice.DrawUserPrimitives<VertexPositionColor>(
                PrimitiveType.TriangleList,
                vertices,
                0,
                vertices.Length / 3
                );

            pass.End();
        }

        effect.End();
    }
}

MyEffect.fx
struct VertexPositionColor
{
	float4 Position : POSITION;
	float4 Color : COLOR;
};

VertexPositionColor MyVertexShader(VertexPositionColor input)
{
	return input;
}

float4 MyPixelShader(float4 color : COLOR) : COLOR
{
	if(color.r % 0.1f < 0.05f)
		return float4(1,1,1,1);
	else
		return color;
}

technique MyTechnique
{
	pass MyPass
	{
		VertexShader = compile vs_2_0 MyVertexShader();
		PixelShader = compile ps_2_0 MyPixelShader();
	}
}


stripeTriangle.jpg
ほどよくしましまになっているのがわかると思います。
ピクセルシェーダに与えられる色の赤いチャンネルをもとにして
条件分岐を行ったのです。
こんなことをしても実際には何の役にも立たないかもしれませんが、
HLSLの威力がよくわかる例ではないでしょうか。
少なくともこれはBasicEffectでは出来ませんからね。







拍手[0回]

PR