programming4us
programming4us
MULTIMEDIA

Game Programming with DirectX : 3D Models - OBJ Models (part 3) - Preparing OBJ Files for Direct3D

- Free product key for windows 10
- Free Product Key for Microsoft office 365
- Malwarebytes Premium 3.7.1 Serial Keys (LifeTime) 2019

3. Preparing OBJ Files for Direct3D

In the IntializeDemo() function, the shader and input layout is first created as usual. After that the OBJ file is loaded in an ObjModel object. A loop then follows that loops through each mesh of the model and creates a vertex buffer and texture out of it. This vertex buffer and texture is added to the DX10Mesh list and is what we render later in the rendering function. The InitializeDemo() function is shown in Listing 11, where the order of the function’s execution is as follows.

1.
Load the shader.

2.
Create the input layout.

3.
Load the OBJ file.

4.
Loop through each mesh.

5.
Load the mesh’s texture.

6.
Create a temp array of DX10Vertex and fill it with the vertex information (you could use the mesh itself, but additional information is in it that Direct3D 10 does not need).

7.
Create the mesh’s vertex buffer.

8.
Delete the temporary memory.

9.
Set the view and projection matrices.

Listing 11. The InitializeDemo() Function from the OBJ Models Demo
bool InitializeDemo()
{
   // Load the shader.

   DWORD shaderFlags = D3D10_SHADER_ENABLE_STRICTNESS;

#if defined( DEBUG )  || defined( _DEBUG )
   shaderFlags |= D3D10_SHADER_DEBUG;
#endif

   ID3D10Blob *errors = NULL;

   HRESULT hr = D3DX10CreateEffectFromFile("TextureMap.fx", NULL,
      NULL, "fx_4_0", shaderFlags, 0, g_d3dDevice, NULL, NULL,
      &g_shader, &errors, NULL);

   if(errors != NULL)
   {
      MessageBox(NULL, (LPCSTR)errors->GetBufferPointer(),
                 "Error in Shader!", MB_OK);

      errors->Release()
   }

   if(FAILED(hr))
      return false;

   g_textureMapTech = g_shader->GetTechniqueByName(
      "TextureMapping");

   g_worldEffectVar = g_shader->GetVariableByName(
      "World")->AsMatrix();

   g_viewEffectVar = g_shader->GetVariableByName(
      "View")->AsMatrix();

   g_projEffectVar = g_shader->GetVariableByName(
      "Projection")->AsMatrix();

   g_decalEffectVar = g_shader->GetVariableByName(
      "decal")->AsShaderResource();
   // Create the layout.

   D3D10_INPUT_ELEMENT_DESC layout[] =
   {
      { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0,
        D3D10_INPUT_PER_VERTEX_DATA, 0 },
      { "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12,
        D3D10_INPUT_PER_VERTEX_DATA, 0 },
      { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 24,
        D3D10_INPUT_PER_VERTEX_DATA, 0 },
   };

   unsigned int numElements = sizeof(layout) / sizeof(layout[0]);
   D3D10_PASS_DESC passDesc;

   g_textureMapTech->GetPassByIndex(0)->GetDesc(&passDesc);

   hr = g_d3dDevice->CreateInputLayout(layout, numElements,
      passDesc.pIAInputSignature, passDesc.IAInputSignatureSize,
      &g_layout);

   if(FAILED(hr))
      return false;


   // Load the model from the file.

   ObjModel model;

   if(model.LoadOBJ("box.ob] ") == false)
      return false;

   g_meshes.reserve(model.GetMeshCount());
   D3D10_BUFFER_DESC buffDesc;
   D3D10_SUBRESOURCE_DATA resData;

   // Loop through and create vertex buffers for each mesh.
   for(int m = 0; m < model.GetMeshCount(); m++)
   {
      DX10Mesh mesh;
      g_meshes.push_back(mesh);

      // Load the texture.
      string textureFile = model.GetMeshTextureFile(m);

      hr = D3DX10CreateShaderResourceViewFromFile(g_d3dDevice,
         textureFile.c_str(), NULL, NULL,
         &g_meshes[m].m_decal, NULL);

      if(FAILED(hr))
         return false;

      g_meshes[m].m_totalVerts = model.GetMeshTotalVerts(m);

      DX10Vertex *vertices =
         new DX10Vertex[g_meshes[m].m_totalVerts];

      float *modelVerts = model.GetMeshVertices(m);
      float *modelNorms = model.GetMeshNormals(m);
      float *modelTexC = model.GetMeshTexCoords(m);

      for(int i = 0; i < g_meshes[m].m_totalVerts;
      {
         vertices[i].pos.x = *(modelVerts + 0);
         vertices[i].pos.y = *(modelVerts + 1);
         vertices[i].pos.z = *(modelVerts + 2);
         modelVerts += 3;
         vertices[i].normal.x = *(modelNorms + 0);
         vertices[i].normal.y = *(modelNorms + 1);
         vertices[i].normal.z = *(modelNorms + 2);
         modelNorms += 3;

         vertices[i].tex0.x = *(modelTexC + 0);
         vertices[i].tex0.y = *(modelTexC + 1);
         modelTexC +=2;
      }

      // Create the vertex buffer.

      buffDesc.Usage = D3D10_USAGE_DEFAULT;

      buffDesc.ByteWidth = sizeof(DX10Vertex) *
         g_meshes[m].m_totalVerts;

      buffDesc.BindFlags = D3D10_BIND_VERTEX_BUFFER;
      buffDesc.CPUAccessFlags = 0;
      buffDesc.MiscFlags = 0;
      resData.pSysMem = vertices;

      hr = g_d3dDevice->CreateBuffer(&buffDesc, &resData,
         &g_meshes[m].m_vertices);

      if(FAILED(hr))
         return false;

      delete[] vertices;
   }

   // Set the shader matrix variables that won't change once here.
   D3DXMatrixIdentity(&g_worldMat);
   D3DXMatrixIdentity(&g_viewMat);
   g_viewEffectVar->SetMatrix((float*)&g_viewMat);
   g_pro]EffectVar->SetMatrix((float*)&g_projMat);

   return true;
}

					  

