커스텀쉐이더를 이용하여 3D모델을 표시하는 프로그램을 만든다.
리소스 추가
이번 프로그램에서는 3D모델 하나와 텍스쳐 한 장과 효과 하나를 사용합니다.
모델과 텍스쳐는 XNA Creators Club 에서 가지고 왔습니다.
폴더구성은 다음과 같습니다.
효과파일 편집
TextureEffect.fx를 편집한다.
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(); } } |
소스코드 편집
Game1.cs를 편집한다.
Game1.cs
using System; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using Microsoft.Xna.Framework.Audio; //커스텀 쉐이더 이용하기 namespace CustomShaderEx { public class Game1 : Microsoft.Xna.Framework.Game { //그래픽스 private GraphicsDeviceManager graphics; //그래픽스 private ContentManager content; //컨텐츠 //모델 private Model model; //모델 private Vector3 modelPos = Vector3.Zero; //모델 위치 private float modelRot = 0.0f; //모델 회전 //텍스쳐 private Texture texture; //텍스쳐 //이펙트 private Effect effect; //이펙트 private EffectParameter worldViewProjParam; //변환행렬 //카메라 private float aspectRatio; //종횡도 private Vector3 cameraPos; //카메라위치 //constructor public Game1() { //그래픽스 graphics = new GraphicsDeviceManager(this); content = new ContentManager(Services); //화면사이즈 graphics.PreferredBackBufferWidth = 853; graphics.PreferredBackBufferHeight = 480; } //초기화 protected override void Initialize() { base.Initialize(); } //그래픽스 컨텐츠의 로드 protected override void LoadGraphicsContent(bool loadAllContent) { if (loadAllContent) { //모델 읽어오기 model = content.Load<Model>(@"Content\Models\p1_wedge"); //텍스쳐 읽어오기 texture = content.Load<Texture2D>(@"Content\Textures\wedge_p1_diff_v1"); //이펙트 불러오기 effect = content.Load<Effect>(@"Content\Shaders\TextureEffect"); effect.CurrentTechnique = effect.Techniques["TextureTeck"]; worldViewProjParam = effect.Parameters["worldViewProj"]; //텍스쳐에 이펙트 주기 effect.Parameters["UserTexture"].SetValue(texture); //모델에 이펙트 주기 foreach (ModelMesh mesh in model.Meshes) { for(int i = 0;i < mesh.MeshParts.Count;i++) { mesh.MeshParts[i].Effect = effect; } } } //카메라 초기화 aspectRatio = (float)graphics.GraphicsDevice.Viewport.Width / graphics.GraphicsDevice.Viewport.Height; //종횡도 cameraPos = new Vector3(0.0f, 50.0f, 5000.0f); //카메라 } //그래픽스 컨텐츠 놓기 protected override void UnloadGraphicsContent(bool unloadAllContent) { if (unloadAllContent) content.Unload(); } //업뎃 protected override void Update(GameTime gameTime) { //어플리케이션 종료 if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) { this.Exit(); } //모델 회전 modelRot += (float)gameTime.ElapsedGameTime.TotalMilliseconds * MathHelper.ToRadians(0.1f); //베이스 업뎃 base.Update(gameTime); } //그리기 protected override void Draw(GameTime gameTime) { //배경 그리기 graphics.GraphicsDevice.Clear(Color.CornflowerBlue); //월드 매트릭스 Matrix world = Matrix.CreateRotationY(modelRot) * //모델 회전 Matrix.CreateTranslation(modelPos); //모델 위치 //뷰 매트릭스 Matrix view = Matrix.CreateLookAt( cameraPos, //카메라위치 Vector3.Zero, //참조점 Vector3.Up); //UP레벨 //사영 변환행렬 Matrix projection = Matrix.CreatePerspectiveFieldOfView( MathHelper.ToRadians(45.0f), //시야각(라디안단위) aspectRatio, //종횡도 1.0f, //니어 클립면의 거리 10000.0f); //파 클립면의 거리 //효과 커밋 체인지 effect.CommitChanges(); //월드x뷰x사영 매트릭스 worldViewProjParam.SetValue(world * view * projection); //모델 그리기 foreach (ModelMesh mesh in model.Meshes) { mesh.Draw(); } //베이스 그리기 base.Draw(gameTime); } } } |
'프로그래밍' 카테고리의 다른 글
ViewingPipeline (0) | 2009.07.14 |
---|---|
3D프리미티브 표시하기 (0) | 2009.07.14 |
3D모델 조작하기 (0) | 2009.07.14 |
간단한 버튼이나 메뉴 키이벤트 처리 방법 (0) | 2009.07.14 |
How To XNA : 2. 비어있는 게임 화면과 구조 (0) | 2009.07.14 |
댓글