▼XNA Game Studioメモ▼
テクスチャを貼った3Dプリミティブを表示する


テクスチャを貼った3Dプリミティブを表示するプログラムを作成する。



画像リソースの追加
今回のプログラムには画像を1枚使用する。 プロジェクトに追加。


heniheni.png


エフェクトファイルの追加
今回のプログラムにはエフェクトファイルを1つ使用する。 プロジェクトに追加。

TextureEffect.fx
float4x4 worldViewProj : WORLDVIEWPROJECTION;
texture  cubeTexture;

struct VS_INPUT {
    float4 pos      : POSITION;
    float4 texcoord : TEXCOORD0;
};

struct VS_OUTPUT {
    float4 pos      : POSITION;
    float4 texcoord : TEXCOORD0;
};

sampler textureSampler = sampler_state {
    Texture  =<cubeTexture>;
    mipfilter=LINEAR; 
};
 
VS_OUTPUT VS_TextureTech(VS_INPUT In) {

    VS_OUTPUT Out=(VS_OUTPUT)0;

    Out.pos     =mul(In.pos,worldViewProj);
    Out.texcoord=In.texcoord;

    return Out;
}

float4 PS_TextureTech(VS_OUTPUT Out) : COLOR {
    return tex2D(textureSampler,Out.texcoord).rgba;
}

technique TextureTech {
    pass P0 {
        vertexShader=compile vs_2_0 VS_TextureTech();
        pixelShader =compile ps_2_0 PS_TextureTech();
    }
}


ソースコードの編集

GameMain.cs
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
using Microsoft.Xna.Framework.Content;

//テクスチャを貼った3Dプリミティブの表示
namespace TextureEx {
    public class GameMain : Game {
        //システム
        private GraphicsDeviceManager graphics;//グラフィックス

        //3Dプリミティブ
        private Matrix                  worldViewProj;//ワールドxビューx射影行列
        private Effect                  effect;       //エフェクト
        private VertexDeclaration       cubeVertexDec;//頂点定義
        private VertexPositionTexture[] cubeVertices; //頂点郡
        private VertexBuffer            vertexBuffer; //頂点バッファ
        private short[]                 cubeIndices;  //インデックスリスト
        private IndexBuffer             indexBuffer;  //インデックスバッファ
        private Texture                 cubeTexture;  //立方体のテクスチャ

        //コンストラクタ
        public GameMain() {
            graphics=new GraphicsDeviceManager(this);
            Content.RootDirectory="Content";
        }

        //座標変換の初期化
        private void InitializeTransform() {
            //ワールド変換行列
            Matrix world = 
                Matrix.CreateRotationX((float)Math.PI/6.0f)*//X軸30度回転
                Matrix.CreateRotationY((float)Math.PI/6.0f);//Y軸30度回転

            //ビュー変換行列
            Matrix view = Matrix.CreateLookAt(
                new Vector3(0, 0, 5),//視点
                Vector3.Zero,        //参照点
                Vector3.Up);         //UPベクトル

            //射影変換行列
            Matrix projection = Matrix.CreatePerspectiveFieldOfView(
                (float)Math.PI / 4.0f,//視野角(ラジアン単位)
                (float)graphics.GraphicsDevice.Viewport.Width / 
                (float)graphics.GraphicsDevice.Viewport.Height,//アスペクト比
                1.0f,                 //ニアクリップ面の距離 
                100.0f);              //ファークリップ面の距離

            //ワールドxビューx射影行列
            worldViewProj = world * view * projection;
        }

        //エフェクトの読み込み
        private void InitializeEffect() {
            cubeTexture=Content.Load<Texture2D>("heniheni");           //テクスチャ
            effect = Content.Load<Effect>("TextureEffect");            //エフェクトファイル
            effect.Parameters["worldViewProj"].SetValue(worldViewProj);//関連付け
            effect.Parameters["cubeTexture"].SetValue(cubeTexture);
            effect.CurrentTechnique = effect.Techniques["TextureTech"];//テクニック
        }