Rendering OBJ Models

The last piece of this demo deals with the rendering and shutdown functions. In this demo the model is rotating. This is done by creating the world matrix for the model that rotates a little bit along the X and Y axis each frame. This is done in the Update() function, which is called after the rendering to slightly update the world matrix. The Update() function is shown in Listing 12.

Listing 12. The Update() Function from the OBJ Models Demo
void Update()
{
   g_xRot += 0.0001f;
   g_yRot += 0.0002f;

   if(g_xRot < 0) g_xRot = 359;
   else if(g_xRot >= 360) g_xRot = 0;

   if(g_yRot < 0) g_yRot = 359;
   else if(g_yRot >= 360) g_yRot = 0;

   D3DXMATRIX trans, rotX, rotY;

   D3DXMatrixRotationX(&rotX, g_xRot);
   D3DXMatrixRotationY(&rotY, g_yRot);
   D3DXMatrixTranslation(&trans, 0, 0, 6);

   g_worldMat = (rotX * rotY) * trans;
}

The rendering function is pretty much the same as in previous demos, with the exception that there is now a loop that loops through and sets the vertex buffer and texture for each mesh in the mesh list. Each mesh is rendered out one at a time in this manner. The Shutdown() function is also the same as in previous demos, with the exception of a loop being used to release the vertex buffers and textures that were loaded in the InitializeDemo() function. The RenderScene() and Shutdown() functions from the OBJ Models demo are shown in Listing 13.

