当我尝试在VS 2010中编译时,我得到以下两个链接错误 . 我确保我的包和库设置在项目属性> VC目录中是正确的并且还检查以确保Project> Linker> Input具有d3d9.lib &d3dx9.lib就在它里面 . 我也尝试在D3DGraphics.h中为上面的两个库添加#pragma comment但是无济于事:(

编译错误....

1> D3DGraphics.obj:错误LNK2019:函数“public:long thiscall D3DGraphics::SetupD3D(struct HWND *)”中引用的未解析外部符号_Direct3DCreate9 @ 4(?SetupD3D @ D3DGraphics @@ QAEJPAUHWND __ @@@ Z)

1> main.obj:错误LNK2019:未解析的外部符号“public:__thiscall FIREWORKCLASS :: FIREWORKCLASS(struct IDirect3DDevice9 *)”(?? 0FIREWORKCLASS @@ QAE @ PAUIDirect3DDevice9 @@@ Z)在函数“void __cdecl SetupFirework1(void)”中引用“(?SetupFirework1 @@ YAXXZ)

......:致命错误LNK1120:2个未解析的外部


完整的程序结构如下......

D3DGraphics.h

#include <d3d9.h>   // necessary Direct3D libraries


// Global pointer to the Direct 3D device
extern IDirect3DDevice9*    g_pd3dDevice; 

// Used to create the Direct3D object
extern IDirect3D9*          g_pD3D; 

class D3DGraphics
{
public:

// Global pointer to the Direct3D object
IDirect3D9*         g_pD3D; 

// Global pointer to the Direct 3D device
IDirect3DDevice9*   g_pd3dDevice; 

//The class constructor - executes whenever an instance is created.
//D3DGraphics() { /* does nothing */ }

// Method to setup D3D parameters
HRESULT SetupD3D ( HWND hWnd );  

// Destructor. 
// A method that executes when an instance is destroyed.
~D3DGraphics(); 

void Render();

void Cleanup(); // close Direct3D and release resources

};

D3DGraphics.cpp

#include "D3DGraphics.h"

// Global pointer to the Direct 3D device
IDirect3DDevice9*   g_pd3dDevice; 

// Used to create the Direct3D object
IDirect3D9*     g_pD3D; 


//// Constructor code
//D3DGraphics :: D3DGraphics()
//{
//
//}

// TYPE Classname :: MethodName
HRESULT D3DGraphics :: SetupD3D ( HWND hWnd)
{

// Create a D3D object called g_pD3D, return a fail message if this can't be done.
if (NULL == (g_pD3D = Direct3DCreate9(D3D_SDK_VERSION))) return E_FAIL;



/*  *** Setup a data structure of paramteres to create the Direct3D device *** */

// data structure is called d3dpp
D3DPRESENT_PARAMETERS d3dpp;

// used to clear all data from the structure to ensure no spurious values will be used
ZeroMemory( &d3dpp,sizeof( d3dpp ) );

// application will be windowed
d3dpp.Windowed = TRUE;                      

// back to front buffer behavior - DISCARD = random data used for error checking
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; 

// back buffer format - UNKNOWN = use current display resolution to retain consistency
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;    

// D3D device to create and manage depth and stencil buffer automatically
d3dpp.EnableAutoDepthStencil = TRUE;    

// format of the surfaces which hold the depth & stencil buffers - D16 = 16Bit colours
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;  

    ////////////* ***END data structure creation*** *////////////



/*  *** Create the Direct3D Device using the defined parameters from the data strucutre d3dpp *** */

// Create the Direct3D Device and return a pointer to it, or return E_FAIL if it can't be created
if (FAILED(g_pD3D -> CreateDevice(  D3DADAPTER_DEFAULT,
                                    D3DDEVTYPE_HAL,
                                    hWnd,
                                    D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                                    &d3dpp,
                                    &g_pd3dDevice)))

{
    return E_FAIL;
}

// Enable the Z buffer
g_pd3dDevice -> SetRenderState(D3DRS_ZENABLE, TRUE);

return S_OK;
}

// Destructor code
D3DGraphics :: ~D3DGraphics()   
{
//???
}