        //立方体の初期化
        private void InitializeCube() {
            //立方体の頂点定義
            cubeVertexDec = new VertexDeclaration(
                graphics.GraphicsDevice,              //グラフィックスデバイス
                VertexPositionTexture.VertexElements);//要素配列

            //頂点
            Vector3 topLeftFront     = new Vector3(-1.0f,  1.0f,  1.0f);
            Vector3 bottomLeftFront  = new Vector3(-1.0f, -1.0f,  1.0f);
            Vector3 topRightFront    = new Vector3( 1.0f,  1.0f,  1.0f);
            Vector3 bottomRightFront = new Vector3( 1.0f, -1.0f,  1.0f);
            Vector3 topLeftBack      = new Vector3(-1.0f,  1.0f, -1.0f);
            Vector3 topRightBack     = new Vector3( 1.0f,  1.0f, -1.0f);
            Vector3 bottomLeftBack   = new Vector3(-1.0f, -1.0f, -1.0f);
            Vector3 bottomRightBack  = new Vector3( 1.0f, -1.0f, -1.0f);

            //テクスチャ頂点
            Vector2 textureTopLeft     = new Vector2(0.0f, 0.0f);
            Vector2 textureTopRight    = new Vector2(1.0f, 0.0f);
            Vector2 textureBottomLeft  = new Vector2(0.0f, 1.0f);
            Vector2 textureBottomRight = new Vector2(1.0f, 1.0f);


            //立方体の頂点
            cubeVertices = new VertexPositionTexture[36];

            //前面
            cubeVertices[0] = new VertexPositionTexture(topLeftFront,    textureTopLeft);
            cubeVertices[1] = new VertexPositionTexture(bottomLeftFront, textureBottomLeft);
            cubeVertices[2] = new VertexPositionTexture(topRightFront,   textureTopRight); 
            cubeVertices[3] = new VertexPositionTexture(bottomRightFront,textureBottomRight);

            //背面
            cubeVertices[4] = new VertexPositionTexture(topLeftBack,    textureTopRight);
            cubeVertices[5] = new VertexPositionTexture(topRightBack,   textureTopLeft); 
            cubeVertices[6] = new VertexPositionTexture(bottomLeftBack, textureBottomRight);
            cubeVertices[7] = new VertexPositionTexture(bottomRightBack,textureBottomLeft); 

            //上面
            cubeVertices[8]  = new VertexPositionTexture(topLeftFront, textureBottomLeft);
            cubeVertices[9]  = new VertexPositionTexture(topRightBack, textureTopRight);
            cubeVertices[10] = new VertexPositionTexture(topLeftBack,  textureTopLeft);
            cubeVertices[11] = new VertexPositionTexture(topRightFront,textureBottomRight);

            //下面
            cubeVertices[12] = new VertexPositionTexture(bottomLeftFront, textureTopLeft);
            cubeVertices[13] = new VertexPositionTexture(bottomLeftBack,  textureBottomLeft); 
            cubeVertices[14] = new VertexPositionTexture(bottomRightBack, textureBottomRight);
            cubeVertices[15] = new VertexPositionTexture(bottomRightFront,textureTopRight);

            //左面
            cubeVertices[16] = new VertexPositionTexture(topLeftFront,    textureTopRight);
            cubeVertices[17] = new VertexPositionTexture(bottomLeftFront, textureBottomRight);
            cubeVertices[18] = new VertexPositionTexture(topRightFront,   textureTopLeft);
            cubeVertices[19] = new VertexPositionTexture(bottomRightFront,textureBottomLeft);

            //頂点バッファ
            vertexBuffer = new VertexBuffer(
                graphics.GraphicsDevice,
                VertexPositionTexture.SizeInBytes * cubeVertices.Length,
                BufferUsage.None);
            vertexBuffer.SetData<VertexPositionTexture>(cubeVertices);
            
            //インデックスリスト
            cubeIndices = new short[] {   
                 0,  1,  2,  //前面 
                 1,  3,  2,
                 4,  5,  6,  //背面
                 6,  5,  7,
                 8,  9, 10,  //上面
                 8, 11,  9,
                12, 13, 14,  //下面
                12, 14, 15,
                16, 13, 17,  //左面
                10, 13, 16,
                18, 19, 14,  //右面
                 9, 18, 14 };

            //インデックスバッファ
            indexBuffer = new IndexBuffer(graphics.GraphicsDevice,
                sizeof(short) * cubeIndices.Length,
                BufferUsage.None,
                IndexElementSize.SixteenBits);
            indexBuffer.SetData<short>(cubeIndices);
        }

