SlimDX Tutorial 6 - 텍스쳐

텍스쳐매핑하는 튜토리얼입니다.

폴더내에 텍스쳐파일을 넣어주어야 실행시 에러가 발생하지 않습니다.

#include <Windows.h>

using namespace System;
using namespace System::Windows::Forms;
using namespace System::Drawing;
using namespace SlimDX;
using namespace SlimDX::Direct3D9;


struct TextureVertex
{
 Vector3 positon;    
 int color;
 float tu, tv;
};

public ref class WndForm : public Form
{   
 Direct3D^ direct3D;
 PresentParameters^ presentParams;   
 Device^ device;

 VertexBuffer^ vertexBuffer;
 Texture^ texture;   

public:
 String^ lastError;

 WndForm(void)
 {   
  this->ClientSize = System::Drawing::Size(400, 300);
  this->StartPosition = FormStartPosition::CenterScreen;
  this->Text = "D3D Tutorial 6";
 }

 ~WndForm()
 {
  this->!WndForm();
 }

 !WndForm()
 {
  Release();
 }

 void Release()
 {
  if (vertexBuffer)
   delete vertexBuffer;
  
  if (texture)
   delete texture;

  if (direct3D)
   delete direct3D;
  if (device)
   delete device;
 }

 bool InitD3D()
 {
  try {
   // 환경변수 세팅
   direct3D = gcnew Direct3D();
   presentParams = gcnew PresentParameters();
   presentParams->Windowed = true;
   presentParams->SwapEffect = SwapEffect::Discard;
   presentParams->BackBufferFormat = Format::Unknown;
   presentParams->EnableAutoDepthStencil = true;
   presentParams->AutoDepthStencilFormat = Format::D16;

   // 디바이스 생성
   device = gcnew Device(direct3D, 0, DeviceType::Hardware, this->Handle, CreateFlags::SoftwareVertexProcessing, presentParams);
   // 디바이스 세팅
   device->SetRenderState(RenderState::CullMode, Cull::None);
   device->SetRenderState(RenderState::ZEnable, true);
   device->SetRenderState(RenderState::Lighting, false);

   // 텍스쳐 생성
   texture = Texture::FromFile(device, "tiger.bmp");
   if (!texture) {
    lastError = "texture not found";
    return false;
   }
   device->SetTexture(0, texture);
   device->SetTextureStageState(0, TextureStage::ColorOperation, TextureOperation::Modulate);
   device->SetTextureStageState(0, TextureStage::ColorArg1, TextureArgument::Texture);
   device->SetTextureStageState(0, TextureStage::ColorArg2, TextureArgument::Diffuse);
   device->SetTextureStageState(0, TextureStage::AlphaOperation, TextureOperation::Disable);

   // 버퍼 생성            
   vertexBuffer = gcnew VertexBuffer(device, 100 * sizeof(TextureVertex), Usage::WriteOnly, VertexFormat::Position | VertexFormat::Diffuse | VertexFormat::Texture1, Pool::Default);

   DataStream^ stream = vertexBuffer->Lock(0, 0, LockFlags::None);
   IntPtr vptr = stream->DataPointer;          
   TextureVertex *vert = (TextureVertex *)vptr.ToPointer();
   for (int i = 0; i < 50; i++) {
    float theta = (float)(2 * Math::PI * i) / (50 - 1);
    vert[2 * i].positon = Vector3((float)Math::Sin(theta), -1.0f, (float)Math::Cos(theta));
    vert[2 * i].color = 0xffffffff;
    vert[2 * i].tu = ((float)i) / (50 - 1);
    vert[2 * i].tv = 1.0f;
    vert[2 * i + 1].positon = Vector3((float)Math::Sin(theta), 1.0f, (float)Math::Cos(theta));
    vert[2 * i + 1].color = 0xff808080;
    vert[2 * i + 1].tu = ((float)i) / (50 - 1);
    vert[2 * i + 1].tv = 0.0f;
   }                       
   vertexBuffer->Unlock();
   return true;
  }
  catch (Direct3D9Exception^ ex) {
   lastError = ex->ToString();
   return false;
  }
 }

 void SetupMatrix()
 {
  device->SetTransform(TransformState::World, Matrix::RotationAxis(Vector3((float)Math::Cos(Environment::TickCount / 250.0f), 1, (float)Math::Sin(Environment::TickCount / 250.0f)), Environment::TickCount / 1000.0f));
  device->SetTransform(TransformState::View, Matrix::LookAtLH(Vector3(0.0f, 3.0f, -5.0f), Vector3(0.0f, 0.0f, 0.0f), Vector3(0.0f, 1.0f, 0.0f)));
  device->SetTransform(TransformState::Projection, Matrix::PerspectiveFovLH((float)Math::PI / 4, 1.0f, 1.0f, 100.0f));        
 }

 void Render()
 {
  if (!device)
   return;

  // 렌더링 시작
  device->Clear(ClearFlags::Target | ClearFlags::ZBuffer, System::Drawing::Color::Black, 1.0f, 0);
  device->BeginScene();

  SetupMatrix();

  // 렌더링       
  device->SetStreamSource(0, vertexBuffer, 0, sizeof(TextureVertex));     
  device->VertexFormat = VertexFormat::Position | VertexFormat::Diffuse | VertexFormat::Texture1;
  device->DrawPrimitives(PrimitiveType::TriangleStrip, 0, (4*25)-2);

  // 렌더링 끝
  device->EndScene();
  device->Present();
 }   
};

INT WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, INT)
{   
 WndForm^ frm = gcnew WndForm();

 if (!frm->InitD3D()) {
  MessageBox::Show(frm->lastError);
  delete frm;
  return 0; 
 }

 frm->Show();

 while (frm->Created) {
  frm->Render();
  Application::DoEvents();
 }

 if (frm)
  delete frm;
 
 return 0;
}

0 개의 댓글:

댓글 쓰기