본문 바로가기
프로그래밍

3D프리미티브 표시하기

by 건우아빠유리남편 2009. 7. 14.
반응형

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

        }

    }

}


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

'프로그래밍' 카테고리의 다른 글

텍스쳐를 붙인 3D프리미티브 표시하기  (0) 2009.07.14
ViewingPipeline  (0) 2009.07.14
커스텀쉐이더 이용하기  (0) 2009.07.14
3D모델 조작하기  (0) 2009.07.14
간단한 버튼이나 메뉴 키이벤트 처리 방법  (0) 2009.07.14

댓글