Listing 13. The RenderScene() and Shutdown() Functions
void RenderScene()
{
   float col[4] = { 0, 0, 0, 1 };

   g_d3dDevice->ClearRenderTargetView(g_renderTargetView, col);
   g_d3dDevice->ClearDepthStencilView(g_depthStencilView,
                                      D3D10_CLEAR_DEPTH, 1.0f, 0);

   g_d3dDevice->IASetInputLayout(g_layout);

   g_d3dDevice->IASetPrimitiveTopology(
      D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

   D3D10_TECHNIQUE_DESC techDesc;
   g_textureMapTech->GetDesc(&techDesc);

   unsigned int stride = sizeof(DX10Vertex);
   unsigned int offset = 0;

   for(int m = 0; m < (int)g_meshes.size(); m++)
   {
      g_worldEffectVar->SetMatrix((float*)&g_worldMat);
      g_decalEffectVar->SetResource(g_meshes[m].m_decal);

      g_d3dDevice->IASetVertexBuffers(0, 1,
         &g_meshes[m].m_vertices, &stride, &offset);
      for(unsigned int i = 0; i < techDesc.Passes; i++)
      {
         g_textureMapTech->GetPassByIndex(i)->Apply(0);
         g_d3dDevice->Draw(g_meshes[m].m_totalVerts, 0);
      }
    }

    g_swapChain->Present(0, 0);

    Update();
}

void Shutdown()
{
   if(g_d3dDevice) g_d3dDevice->ClearState();
   if(g_swapChain) g_swapChain->Release()
   if(g_renderTargetView) g_renderTargetView->Release()
   if(g_depthStencilTex) g_depthStencilTex->Release()
   if(g_depthStencilView) g_depthStencilView->Release()

   if(g_shader) g_shader->Release()
   if(g_layout) g_layout->Release()

   for(int m = 0; m < (int)g_meshes.size(); m++)
   {
      if(g_meshes[m].m_vertices)
         g_meshes[m].m_vertices->Release()

      if(g_meshes[m].m_decal)
      {
         ID3D10Resource *pRes;
         g_meshes[m].m_decal->GetResource(&pRes);

         pRes->Release()
         g_meshes[m].m_decal->Release()
      }
   }

   if(g_d3dDevice) g_d3dDevice->Release()
}

					  

To conclude this demo we must take a look at the shader’s file. Because we are rendering a model with volume, we must set the depth buffer state so that the geometry renders correctly. Without it we must render the triangles from back to front order to ensure that triangles behind other triangles are not rendered on top, but with the depth buffer the hardware ensures that primitives are drawn correctly.

Depth testing is a technique used to avoid having to render primitives in a specific order. In Direct3D and other APIs, a depth buffer is an actual buffer in the graphics card memory, similar to the color buffer that is the rendered image that is written to every time an object is rendered. The depth buffer stores depth values on the pixel level, which are the projected distances between the surface and the camera. Thus, when new primitives are rendered, Direct3D can look at the depth buffer (depth testing) and determine if the new primitive is in front of or behind one that was already rendered. If it is in front of the old primitive, then the new primitive is rendered; if it is not, the rendered scene is not affected.

The OBJ Models demo’s HLSL effect file is shown in Listing 14. The DepthStencilState is set in the technique by calling the HLSL function SetDepthStencilState(). A screenshot of the OBJ Models demo is shown in Figure 1.

Listing 14. The OBJ Models Demo’s HLSL Effect Shader
/*
  Texture Mapping HLSL Shader
  Ultimate Game Programming with DirectX 2nd Edition
  Created by Allen Sherrod
*/

Texture2D decal;
SamplerState DecalSampler
{
  Filter = MIN_MAG_MIP_LINEAR;
  AddressU = Wrap;
  ddressV = Wrap;
};

DepthStencilState DepthStencilInfo
{
   DepthEnable = true;
   DepthWriteMask = ALL;
   DepthFunc = Less;

   // Set up stencil states
   StencilEnable = true;
   StencilReadMask = 0xFF;
   StencilWriteMask = 0×00;

   FrontFaceStencilFunc = Not_Equal;
   FrontFaceStencilPass = Keep;
   FrontFaceStencilFail = Zero;

   BackFaceStencilFunc = Not_Equal;
   BackFaceStencilPass = Keep;
   BackFaceStencilFail = Zero;
};


cbuffer cbChangesEveryFrame
{
   matrix World;
   matrix View;
};
cbuffer cbChangeOnResize
{
   matrix Projection;
};

struct VS_INPUT
{
   float4 Pos : POSITION;
   float3 Norm : NORMAL;
   float2 Tex : TEXCOORD;
};

struct PS_INPUT
{
   float4 Pos : SV_POSITION;
   float2 Tex : TEXCOORDO;
};

PS_INPUT TextureMapVS(VS_INPUT input)
{
   PS_INPUT output = (PS_INPUT)0;

   float4 Pos = mul(input.Pos, World);
   Pos = mul(Pos, View);
   output.Pos = mul(Pos, Projection);

   output.Tex = input.Tex;

   return output;
}

float4 TextureMapPS(PS_INPUT input) : SV_Target
{
   return decal.Sample(DecalSampler, input.Tex);
}

techniquel0 TextureMapping
{
   pass P0
   {
      SetDepthStencilState(DepthStencilInfo, 0);

      SetVertexShader(CompileShader(vs_4_0, TextureMapVS()));
      SetGeometryShader(NULL);
      SetPixelShader(CompileShader(ps_4_0, TextureMapPS()));
   }
}

					  

Figure 1. The OBJ loader.
Other  
 
Top 10
Free Mobile And Desktop Apps For Accessing Restricted Websites
MASERATI QUATTROPORTE; DIESEL : Lure of Italian limos
TOYOTA CAMRY 2; 2.5 : Camry now more comely
KIA SORENTO 2.2CRDi : Fuel-sipping slugger
How To Setup, Password Protect & Encrypt Wireless Internet Connection
Emulate And Run iPad Apps On Windows, Mac OS X & Linux With iPadian
Backup & Restore Game Progress From Any Game With SaveGameProgress
Generate A Facebook Timeline Cover Using A Free App
New App for Women ‘Remix’ Offers Fashion Advice & Style Tips
SG50 Ferrari F12berlinetta : Prancing Horse for Lion City's 50th
- Messages forwarded by Outlook rule go nowhere
- Create and Deploy Windows 7 Image
- How do I check to see if my exchange 2003 is an open relay? (not using a open relay tester tool online, but on the console)
- Creating and using an unencrypted cookie in ASP.NET
- Directories
- Poor Performance on Sharepoint 2010 Server
- SBS 2008 ~ The e-mail alias already exists...
- Public to Private IP - DNS Changes
- Send Email from Winform application
- How to create a .mdb file from ms sql server database.......
programming4us programming4us
programming4us
 
 
programming4us