void D3DGraphics :: Cleanup()
{
//release the D3DDevice creation resources
if (g_pD3D != NULL) g_pD3D -> Release();

//release the rendering device creation resources
if (g_pd3dDevice !=NULL) g_pd3dDevice -> Release();
// Render the frame to the back buffer.
}




/*  *** The Render cycle for drawing graphics on the screen *** */

void D3DGraphics :: Render()
{
// black background colour
DWORD BackgroundColour = 0x0000000;    

// Clear the contents of the backbuffer & Zbuffer and set its colour.
g_pd3dDevice -> Clear(0,                                   // 0 rectangles to be     cleared
                      NULL,                                // no array of rectangle coordinates
                      D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,  // which buffers should be cleared
                      BackgroundColour,                    // the background colour to use, defined as black 0x0000000
                      1.0f,                                // Z buffer value
                      0);                                  // stencil buffer value

// Begin rendering the scene.
if (SUCCEEDED(g_pd3dDevice -> BeginScene()))
{

    /// ...GRAPHICS ARE DRAWN HERE...///

    // end the rendering
    g_pd3dDevice -> EndScene();
}

// Present the backbuffer to the display.
g_pd3dDevice -> Present(NULL, NULL, NULL, NULL);
}
        ////////////*  *** END The Render cycle *** *////////////

Fireworks.h

#include "D3DGraphics.h"
#include <d3dx9math.h>  // required in this file for D3DXVECTOR3

// class for a single firework spark
class SPARKCLASS
{
public:
    SPARKCLASS();

    D3DXVECTOR3 Position;
    float       XVelocity, YVelocity, ZVelocity;
    float       Time;
    int         LifeTime;
};

// max number of sparks that can exist in the system
const int MaxNumberOfSparks = 500;


// class for the firework particle system
class FIREWORKCLASS
{
    public:
    FIREWORKCLASS (LPDIRECT3DDEVICE9);

    void     Update();
    void     Render();

    float    LaunchAngle;
    float    LaunchVelocity;
    float    ParticleSize;

    int      Lifetime;
    int      StartInterval, StartCounter, NumberToStart;
    float    TimeIncrement;
    D3DCOLOR SparkColour;

    D3DXVECTOR3  Origin;

    private:
    //array of sparks
    SPARKCLASS Sparks[MaxNumberOfSparks];

    //starts a new particle
    void StartParticle(int);

    //counter for the number of sparks that are alive
    int SparksAlive;

    //vertex buffer for the points
    LPDIRECT3DVERTEXBUFFER9     pPointBuffer;

    //the Direct3D Deice onto which sparks will be rendered 
    LPDIRECT3DDEVICE9           pRenderTarget;

};



    struct POINTVERTEX
    {
        D3DXVECTOR3  Position;
        D3DCOLOR    Colour;
    };



    // the structure of a vertex in our vertex buffer
#define D3DFVF_POINTVERTEX  (D3DFVF_XYZ  |  D3DFVF_DIFFUSE)

Fireworks.cpp

#include "Fireworks.h"


 void FIREWORKCLASS :: StartParticle(int P)
{
 // set this spark's lifetime to the maximum
 Sparks[P].LifeTime = Lifetime;
 Sparks[P].Time = 0.0f;

Sparks[P].Position.x = 0;
Sparks[P].Position.y = 0;
Sparks[P].Position.z = 0;

// select a random angle around a circle
float DirectionAngle = (float)rand()/(180/D3DX_PI);

//calculate the vertical component of velocity
Sparks[P].YVelocity = LaunchVelocity
                      * (float)sin(LaunchAngle);

//calculate the horizontal components of velocity - X & Z
Sparks[P].XVelocity = LaunchVelocity
                     * (float)sin(LaunchAngle)
                     * (float)cos(DirectionAngle);

Sparks[P].ZVelocity = LaunchVelocity
                     * (float)sin(LaunchAngle)
                     * (float)cos(DirectionAngle);

//since another spark now exists, increment the spark counter
SparksAlive++;
 }



