スタティックメッシュ:OBJ

「スタティックメッシュ:OBJ」の編集履歴(バックアップ)一覧はこちら

スタティックメッシュ:OBJ」(2011/03/11 (金) 21:31:10) の最新版変更点

追加された行は緑色になります。

削除された行は赤色になります。

<p><strong>OBJファイルを読み込んで表示します。</strong></p> <p><a href="http://neo-arcadia.seesaa.net/"><strong>http://neo-arcadia.seesaa.net/</strong></a><strong><br /> こちらからモデルを借りてきて表示しています。</strong></p> <p><strong><img alt="" src="http://www43.atwiki.jp/directx11?cmd=upload&amp;act=open&amp;pageid=20&amp;file=obj.png" /></strong></p> <table border="1" cellspacing="1" cellpadding="1" width="600"><tbody><tr><td> <p>#pragma comment(lib,"d3d11.lib")<br /> #pragma comment(lib,"d3dx11.lib")<br /> #pragma comment(lib,"d3dx10.lib")<br /> #pragma comment(lib,"d3dCompiler.lib")<br /> #include &lt;stdio.h&gt;<br /> #include &lt;vector&gt;<br /> #include &lt;d3dx11.h&gt;<br /> #include &lt;d3dx10.h&gt;<br /> #include &lt;d3dCompiler.h&gt;</p> <p>#define FILE_NAME "axel.obj"</p> <p>using namespace std;</p> <p>//安全に解放する<br /> #define SAFE_RELEASE(x) if(x){x-&gt;Release(); x=NULL;}</p> <p>//定数定義<br /> #define WINDOW_WIDTH 320 //ウィンドウ幅<br /> #define WINDOW_HEIGHT 240 //ウィンドウ高さ</p> <p>//グローバル変数<br /> HWND hWnd=NULL;<br /> ID3D11Device* Device = NULL;      //デバイス<br /> ID3D11DeviceContext* DeviceContext=NULL;   //デバイスコンテキスト<br /> IDXGISwapChain* SwapChain = NULL;     //スワップチェイン<br /> ID3D11RenderTargetView* RenderTargetView = NULL; //レンダーターゲットビュー<br /> ID3D11DepthStencilView* DepthStencilView = NULL;<br /> ID3D11Texture2D*  DepthStencil = NULL;<br /> ID3D11InputLayout* VertexLayout=NULL;</p> <p>ID3D11VertexShader* VertexShader=NULL;//頂点シェーダー<br /> ID3D11PixelShader* PixelShader=NULL;//ピクセルシェーダー</p> <p>ID3D11Buffer* ConstantBuffer[2];//コンスタントバッファ</p> <p>D3DXVECTOR3 LightDir(1,1,-1);//ライト方向</p> <p>ID3D11SamplerState* SampleLinear=NULL;//テクスチャーのサンプラー<br /> ID3D11ShaderResourceView* Texture=NULL;//テクスチャー</p> <p>//シェーダーに渡す値<br /> struct SHADER_GLOBAL0<br /> {<br />  D3DXMATRIX mW;//ワールド行列<br />  D3DXMATRIX mWVP;//ワールドから射影までの変換行列<br />  D3DXVECTOR4 vLightDir;//ライト方向<br />  D3DXVECTOR4 vEye;//カメラ位置<br /> };<br /> struct SHADER_GLOBAL1<br /> {<br />  D3DXVECTOR4 vAmbient;//アンビエント<br />  D3DXVECTOR4 vDiffuse;//ディフューズ<br />  D3DXVECTOR4 vSpecular;//鏡面反射<br /> };</p> <p>//マテリアル構造体<br /> struct MATERIAL<br /> {<br />  CHAR Name[255];<br />  D3DXVECTOR4 Ka;//アンビエント<br />  D3DXVECTOR4 Kd;//ディフューズ<br />  D3DXVECTOR4 Ks;//スペキュラー<br />  CHAR TextureName[255];//テクスチャファイル名<br />  ID3D11ShaderResourceView* pTexture;//テクスチャデータ<br />  DWORD MaxFace;//ポリゴン数<br /> }mat;</p> <p>//頂点構造体<br /> struct VERTEX<br /> {<br />  D3DXVECTOR3 Pos;//位置<br />  D3DXVECTOR3 Normal;//法線<br />  D3DXVECTOR2 UV;//UV<br /> }vert;</p> <p>//.OBJファイルクラス<br /> class OBJ{<br /> protected:<br />  vector &lt;MATERIAL&gt; Material;//マテリアル<br />  vector &lt;VERTEX&gt; Vertex;//頂点構造体<br />  ID3D11Buffer* VertexBuffer;//頂点バッファ<br />  ID3D11Buffer** IndexBuffer;//インデックスバッファ<br />  HRESULT LoadMaterialFromFile(LPSTR FileName);//マテリアルファイル読み込み<br /> public:<br />  void Draw();//描画<br />  HRESULT Load(LPSTR FileName);//読み込み<br /> };</p> <p>OBJ obj;</p> <p>//メッシュの描画<br /> void OBJ::Draw()<br /> {<br />  //バーテックスバッファをセット<br />  UINT stride = sizeof( VERTEX );<br />  UINT offset = 0;<br />  DeviceContext-&gt;IASetVertexBuffers( 0, 1, &amp;VertexBuffer, &amp;stride, &amp;offset );<br />  //マテリアルの数だけ、それぞれのマテリアルのインデックスバッファを描画<br />  for(DWORD i=0;i&lt;Material.size();i++)<br />  {<br />   //使用されていないマテリアル対策<br />   if(Material[i].MaxFace==0)<br />   {<br />    continue;<br />   }<br />   //インデックスバッファをセット<br />   DeviceContext-&gt;IASetIndexBuffer(IndexBuffer[i], DXGI_FORMAT_R32_UINT, 0 );<br />   //プリミティブ・トポロジーをセット<br />   DeviceContext-&gt;IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST );<br />   //マテリアルの各要素をシェーダーに渡す<br />   D3D11_MAPPED_SUBRESOURCE pData;<br />   if( SUCCEEDED( DeviceContext-&gt;Map( ConstantBuffer[1],0, D3D11_MAP_WRITE_DISCARD, 0, &amp;pData ) ) )<br />   {<br />    SHADER_GLOBAL1 sg;   <br />    sg.vAmbient=Material[i].Ka;<br />    sg.vDiffuse=Material[i].Kd;<br />    sg.vSpecular=Material[i].Ks;<br />    memcpy_s( pData.pData, pData.RowPitch, (void*)&amp;sg, sizeof( SHADER_GLOBAL1 ) );<br />    DeviceContext-&gt;Unmap( ConstantBuffer[1], 0 );<br />   }<br />   DeviceContext-&gt;VSSetConstantBuffers(1,1,&amp;ConstantBuffer[1] );<br />   DeviceContext-&gt;PSSetConstantBuffers(1,1,&amp;ConstantBuffer[1] );<br />   //テクスチャをシェーダーに渡す<br />   if(Material[i].TextureName[0] != NULL)<br />   {<br />    DeviceContext-&gt;PSSetSamplers(0,1,&amp;SampleLinear);<br />    DeviceContext-&gt;PSSetShaderResources(0,1,&amp;Material[i].pTexture);<br />   }<br />   DeviceContext-&gt;DrawIndexed(Material[i].MaxFace*3 , 0 ,0);<br />  }<br /> }</p> <p>//マテリアルファイルを読み込む関数<br /> HRESULT OBJ::LoadMaterialFromFile(LPSTR FileName)<br /> {<br />  FILE* fp=NULL;<br />  fopen_s(&amp;fp,FileName,"rt");<br />  char key[255]={0};<br />  bool flag=false;<br />  D3DXVECTOR4 v(0,0,0,0);<br />  <br />  fseek(fp,SEEK_SET,0);</p> <p> while(!feof(fp))<br />  {<br />   //キーワード読み込み<br />   fscanf_s(fp,"%s ",key,sizeof(key));<br />   //マテリアル名<br />   if(strcmp(key,"newmtl")==0)<br />   {<br />    if(flag)Material.push_back(mat);<br />    flag=true;<br />    fscanf_s(fp,"%s ",key,sizeof(key));<br />    strcpy_s(mat.Name,key);<br />   }<br />   //Ka アンビエント<br />   if(strcmp(key,"Ka")==0)<br />   {<br />    fscanf_s(fp,"%f %f %f",&amp;v.x,&amp;v.y,&amp;v.z);<br />    mat.Ka=v;<br />   }<br />   //Kd ディフューズ<br />   if(strcmp(key,"Kd")==0)<br />   {<br />    fscanf_s(fp,"%f %f %f",&amp;v.x,&amp;v.y,&amp;v.z);<br />    mat.Kd=v;<br />   }<br />   //Ks スペキュラー<br />   if(strcmp(key,"Ks")==0)<br />   {<br />    fscanf_s(fp,"%f %f %f",&amp;v.x,&amp;v.y,&amp;v.z);<br />    mat.Ks=v;<br />   }<br />   //map_Kd テクスチャ<br />   if(strcmp(key,"map_Kd")==0)<br />   {<br />    fscanf_s(fp,"%s",&amp;mat.TextureName,sizeof(mat.TextureName));<br />    //テクスチャを作成<br />    if(FAILED(D3DX11CreateShaderResourceViewFromFileA( Device, mat.TextureName, NULL, NULL, &amp;mat.pTexture, NULL )))<br />    {<br />     return E_FAIL;<br />    }<br />   }<br />  }<br />  fclose(fp);<br />  if(flag)Material.push_back(mat);<br />  <br />  return S_OK;<br /> }</p> <p>//OBJファイルからメッシュに必要な情報を読み込む<br /> HRESULT OBJ::Load(LPSTR FileName)<br /> {<br />  //一時代入用<br />  D3DXVECTOR3 vec3d;<br />  D3DXVECTOR2 vec2d;<br />  vector &lt;D3DXVECTOR3&gt; Pos;<br />  vector &lt;D3DXVECTOR3&gt; Normal;<br />  vector &lt;D3DXVECTOR2&gt; UV;<br />  vector &lt;int&gt; FaceIndex;<br />  int v1=0,v2=0,v3=0;<br />  int vn1=0,vn2=0,vn3=0;<br />  int vt1=0,vt2=0,vt3=0;<br />  DWORD dwFCount=0;//読み込みカウンタ</p> <p> char key[255]={0};<br />  //OBJファイルを開いて内容を読み込む<br />  FILE* fp=NULL;<br />  fopen_s(&amp;fp,FileName,"rt");<br />  <br />  //読み込み <br />  fseek(fp,SEEK_SET,0);</p> <p> while(!feof(fp))<br />  {<br />   //キーワード<br />   ZeroMemory(key,sizeof(key));<br />   fscanf_s(fp,"%s ",key,sizeof(key)); <br />   //マテリアル<br />   if(strcmp(key,"mtllib")==0)<br />   {<br />    fscanf_s(fp,"%s ",key,sizeof(key));<br />    LoadMaterialFromFile(key);<br />   }<br />   //頂点<br />   if(strcmp(key,"v")==0)<br />   {<br />    fscanf_s(fp,"%f %f %f",&amp;vec3d.x,&amp;vec3d.y,&amp;vec3d.z);<br />    Pos.push_back(vec3d);<br />    Vertex.push_back(vert);<br />   }<br />   //法線<br />   if(strcmp(key,"vn")==0)<br />   {  <br />    fscanf_s(fp,"%f %f %f",&amp;vec3d.x,&amp;vec3d.y,&amp;vec3d.z);<br />    Normal.push_back(vec3d);<br />   }<br />   //テクスチャ<br />   if(strcmp(key,"vt")==0)<br />   {  <br />    fscanf_s(fp,"%f %f",&amp;vec2d.x,&amp;vec2d.y);<br />    UV.push_back(-vec2d);<br />   }<br />   //フェイス<br />   if(strcmp(key,"f")==0)<br />   {<br />    FaceIndex.push_back(0);<br />   }<br />  } </p> <p> //マテリアルの数だけインデックスバッファを作成<br />  IndexBuffer=new ID3D11Buffer*[Material.size()];</p> <p> bool boFlag=false;<br />  for(DWORD i=0;i&lt;Material.size();i++)<br />  {  <br />   fseek(fp,SEEK_SET,0);<br />   dwFCount=0;</p> <p>  while(!feof(fp))<br />   {<br />    //キーワード<br />    ZeroMemory(key,sizeof(key));<br />    fscanf_s(fp,"%s ",key,sizeof(key));</p> <p>   //フェイス 読み込み→頂点インデックスに<br />    if(strcmp(key,"usemtl")==0)<br />    {<br />     fscanf_s(fp,"%s ",key,sizeof(key));<br />     if(strcmp(key,Material[i].Name)==0)<br />     {<br />      boFlag=true;<br />     }<br />     else<br />     {<br />       boFlag=false;<br />     }<br />    }<br />    if(strcmp(key,"f")==0 &amp;&amp; boFlag==true)<br />    {<br />     if(Material[i].pTexture!=NULL)//テクスチャーありサーフェイス<br />     {<br />      fscanf_s(fp,"%d/%d/%d %d/%d/%d %d/%d/%d",&amp;v1,&amp;vt1,&amp;vn1,&amp;v2,&amp;vt2,&amp;vn2,&amp;v3,&amp;vt3,&amp;vn3);<br />     }<br />     else//テクスチャー無しサーフェイス<br />     {<br />      fscanf_s(fp,"%d//%d %d//%d %d//%d",&amp;v1,&amp;vn1,&amp;v2,&amp;vn2,&amp;v3,&amp;vn3);<br />     }<br />     FaceIndex[dwFCount*3]=v1-1;<br />     FaceIndex[dwFCount*3+1]=v2-1;<br />     FaceIndex[dwFCount*3+2]=v3-1;<br />     dwFCount++;<br />     //頂点構造体に代入<br />     Vertex[v1-1].Pos=Pos[v1-1];<br />     Vertex[v1-1].Normal=Normal[vn1-1];<br />     Vertex[v1-1].UV=UV[vt1-1];<br />     Vertex[v2-1].Pos=Pos[v2-1];<br />     Vertex[v2-1].Normal=Normal[vn2-1];<br />     Vertex[v2-1].UV=UV[vt2-1];<br />     Vertex[v3-1].Pos=Pos[v3-1];<br />     Vertex[v3-1].Normal=Normal[vn3-1];<br />     Vertex[v3-1].UV=UV[vt3-1];<br />    }<br />   }<br />   if(dwFCount==0)//使用されていないマテリアル対策<br />   {<br />    IndexBuffer[i]=NULL;<br />    continue;<br />   }</p> <p>  //インデックスバッファを作成<br />   D3D11_BUFFER_DESC bd;<br />   bd.Usage = D3D11_USAGE_DEFAULT;<br />   bd.ByteWidth = sizeof( int ) * dwFCount * 3;<br />   bd.BindFlags = D3D11_BIND_INDEX_BUFFER;<br />   bd.CPUAccessFlags = 0;<br />   bd.MiscFlags = 0;<br />   D3D11_SUBRESOURCE_DATA InitData;<br />   InitData.pSysMem = &amp;FaceIndex[0];<br />   InitData.SysMemPitch=0;<br />   InitData.SysMemSlicePitch=0;<br />   if( FAILED( Device-&gt;CreateBuffer( &amp;bd, &amp;InitData, &amp;IndexBuffer[i] ) ) )return FALSE;<br />   Material[i].MaxFace=dwFCount;  <br />  }<br />  FaceIndex.clear();<br />  fclose(fp);</p> <p> //バーテックスバッファを作成<br />  D3D11_BUFFER_DESC bd;<br />  bd.Usage = D3D11_USAGE_DEFAULT;<br />  bd.ByteWidth = sizeof( VERTEX ) *Vertex.size();<br />  bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;<br />  bd.CPUAccessFlags = 0;<br />  bd.MiscFlags = 0;<br />  D3D11_SUBRESOURCE_DATA InitData;<br />  InitData.pSysMem = &amp;Vertex[0];<br />  if( FAILED( Device-&gt;CreateBuffer( &amp;bd, &amp;InitData, &amp;VertexBuffer ) ) )return FALSE; </p> <p><br />  Pos.clear();<br />  Normal.clear();<br />  UV.clear();<br />  Vertex.clear(); </p> <p> return S_OK;<br /> }</p> <p>//Direct3Dの初期化関数<br /> HRESULT InitD3D(HWND hWnd)<br /> {<br />  // デバイスとスワップチェーンの作成<br />  DXGI_SWAP_CHAIN_DESC sd;<br />     ZeroMemory( &amp;sd, sizeof(sd) );<br />     sd.BufferCount = 1;         //バックバッファの数<br />     sd.BufferDesc.Width = WINDOW_WIDTH;     //バッファの幅<br />     sd.BufferDesc.Height = WINDOW_HEIGHT;    //バッファの高さ<br />     sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; //バッファのフォーマット<br />     sd.BufferDesc.RefreshRate.Numerator = 60;   //リフレッシュレート<br />     sd.BufferDesc.RefreshRate.Denominator = 1;<br />     sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;<br />     sd.OutputWindow = hWnd;<br />     sd.SampleDesc.Count = 1;<br />     sd.SampleDesc.Quality = 0;<br />     sd.Windowed = TRUE;</p> <p> D3D_FEATURE_LEVEL  FeatureLevel = D3D_FEATURE_LEVEL_11_0;<br />  D3D_FEATURE_LEVEL* pFeatureLevel = NULL;</p> <p><br />     if( FAILED( D3D11CreateDeviceAndSwapChain( NULL, D3D_DRIVER_TYPE_HARDWARE, NULL,0,<br />      &amp;FeatureLevel,1,D3D11_SDK_VERSION, &amp;sd, &amp;SwapChain, &amp;Device ,NULL,&amp;DeviceContext) ) )<br />     {<br />         return FALSE;<br />     }<br />  //レンダーターゲットビューの作成<br />  ID3D11Texture2D *BackBuffer;<br />     SwapChain-&gt;GetBuffer( 0, __uuidof( ID3D11Texture2D ),(LPVOID*)&amp;BackBuffer);   <br />     Device-&gt;CreateRenderTargetView( BackBuffer, NULL, &amp;RenderTargetView );<br />     SAFE_RELEASE(BackBuffer);<br />  //深度ステンシルビューの作成<br />     D3D11_TEXTURE2D_DESC descDepth;<br />     descDepth.Width = WINDOW_WIDTH;<br />     descDepth.Height = WINDOW_HEIGHT;<br />     descDepth.MipLevels = 1;<br />     descDepth.ArraySize = 1;<br />     descDepth.Format = DXGI_FORMAT_D32_FLOAT;<br />     descDepth.SampleDesc.Count = 1;<br />     descDepth.SampleDesc.Quality = 0;<br />     descDepth.Usage = D3D11_USAGE_DEFAULT;<br />     descDepth.BindFlags = D3D11_BIND_DEPTH_STENCIL;<br />     descDepth.CPUAccessFlags = 0;<br />     descDepth.MiscFlags = 0;<br />     Device-&gt;CreateTexture2D( &amp;descDepth, NULL, &amp;DepthStencil );</p> <p>    Device-&gt;CreateDepthStencilView( DepthStencil, NULL, &amp;DepthStencilView );<br />  //レンダーターゲットビューと深度ステンシルビューをパイプラインにバインド <br />  DeviceContext-&gt;OMSetRenderTargets(1, &amp;RenderTargetView,DepthStencilView);</p> <p> //ビューポートの設定<br />  D3D11_VIEWPORT vp;<br />     vp.Width = WINDOW_WIDTH;<br />     vp.Height = WINDOW_HEIGHT;<br />     vp.MinDepth = 0.0f;<br />     vp.MaxDepth = 1.0f;<br />     vp.TopLeftX = 0;<br />     vp.TopLeftY = 0;<br />     DeviceContext-&gt;RSSetViewports( 1, &amp;vp );</p> <p> //hlslファイル読み込み<br />  ID3DBlob *pCompiledShader=NULL;<br />  ID3DBlob *pErrors=NULL;<br />  //ブロブから頂点シェーダー作成<br />  if(FAILED(D3DX11CompileFromFile(L"shader.hlsl",NULL,NULL,"VS","vs_5_0",0,0,NULL,&amp;pCompiledShader,&amp;pErrors,NULL)))<br />  {<br />   MessageBox(0,L"頂点シェーダー読み込み失敗",NULL,MB_OK);<br />   return E_FAIL;<br />     }<br />  SAFE_RELEASE(pErrors);</p> <p>  if(FAILED(Device-&gt;CreateVertexShader(pCompiledShader-&gt;GetBufferPointer(),pCompiledShader-&gt;GetBufferSize(),NULL,&amp;VertexShader)))<br />  {<br />   SAFE_RELEASE(pCompiledShader);<br />   MessageBox(0,L"頂点シェーダー作成失敗",NULL,MB_OK);<br />   return E_FAIL;<br />  }<br />  //頂点インプットレイアウトを定義 <br />  D3D11_INPUT_ELEMENT_DESC layout[] =<br />  {<br />   { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },<br />   { "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },<br />   { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0 },<br />  };<br />  UINT numElements = sizeof(layout)/sizeof(layout[0]);</p> <p> //頂点インプットレイアウトを作成<br />  if( FAILED( Device-&gt;CreateInputLayout( layout, numElements, pCompiledShader-&gt;GetBufferPointer(), pCompiledShader-&gt;GetBufferSize(), &amp;VertexLayout ) ) )<br />   return FALSE;<br />  //頂点インプットレイアウトをセット<br />  DeviceContext-&gt;IASetInputLayout( VertexLayout );</p> <p> //ブロブからピクセルシェーダー作成<br />  if(FAILED(D3DX11CompileFromFile(L"shader.hlsl",NULL,NULL,"PS","ps_5_0",0,0,NULL,&amp;pCompiledShader,&amp;pErrors,NULL)))<br />  {<br />   MessageBox(0,L"ピクセルシェーダー読み込み失敗",NULL,MB_OK);<br />   return E_FAIL;<br />     }<br />  SAFE_RELEASE(pErrors);<br />  if(FAILED(Device-&gt;CreatePixelShader(pCompiledShader-&gt;GetBufferPointer(),pCompiledShader-&gt;GetBufferSize(),NULL,&amp;PixelShader)))<br />  {<br />   SAFE_RELEASE(pCompiledShader);<br />   MessageBox(0,L"ピクセルシェーダー作成失敗",NULL,MB_OK);<br />   return E_FAIL;<br />  }<br />  SAFE_RELEASE(pCompiledShader);</p> <p> //ラスタライズ設定<br />  D3D11_RASTERIZER_DESC rdc;<br />  ZeroMemory(&amp;rdc,sizeof(rdc));<br />  rdc.CullMode=D3D11_CULL_NONE;<br />  rdc.FillMode=D3D11_FILL_SOLID;<br />  <br />  ID3D11RasterizerState* pIr=NULL;<br />  Device-&gt;CreateRasterizerState(&amp;rdc,&amp;pIr);<br />  DeviceContext-&gt;RSSetState(pIr);<br />  SAFE_RELEASE(pIr);<br />  //コンスタントバッファー作成 ここでは変換行列渡し用<br />  D3D11_BUFFER_DESC cb;<br />  cb.BindFlags= D3D11_BIND_CONSTANT_BUFFER;<br />  cb.ByteWidth= sizeof( SHADER_GLOBAL0 );<br />  cb.CPUAccessFlags=D3D11_CPU_ACCESS_WRITE;<br />  cb.MiscFlags =0;<br />  cb.StructureByteStride=0;<br />  cb.Usage=D3D11_USAGE_DYNAMIC;</p> <p> if( FAILED(Device-&gt;CreateBuffer( &amp;cb,NULL,&amp;ConstantBuffer[0])))<br />  {<br />   return E_FAIL;<br />  }<br />  //コンスタントバッファー作成  マテリアル渡し用<br />  cb.BindFlags= D3D11_BIND_CONSTANT_BUFFER;<br />  cb.ByteWidth= sizeof( SHADER_GLOBAL1 );<br />  cb.CPUAccessFlags=D3D11_CPU_ACCESS_WRITE;<br />  cb.MiscFlags =0;<br />  cb.StructureByteStride=0;<br />  cb.Usage=D3D11_USAGE_DYNAMIC;</p> <p> if( FAILED(Device-&gt;CreateBuffer( &amp;cb,NULL,&amp;ConstantBuffer[1])))<br />  {<br />   return E_FAIL;<br />  }<br />  //テクスチャー用サンプラー作成<br />  D3D11_SAMPLER_DESC SamDesc;<br />  ZeroMemory(&amp;SamDesc,sizeof(D3D11_SAMPLER_DESC));</p> <p> SamDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;<br />     SamDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;<br />     SamDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;<br />     SamDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;<br />     Device-&gt;CreateSamplerState( &amp;SamDesc, &amp;SampleLinear);<br />  //OBJファイルからオリジナルメッシュを作成<br />  obj.Load(FILE_NAME);</p> <p> return S_OK;<br /> }</p> <p>//レンダリング<br /> VOID Render()<br /> {<br />  float ClearColor[4] = {0,0,1,1 }; // クリア色作成 RGBAの順<br />     DeviceContext-&gt;ClearRenderTargetView( RenderTargetView, ClearColor );//画面クリア<br />  DeviceContext-&gt;ClearDepthStencilView( DepthStencilView, D3D11_CLEAR_DEPTH, 1.0f, 0 );//深度バッファクリア</p> <p> //変換行列作成<br />  D3DXMATRIX mWorld;<br />  D3DXMATRIX mView;<br />  D3DXMATRIX mProj;</p> <p> //ワールド行列<br />  static float angle=0;<br />  angle+=0.03f;<br />  D3DXMATRIX mRot;<br />  D3DXMatrixRotationY(&amp;mRot,(float)D3DXToRadian(angle));<br />  mWorld=mRot;<br />  //ビュー行列<br />  D3DXVECTOR3 Eye( 0.0f, 300.0f, -200.0f );<br />     D3DXVECTOR3 At( 0.0f, 0.0f, 0.0f );<br />     D3DXVECTOR3 Up( 0.0f, 1.0f, 0.0f );<br />     D3DXMatrixLookAtLH( &amp;mView, &amp;Eye, &amp;At, &amp;Up );</p> <p> //プロジェクション行列<br />  D3DXMatrixPerspectiveFovLH( &amp;mProj, ( float )D3DX_PI/4 , (float)WINDOW_WIDTH / (float)WINDOW_HEIGHT, 0.1f, 1000.0f );</p> <p> //ワールド・ビュー・プロジェクション行列をシェーダーに渡す<br />  DeviceContext-&gt;VSSetConstantBuffers(0,1,&amp;ConstantBuffer[0] );</p> <p> D3D11_MAPPED_SUBRESOURCE pData;<br />  if( SUCCEEDED( DeviceContext-&gt;Map( ConstantBuffer[0], 0, D3D11_MAP_WRITE_DISCARD, 0, &amp;pData ) ) )<br />  {<br />   SHADER_GLOBAL0 sg;<br />   sg.mW=mWorld;<br />   D3DXMatrixTranspose( &amp;sg.mW, &amp;sg.mW );<br />   sg.mWVP=mWorld*mView*mProj;<br />   D3DXMatrixTranspose( &amp;sg.mWVP, &amp;sg.mWVP );<br />   sg.vLightDir=D3DXVECTOR4(LightDir.x,LightDir.y,LightDir.z,0.0f);<br />   sg.vEye=D3DXVECTOR4(Eye.x,Eye.y,Eye.z,0);<br />   memcpy_s( pData.pData, pData.RowPitch, (void*)&amp;sg, sizeof( SHADER_GLOBAL0 ) );<br />   DeviceContext-&gt;Unmap( ConstantBuffer[0], 0 );<br />  }<br />  DeviceContext-&gt;VSSetConstantBuffers(0,1,&amp;ConstantBuffer[0] );<br />  DeviceContext-&gt;PSSetConstantBuffers(0,1,&amp;ConstantBuffer[0] );<br />  //使用するシェーダーの登録<br />  DeviceContext-&gt;VSSetShader(VertexShader,NULL,0);<br />  DeviceContext-&gt;PSSetShader(PixelShader,NULL,0);<br />  //メッシュを描画<br />  obj.Draw();</p> <p> SwapChain-&gt;Present( 0, 0 );//フリップ<br /> }</p> <p>//終了時解放処理<br /> VOID Cleanup()<br /> {<br />  SAFE_RELEASE(SampleLinear);<br />  SAFE_RELEASE(Texture);<br />  SAFE_RELEASE(DepthStencil);<br />  SAFE_RELEASE(DepthStencilView);<br />  SAFE_RELEASE(VertexShader);<br />  SAFE_RELEASE(PixelShader);<br />  SAFE_RELEASE(ConstantBuffer[0]);<br />  SAFE_RELEASE(ConstantBuffer[1]);<br />  SAFE_RELEASE(VertexLayout); <br />  SAFE_RELEASE(SwapChain);<br />  SAFE_RELEASE(RenderTargetView);<br />  SAFE_RELEASE(DeviceContext);<br />  SAFE_RELEASE(Device);<br /> }</p> <p>//メッセージプロシージャ<br /> LRESULT CALLBACK MsgProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)<br /> {<br />  switch(msg)<br />  {<br />   case WM_DESTROY://終了時<br />    Cleanup();<br />    PostQuitMessage(0);<br />    break;<br />  }<br />  return DefWindowProc (hWnd, msg, wParam, lParam);<br /> }</p> <p>//メイン関数<br /> INT WINAPI WinMain( HINSTANCE hInst,HINSTANCE hPrevInst,LPSTR szStr,INT iCmdShow)<br /> {<br />  //ウインドウクラスの登録<br />     WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,<br />                       GetModuleHandle(NULL), NULL, NULL, NULL, NULL,<br />                       L"Window1", NULL };<br />     RegisterClassEx( &amp;wc );<br />  //タイトルバーとウインドウ枠の分を含めてウインドウサイズを設定<br />  RECT rect;<br />  SetRect(&amp;rect,0,0,WINDOW_WIDTH,WINDOW_HEIGHT);<br />  AdjustWindowRect(&amp;rect, WS_OVERLAPPEDWINDOW, FALSE);<br />  rect.right=rect.right-rect.left;<br />  rect.bottom=rect.bottom-rect.top;<br />  rect.top=0;<br />  rect.left=0;<br />      //ウインドウの生成<br />     hWnd = CreateWindow( L"Window1", L"OBJローダ",<br />     WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, rect.right, rect.bottom,<br />                               NULL, NULL, wc.hInstance, NULL );<br />  <br />  MSG msg;<br />  ZeroMemory(&amp;msg,sizeof(msg));<br />  //Direct3D初期化<br />     if(SUCCEEDED(InitD3D(hWnd)))<br />     {<br />   //ウインドウ表示<br />   ShowWindow(hWnd,SW_SHOW);<br />   UpdateWindow(hWnd);<br />   while(msg.message!=WM_QUIT)<br />   {<br />    if( PeekMessage(&amp;msg,NULL,0,0,PM_REMOVE))<br />    {<br />     TranslateMessage(&amp;msg);<br />     DispatchMessage(&amp;msg);<br />    }<br />    else<br />    {<br />     Render();<br />    }<br />   }<br />  }</p> <p> //終了<br />  return 0;<br /> }</p> </td> </tr></tbody></table><p> </p>
<p><strong>OBJファイルを読み込んで表示します。</strong></p> <p><a href="http://neo-arcadia.seesaa.net/"><strong>http://neo-arcadia.seesaa.net/</strong></a><strong><br /> こちらからモデルを借りてきて表示しています。</strong></p> <p><strong><img alt="" src="http://www43.atwiki.jp/directx11?cmd=upload&amp;act=open&amp;pageid=20&amp;file=obj.png" /></strong></p> <p>shader.hlsl</p> <table border="1" cellspacing="1" cellpadding="1" width="600"><tbody><tr><td> <p>//グローバル<br /> Texture2D g_texDecal: register(t0);<br /> SamplerState g_samLinear : register(s0);</p> <p>//グローバル<br /> cbuffer global_0:register(b0)<br /> {<br />  matrix g_mW;//ワールド行列<br />  matrix g_mWVP; //ワールドから射影までの変換行列<br />  float4 g_vLightDir;  //ライトの方向ベクトル<br />  float4 g_vEye;//カメラ位置<br /> };</p> <p>cbuffer global_1:register(b1)<br /> {<br />  float4 g_Ambient=float4(0,0,0,0);//アンビエント光<br />  float4 g_Diffuse=float4(1,0,0,0); //拡散反射(色)<br />  float4 g_Specular=float4(1,1,1,1);//鏡面反射<br /> };</p> <p>//バーテックスバッファー出力構造体<br /> struct VS_OUTPUT<br /> { <br />      float4 Pos : SV_POSITION;<br />  float4 Color : COLOR0;<br />  float3 Light : TEXCOORD0;<br />     float3 Normal : TEXCOORD1;<br />     float3 EyeVector : TEXCOORD2;<br />  float2 Tex : TEXCOORD3;<br /> };<br /> //<br /> //バーテックスシェーダー<br /> //<br /> VS_OUTPUT VS( float4 Pos : POSITION ,float4 Norm : NORMAL,float2 Tex : TEXCOORD)<br /> {<br />     VS_OUTPUT output = (VS_OUTPUT)0;<br />  //射影変換(ワールド→ビュー→プロジェクション)<br />  //法線をワールド空間に<br />  output.Normal=mul(Norm, g_mW);<br />  output.Pos=mul(Pos,g_mWVP);<br />  //ライト方向<br />  output.Light=g_vLightDir;<br />  //視線ベクトル<br />  float3 PosWorld = normalize(output.Pos);<br />     output.EyeVector = g_vEye - PosWorld;<br />  <br />  float3 Normal = normalize(output.Normal);<br />     float3 LightDir = normalize(output.Light);<br />     float3 ViewDir = normalize(output.EyeVector);<br />     float4 NL = saturate(dot(Normal, LightDir));<br />    <br />     float3 Reflect = normalize(2 * NL * Normal - LightDir);<br />     float4 specular = pow(saturate(dot(Reflect, ViewDir)), 4);</p> <p>    output.Color= g_Diffuse * NL + specular*g_Specular;<br />  <br />  //テクスチャー座標<br />  output.Tex=Tex;</p> <p>    return output;<br /> }</p> <p>//<br /> //ピクセルシェーダー<br /> //<br /> float4 PS( VS_OUTPUT input ) : SV_Target<br /> {<br />  float4 color=g_texDecal.Sample( g_samLinear, input.Tex );<br />  color+=input.Color;</p> <p>    return color;<br /> }</p> </td> </tr></tbody></table><p> </p> <p>main.cpp</p> <table border="1" cellspacing="1" cellpadding="1" width="600"><tbody><tr><td> <p>#pragma comment(lib,"d3d11.lib")<br /> #pragma comment(lib,"d3dx11.lib")<br /> #pragma comment(lib,"d3dx10.lib")<br /> #pragma comment(lib,"d3dCompiler.lib")<br /> #include &lt;stdio.h&gt;<br /> #include &lt;vector&gt;<br /> #include &lt;d3dx11.h&gt;<br /> #include &lt;d3dx10.h&gt;<br /> #include &lt;d3dCompiler.h&gt;</p> <p>#define FILE_NAME "axel.obj"</p> <p>using namespace std;</p> <p>//安全に解放する<br /> #define SAFE_RELEASE(x) if(x){x-&gt;Release(); x=NULL;}</p> <p>//定数定義<br /> #define WINDOW_WIDTH 320 //ウィンドウ幅<br /> #define WINDOW_HEIGHT 240 //ウィンドウ高さ</p> <p>//グローバル変数<br /> HWND hWnd=NULL;<br /> ID3D11Device* Device = NULL;      //デバイス<br /> ID3D11DeviceContext* DeviceContext=NULL;   //デバイスコンテキスト<br /> IDXGISwapChain* SwapChain = NULL;     //スワップチェイン<br /> ID3D11RenderTargetView* RenderTargetView = NULL; //レンダーターゲットビュー<br /> ID3D11DepthStencilView* DepthStencilView = NULL;<br /> ID3D11Texture2D*  DepthStencil = NULL;<br /> ID3D11InputLayout* VertexLayout=NULL;</p> <p>ID3D11VertexShader* VertexShader=NULL;//頂点シェーダー<br /> ID3D11PixelShader* PixelShader=NULL;//ピクセルシェーダー</p> <p>ID3D11Buffer* ConstantBuffer[2];//コンスタントバッファ</p> <p>D3DXVECTOR3 LightDir(1,1,-1);//ライト方向</p> <p>ID3D11SamplerState* SampleLinear=NULL;//テクスチャーのサンプラー<br /> ID3D11ShaderResourceView* Texture=NULL;//テクスチャー</p> <p>//シェーダーに渡す値<br /> struct SHADER_GLOBAL0<br /> {<br />  D3DXMATRIX mW;//ワールド行列<br />  D3DXMATRIX mWVP;//ワールドから射影までの変換行列<br />  D3DXVECTOR4 vLightDir;//ライト方向<br />  D3DXVECTOR4 vEye;//カメラ位置<br /> };<br /> struct SHADER_GLOBAL1<br /> {<br />  D3DXVECTOR4 vAmbient;//アンビエント<br />  D3DXVECTOR4 vDiffuse;//ディフューズ<br />  D3DXVECTOR4 vSpecular;//鏡面反射<br /> };</p> <p>//マテリアル構造体<br /> struct MATERIAL<br /> {<br />  CHAR Name[255];<br />  D3DXVECTOR4 Ka;//アンビエント<br />  D3DXVECTOR4 Kd;//ディフューズ<br />  D3DXVECTOR4 Ks;//スペキュラー<br />  CHAR TextureName[255];//テクスチャファイル名<br />  ID3D11ShaderResourceView* pTexture;//テクスチャデータ<br />  DWORD MaxFace;//ポリゴン数<br /> }mat;</p> <p>//頂点構造体<br /> struct VERTEX<br /> {<br />  D3DXVECTOR3 Pos;//位置<br />  D3DXVECTOR3 Normal;//法線<br />  D3DXVECTOR2 UV;//UV<br /> }vert;</p> <p>//.OBJファイルクラス<br /> class OBJ{<br /> protected:<br />  vector &lt;MATERIAL&gt; Material;//マテリアル<br />  vector &lt;VERTEX&gt; Vertex;//頂点構造体<br />  ID3D11Buffer* VertexBuffer;//頂点バッファ<br />  ID3D11Buffer** IndexBuffer;//インデックスバッファ<br />  HRESULT LoadMaterialFromFile(LPSTR FileName);//マテリアルファイル読み込み<br /> public:<br />  void Draw();//描画<br />  HRESULT Load(LPSTR FileName);//読み込み<br /> };</p> <p>OBJ obj;</p> <p>//メッシュの描画<br /> void OBJ::Draw()<br /> {<br />  //バーテックスバッファをセット<br />  UINT stride = sizeof( VERTEX );<br />  UINT offset = 0;<br />  DeviceContext-&gt;IASetVertexBuffers( 0, 1, &amp;VertexBuffer, &amp;stride, &amp;offset );<br />  //マテリアルの数だけ、それぞれのマテリアルのインデックスバッファを描画<br />  for(DWORD i=0;i&lt;Material.size();i++)<br />  {<br />   //使用されていないマテリアル対策<br />   if(Material[i].MaxFace==0)<br />   {<br />    continue;<br />   }<br />   //インデックスバッファをセット<br />   DeviceContext-&gt;IASetIndexBuffer(IndexBuffer[i], DXGI_FORMAT_R32_UINT, 0 );<br />   //プリミティブ・トポロジーをセット<br />   DeviceContext-&gt;IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST );<br />   //マテリアルの各要素をシェーダーに渡す<br />   D3D11_MAPPED_SUBRESOURCE pData;<br />   if( SUCCEEDED( DeviceContext-&gt;Map( ConstantBuffer[1],0, D3D11_MAP_WRITE_DISCARD, 0, &amp;pData ) ) )<br />   {<br />    SHADER_GLOBAL1 sg;   <br />    sg.vAmbient=Material[i].Ka;<br />    sg.vDiffuse=Material[i].Kd;<br />    sg.vSpecular=Material[i].Ks;<br />    memcpy_s( pData.pData, pData.RowPitch, (void*)&amp;sg, sizeof( SHADER_GLOBAL1 ) );<br />    DeviceContext-&gt;Unmap( ConstantBuffer[1], 0 );<br />   }<br />   DeviceContext-&gt;VSSetConstantBuffers(1,1,&amp;ConstantBuffer[1] );<br />   DeviceContext-&gt;PSSetConstantBuffers(1,1,&amp;ConstantBuffer[1] );<br />   //テクスチャをシェーダーに渡す<br />   if(Material[i].TextureName[0] != NULL)<br />   {<br />    DeviceContext-&gt;PSSetSamplers(0,1,&amp;SampleLinear);<br />    DeviceContext-&gt;PSSetShaderResources(0,1,&amp;Material[i].pTexture);<br />   }<br />   DeviceContext-&gt;DrawIndexed(Material[i].MaxFace*3 , 0 ,0);<br />  }<br /> }</p> <p>//マテリアルファイルを読み込む関数<br /> HRESULT OBJ::LoadMaterialFromFile(LPSTR FileName)<br /> {<br />  FILE* fp=NULL;<br />  fopen_s(&amp;fp,FileName,"rt");<br />  char key[255]={0};<br />  bool flag=false;<br />  D3DXVECTOR4 v(0,0,0,0);<br />  <br />  fseek(fp,SEEK_SET,0);</p> <p> while(!feof(fp))<br />  {<br />   //キーワード読み込み<br />   fscanf_s(fp,"%s ",key,sizeof(key));<br />   //マテリアル名<br />   if(strcmp(key,"newmtl")==0)<br />   {<br />    if(flag)Material.push_back(mat);<br />    flag=true;<br />    fscanf_s(fp,"%s ",key,sizeof(key));<br />    strcpy_s(mat.Name,key);<br />   }<br />   //Ka アンビエント<br />   if(strcmp(key,"Ka")==0)<br />   {<br />    fscanf_s(fp,"%f %f %f",&amp;v.x,&amp;v.y,&amp;v.z);<br />    mat.Ka=v;<br />   }<br />   //Kd ディフューズ<br />   if(strcmp(key,"Kd")==0)<br />   {<br />    fscanf_s(fp,"%f %f %f",&amp;v.x,&amp;v.y,&amp;v.z);<br />    mat.Kd=v;<br />   }<br />   //Ks スペキュラー<br />   if(strcmp(key,"Ks")==0)<br />   {<br />    fscanf_s(fp,"%f %f %f",&amp;v.x,&amp;v.y,&amp;v.z);<br />    mat.Ks=v;<br />   }<br />   //map_Kd テクスチャ<br />   if(strcmp(key,"map_Kd")==0)<br />   {<br />    fscanf_s(fp,"%s",&amp;mat.TextureName,sizeof(mat.TextureName));<br />    //テクスチャを作成<br />    if(FAILED(D3DX11CreateShaderResourceViewFromFileA( Device, mat.TextureName, NULL, NULL, &amp;mat.pTexture, NULL )))<br />    {<br />     return E_FAIL;<br />    }<br />   }<br />  }<br />  fclose(fp);<br />  if(flag)Material.push_back(mat);<br />  <br />  return S_OK;<br /> }</p> <p>//OBJファイルからメッシュに必要な情報を読み込む<br /> HRESULT OBJ::Load(LPSTR FileName)<br /> {<br />  //一時代入用<br />  D3DXVECTOR3 vec3d;<br />  D3DXVECTOR2 vec2d;<br />  vector &lt;D3DXVECTOR3&gt; Pos;<br />  vector &lt;D3DXVECTOR3&gt; Normal;<br />  vector &lt;D3DXVECTOR2&gt; UV;<br />  vector &lt;int&gt; FaceIndex;<br />  int v1=0,v2=0,v3=0;<br />  int vn1=0,vn2=0,vn3=0;<br />  int vt1=0,vt2=0,vt3=0;<br />  DWORD dwFCount=0;//読み込みカウンタ</p> <p> char key[255]={0};<br />  //OBJファイルを開いて内容を読み込む<br />  FILE* fp=NULL;<br />  fopen_s(&amp;fp,FileName,"rt");<br />  <br />  //読み込み <br />  fseek(fp,SEEK_SET,0);</p> <p> while(!feof(fp))<br />  {<br />   //キーワード<br />   ZeroMemory(key,sizeof(key));<br />   fscanf_s(fp,"%s ",key,sizeof(key)); <br />   //マテリアル<br />   if(strcmp(key,"mtllib")==0)<br />   {<br />    fscanf_s(fp,"%s ",key,sizeof(key));<br />    LoadMaterialFromFile(key);<br />   }<br />   //頂点<br />   if(strcmp(key,"v")==0)<br />   {<br />    fscanf_s(fp,"%f %f %f",&amp;vec3d.x,&amp;vec3d.y,&amp;vec3d.z);<br />    Pos.push_back(vec3d);<br />    Vertex.push_back(vert);<br />   }<br />   //法線<br />   if(strcmp(key,"vn")==0)<br />   {  <br />    fscanf_s(fp,"%f %f %f",&amp;vec3d.x,&amp;vec3d.y,&amp;vec3d.z);<br />    Normal.push_back(vec3d);<br />   }<br />   //テクスチャ<br />   if(strcmp(key,"vt")==0)<br />   {  <br />    fscanf_s(fp,"%f %f",&amp;vec2d.x,&amp;vec2d.y);<br />    UV.push_back(-vec2d);<br />   }<br />   //フェイス<br />   if(strcmp(key,"f")==0)<br />   {<br />    FaceIndex.push_back(0);<br />   }<br />  } </p> <p> //マテリアルの数だけインデックスバッファを作成<br />  IndexBuffer=new ID3D11Buffer*[Material.size()];</p> <p> bool boFlag=false;<br />  for(DWORD i=0;i&lt;Material.size();i++)<br />  {  <br />   fseek(fp,SEEK_SET,0);<br />   dwFCount=0;</p> <p>  while(!feof(fp))<br />   {<br />    //キーワード<br />    ZeroMemory(key,sizeof(key));<br />    fscanf_s(fp,"%s ",key,sizeof(key));</p> <p>   //フェイス 読み込み→頂点インデックスに<br />    if(strcmp(key,"usemtl")==0)<br />    {<br />     fscanf_s(fp,"%s ",key,sizeof(key));<br />     if(strcmp(key,Material[i].Name)==0)<br />     {<br />      boFlag=true;<br />     }<br />     else<br />     {<br />       boFlag=false;<br />     }<br />    }<br />    if(strcmp(key,"f")==0 &amp;&amp; boFlag==true)<br />    {<br />     if(Material[i].pTexture!=NULL)//テクスチャーありサーフェイス<br />     {<br />      fscanf_s(fp,"%d/%d/%d %d/%d/%d %d/%d/%d",&amp;v1,&amp;vt1,&amp;vn1,&amp;v2,&amp;vt2,&amp;vn2,&amp;v3,&amp;vt3,&amp;vn3);<br />     }<br />     else//テクスチャー無しサーフェイス<br />     {<br />      fscanf_s(fp,"%d//%d %d//%d %d//%d",&amp;v1,&amp;vn1,&amp;v2,&amp;vn2,&amp;v3,&amp;vn3);<br />     }<br />     FaceIndex[dwFCount*3]=v1-1;<br />     FaceIndex[dwFCount*3+1]=v2-1;<br />     FaceIndex[dwFCount*3+2]=v3-1;<br />     dwFCount++;<br />     //頂点構造体に代入<br />     Vertex[v1-1].Pos=Pos[v1-1];<br />     Vertex[v1-1].Normal=Normal[vn1-1];<br />     Vertex[v1-1].UV=UV[vt1-1];<br />     Vertex[v2-1].Pos=Pos[v2-1];<br />     Vertex[v2-1].Normal=Normal[vn2-1];<br />     Vertex[v2-1].UV=UV[vt2-1];<br />     Vertex[v3-1].Pos=Pos[v3-1];<br />     Vertex[v3-1].Normal=Normal[vn3-1];<br />     Vertex[v3-1].UV=UV[vt3-1];<br />    }<br />   }<br />   if(dwFCount==0)//使用されていないマテリアル対策<br />   {<br />    IndexBuffer[i]=NULL;<br />    continue;<br />   }</p> <p>  //インデックスバッファを作成<br />   D3D11_BUFFER_DESC bd;<br />   bd.Usage = D3D11_USAGE_DEFAULT;<br />   bd.ByteWidth = sizeof( int ) * dwFCount * 3;<br />   bd.BindFlags = D3D11_BIND_INDEX_BUFFER;<br />   bd.CPUAccessFlags = 0;<br />   bd.MiscFlags = 0;<br />   D3D11_SUBRESOURCE_DATA InitData;<br />   InitData.pSysMem = &amp;FaceIndex[0];<br />   InitData.SysMemPitch=0;<br />   InitData.SysMemSlicePitch=0;<br />   if( FAILED( Device-&gt;CreateBuffer( &amp;bd, &amp;InitData, &amp;IndexBuffer[i] ) ) )return FALSE;<br />   Material[i].MaxFace=dwFCount;  <br />  }<br />  FaceIndex.clear();<br />  fclose(fp);</p> <p> //バーテックスバッファを作成<br />  D3D11_BUFFER_DESC bd;<br />  bd.Usage = D3D11_USAGE_DEFAULT;<br />  bd.ByteWidth = sizeof( VERTEX ) *Vertex.size();<br />  bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;<br />  bd.CPUAccessFlags = 0;<br />  bd.MiscFlags = 0;<br />  D3D11_SUBRESOURCE_DATA InitData;<br />  InitData.pSysMem = &amp;Vertex[0];<br />  if( FAILED( Device-&gt;CreateBuffer( &amp;bd, &amp;InitData, &amp;VertexBuffer ) ) )return FALSE; </p> <p><br />  Pos.clear();<br />  Normal.clear();<br />  UV.clear();<br />  Vertex.clear(); </p> <p> return S_OK;<br /> }</p> <p>//Direct3Dの初期化関数<br /> HRESULT InitD3D(HWND hWnd)<br /> {<br />  // デバイスとスワップチェーンの作成<br />  DXGI_SWAP_CHAIN_DESC sd;<br />     ZeroMemory( &amp;sd, sizeof(sd) );<br />     sd.BufferCount = 1;         //バックバッファの数<br />     sd.BufferDesc.Width = WINDOW_WIDTH;     //バッファの幅<br />     sd.BufferDesc.Height = WINDOW_HEIGHT;    //バッファの高さ<br />     sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; //バッファのフォーマット<br />     sd.BufferDesc.RefreshRate.Numerator = 60;   //リフレッシュレート<br />     sd.BufferDesc.RefreshRate.Denominator = 1;<br />     sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;<br />     sd.OutputWindow = hWnd;<br />     sd.SampleDesc.Count = 1;<br />     sd.SampleDesc.Quality = 0;<br />     sd.Windowed = TRUE;</p> <p> D3D_FEATURE_LEVEL  FeatureLevel = D3D_FEATURE_LEVEL_11_0;<br />  D3D_FEATURE_LEVEL* pFeatureLevel = NULL;</p> <p><br />     if( FAILED( D3D11CreateDeviceAndSwapChain( NULL, D3D_DRIVER_TYPE_HARDWARE, NULL,0,<br />      &amp;FeatureLevel,1,D3D11_SDK_VERSION, &amp;sd, &amp;SwapChain, &amp;Device ,NULL,&amp;DeviceContext) ) )<br />     {<br />         return FALSE;<br />     }<br />  //レンダーターゲットビューの作成<br />  ID3D11Texture2D *BackBuffer;<br />     SwapChain-&gt;GetBuffer( 0, __uuidof( ID3D11Texture2D ),(LPVOID*)&amp;BackBuffer);   <br />     Device-&gt;CreateRenderTargetView( BackBuffer, NULL, &amp;RenderTargetView );<br />     SAFE_RELEASE(BackBuffer);<br />  //深度ステンシルビューの作成<br />     D3D11_TEXTURE2D_DESC descDepth;<br />     descDepth.Width = WINDOW_WIDTH;<br />     descDepth.Height = WINDOW_HEIGHT;<br />     descDepth.MipLevels = 1;<br />     descDepth.ArraySize = 1;<br />     descDepth.Format = DXGI_FORMAT_D32_FLOAT;<br />     descDepth.SampleDesc.Count = 1;<br />     descDepth.SampleDesc.Quality = 0;<br />     descDepth.Usage = D3D11_USAGE_DEFAULT;<br />     descDepth.BindFlags = D3D11_BIND_DEPTH_STENCIL;<br />     descDepth.CPUAccessFlags = 0;<br />     descDepth.MiscFlags = 0;<br />     Device-&gt;CreateTexture2D( &amp;descDepth, NULL, &amp;DepthStencil );</p> <p>    Device-&gt;CreateDepthStencilView( DepthStencil, NULL, &amp;DepthStencilView );<br />  //レンダーターゲットビューと深度ステンシルビューをパイプラインにバインド <br />  DeviceContext-&gt;OMSetRenderTargets(1, &amp;RenderTargetView,DepthStencilView);</p> <p> //ビューポートの設定<br />  D3D11_VIEWPORT vp;<br />     vp.Width = WINDOW_WIDTH;<br />     vp.Height = WINDOW_HEIGHT;<br />     vp.MinDepth = 0.0f;<br />     vp.MaxDepth = 1.0f;<br />     vp.TopLeftX = 0;<br />     vp.TopLeftY = 0;<br />     DeviceContext-&gt;RSSetViewports( 1, &amp;vp );</p> <p> //hlslファイル読み込み<br />  ID3DBlob *pCompiledShader=NULL;<br />  ID3DBlob *pErrors=NULL;<br />  //ブロブから頂点シェーダー作成<br />  if(FAILED(D3DX11CompileFromFile(L"shader.hlsl",NULL,NULL,"VS","vs_5_0",0,0,NULL,&amp;pCompiledShader,&amp;pErrors,NULL)))<br />  {<br />   MessageBox(0,L"頂点シェーダー読み込み失敗",NULL,MB_OK);<br />   return E_FAIL;<br />     }<br />  SAFE_RELEASE(pErrors);</p> <p>  if(FAILED(Device-&gt;CreateVertexShader(pCompiledShader-&gt;GetBufferPointer(),pCompiledShader-&gt;GetBufferSize(),NULL,&amp;VertexShader)))<br />  {<br />   SAFE_RELEASE(pCompiledShader);<br />   MessageBox(0,L"頂点シェーダー作成失敗",NULL,MB_OK);<br />   return E_FAIL;<br />  }<br />  //頂点インプットレイアウトを定義 <br />  D3D11_INPUT_ELEMENT_DESC layout[] =<br />  {<br />   { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },<br />   { "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },<br />   { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0 },<br />  };<br />  UINT numElements = sizeof(layout)/sizeof(layout[0]);</p> <p> //頂点インプットレイアウトを作成<br />  if( FAILED( Device-&gt;CreateInputLayout( layout, numElements, pCompiledShader-&gt;GetBufferPointer(), pCompiledShader-&gt;GetBufferSize(), &amp;VertexLayout ) ) )<br />   return FALSE;<br />  //頂点インプットレイアウトをセット<br />  DeviceContext-&gt;IASetInputLayout( VertexLayout );</p> <p> //ブロブからピクセルシェーダー作成<br />  if(FAILED(D3DX11CompileFromFile(L"shader.hlsl",NULL,NULL,"PS","ps_5_0",0,0,NULL,&amp;pCompiledShader,&amp;pErrors,NULL)))<br />  {<br />   MessageBox(0,L"ピクセルシェーダー読み込み失敗",NULL,MB_OK);<br />   return E_FAIL;<br />     }<br />  SAFE_RELEASE(pErrors);<br />  if(FAILED(Device-&gt;CreatePixelShader(pCompiledShader-&gt;GetBufferPointer(),pCompiledShader-&gt;GetBufferSize(),NULL,&amp;PixelShader)))<br />  {<br />   SAFE_RELEASE(pCompiledShader);<br />   MessageBox(0,L"ピクセルシェーダー作成失敗",NULL,MB_OK);<br />   return E_FAIL;<br />  }<br />  SAFE_RELEASE(pCompiledShader);</p> <p> //ラスタライズ設定<br />  D3D11_RASTERIZER_DESC rdc;<br />  ZeroMemory(&amp;rdc,sizeof(rdc));<br />  rdc.CullMode=D3D11_CULL_NONE;<br />  rdc.FillMode=D3D11_FILL_SOLID;<br />  <br />  ID3D11RasterizerState* pIr=NULL;<br />  Device-&gt;CreateRasterizerState(&amp;rdc,&amp;pIr);<br />  DeviceContext-&gt;RSSetState(pIr);<br />  SAFE_RELEASE(pIr);<br />  //コンスタントバッファー作成 ここでは変換行列渡し用<br />  D3D11_BUFFER_DESC cb;<br />  cb.BindFlags= D3D11_BIND_CONSTANT_BUFFER;<br />  cb.ByteWidth= sizeof( SHADER_GLOBAL0 );<br />  cb.CPUAccessFlags=D3D11_CPU_ACCESS_WRITE;<br />  cb.MiscFlags =0;<br />  cb.StructureByteStride=0;<br />  cb.Usage=D3D11_USAGE_DYNAMIC;</p> <p> if( FAILED(Device-&gt;CreateBuffer( &amp;cb,NULL,&amp;ConstantBuffer[0])))<br />  {<br />   return E_FAIL;<br />  }<br />  //コンスタントバッファー作成  マテリアル渡し用<br />  cb.BindFlags= D3D11_BIND_CONSTANT_BUFFER;<br />  cb.ByteWidth= sizeof( SHADER_GLOBAL1 );<br />  cb.CPUAccessFlags=D3D11_CPU_ACCESS_WRITE;<br />  cb.MiscFlags =0;<br />  cb.StructureByteStride=0;<br />  cb.Usage=D3D11_USAGE_DYNAMIC;</p> <p> if( FAILED(Device-&gt;CreateBuffer( &amp;cb,NULL,&amp;ConstantBuffer[1])))<br />  {<br />   return E_FAIL;<br />  }<br />  //テクスチャー用サンプラー作成<br />  D3D11_SAMPLER_DESC SamDesc;<br />  ZeroMemory(&amp;SamDesc,sizeof(D3D11_SAMPLER_DESC));</p> <p> SamDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;<br />     SamDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;<br />     SamDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;<br />     SamDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;<br />     Device-&gt;CreateSamplerState( &amp;SamDesc, &amp;SampleLinear);<br />  //OBJファイルからオリジナルメッシュを作成<br />  obj.Load(FILE_NAME);</p> <p> return S_OK;<br /> }</p> <p>//レンダリング<br /> VOID Render()<br /> {<br />  float ClearColor[4] = {0,0,1,1 }; // クリア色作成 RGBAの順<br />     DeviceContext-&gt;ClearRenderTargetView( RenderTargetView, ClearColor );//画面クリア<br />  DeviceContext-&gt;ClearDepthStencilView( DepthStencilView, D3D11_CLEAR_DEPTH, 1.0f, 0 );//深度バッファクリア</p> <p> //変換行列作成<br />  D3DXMATRIX mWorld;<br />  D3DXMATRIX mView;<br />  D3DXMATRIX mProj;</p> <p> //ワールド行列<br />  static float angle=0;<br />  angle+=0.03f;<br />  D3DXMATRIX mRot;<br />  D3DXMatrixRotationY(&amp;mRot,(float)D3DXToRadian(angle));<br />  mWorld=mRot;<br />  //ビュー行列<br />  D3DXVECTOR3 Eye( 0.0f, 300.0f, -200.0f );<br />     D3DXVECTOR3 At( 0.0f, 0.0f, 0.0f );<br />     D3DXVECTOR3 Up( 0.0f, 1.0f, 0.0f );<br />     D3DXMatrixLookAtLH( &amp;mView, &amp;Eye, &amp;At, &amp;Up );</p> <p> //プロジェクション行列<br />  D3DXMatrixPerspectiveFovLH( &amp;mProj, ( float )D3DX_PI/4 , (float)WINDOW_WIDTH / (float)WINDOW_HEIGHT, 0.1f, 1000.0f );</p> <p> //ワールド・ビュー・プロジェクション行列をシェーダーに渡す<br />  DeviceContext-&gt;VSSetConstantBuffers(0,1,&amp;ConstantBuffer[0] );</p> <p> D3D11_MAPPED_SUBRESOURCE pData;<br />  if( SUCCEEDED( DeviceContext-&gt;Map( ConstantBuffer[0], 0, D3D11_MAP_WRITE_DISCARD, 0, &amp;pData ) ) )<br />  {<br />   SHADER_GLOBAL0 sg;<br />   sg.mW=mWorld;<br />   D3DXMatrixTranspose( &amp;sg.mW, &amp;sg.mW );<br />   sg.mWVP=mWorld*mView*mProj;<br />   D3DXMatrixTranspose( &amp;sg.mWVP, &amp;sg.mWVP );<br />   sg.vLightDir=D3DXVECTOR4(LightDir.x,LightDir.y,LightDir.z,0.0f);<br />   sg.vEye=D3DXVECTOR4(Eye.x,Eye.y,Eye.z,0);<br />   memcpy_s( pData.pData, pData.RowPitch, (void*)&amp;sg, sizeof( SHADER_GLOBAL0 ) );<br />   DeviceContext-&gt;Unmap( ConstantBuffer[0], 0 );<br />  }<br />  DeviceContext-&gt;VSSetConstantBuffers(0,1,&amp;ConstantBuffer[0] );<br />  DeviceContext-&gt;PSSetConstantBuffers(0,1,&amp;ConstantBuffer[0] );<br />  //使用するシェーダーの登録<br />  DeviceContext-&gt;VSSetShader(VertexShader,NULL,0);<br />  DeviceContext-&gt;PSSetShader(PixelShader,NULL,0);<br />  //メッシュを描画<br />  obj.Draw();</p> <p> SwapChain-&gt;Present( 0, 0 );//フリップ<br /> }</p> <p>//終了時解放処理<br /> VOID Cleanup()<br /> {<br />  SAFE_RELEASE(SampleLinear);<br />  SAFE_RELEASE(Texture);<br />  SAFE_RELEASE(DepthStencil);<br />  SAFE_RELEASE(DepthStencilView);<br />  SAFE_RELEASE(VertexShader);<br />  SAFE_RELEASE(PixelShader);<br />  SAFE_RELEASE(ConstantBuffer[0]);<br />  SAFE_RELEASE(ConstantBuffer[1]);<br />  SAFE_RELEASE(VertexLayout); <br />  SAFE_RELEASE(SwapChain);<br />  SAFE_RELEASE(RenderTargetView);<br />  SAFE_RELEASE(DeviceContext);<br />  SAFE_RELEASE(Device);<br /> }</p> <p>//メッセージプロシージャ<br /> LRESULT CALLBACK MsgProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)<br /> {<br />  switch(msg)<br />  {<br />   case WM_DESTROY://終了時<br />    Cleanup();<br />    PostQuitMessage(0);<br />    break;<br />  }<br />  return DefWindowProc (hWnd, msg, wParam, lParam);<br /> }</p> <p>//メイン関数<br /> INT WINAPI WinMain( HINSTANCE hInst,HINSTANCE hPrevInst,LPSTR szStr,INT iCmdShow)<br /> {<br />  //ウインドウクラスの登録<br />     WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,<br />                       GetModuleHandle(NULL), NULL, NULL, NULL, NULL,<br />                       L"Window1", NULL };<br />     RegisterClassEx( &amp;wc );<br />  //タイトルバーとウインドウ枠の分を含めてウインドウサイズを設定<br />  RECT rect;<br />  SetRect(&amp;rect,0,0,WINDOW_WIDTH,WINDOW_HEIGHT);<br />  AdjustWindowRect(&amp;rect, WS_OVERLAPPEDWINDOW, FALSE);<br />  rect.right=rect.right-rect.left;<br />  rect.bottom=rect.bottom-rect.top;<br />  rect.top=0;<br />  rect.left=0;<br />      //ウインドウの生成<br />     hWnd = CreateWindow( L"Window1", L"OBJローダ",<br />     WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, rect.right, rect.bottom,<br />                               NULL, NULL, wc.hInstance, NULL );<br />  <br />  MSG msg;<br />  ZeroMemory(&amp;msg,sizeof(msg));<br />  //Direct3D初期化<br />     if(SUCCEEDED(InitD3D(hWnd)))<br />     {<br />   //ウインドウ表示<br />   ShowWindow(hWnd,SW_SHOW);<br />   UpdateWindow(hWnd);<br />   while(msg.message!=WM_QUIT)<br />   {<br />    if( PeekMessage(&amp;msg,NULL,0,0,PM_REMOVE))<br />    {<br />     TranslateMessage(&amp;msg);<br />     DispatchMessage(&amp;msg);<br />    }<br />    else<br />    {<br />     Render();<br />    }<br />   }<br />  }</p> <p> //終了<br />  return 0;<br /> }</p> </td> </tr></tbody></table><p> </p>

表示オプション

横に並べて表示:
変化行の前後のみ表示:
ツールボックス

下から選んでください:

新しいページを作成する
ヘルプ / FAQ もご覧ください。