프로그래밍

3D프리미티브 표시하기

건우아빠유리남편 2009. 7. 14. 13:09
반응형

3D프리미티브를 보여주는 프로그램을 작성한다.

 

리소스 추가

이번 프로그램에서는 이펙트파일을 하나 프로젝트에 추가하여 사용합니다.

이펙트파일에 대해서는 다음에 다시 알려드리겠습니다.

 

SimpleEffect.fx

float4x4 worldViewProj : WORLDVIEWPROJECTION;

 

struct VS_INPUT {

    float4 pos   : POSITION;

    float4 color : COLOR0;

};

 

struct VS_OUTPUT {

    float4 pos   : POSITION;

    float4 color : COLOR0;

};

 

VS_OUTPUT VS_TransformTec(VS_INPUT In) {

 

    VS_OUTPUT Out=(VS_OUTPUT)0;

 

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

    Out.color=In.color;

 

    return Out;

}

 

float4 PS_TransformTec(VS_OUTPUT Out) : COLOR {

    return Out.color;

}

 

technique TransformTec {

    pass P0 {

        vertexShader=compile vs_2_0 VS_TransformTec();

        pixelShader =compile ps_1_1 PS_TransformTec();

    }

}

이펙트 일에 주석을 달면 컴파일에러가

 

float4x4 worldViewProj : WORLDVIEWPROJECTION;

월드xx사영행렬

struct VS_INPUT

정점쉐이더입력구조체

struct VS_OUTPUT

정점쉐이더출력구조체

VS_OUTPUT VS_TransformTec(VS_INPUT In)

정점쉐이더를 처리해주는 함수

float4 PS_TransformTec(VS_OUTPUT Out) : COLOR

픽셀쉐이더를 처리해주는 함수

technique TransformTec

테크닉 (메인함수와 비슷합니다.)

 

소스코드 편집

Game1.cs를 편집합니다.


