home *** CD-ROM | disk | FTP | other *** search
/ Windows Game Programming for Dummies (2nd Edition) / WinGamProgFD.iso / pc / DirectX SDK / DXSDK / samples / Multimedia / Direct3D / Tutorials / Tut05_Textures / Textures.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2001-10-31  |  12.9 KB  |  342 lines

  1. //-----------------------------------------------------------------------------
  2. // File: Textures.cpp
  3. //
  4. // Desc: Better than just lights and materials, 3D objects look much more
  5. //       convincing when texture-mapped. Textures can be thought of as a sort
  6. //       of wallpaper, that is shrinkwrapped to fit a texture. Textures are
  7. //       typically loaded from image files, and D3DX provides a utility to
  8. //       function to do this for us. Like a vertex buffer, textures have
  9. //       Lock() and Unlock() functions to access (read or write) the image
  10. //       data. Textures have a width, height, miplevel, and pixel format. The
  11. //       miplevel is for "mipmapped" textures, an advanced performance-
  12. //       enhancing feature which uses lower resolutions of the texture for
  13. //       objects in the distance where detail is less noticeable. The pixel
  14. //       format determines how the colors are stored in a texel. The most
  15. //       common formats are the 16-bit R5G6B5 format (5 bits of red, 6-bits of
  16. //       green and 5 bits of blue) and the 32-bit A8R8G8B8 format (8 bits each
  17. //       of alpha, red, green, and blue).
  18. //
  19. //       Textures are associated with geometry through texture coordinates.
  20. //       Each vertex has one or more sets of texture coordinates, which are
  21. //       named tu and tv and range from 0.0 to 1.0. Texture coordinates can be
  22. //       supplied by the geometry, or can be automatically generated using
  23. //       Direct3D texture coordinate generation (which is an advanced feature).
  24. //
  25. // Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
  26. //-----------------------------------------------------------------------------
  27. #include <d3dx8.h>
  28. #include <mmsystem.h>
  29.  
  30.  
  31.  
  32.  
  33. //-----------------------------------------------------------------------------
  34. // Global variables
  35. //-----------------------------------------------------------------------------
  36. LPDIRECT3D8             g_pD3D       = NULL; // Used to create the D3DDevice
  37. LPDIRECT3DDEVICE8       g_pd3dDevice = NULL; // Our rendering device
  38. LPDIRECT3DVERTEXBUFFER8 g_pVB        = NULL; // Buffer to hold vertices
  39. LPDIRECT3DTEXTURE8      g_pTexture   = NULL; // Our texture
  40.  
  41. // A structure for our custom vertex type. We added texture coordinates
  42. struct CUSTOMVERTEX
  43. {
  44.     D3DXVECTOR3 position; // The position
  45.     D3DCOLOR    color;    // The color
  46.     FLOAT       tu, tv;   // The texture coordinates
  47. };
  48.  
  49. // Our custom FVF, which describes our custom vertex structure
  50. #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1)
  51.  
  52.  
  53.  
  54.  
  55. //-----------------------------------------------------------------------------
  56. // Name: InitD3D()
  57. // Desc: Initializes Direct3D
  58. //-----------------------------------------------------------------------------
  59. HRESULT InitD3D( HWND hWnd )
  60. {
  61.     // Create the D3D object.
  62.     if( NULL == ( g_pD3D = Direct3DCreate8( D3D_SDK_VERSION ) ) )
  63.         return E_FAIL;
  64.  
  65.     // Get the current desktop display mode, so we can set up a back
  66.     // buffer of the same format
  67.     D3DDISPLAYMODE d3ddm;
  68.     if( FAILED( g_pD3D->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &d3ddm ) ) )
  69.         return E_FAIL;
  70.  
  71.     // Set up the structure used to create the D3DDevice. Since we are now
  72.     // using more complex geometry, we will create a device with a zbuffer.
  73.     D3DPRESENT_PARAMETERS d3dpp;
  74.     ZeroMemory( &d3dpp, sizeof(d3dpp) );
  75.     d3dpp.Windowed = TRUE;
  76.     d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
  77.     d3dpp.BackBufferFormat = d3ddm.Format;
  78.     d3dpp.EnableAutoDepthStencil = TRUE;
  79.     d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
  80.  
  81.     // Create the D3DDevice
  82.     if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
  83.                                       D3DCREATE_SOFTWARE_VERTEXPROCESSING,
  84.                                       &d3dpp, &g_pd3dDevice ) ) )
  85.     {
  86.         return E_FAIL;
  87.     }
  88.  
  89.     // Turn off culling
  90.     g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
  91.  
  92.     // Turn off D3D lighting
  93.     g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
  94.  
  95.     // Turn on the zbuffer
  96.     g_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE );
  97.  
  98.     return S_OK;
  99. }
  100.  
  101.  
  102.  
  103.  
  104. //-----------------------------------------------------------------------------
  105. // Name: InitGeometry()
  106. // Desc: Create the textures and vertex buffers
  107. //-----------------------------------------------------------------------------
  108. HRESULT InitGeometry()
  109. {
  110.     // Use D3DX to create a texture from a file based image
  111.     if( FAILED( D3DXCreateTextureFromFile( g_pd3dDevice, "banana.bmp",
  112.                                            &g_pTexture ) ) )
  113.         return E_FAIL;
  114.  
  115.     // Create the vertex buffer.
  116.     if( FAILED( g_pd3dDevice->CreateVertexBuffer( 50*2*sizeof(CUSTOMVERTEX),
  117.                                                   0, D3DFVF_CUSTOMVERTEX,
  118.                                                   D3DPOOL_DEFAULT, &g_pVB ) ) )
  119.     {
  120.         return E_FAIL;
  121.     }
  122.  
  123.     // Fill the vertex buffer. We are setting the tu and tv texture
  124.     // coordinates, which range from 0.0 to 1.0
  125.     CUSTOMVERTEX* pVertices;
  126.     if( FAILED( g_pVB->Lock( 0, 0, (BYTE**)&pVertices, 0 ) ) )
  127.         return E_FAIL;
  128.     for( DWORD i=0; i<50; i++ )
  129.     {
  130.         FLOAT theta = (2*D3DX_PI*i)/(50-1);
  131.  
  132.         pVertices[2*i+0].position = D3DXVECTOR3( sinf(theta),-1.0f, cosf(theta) );
  133.         pVertices[2*i+0].color    = 0xffffffff;
  134.         pVertices[2*i+0].tu       = ((FLOAT)i)/(50-1);
  135.         pVertices[2*i+0].tv       = 1.0f;
  136.  
  137.         pVertices[2*i+1].position = D3DXVECTOR3( sinf(theta), 1.0f, cosf(theta) );
  138.         pVertices[2*i+1].color    = 0xff808080;
  139.         pVertices[2*i+1].tu       = ((FLOAT)i)/(50-1);
  140.         pVertices[2*i+1].tv       = 0.0f;
  141.     }
  142.     g_pVB->Unlock();
  143.  
  144.     return S_OK;
  145. }
  146.  
  147.  
  148.  
  149.  
  150. //-----------------------------------------------------------------------------
  151. // Name: Cleanup()
  152. // Desc: Releases all previously initialized objects
  153. //-----------------------------------------------------------------------------
  154. VOID Cleanup()
  155. {
  156.     if( g_pTexture != NULL )
  157.         g_pTexture->Release();
  158.  
  159.     if( g_pVB != NULL )
  160.         g_pVB->Release();
  161.  
  162.     if( g_pd3dDevice != NULL )
  163.         g_pd3dDevice->Release();
  164.  
  165.     if( g_pD3D != NULL )
  166.         g_pD3D->Release();
  167. }
  168.  
  169.  
  170.  
  171. //-----------------------------------------------------------------------------
  172. // Name: SetupMatrices()
  173. // Desc: Sets up the world, view, and projection transform matrices.
  174. //-----------------------------------------------------------------------------
  175. VOID SetupMatrices()
  176. {
  177.     // For our world matrix, we will just leave it as the identity
  178.     D3DXMATRIX matWorld;
  179.     D3DXMatrixIdentity( &matWorld );
  180.     D3DXMatrixRotationX( &matWorld, timeGetTime()/1000.0f );
  181.     g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
  182.  
  183.     // Set up our view matrix. A view matrix can be defined given an eye point,
  184.     // a point to lookat, and a direction for which way is up. Here, we set the
  185.     // eye five units back along the z-axis and up three units, look at the
  186.     // origin, and define "up" to be in the y-direction.
  187.     D3DXMATRIX matView;
  188.     D3DXMatrixLookAtLH( &matView, &D3DXVECTOR3( 0.0f, 3.0f,-5.0f ),
  189.                                   &D3DXVECTOR3( 0.0f, 0.0f, 0.0f ),
  190.                                   &D3DXVECTOR3( 0.0f, 1.0f, 0.0f ) );
  191.     g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );
  192.  
  193.     // For the projection matrix, we set up a perspective transform (which
  194.     // transforms geometry from 3D view space to 2D viewport space, with
  195.     // a perspective divide making objects smaller in the distance). To build
  196.     // a perpsective transform, we need the field of view (1/4 pi is common),
  197.     // the aspect ratio, and the near and far clipping planes (which define at
  198.     // what distances geometry should be no longer be rendered).
  199.     D3DXMATRIX matProj;
  200.     D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, 1.0f, 1.0f, 100.0f );
  201.     g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );
  202. }
  203.  
  204.  
  205.  
  206.  
  207. //-----------------------------------------------------------------------------
  208. // Name: Render()
  209. // Desc: Draws the scene
  210. //-----------------------------------------------------------------------------
  211. VOID Render()
  212. {
  213.     // Clear the backbuffer and the zbuffer
  214.     g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,
  215.                          D3DCOLOR_XRGB(0,0,255), 1.0f, 0 );
  216.  
  217.     // Begin the scene
  218.     g_pd3dDevice->BeginScene();
  219.  
  220.     // Setup the world, view, and projection matrices
  221.     SetupMatrices();
  222.  
  223.     // Setup our texture. Using textures introduces the texture stage states,
  224.     // which govern how textures get blended together (in the case of multiple
  225.     // textures) and lighting information. In this case, we are modulating
  226.     // (blending) our texture with the diffuse color of the vertices.
  227.     g_pd3dDevice->SetTexture( 0, g_pTexture );
  228.     g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_MODULATE );
  229.     g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
  230.     g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
  231.     g_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP,   D3DTOP_DISABLE );
  232.  
  233. #ifdef SHOW_HOW_TO_USE_TCI
  234.     // Note: to use D3D texture coordinate generation, use the stage state
  235.     // D3DTSS_TEXCOORDINDEX, as shown below. In this example, we are using
  236.     // the position of the vertex in camera space to generate texture
  237.     // coordinates. The tex coord index (TCI) parameters are passed into a
  238.     // texture transform, which is a 4x4 matrix which transforms the x,y,z
  239.     // TCI coordinates into tu, tv texture coordinates.
  240.  
  241.     // In this example, the texture matrix is setup to 
  242.     // transform the texture from (-1,+1) position coordinates to (0,1) 
  243.     // texture coordinate space:
  244.     //    tu =  0.5*x + 0.5
  245.     //    tv = -0.5*y + 0.5
  246.     D3DXMATRIX mat;
  247.     mat._11 = 0.25f; mat._12 = 0.00f; mat._13 = 0.00f; mat._14 = 0.00f;
  248.     mat._21 = 0.00f; mat._22 =-0.25f; mat._23 = 0.00f; mat._24 = 0.00f;
  249.     mat._31 = 0.00f; mat._32 = 0.00f; mat._33 = 1.00f; mat._34 = 0.00f;
  250.     mat._41 = 0.50f; mat._42 = 0.50f; mat._43 = 0.00f; mat._44 = 1.00f;
  251.  
  252.     g_pd3dDevice->SetTransform( D3DTS_TEXTURE0, &mat );
  253.     g_pd3dDevice->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2 );
  254.     g_pd3dDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION );
  255. #endif
  256.  
  257.     // Render the vertex buffer contents
  258.     g_pd3dDevice->SetStreamSource( 0, g_pVB, sizeof(CUSTOMVERTEX) );
  259.     g_pd3dDevice->SetVertexShader( D3DFVF_CUSTOMVERTEX );
  260.     g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2*50-2 );
  261.  
  262.     // End the scene
  263.     g_pd3dDevice->EndScene();
  264.  
  265.     // Present the backbuffer contents to the display
  266.     g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
  267. }
  268.  
  269.  
  270.  
  271.  
  272. //-----------------------------------------------------------------------------
  273. // Name: MsgProc()
  274. // Desc: The window's message handler
  275. //-----------------------------------------------------------------------------
  276. LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
  277. {
  278.     switch( msg )
  279.     {
  280.         case WM_DESTROY:
  281.             PostQuitMessage( 0 );
  282.             return 0;
  283.     }
  284.  
  285.     return DefWindowProc( hWnd, msg, wParam, lParam );
  286. }
  287.  
  288.  
  289.  
  290.  
  291. //-----------------------------------------------------------------------------
  292. // Name: WinMain()
  293. // Desc: The application's entry point
  294. //-----------------------------------------------------------------------------
  295. INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
  296. {
  297.     // Register the window class
  298.     WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,
  299.                       GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
  300.                       "D3D Tutorial", NULL };
  301.     RegisterClassEx( &wc );
  302.  
  303.     // Create the application's window
  304.     HWND hWnd = CreateWindow( "D3D Tutorial", "D3D Tutorial 05: Textures",
  305.                               WS_OVERLAPPEDWINDOW, 100, 100, 300, 300,
  306.                               GetDesktopWindow(), NULL, wc.hInstance, NULL );
  307.  
  308.     // Initialize Direct3D
  309.     if( SUCCEEDED( InitD3D( hWnd ) ) )
  310.     {
  311.         // Create the scene geometry
  312.         if( SUCCEEDED( InitGeometry() ) )
  313.         {
  314.             // Show the window
  315.             ShowWindow( hWnd, SW_SHOWDEFAULT );
  316.             UpdateWindow( hWnd );
  317.  
  318.             // Enter the message loop
  319.             MSG msg;
  320.             ZeroMemory( &msg, sizeof(msg) );
  321.             while( msg.message!=WM_QUIT )
  322.             {
  323.                 if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
  324.                 {
  325.                     TranslateMessage( &msg );
  326.                     DispatchMessage( &msg );
  327.                 }
  328.                 else
  329.                     Render();
  330.             }
  331.         }
  332.     }
  333.  
  334.     // Clean up everything and exit the app
  335.     Cleanup();
  336.     UnregisterClass( "D3D Tutorial", wc.hInstance );
  337.     return 0;
  338. }
  339.  
  340.  
  341.  
  342.