locked
direct3D Beginners question RRS feed

  • Question

  • #include<d3d9.h>
    #include<d3dx9.h>
    
    
    #pragma comment(lib, "d3d9.lib")
    #pragma comment(lib, "d3dx9.lib")
    
    #define WINDOW_CLASS    "UGPDX"
    #define WINDOW_NAME     "Off-Screen Rendering"
    #define WINDOW_WIDTH    640
    #define WINDOW_HEIGHT   480
    
    // Function Prototypes...
    bool InitializeD3D(HWND hWnd, bool fullscreen);
    bool InitializeObjects();
    void RenderScene();
    void Shutdown();
    
    
    // Direct3D object and device.
    LPDIRECT3D9 g_D3D = NULL;
    LPDIRECT3DDEVICE9 g_D3DDevice = NULL;
    
    // Matrices.
    D3DXMATRIX g_projection;
    D3DXMATRIX g_ViewMatrix;
    
    // stD3DVertex buffer to hold the square's geometry.
    LPDIRECT3DVERTEXBUFFER9 g_VertexBuffer = NULL;
    
    // g_Teapot object and its material.
    LPD3DXMESH g_Teapot = NULL;
    D3DMATERIAL9 g_Material;
    float g_RotationAngle = 0.0f;
    
    // Light object.
    D3DLIGHT9 g_Light;
    
    // Back buffer, offscreen texture, offscreen surface.
    LPDIRECT3DSURFACE9 g_BackSurface = NULL;
    LPDIRECT3DTEXTURE9 g_SurfaceTexture = NULL;
    LPDIRECT3DSURFACE9 g_OffScreenSurface = NULL;
    
    
    // A structure for our custom vertex type
    struct stD3DVertex
    {
        float x, y, z;
        float tu, tv;
    };
    
    // Our custom FVF, which describes our custom vertex structure
    #define D3DFVF_VERTEX (D3DFVF_XYZ | D3DFVF_TEX1)
    
    
    LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
       switch(msg)
          {
             case WM_DESTROY:
                PostQuitMessage(0);
                return 0;
                break;
    
             case WM_KEYUP:
                if(wParam == VK_ESCAPE) PostQuitMessage(0);
                break;
          }
    
       return DefWindowProc(hWnd, msg, wParam, lParam);
    }
    
    
    int WINAPI WinMain(HINSTANCE hInst, HINSTANCE prevhInst, LPSTR cmdLine, int show)
    {
       // Register the window class
       WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,
                         GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
                         WINDOW_CLASS, NULL };
       RegisterClassEx(&wc);
    
       // Create the application's window
       HWND hWnd = CreateWindow(WINDOW_CLASS, WINDOW_NAME, WS_OVERLAPPEDWINDOW,
                                100, 100, WINDOW_WIDTH, WINDOW_HEIGHT,
                                GetDesktopWindow(), NULL, wc.hInstance, NULL);
    
       // Initialize Direct3D
       if(InitializeD3D(hWnd, false))
          {
             // Show the window
             ShowWindow(hWnd, SW_SHOWDEFAULT);
             UpdateWindow(hWnd);
    
             // Enter the message loop
             MSG msg;
             ZeroMemory(&msg, sizeof(msg));
    
             while(msg.message != WM_QUIT)
                {
                   if(PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
                      {
                         TranslateMessage(&msg);
                         DispatchMessage(&msg);
                      }
                   else
                      RenderScene();
                }
          }
    
       // Release any and all resources.
       Shutdown();
    
       // Unregister our window.
       UnregisterClass(WINDOW_CLASS, wc.hInstance);
       return 0;
    }
    
    
    bool InitializeD3D(HWND hWnd, bool fullscreen)
    {
       D3DDISPLAYMODE displayMode;
    
       // Create the D3D object.
       g_D3D = Direct3DCreate9(D3D_SDK_VERSION);
       if(g_D3D == NULL) return false;
    
       // Get the desktop display mode.
       if(FAILED(g_D3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &displayMode)))
          return false;
    
       // Set up the structure used to create the D3DDevice
       D3DPRESENT_PARAMETERS d3dpp;
       ZeroMemory(&d3dpp, sizeof(d3dpp));
    
       if(fullscreen)
          {
             d3dpp.Windowed = FALSE;
             d3dpp.BackBufferWidth = WINDOW_WIDTH;
             d3dpp.BackBufferHeight = WINDOW_HEIGHT;
          }
       else
          d3dpp.Windowed = TRUE;
       d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
       d3dpp.BackBufferFormat = displayMode.Format;
       d3dpp.BackBufferCount = 1;
       d3dpp.EnableAutoDepthStencil = TRUE;
       d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
    
       // Create the D3DDevice
       if(FAILED(g_D3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
                 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_D3DDevice)))
          {
             return false;
          }
    
       // Initialize any objects we will be displaying.
       if(!InitializeObjects()) return false;
    
       return true;
    }
    
    
    bool InitializeObjects()
    {
       // Setup the g_Light source.
       g_Light.Type = D3DLIGHT_DIRECTIONAL;
       g_Light.Direction = D3DXVECTOR3(0.0f, 0.0f, 1.0f);
       g_Light.Diffuse.r = 1;
       g_Light.Diffuse.g = 1;
       g_Light.Diffuse.b = 1;
       g_Light.Diffuse.a = 1;
       g_Light.Specular.r = 1;
       g_Light.Specular.g = 1;
       g_Light.Specular.b = 1;
       g_Light.Specular.a = 1;
    
       g_D3DDevice->SetLight(0, &g_Light);
       g_D3DDevice->LightEnable(0, TRUE);
    
       // Setup the material properties for the teapot.
       ZeroMemory(&g_Material, sizeof(D3DMATERIAL9));
       g_Material.Diffuse.r = g_Material.Ambient.r = 0.6f;
       g_Material.Diffuse.g = g_Material.Ambient.g = 0.6f;
       g_Material.Diffuse.b = g_Material.Ambient.b = 0.7f;
       g_Material.Specular.r = 0.4f;
       g_Material.Specular.g = 0.4f;
       g_Material.Specular.b = 0.4f;
       g_Material.Power = 8.0f;
    
       // Create the teapot.
       if(FAILED(D3DXCreateTeapot(g_D3DDevice, &g_Teapot, NULL)))
          return false;
    
    
       // Create the texture that will be rendered to.
       if(FAILED(D3DXCreateTexture(g_D3DDevice, WINDOW_WIDTH,
          WINDOW_HEIGHT, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8,
          D3DPOOL_DEFAULT, &g_SurfaceTexture))) return false;
    
       // Set texture to offscreen surface.
       g_SurfaceTexture->GetSurfaceLevel(0, &g_OffScreenSurface);
    
    
       // Square that will be textured with offscreen rendering data.
       stD3DVertex square[] =
       {
          {-1, 1,  -1, 0, 0}, {1, 1,  -1, 1, 0},
          {-1, -1, -1, 0, 1}, {1, -1, -1, 1, 1}
       };
    
       g_D3DDevice->CreateVertexBuffer(4 * sizeof(stD3DVertex), 0,
                      D3DFVF_VERTEX, D3DPOOL_DEFAULT,
                      &g_VertexBuffer, NULL);
    
       void *pData = NULL;
       g_VertexBuffer->Lock(0, sizeof(square), (void**)&pData, 0);
       memcpy(pData, square, sizeof(square));
       g_VertexBuffer->Unlock();
    
    
       // Set the image states to get a good quality image.
    	g_D3DDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
    	g_D3DDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
    
    	// Set default rendering states.
       g_D3DDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
    	g_D3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
       g_D3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE);
    
    
       // Set the projection matrix.
       D3DXMatrixPerspectiveFovLH(&g_projection, 45.0f,
          WINDOW_WIDTH/WINDOW_HEIGHT, 0.1f, 1000.0f);
       g_D3DDevice->SetTransform(D3DTS_PROJECTION, &g_projection);
    
    
       // Define camera information.
       D3DXVECTOR3 cameraPos(0.0f, 0.0f, -4.0f);
       D3DXVECTOR3 lookAtPos(0.0f, 0.0f, 0.0f);
       D3DXVECTOR3 upDir(0.0f, 1.0f, 0.0f);
    
       // Build view matrix.
       D3DXMatrixLookAtLH(&g_ViewMatrix, &cameraPos,
                          &lookAtPos, &upDir);
    
       return true;
    }
    
    
    void RenderScene()
    {
       // Get a copy of the back buffer.
       g_D3DDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO,
                                  &g_BackSurface);
    
       // Prepare to draw to the offscreen surface.
       g_D3DDevice->SetRenderTarget(0, g_OffScreenSurface);
    
       // Clear the offscreen surface.
       g_D3DDevice->Clear(0, NULL, D3DCLEAR_TARGET |D3DCLEAR_ZBUFFER,
                          D3DCOLOR_XRGB(200,200,200), 1.0f, 0);
    
       // Begin the scene.  Start rendering.
       g_D3DDevice->BeginScene();
    
          // Turn on lighting.
          g_D3DDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
    
          // Set projection.
          g_D3DDevice->SetTransform(D3DTS_PROJECTION, &g_projection);
    
          // Create rotation matrix to rotate teapot.
          D3DXMATRIXA16 w;
          D3DXMatrixRotationY(&w, g_RotationAngle);
          g_D3DDevice->SetTransform(D3DTS_WORLD, &w);
    
          // Add to the rotation.
          g_RotationAngle += 0.02f;
          if(g_RotationAngle >= 360) g_RotationAngle = 0.0f;
    
          // Apply the view (camera).
          g_D3DDevice->SetTransform(D3DTS_VIEW, &g_ViewMatrix);
    
          // Set the material and draw the Teapot.
          g_D3DDevice->SetMaterial(&g_Material);
          g_D3DDevice->SetTexture(0, NULL);
          g_Teapot->DrawSubset(0);
    
       // End the scene.  Stop rendering.
       g_D3DDevice->EndScene();
    
    
       // Switch back to our back buffer.
       g_D3DDevice->SetRenderTarget(0, g_BackSurface);
    
       // Clear the back buffer.
       g_D3DDevice->Clear(0, NULL,  D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER ,
                          D3DCOLOR_XRGB(0,0,0), 1.0f, 0);
    
       // Begin the scene.  Start rendering.
       g_D3DDevice->BeginScene();
    
          // Turn off lighting. Don't need it.
          g_D3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
    
          // Set projection.
          g_D3DDevice->SetTransform(D3DTS_PROJECTION, &g_projection);
    
          // Rotate just a little to see this is a flat surface.
          D3DXMatrixRotationY(&w, 120);
          g_D3DDevice->SetTransform(D3DTS_WORLD, &w);
    
          // Apply the view (camera).
          g_D3DDevice->SetTransform(D3DTS_VIEW, &g_ViewMatrix);
    
          g_D3DDevice->SetTexture(0, g_SurfaceTexture);
          g_D3DDevice->SetStreamSource(0, g_VertexBuffer, 0,
                                       sizeof(stD3DVertex));
          g_D3DDevice->SetFVF(D3DFVF_VERTEX);
          g_D3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP,  0, 2);
    
       // End the scene.  Stop rendering.
       g_D3DDevice->EndScene();
    
       // Display the scene.
       g_D3DDevice->Present(NULL, NULL, NULL, NULL);
    }
    
    
    void Shutdown()
    {
       if(g_D3DDevice != NULL) g_D3DDevice->Release();
       g_D3DDevice = NULL;
    
       if(g_D3D != NULL) g_D3D->Release();
       g_D3D = NULL;
    
       if(g_VertexBuffer != NULL) g_VertexBuffer->Release();
       g_VertexBuffer = NULL;
    
       if(g_Teapot != NULL) g_Teapot->Release();
       g_Teapot = NULL;
    
       if(g_BackSurface != NULL) g_BackSurface->Release();
       g_BackSurface = NULL;
    
       if(g_SurfaceTexture != NULL) g_SurfaceTexture->Release();
       g_SurfaceTexture = NULL;
    
       if(g_OffScreenSurface != NULL) g_OffScreenSurface->Release();
       g_OffScreenSurface = NULL;
    }

    I can not run this example.Get image is spent.

    When the depth buffer may be cleared out of the wrong.

    My card is NVIDIA GT240。

    How's going on in the end?????????????

    • Moved by Nancy Shao Monday, April 5, 2010 7:38 AM Not appropriate forum (From:Visual C++ General)
    Saturday, March 27, 2010 5:59 PM

All replies