Game1.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 PrimitiveEx {

    public class Game1 : Game {

        //시스템

        private GraphicsDeviceManager graphics;

        private ContentManager        content;  

 

        //3D프리미티브

        private Matrix           worldViewProj; //월드xx사영행렬

        private Effect                effect;       //이펙트

        private VertexDeclaration     cubeVertexDec; //정점정의

        private VertexPositionColor[] cubeVertices; //정점s

        private VertexBuffer          vertexBuffer; //정점버퍼

        private short[]               cubeIndices;  //인덱스리스트

        private IndexBuffer           indexBuffer;  //인덱스버퍼

 

        //constructor

        public Game1() {

            graphics = new GraphicsDeviceManager(this);

            content  = new ContentManager(Services);

        }

 

        //좌표변환 초기화

        private void InitializeTransform() {

            //월드 매트릭스

            Matrix world =

                Matrix.CreateRotationX((float)Math.PI / 6.0f) * //X30도회전

                Matrix.CreateRotationY((float)Math.PI / 6.0f);  //Y30도회전

 

            //뷰 매트릭스

            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);              //파 클립면의 거리

 

            //월드xx사영 매트릭스

            worldViewProj = world * view * projection;

        }

 

        //이펙트 읽어오기

        private void InitializeEffect() {

            effect = content.Load<Effect>("SimpleEffect");              //이펙트 파일

            effect.Parameters["worldViewProj"].SetValue(worldViewProj); //이어주기

            effect.CurrentTechnique = effect.Techniques["TransformTec"]; //테크닉

        }

 

        //입방체 초기화

        private void InitializeCube() {

            //입방체 정점정의

            cubeVertexDec = new VertexDeclaration(

                graphics.GraphicsDevice,            //그래픽스 디바이스

                VertexPositionColor.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);

 

            //입방체 정점

            cubeVertices = new VertexPositionColor[24];

 

            //정면

            cubeVertices[0] = new VertexPositionColor(topLeftFront,    Color.Red);

            cubeVertices[1] = new VertexPositionColor(bottomLeftFront, Color.Red);

            cubeVertices[2] = new VertexPositionColor(topRightFront,   Color.Red);

            cubeVertices[3] = new VertexPositionColor(bottomRightFront,Color.Red);

 

            //뒷면

            cubeVertices[4] = new VertexPositionColor(topLeftBack,    Color.Orange);

            cubeVertices[5] = new VertexPositionColor(topRightBack,   Color.Orange);

            cubeVertices[6] = new VertexPositionColor(bottomLeftBack, Color.Orange);

            cubeVertices[7] = new VertexPositionColor(bottomRightBack,Color.Orange);

 

            //윗면

            cubeVertices[8]  = new VertexPositionColor(topLeftFront,  Color.Yellow);

            cubeVertices[9]  = new VertexPositionColor(topRightBack,  Color.Yellow);

            cubeVertices[10] = new VertexPositionColor(topLeftBack,   Color.Yellow);

            cubeVertices[11] = new VertexPositionColor(topRightFront, Color.Yellow);

 

            //아랫면

            cubeVertices[12] = new VertexPositionColor(bottomLeftFront, Color.Purple);

            cubeVertices[13] = new VertexPositionColor(bottomLeftBack,  Color.Purple);

            cubeVertices[14] = new VertexPositionColor(bottomRightBack, Color.Purple);

            cubeVertices[15] = new VertexPositionColor(bottomRightFront,Color.Purple);

 

            //왼쪽면

            cubeVertices[16] = new VertexPositionColor(topLeftFront,   Color.Blue);

            cubeVertices[17] = new VertexPositionColor(bottomLeftBack, Color.Blue);

            cubeVertices[18] = new VertexPositionColor(bottomLeftFront,Color.Blue);

            cubeVertices[19] = new VertexPositionColor(topLeftBack,    Color.Blue);

 

            //오른쪽 면

            cubeVertices[20] = new VertexPositionColor(topRightFront,   Color.Green);

            cubeVertices[21] = new VertexPositionColor(bottomRightFront,Color.Green);

            cubeVertices[22] = new VertexPositionColor(bottomRightBack, Color.Green);

            cubeVertices[23] = new VertexPositionColor(topRightBack,    Color.Green);

 

            //인덱스 리스트

            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, 17, 18, //청색 왼쪽면

                19, 17, 16,

                20, 21, 22, //녹색 오른쪽면

                23, 20, 22};

 

            //정점 버퍼

            vertexBuffer = new VertexBuffer(

                graphics.GraphicsDevice,

                cubeVertices.Length * VertexPositionColor.SizeInBytes,

                ResourceUsage.None,

                ResourceManagementMode.Automatic);

            vertexBuffer.SetData<VertexPositionColor>(cubeVertices);

 

            //인덱스 버퍼

            indexBuffer = new IndexBuffer(graphics.GraphicsDevice,

                sizeof(short) * cubeIndices.Length,

                ResourceUsage.None,

                ResourceManagementMode.Automatic,

                IndexElementSize.SixteenBits);

            indexBuffer.SetData<short>(cubeIndices);

        }

 

        //그래픽 로드

        protected override void LoadGraphicsContent(bool loadAllContent) {

            InitializeTransform();

            if (loadAllContent) {

                InitializeEffect();

                InitializeCube();

            }

        }

 

        //그래픽 언로드

        protected override void UnloadGraphicsContent(bool unloadAllContent) {

            if (unloadAllContent == true) {

                content.Unload();

            }

        }

 

        //그리기

        protected override void Draw(GameTime gameTime) {

            //클리어

            graphics.GraphicsDevice.Clear(Color.White);

 

            //Cull모드 지정

            graphics.GraphicsDevice.RenderState.CullMode =

                CullMode.CullClockwiseFace;

 

            //정점정의

            graphics.GraphicsDevice.VertexDeclaration = cubeVertexDec;

 

            //정점버퍼지정

            graphics.GraphicsDevice.Vertices[0].SetSource(

                vertexBuffer, 0, VertexPositionColor.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);

        }

    }

}


프리미티브란 기본도형을 말함
반응형