void FIREWORKCLASS :: Render()
    {
        //enable point sprites and set the size of the point
        pRenderTarget -> SetRenderState(D3DRS_POINTSPRITEENABLE, true);
        pRenderTarget -> SetRenderState(D3DRS_POINTSCALEENABLE, true);

        pRenderTarget -> SetRenderTarget(D3DRS_LIGHTING, false);

        //scale the points according to distance
        pRenderTarget -> SetRenderState(D3DRS_POINTSIZE,
                                FtoDW(ParticleSize));
        pRenderTarget -> SetRenderState(D3DRS_POINTSIZE_MIN, FtoDW(0.0f));
        pRenderTarget -> SetRenderState(D3DRS_POINTSCALE_A, FtoDW(0.0f));
        pRenderTarget -> SetRenderState(D3DRS_POINTSCALE_B, FtoDW(0.0f));
        pRenderTarget -> SetRenderState(D3DRS_POINTSCALE_C, FtoDW(0.0f));

        //render the contents of the vertex buffer
        pRenderTarget -> SetStreamSource(0, pPointBuffer, 0,
                            sizeof(POINTVERTEX));

        pRenderTarget -> SetFVF(D3DFVF_POINTVERTEX);
        pRenderTarget -> DrawPrimitive(D3DPT_POINTLIST, 0, 0);  // 0, ?? 

        //reset the render states
        pRenderTarget -> SetRenderState(D3DRS_POINTSPRITEENABLE, false);
        pRenderTarget -> SetRenderState(D3DRS_POINTSCALEENABLE, false);
        pRenderTarget -> SetRenderState(D3DRS_LIGHTING, true);

    }

* Main.cpp *

#define D3D_DEBUG_INFO  // Enable debugging information
#include "Windows.h"
#include "Fireworks.h"



//global pointer to Firework1 object
FIREWORKCLASS *g_Firework1 = NULL;

void SetupFirework1()
{
g_Firework1 = new FIREWORKCLASS(g_pd3dDevice);

g_Firework1 -> Origin.x = 0.0f;
g_Firework1 -> Origin.x = 0.0f;
g_Firework1 -> Origin.x = 0.0f;

g_Firework1 -> StartInterval = 10;
g_Firework1 -> StartCounter  = 10;

g_Firework1 -> LaunchAngle    = D3DXToRadian(80);
g_Firework1 -> LaunchVelocity = 40.0f;

g_Firework1 -> TimeIncrement  = 0.04f;
g_Firework1 -> Lifetime       = 200;

g_Firework1 -> NumberToStart  = 8;
g_Firework1 -> ParticleSize   = 2.0f;
g_Firework1 -> SparkColour   = 0x00FFE000; // yellow

  }


// The window's message handling function.
LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
    case WM_DESTROY:
    {

        // The user has clicked on the 'close' button on the window's title bar.
        // Send a 'WM_QUIT' message to the application to close it down.
        PostQuitMessage(0);
        return 0;
    }
}

return DefWindowProc(hWnd, msg, wParam, lParam);
}



// WinMain() - The application's entry point.
// This sort of procedure is mostly standard, and could be used in most
// DirectX applications.
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR, int)
{

/*  ***Create the application window*** */

// Register the window class
WNDCLASSEX wc = {sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,
                 GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
                 "Blank", NULL};
RegisterClassEx(&wc);

// Create the application's window
HWND hWnd = CreateWindow( "Blank", "---Fireworks---",
                          WS_OVERLAPPEDWINDOW, 100, 100, 800, 800,  // ?, ?, size(x), size(y) 
                          GetDesktopWindow(), NULL, wc.hInstance, NULL);
/* ***END application window creation*** */




// Create an instance of the D3DGraphics class called D3D
D3DGraphics D3D;

// Initialize Direct3D
if (SUCCEEDED(D3D.SetupD3D(hWnd)))
{
    // Show the window
    ShowWindow(hWnd, SW_SHOWDEFAULT);
    UpdateWindow(hWnd);

    // Enter the message loop
    MSG msg;
    ZeroMemory(&msg, sizeof(msg));

    // Respond to messages until a 'WM_QUIT' message is received.
    while (msg.message != WM_QUIT)
    {
        if (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        else
//          g_Firework1 -> Update();    // update Firework1 particles
            D3D.Render();           // render the scene
    }
    // Execute the class destructor to clear any resources that 
    // D3DGraphics class has created/used.
    D3D.Cleanup();  
}

UnregisterClass("Blank", wc.hInstance);
return 0;
}