        //初期化
        protected override void Initialize() {
            base.Initialize();
        }

        //グラフィクスコンテントの読み込み
        protected override void LoadContent() {
            InitializeTransform();
            InitializeEffect();
            InitializeCube();
        }

        //グラフィクスコンテントの解放
        protected override void UnloadContent() {
        }

        //更新
        protected override void Update(GameTime gameTime) {
            //ベースの更新
            base.Update(gameTime);
        }

        //描画
        protected override void Draw(GameTime gameTime) {
            //画面のクリア
            graphics.GraphicsDevice.Clear(Color.CornflowerBlue);

            //カリングモードの指定
            graphics.GraphicsDevice.RenderState.CullMode =
                CullMode.CullClockwiseFace;

            //頂点定義の指定
            graphics.GraphicsDevice.VertexDeclaration = cubeVertexDec;

            //頂点バッファの指定
            graphics.GraphicsDevice.Vertices[0].SetSource(
                vertexBuffer,
                0,
                VertexPositionTexture.SizeInBytes);

            //インデックスバッファの指定
            graphics.GraphicsDevice.Indices = indexBuffer;

            //立方体の描画
            effect.Begin();
            foreach (EffectPass pass in effect.CurrentTechnique.Passes) {
                pass.Begin();
                graphics.GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList,
                    0,
                    0,
                    cubeVertices.Length,
                    0,
                    12);
                pass.End();
            }
            effect.End();

            //ベースの描画
            base.Draw(gameTime);
        }    
    }
}


テクスチャを暗くする


エフェクトの一部を書き換えてテクスチャを暗くしてみる。



変更点
ピクセルシェーダの処理の戻り値に0.5fを掛けて明るさを半分にする。
float4 PS_TextureTech(VS_OUTPUT Out) : COLOR {
    return 0.5f*tex2D(textureSampler,Out.texcoord).rgba;
}


テクスチャを補色にする


エフェクトの一部を書き換えてテクスチャを補色(色相環で対抗位置にある色)にしてみる。



変更点
ピクセルシェーダの処理の戻り値を「1.0f-テクスチャ色」にする。
float4 PS_TextureTech(VS_OUTPUT Out) : COLOR {
    return 1.0f-tex2D(textureSampler,Out.texcoord).rgba;
}


テクスチャの赤色成分を消す


エフェクトの一部を書き換えてテクスチャの赤色成分を消してみる(赤のマスキング)。



変更点
ピクセルシェーダの処理の戻り値の赤成分(r)に0を指定する。
float4 PS_TextureTech(VS_OUTPUT Out) : COLOR {
    float4 col=tex2D(textureSampler,Out.texcoord).rgba;
    col.r=0.0f;
    return col;
}


テクスチャを赤色成分のみにする


エフェクトの一部を書き換えてテクスチャを赤色成分のみしてみる。



変更点
ピクセルシェーダの処理の戻り値の緑成分(g)、青成分(b)、α成分(a)をに0を指定する。
float4 PS_TextureTech(VS_OUTPUT Out) : COLOR {
    float4 col=tex2D(textureSampler,Out.texcoord).rgba;
    col.gba=0.0f;
    return col;
}


テクスチャの一部だけ赤くする


エフェクトの一部を書き換えてテクスチャの一部だけ赤くしてみる。



変更点
ピクセルシェーダの処理の戻り値をx座標とy座標が0.1以下の時に赤くしている。
float4 PS_TextureTech(VS_OUTPUT Out) : COLOR {
    float4 col=tex2D(textureSampler,Out.texcoord).rgba;
    if (Out.texcoord.x<=0.5f && Out.texcoord.y<=0.5f) col.gba=0.0f;
    return col;
}




−戻る−