Share Pastebin
Guest
Public paste!

Untitled

By: a guest | Feb 16th, 2010 | Syntax: C++ | Size: 24.29 KB | Hits: 94 | Expires: Never
Copy text to clipboard
  1. #if !defined(WIN32_LEAN_AND_MEAN)
  2. #define WIN32_LEAN_AND_MEAN
  3. #endif
  4.  
  5. #if defined(_DEBUG)
  6. #define D3D_DEBUG_INFO
  7. #endif
  8.  
  9. #include <windows.h>
  10. #include <d3d9.h>
  11. #include <d3dx9.h>
  12. #include <sstream>
  13. #include <stdexcept>
  14. #include <string>
  15.  
  16. #if defined(_DEBUG)
  17. #include <crtdbg.h>
  18. #endif
  19.  
  20. //-----------------------------------------------------------------------------
  21. // Macros.
  22. //-----------------------------------------------------------------------------
  23.  
  24. #define SAFE_RELEASE(x) if ((x) != 0) { (x)->Release(); (x) = 0; }
  25.  
  26. //-----------------------------------------------------------------------------
  27. // Constants.
  28. //-----------------------------------------------------------------------------
  29.  
  30. #if !defined(CLEARTYPE_QUALITY)
  31. #define CLEARTYPE_QUALITY 5
  32. #endif
  33.  
  34. #if !defined(WHEEL_DELTA)
  35. #define WHEEL_DELTA 120
  36. #endif
  37.  
  38. #if !defined(WM_MOUSEWHEEL)
  39. #define WM_MOUSEWHEEL 0x020A
  40. #endif
  41.  
  42. #define APP_TITLE "D3D9 Normal Mapping"
  43.  
  44. #define EARTH_MESH                      "D:/Media/general.x"
  45.  
  46. const float CAMERA_FOVY = D3DXToRadian(45.0f);
  47. const float CAMERA_ZNEAR = 0.1f;
  48. const float CAMERA_ZFAR = 100.0f;
  49.  
  50. const float DOLLY_MIN = 0.0f;
  51. const float DOLLY_MAX = 10.0f;
  52.  
  53. const float MOUSE_ROTATE_SPEED = 0.30f;
  54. const float MOUSE_DOLLY_SPEED = 0.02f;
  55. const float MOUSE_TRACK_SPEED = 0.005f;
  56. const float MOUSE_WHEEL_DOLLY_SPEED = 0.005f;
  57.  
  58. const float LIGHT_RADIUS = 10.0f;
  59. const float LIGHT_SPOT_INNER_CONE = D3DXToRadian(10.0f);
  60. const float LIGHT_SPOT_OUTER_CONE = D3DXToRadian(30.0f);
  61.  
  62.  
  63.  
  64. LPDIRECT3DTEXTURE9         g_pBaseTexture = NULL;    //  base map texture surfaces
  65. LPDIRECT3DTEXTURE9       g_pBaseNormal = NULL;    //  normal / height map texture surfaces
  66.  
  67. //-----------------------------------------------------------------------------
  68. // User Defined Types.
  69. //-----------------------------------------------------------------------------
  70.  
  71. struct Vertex
  72. {
  73.     float pos[3];
  74.     float texCoord[2];
  75.     float normal[3];
  76.     float tangent[4];
  77. };
  78.  
  79. struct Light
  80. {
  81.     enum {DIR_LIGHT, POINT_LIGHT, SPOT_LIGHT};
  82.  
  83.     int type;
  84.     float dir[3];
  85.     float pos[3];
  86.     float ambient[4];
  87.     float diffuse[4];
  88.     float specular[4];
  89.     float spotInnerCone;
  90.     float spotOuterCone;
  91.     float radius;
  92. };
  93.  
  94. struct Material
  95. {
  96.     float ambient[4];
  97.     float diffuse[4];
  98.     float emissive[4];
  99.     float specular[4];
  100.     float shininess;
  101. };
  102.  
  103. //-----------------------------------------------------------------------------
  104. // Globals.
  105. //-----------------------------------------------------------------------------
  106.  
  107. HWND                         g_hWnd;
  108. HINSTANCE                    g_hInstance;
  109. IDirect3D9                  *g_pDirect3D;
  110. IDirect3DDevice9            *g_pDevice;
  111. ID3DXFont                   *g_pFont;
  112. ID3DXEffect                 *g_pEffect;
  113. IDirect3DVertexDeclaration9 *g_pVertexDecl;
  114. IDirect3DVertexBuffer9      *g_pVertexBuffer;
  115. IDirect3DTexture9           *g_pNullTexture;
  116. IDirect3DTexture9           *g_pColorMap;
  117. IDirect3DTexture9           *g_pNormalMap;
  118. DWORD                        g_msaaSamples;
  119. DWORD                        g_maxAnisotrophy;
  120. int                          g_framesPerSecond;
  121. int                          g_windowWidth;
  122. int                          g_windowHeight;
  123. bool                         g_enableVerticalSync;
  124. bool                         g_isFullScreen;
  125. bool                         g_hasFocus;
  126. bool                         g_wireframe;
  127. bool                         g_displayHelp;
  128. float                        g_pitch;
  129. float                        g_heading;
  130. float                        g_sceneAmbient[4] = {0.2f, 0.2f, 0.2f, 1.0f};
  131. D3DPRESENT_PARAMETERS        g_params;
  132. D3DXVECTOR3                  g_cameraPos(0.0f, 0.0f, -2.5f);
  133. D3DXVECTOR3                  g_cubePos(0.0f, 0.0f, 2.0f);
  134.  
  135. Light g_light =
  136. {
  137.     Light::DIR_LIGHT,
  138.     0.0f, 0.0f, 1.0f,                               // dir
  139.     0.0f, 0.0f, 0.0f, //g_cameraPos.x, g_cameraPos.y, g_cameraPos.z,    // pos
  140.     1.0f, 1.0f, 1.0f, 0.0f,                         // ambient
  141.     1.0f, 1.0f, 1.0f, 0.0f,                         // diffuse
  142.     1.0f, 1.0f, 1.0f, 0.0f,                         // specular
  143.     LIGHT_SPOT_INNER_CONE,                          // spotInnerCone
  144.     LIGHT_SPOT_OUTER_CONE,                          // spotOuterCone
  145.     LIGHT_RADIUS                                    // radius
  146. };
  147.  
  148. Material g_material =
  149. {
  150.     0.2f, 0.2f, 0.2f, 1.0f,                         // ambient
  151.     0.8f, 0.8f, 0.8f, 1.0f,                         // diffuse
  152.     0.0f, 0.0f, 0.0f, 1.0f,                         // emissive
  153.     0.7f, 0.7f, 0.7f, 1.0f,                         // specular
  154.     90.0f                                           // shininess
  155. };
  156.  
  157. /*
  158. D3DVERTEXELEMENT9 g_vertexElements[] =
  159. {
  160.     {0,  0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
  161.     {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
  162.     {0, 20, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,   0},
  163.     {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,  0},
  164.     D3DDECL_END()
  165. };*/
  166.  
  167.     const D3DVERTEXELEMENT9 g_vertexElements[] =
  168.     {
  169.         { 0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
  170.         { 0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
  171.         { 0, 20, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,   0 },
  172.         { 0, 32, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,  0 },
  173.         { 0, 44, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0 },
  174.         D3DDECL_END()
  175.     };
  176.  
  177.     ID3DXMesh*                  g_pMesh = NULL;            // Mesh object
  178.  
  179. //-----------------------------------------------------------------------------
  180. // Function Prototypes.
  181. //-----------------------------------------------------------------------------
  182.  
  183. ...
  184.  
  185. //-----------------------------------------------------------------------------
  186. // Functions.
  187. //-----------------------------------------------------------------------------
  188.  
  189. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
  190. {
  191.  
  192. ...
  193.  
  194.     g_hWnd = CreateAppWindow(wcl, APP_TITLE);
  195.  
  196.     if (g_hWnd)
  197.     {
  198.         SetProcessorAffinity();
  199.  
  200.         if (Init())
  201.         {
  202.             ShowWindow(g_hWnd, nShowCmd);
  203.             UpdateWindow(g_hWnd);
  204.  
  205.             while (true)
  206.             {
  207.                 while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
  208.                 {
  209.                     if (msg.message == WM_QUIT)
  210.                         break;
  211.  
  212.                     TranslateMessage(&msg);
  213.                     DispatchMessage(&msg);
  214.                 }
  215.  
  216.                 if (msg.message == WM_QUIT)
  217.                     break;
  218.  
  219.                 if (g_hasFocus)
  220.                 {
  221.  
  222.                     if (DeviceIsValid())
  223.                         RenderTUT();
  224.                 }
  225.                 else
  226.                 {
  227.                     WaitMessage();
  228.                 }
  229.             }
  230.         }
  231.  
  232.         Cleanup();
  233.         UnregisterClass(wcl.lpszClassName, hInstance);
  234.     }
  235.  
  236.     return static_cast<int>(msg.wParam);
  237. }
  238.  
  239. LRESULT CALLBACK WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
  240. {
  241. ...
  242. }
  243.  
  244. void ChooseBestMSAAMode(D3DFORMAT backBufferFmt, D3DFORMAT depthStencilFmt,
  245.                         BOOL windowed, D3DMULTISAMPLE_TYPE &type,
  246.                         DWORD &qualityLevels, DWORD &samplesPerPixel)
  247. {
  248.    ...
  249. }
  250.  
  251. void Cleanup()
  252. {
  253.     ...
  254. }
  255.  
  256. void CleanupApp()
  257. {
  258.     ...
  259. }
  260.  
  261. HWND CreateAppWindow(const WNDCLASSEX &wcl, const char *pszTitle)
  262. {
  263.    ...
  264.     return hWnd;
  265. }
  266.  
  267. bool CreateNullTexture(int width, int height, LPDIRECT3DTEXTURE9 &pTexture)
  268. {
  269.     // Create an empty white texture. This texture is applied to geometry
  270.     // that doesn't have any texture maps. This trick allows the same shader to
  271.     // be used to draw the geometry with and without textures applied.
  272.  
  273.     HRESULT hr = D3DXCreateTexture(g_pDevice, width, height, 0, 0,
  274.                     D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &pTexture);
  275.  
  276.     if (FAILED(hr))
  277.         return false;
  278.  
  279.     LPDIRECT3DSURFACE9 pSurface = 0;
  280.  
  281.     if (SUCCEEDED(pTexture->GetSurfaceLevel(0, &pSurface)))
  282.     {
  283.         D3DLOCKED_RECT rcLock = {0};
  284.  
  285.         if (SUCCEEDED(pSurface->LockRect(&rcLock, 0, 0)))
  286.         {
  287.             BYTE *pPixels = static_cast<BYTE*>(rcLock.pBits);
  288.             int widthInBytes = width * 4;
  289.  
  290.             if (widthInBytes == rcLock.Pitch)
  291.             {
  292.                 memset(pPixels, 0xff, widthInBytes * height);
  293.             }
  294.             else
  295.             {
  296.                 for (int y = 0; y < height; ++y)
  297.                     memset(&pPixels[y * rcLock.Pitch], 0xff, rcLock.Pitch);
  298.             }
  299.  
  300.             pSurface->UnlockRect();
  301.             pSurface->Release();
  302.             return true;
  303.         }
  304.  
  305.         pSurface->Release();
  306.     }
  307.  
  308.     pTexture->Release();
  309.     return false;
  310. }
  311.  
  312. bool DeviceIsValid()
  313. {
  314.     HRESULT hr = g_pDevice->TestCooperativeLevel();
  315.  
  316.     if (FAILED(hr))
  317.     {
  318.         if (hr == D3DERR_DEVICENOTRESET)
  319.             return ResetDevice();
  320.     }
  321.  
  322.     return true;
  323. }
  324.  
  325. float GetElapsedTimeInSeconds()
  326. {
  327.     // Returns the elapsed time (in seconds) since the last time this function
  328. ...
  329.     return actualElapsedTimeSec;
  330. }
  331.  
  332. bool Init()
  333. {
  334.     if (!InitD3D())
  335.     {
  336.         Log("Direct3D initialization failed!");
  337.         return false;
  338.     }
  339.  
  340.     try
  341.     {
  342.         InitApp();
  343.         return true;
  344.     }
  345.     catch (const std::exception &e)
  346.     {
  347.         std::ostringstream msg;
  348.  
  349.         msg << "Application initialization failed!" << std::endl << std::endl;
  350.         msg << e.what();
  351.  
  352.         Log(msg.str().c_str());
  353.         return false;
  354.     }
  355. }
  356.  
  357. void InitApp()
  358. {
  359.     if (!InitFont("Arial", 10, g_pFont))
  360.         throw std::runtime_error("Failed to create font.");
  361.  
  362.     if (!CreateNullTexture(2, 2, g_pNullTexture))
  363.         throw std::runtime_error("Failed to create null texture.");
  364.  
  365.     //if (FAILED(D3DXCreateTextureFromFile(g_pDevice, "Content/Textures/color_map.jpg", &g_pColorMap)))
  366.     if (FAILED(D3DXCreateTextureFromFile(g_pDevice, "D:/BoD/Programming/Client/Media/white.tga", &g_pColorMap)))
  367.         throw std::runtime_error("Failed to load texture: color_map.jpg.");
  368.  
  369.     //if (FAILED(D3DXCreateTextureFromFile(g_pDevice, "Content/Textures/normal_map.jpg", &g_pNormalMap)))
  370.     if (FAILED(D3DXCreateTextureFromFile(g_pDevice, "D:/BoD/Programming/Client/Media/white.tga", &g_pNormalMap)))
  371.         throw std::runtime_error("Failed to load texture: normal_map.jpg.");
  372.  
  373.     if (!LoadShader("Content/Shaders/ParallaxOcclusionMapping.fx", g_pEffect))
  374.         throw std::runtime_error("Failed to load shader: normal_mapping.fx.");
  375.  
  376.     LoadMesh( g_pDevice, &g_pMesh );
  377. }
  378.  
  379.  
  380. bool InitD3D()
  381. {
  382.     HRESULT hr = 0;
  383.     D3DDISPLAYMODE desktop = {0};
  384.  
  385.     g_pDirect3D = Direct3DCreate9(D3D_SDK_VERSION);
  386.  
  387.     if (!g_pDirect3D)
  388.         return false;
  389.  
  390.     // Just use the current desktop display mode.
  391.     hr = g_pDirect3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &desktop);
  392.  
  393.     if (FAILED(hr))
  394.     {
  395.         g_pDirect3D->Release();
  396.         g_pDirect3D = 0;
  397.         return false;
  398.     }
  399.  
  400.     // Setup Direct3D for windowed rendering.
  401.     g_params.BackBufferWidth = 0;
  402.     g_params.BackBufferHeight = 0;
  403.     g_params.BackBufferFormat = desktop.Format;
  404.     g_params.BackBufferCount = 1;
  405.     g_params.hDeviceWindow = g_hWnd;
  406.     g_params.Windowed = TRUE;
  407.     g_params.EnableAutoDepthStencil = TRUE;
  408.     g_params.AutoDepthStencilFormat = D3DFMT_D24S8;
  409.     g_params.Flags = D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL;
  410.     g_params.FullScreen_RefreshRateInHz = 0;
  411.  
  412.     if (g_enableVerticalSync)
  413.         g_params.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
  414.     else
  415.         g_params.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
  416.  
  417.     // Swap effect must be D3DSWAPEFFECT_DISCARD for multi-sampling support.
  418.     g_params.SwapEffect = D3DSWAPEFFECT_DISCARD;
  419.  
  420.     // Select the highest quality multi-sample anti-aliasing (MSAA) mode.
  421.     ChooseBestMSAAMode(g_params.BackBufferFormat, g_params.AutoDepthStencilFormat,
  422.         g_params.Windowed, g_params.MultiSampleType, g_params.MultiSampleQuality,
  423.         g_msaaSamples);
  424.  
  425.     // Most modern video cards should have no problems creating pure devices.
  426.     // Note that by creating a pure device we lose the ability to debug vertex
  427.     // and pixel shaders.
  428.     hr = g_pDirect3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, g_hWnd,
  429.         D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE,
  430.         &g_params, &g_pDevice);
  431.  
  432.     if (FAILED(hr))
  433.     {
  434.         // Fall back to software vertex processing for less capable hardware.
  435.         // Note that in order to debug vertex shaders we must use a software
  436.         // vertex processing device.
  437.         hr = g_pDirect3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
  438.             g_hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &g_params, &g_pDevice);
  439.     }
  440.  
  441.     if (FAILED(hr))
  442.     {
  443.         g_pDirect3D->Release();
  444.         g_pDirect3D = 0;
  445.         return false;
  446.     }
  447.  
  448.     D3DCAPS9 caps;
  449.  
  450.     // Prefer anisotropic texture filtering if it's supported.
  451.     if (SUCCEEDED(g_pDevice->GetDeviceCaps(&caps)))
  452.     {
  453.         if (caps.RasterCaps & D3DPRASTERCAPS_ANISOTROPY)
  454.             g_maxAnisotrophy = caps.MaxAnisotropy;
  455.         else
  456.             g_maxAnisotrophy = 1;
  457.     }
  458.  
  459.     return true;
  460. }
  461.  
  462. bool InitFont(const char *pszFont, int ptSize, LPD3DXFONT &pFont)
  463. {
  464.    ...
  465.     return SUCCEEDED(hr) ? true : false;
  466. }
  467.  
  468. bool LoadShader(const char *pszFilename, LPD3DXEFFECT &pEffect)
  469. {
  470.     ID3DXBuffer *pCompilationErrors = 0;
  471.     DWORD dwShaderFlags = D3DXFX_NOT_CLONEABLE | D3DXSHADER_NO_PRESHADER;
  472.  
  473.     // Both vertex and pixel shaders can be debugged. To enable shader
  474.     // debugging add the following flag to the dwShaderFlags variable:
  475.     //      dwShaderFlags |= D3DXSHADER_DEBUG;
  476.     //
  477.     // Vertex shaders can be debugged with either the REF device or a device
  478.     // created for software vertex processing (i.e., the IDirect3DDevice9
  479.     // object must be created with the D3DCREATE_SOFTWARE_VERTEXPROCESSING
  480.     // behavior). Pixel shaders can be debugged only using the REF device.
  481.     //
  482.     // To enable vertex shader debugging add the following flag to the
  483.     // dwShaderFlags variable:
  484.     //     dwShaderFlags |= D3DXSHADER_FORCE_VS_SOFTWARE_NOOPT;
  485.     //
  486.     // To enable pixel shader debugging add the following flag to the
  487.     // dwShaderFlags variable:
  488.     //     dwShaderFlags |= D3DXSHADER_FORCE_PS_SOFTWARE_NOOPT;
  489.  
  490.     HRESULT hr = D3DXCreateEffectFromFile(g_pDevice, pszFilename, 0, 0,
  491.                     dwShaderFlags, 0, &pEffect, &pCompilationErrors);
  492.  
  493.     if (FAILED(hr))
  494.     {
  495.         if (pCompilationErrors)
  496.         {
  497.             std::string compilationErrors(static_cast<const char *>(
  498.                 pCompilationErrors->GetBufferPointer()));
  499.  
  500.             pCompilationErrors->Release();
  501.             throw std::runtime_error(compilationErrors);
  502.         }
  503.     }
  504.  
  505.     if (pCompilationErrors)
  506.         pCompilationErrors->Release();
  507.  
  508. //CHANGES
  509.         D3DXCreateTextureFromFile( g_pDevice, "C:/Users/X/Desktop/Content/Textures/color_map.jpg", &g_pBaseTexture );
  510.         D3DXCreateTextureFromFile( g_pDevice, "C:/Users/X/Desktop/Content/Textures/normal_map.jpg", &g_pBaseNormal );
  511.  
  512.     g_pEffect->SetTexture( "g_baseTexture", g_pBaseTexture );
  513.     g_pEffect->SetTexture( "g_nmhTexture", g_pBaseNormal  );
  514.  
  515.  
  516.     return pEffect != 0;
  517. }
  518.  
  519. void Log(const char *pszMessage)
  520. {
  521.     MessageBox(0, pszMessage, "Error", MB_ICONSTOP);
  522. }
  523.  
  524. void ProcessMouseInput(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
  525. {
  526. ...
  527. }
  528.  
  529. bool ResetDevice()
  530. {
  531. ...
  532. }
  533.  
  534. void SetProcessorAffinity()
  535. {
  536. ...
  537. }
  538.  
  539. void ToggleFullScreen()
  540. {
  541. ...
  542. }
  543.  
  544.  
  545.  
  546. void  RenderTUT()
  547. {
  548.     static D3DXMATRIX world, view, proj;
  549.     static D3DXMATRIX xRot, yRot, translation;
  550.     static D3DXMATRIX worldViewProjectionMatrix;
  551.     static D3DXMATRIX worldInverseTransposeMatrix;
  552.  
  553.     // Calculate the perspective projection matrix.
  554.     D3DXMatrixPerspectiveFovLH(&proj, CAMERA_FOVY,
  555.         static_cast<float>(g_windowWidth) / static_cast<float>(g_windowHeight),
  556.         CAMERA_ZNEAR, CAMERA_ZFAR);
  557.  
  558.     // Calculate the view matrix.
  559.     D3DXMatrixLookAtLH(&view, &g_cameraPos, &D3DXVECTOR3(0.0f, 0.0f, 0.0f),
  560.         &D3DXVECTOR3(0.0f, 1.0f, 0.0f));
  561.  
  562.     // Calculate world matrix to transform the cube.
  563.     D3DXMatrixRotationX(&xRot, D3DXToRadian(g_pitch));
  564.     D3DXMatrixRotationY(&yRot, D3DXToRadian(g_heading));
  565.     D3DXMatrixMultiply(&world, &yRot, &xRot);
  566.     D3DXMatrixTranslation(&translation, g_cubePos.x, g_cubePos.y, g_cubePos.z);
  567.     D3DXMatrixMultiply(&world, &world, &translation);
  568.  
  569.     // Calculate combined world-view-projection matrix.
  570.     worldViewProjectionMatrix = world * view * proj;
  571.  
  572.     // Calculate the transpose of the inverse of the world matrix.
  573.     D3DXMatrixInverse(&worldInverseTransposeMatrix, 0, &world);
  574.     D3DXMatrixTranspose(&worldInverseTransposeMatrix, &worldInverseTransposeMatrix);
  575.  
  576. /*
  577. float lightDir[4];
  578.     lightDir[0]=g_light.dir[0];
  579.     lightDir[1]=g_light.dir[1];
  580.     lightDir[2]=g_light.dir[2];
  581.     lightDir[3]=0.0f;*/
  582.  
  583.     D3DXVECTOR3 lightDir;
  584.     lightDir.x=g_light.dir[0];
  585.     lightDir.y=g_light.dir[1];
  586.     lightDir.z=g_light.dir[2];
  587.     lightDir[3]=0.0f;
  588.  
  589. D3DXCOLOR vLightDiffuse;
  590. float                       g_fLightScale = 1.0f;
  591. vLightDiffuse = g_fLightScale * D3DXCOLOR( 1, 1, 1, 1 );
  592.  
  593.         g_pEffect->SetValue( "g_LightDir", &lightDir, sizeof( D3DXVECTOR3 ) );
  594.         g_pEffect->SetValue( "g_LightDiffuse", &vLightDiffuse, sizeof( D3DXVECTOR4 ) );
  595.  
  596.     // Set the matrices for the shader.
  597.     //g_pEffect->SetMatrix("worldMatrix", &world);
  598.     g_pEffect->SetMatrix("g_mWorldViewProjection", &worldViewProjectionMatrix);
  599.     g_pEffect->SetMatrix( "g_mWorld", &world );
  600.     g_pEffect->SetMatrix( "g_mView", &view );
  601.  
  602.             D3DXVECTOR4 vEye;
  603.         /*D3DXVECTOR3 vTemp = ( *g_Camera.GetEyePt() );
  604.         vEye.x = vTemp.x;
  605.         vEye.y = vTemp.y;
  606.         vEye.z = vTemp.z;
  607.         vEye.w = 1.0;*/
  608.         vEye.x = g_cameraPos.x;
  609.         vEye.y = g_cameraPos.y;
  610.         vEye.z = g_cameraPos.z;
  611.         vEye.w = 1.0;
  612.  
  613.     g_pEffect->SetVector( "g_vEye", &vEye );
  614.  
  615.     //strzal ;-)
  616.     float                       g_fHeightScale = 100.0f;
  617.  
  618.     g_pEffect->SetValue( "g_fHeightMapScale", &g_fHeightScale, sizeof( float ) );
  619.  
  620.     g_pEffect->SetTechnique( "RenderSceneWithPOM" );
  621.  
  622. /*
  623. UINT iPass, cPasses;
  624.     g_pEffect->Begin( &cPasses, 0 );
  625.         for( iPass = 0; iPass < cPasses; iPass++ )
  626.         {
  627.             g_pEffect->BeginPass( iPass );
  628.             g_pMesh->DrawSubset( 0 );
  629.             g_pEffect->EndPass();
  630.         }
  631.         g_pEffect->End();
  632.     }
  633.  
  634. */
  635.  
  636.     g_pDevice->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
  637.         D3DCOLOR_XRGB(100, 149, 237),   // CornflowerBlue
  638.         1.0f, 0);
  639.  
  640.     if (FAILED(g_pDevice->BeginScene()))
  641.         return;
  642.  
  643. UINT    totalPasses;
  644.  
  645.         if (SUCCEEDED(g_pEffect->Begin(&totalPasses, 0)))
  646.         {
  647.         for( UINT iPass = 0; iPass < totalPasses; iPass++ )
  648.         {
  649.             g_pEffect->BeginPass( iPass );
  650.             g_pMesh->DrawSubset( 0 );
  651.             g_pEffect->EndPass();
  652.         }
  653.         g_pEffect->End();
  654.         }
  655.  
  656.     g_pDevice->EndScene();
  657. g_pDevice->Present(0, 0, 0, 0);
  658. }
  659.  
  660.  
  661. //--------------------------------------------------------------------------------------
  662. // This function loads the mesh and ensures the mesh has normals; it also
  663. // optimizes the mesh for the graphics card's vertex cache, which improves
  664. // performance by organizing the internal triangle list for less cache misses.
  665. //--------------------------------------------------------------------------------------
  666. HRESULT LoadMesh( IDirect3DDevice9* pd3dDevice, ID3DXMesh** ppMesh )
  667. {
  668.     ID3DXMesh* pMesh = NULL;
  669.     HRESULT hr;
  670.  
  671.     //====================================================================//
  672.     // Load the mesh with D3DX and get back a ID3DXMesh*.  For this       //
  673.     // sample we'll ignore the X file's embedded materials since we know  //
  674.     // exactly the model we're loading.  See the mesh samples such as     //
  675.     // "OptimizedMesh" for a more generic mesh loading example.           //
  676.     //====================================================================//
  677.         HRESULT hResult = D3DXLoadMeshFromX( EARTH_MESH, D3DXMESH_SYSTEMMEM, g_pDevice, NULL,
  678.                                                                         NULL, NULL, NULL, &pMesh );
  679.  
  680.     // Create a new vertex declaration to hold all the required data
  681.     const D3DVERTEXELEMENT9 vertexDecl[] =
  682.     {
  683.         { 0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
  684.         { 0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
  685.         { 0, 20, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,   0 },
  686.         { 0, 32, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,  0 },
  687.         { 0, 44, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0 },
  688.         D3DDECL_END()
  689.     };
  690.  
  691.     LPD3DXMESH pTempMesh = NULL;
  692.  
  693.     // Clone mesh to match the specified declaration:
  694.     if( FAILED( pMesh->CloneMesh( pMesh->GetOptions(), vertexDecl, pd3dDevice, &pTempMesh ) ) )
  695.     {
  696.         SAFE_RELEASE( pTempMesh );
  697.         return E_FAIL;
  698.     }
  699.  
  700.     //====================================================================//
  701.     // Check if the old declaration contains normals, tangents, binormals //
  702.     //====================================================================//
  703.     bool bHadNormal = false;
  704.     bool bHadTangent = false;
  705.     bool bHadBinormal = false;
  706.  
  707.     D3DVERTEXELEMENT9 vertexOldDecl[ MAX_FVF_DECL_SIZE ];
  708.  
  709.     if( pMesh && SUCCEEDED( pMesh->GetDeclaration( vertexOldDecl ) ) )
  710.     {
  711.         // Go through the declaration and look for the right channels, hoping for a match:
  712.         for( UINT iChannelIndex = 0; iChannelIndex < D3DXGetDeclLength( vertexOldDecl ); iChannelIndex++ )
  713.         {
  714.             if( vertexOldDecl[iChannelIndex].Usage == D3DDECLUSAGE_NORMAL )
  715.             {
  716.                 bHadNormal = true;
  717.             }
  718.  
  719.             if( vertexOldDecl[iChannelIndex].Usage == D3DDECLUSAGE_TANGENT )
  720.             {
  721.                 bHadTangent = true;
  722.             }
  723.  
  724.             if( vertexOldDecl[iChannelIndex].Usage == D3DDECLUSAGE_BINORMAL )
  725.             {
  726.                 bHadBinormal = true;
  727.             }
  728.         }
  729.     }
  730.  
  731.     if( pTempMesh == NULL && ( bHadNormal == false || bHadTangent == false || bHadBinormal == false ) )
  732.     {
  733.         // We failed to clone the mesh and we need the tangent space for our effect:
  734.         return E_FAIL;
  735.     }
  736.  
  737.     //==============================================================//
  738.     // Generate normals / tangents / binormals if they were missing //
  739.     //==============================================================//
  740.     SAFE_RELEASE( pMesh );
  741.     pMesh = pTempMesh;
  742.  
  743.     if( !bHadNormal )
  744.     {
  745.         // Compute normals in case the meshes have them
  746.         D3DXComputeNormals( pMesh, NULL );
  747.     }
  748.  
  749.     DWORD* rgdwAdjacency = NULL;
  750.     rgdwAdjacency = new DWORD[ pMesh->GetNumFaces() * 3 ];
  751.  
  752.     if( rgdwAdjacency == NULL )
  753.     {
  754.         return E_OUTOFMEMORY;
  755.     }
  756.     pMesh->GenerateAdjacency( 1e-6f, rgdwAdjacency );
  757.  
  758.     // Optimize the mesh for this graphics card's vertex cache
  759.     // so when rendering the mesh's triangle list the vertices will
  760.     // cache hit more often so it won't have to re-execute the vertex shader
  761.     // on those vertices so it will improve perf.
  762.     pMesh->OptimizeInplace( D3DXMESHOPT_VERTEXCACHE, rgdwAdjacency, NULL, NULL, NULL );
  763.  
  764.     if( !bHadTangent || !bHadBinormal )
  765.     {
  766.         ID3DXMesh* pNewMesh;
  767.  
  768.         // Compute tangents, which are required for normal mapping
  769.         if( FAILED( D3DXComputeTangentFrameEx( pMesh, D3DDECLUSAGE_TEXCOORD, 0, D3DDECLUSAGE_TANGENT, 0,
  770.                                                D3DDECLUSAGE_BINORMAL, 0,
  771.                                                D3DDECLUSAGE_NORMAL, 0, 0, rgdwAdjacency, -1.01f,
  772.                                                -0.01f, -1.01f, &pNewMesh, NULL ) ) )
  773.         {
  774.             return E_FAIL;
  775.         }
  776.  
  777.         SAFE_RELEASE( pMesh );
  778.         pMesh = pNewMesh;
  779.     }
  780.  
  781. //    SAFE_DELETE_ARRAY( rgdwAdjacency );
  782.  
  783.     *ppMesh = pMesh;
  784.  
  785.     return S_OK;
  786.  
  787. }