Trying to compile DirectX sample 02

Started by
8 comments, last by yckx 13 years, 2 months ago
I was trying to compile Tutorial 02 from the DirectX SDK's directory in Microsoft Visual Studio 2010.
I'm getting this error message:
winmain.obj : error LNK2019: unresolved external symbol _D3DX10CreateEffectFromFileW@48 referenced in function "long __cdecl InitDevice(void)" (?InitDevice@@YAJXZ)

I've spent days trying to find what the problem is and I found that I'm probably missing a lib file, however, I have no idea which one.
Here's my code:


#include <windows.h>
#include <d3d10_1.h>
#include <d3d10.h>
#include <d3dx10.h>
#include "resource.h"
#pragma comment(lib, "d3d10.lib")
#pragma comment(lib, "d3dx10.lib")

//--------------------------------------------------------------------------------------
// Structures
//--------------------------------------------------------------------------------------
struct SimpleVertex
{
D3DXVECTOR3 Pos;
};


//--------------------------------------------------------------------------------------
// Global Variables
//--------------------------------------------------------------------------------------
HINSTANCE g_hInst = NULL;
HWND g_hWnd = NULL;
D3D10_DRIVER_TYPE g_driverType = D3D10_DRIVER_TYPE_NULL;
ID3D10Device* g_pd3dDevice = NULL;
IDXGISwapChain* g_pSwapChain = NULL;
ID3D10RenderTargetView* g_pRenderTargetView = NULL;
ID3D10Effect* g_pEffect = NULL;
ID3D10EffectTechnique* g_pTechnique = NULL;
ID3D10InputLayout* g_pVertexLayout = NULL;
ID3D10Buffer* g_pVertexBuffer = NULL;


//--------------------------------------------------------------------------------------
// Forward declarations
//--------------------------------------------------------------------------------------
HRESULT InitWindow( HINSTANCE hInstance, int nCmdShow );
HRESULT InitDevice();
void CleanupDevice();
LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM );
void Render();


//--------------------------------------------------------------------------------------
// Entry point to the program. Initializes everything and goes into a message processing
// loop. Idle time is used to render the scene.
//--------------------------------------------------------------------------------------
int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow )
{
UNREFERENCED_PARAMETER( hPrevInstance );
UNREFERENCED_PARAMETER( lpCmdLine );

if( FAILED( InitWindow( hInstance, nCmdShow ) ) )
return 0;

if( FAILED( InitDevice() ) )
{
CleanupDevice();
return 0;
}

// Main message loop
MSG msg = {0};
while( WM_QUIT != msg.message )
{
if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
else
{
Render();
}
}

CleanupDevice();

return ( int )msg.wParam;
}


//--------------------------------------------------------------------------------------
// Register class and create window
//--------------------------------------------------------------------------------------
HRESULT InitWindow( HINSTANCE hInstance, int nCmdShow )
{
// Register class
WNDCLASSEX wcex;
wcex.cbSize = sizeof( WNDCLASSEX );
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon( hInstance, ( LPCTSTR )IDI_TUTORIAL1 );
wcex.hCursor = LoadCursor( NULL, IDC_ARROW );
wcex.hbrBackground = ( HBRUSH )( COLOR_WINDOW + 1 );
wcex.lpszMenuName = NULL;
wcex.lpszClassName = L"TutorialWindowClass";
wcex.hIconSm = LoadIcon( wcex.hInstance, ( LPCTSTR )IDI_TUTORIAL1 );
if( !RegisterClassEx( &wcex ) )
return E_FAIL;

// Create window
g_hInst = hInstance;
RECT rc = { 0, 0, 640, 480 };
AdjustWindowRect( &rc, WS_OVERLAPPEDWINDOW, FALSE );
g_hWnd = CreateWindow( L"TutorialWindowClass", L"Direct3D 10 Tutorial 2: Rendering a Triangle",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top, NULL, NULL, hInstance,
NULL );
if( !g_hWnd )
return E_FAIL;

ShowWindow( g_hWnd, nCmdShow );

return S_OK;
}


//--------------------------------------------------------------------------------------
// Create Direct3D device and swap chain
//--------------------------------------------------------------------------------------
HRESULT InitDevice()
{
HRESULT hr = S_OK;

RECT rc;
GetClientRect( g_hWnd, &rc );
UINT width = rc.right - rc.left;
UINT height = rc.bottom - rc.top;

UINT createDeviceFlags = 0;
#ifdef _DEBUG
createDeviceFlags |= D3D10_CREATE_DEVICE_DEBUG;
#endif

D3D10_DRIVER_TYPE driverTypes[] =
{
D3D10_DRIVER_TYPE_HARDWARE,
D3D10_DRIVER_TYPE_REFERENCE,
};
UINT numDriverTypes = sizeof( driverTypes ) / sizeof( driverTypes[0] );

DXGI_SWAP_CHAIN_DESC sd;
ZeroMemory( &sd, sizeof( sd ) );
sd.BufferCount = 1;
sd.BufferDesc.Width = width;
sd.BufferDesc.Height = height;
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
sd.BufferDesc.RefreshRate.Numerator = 60;
sd.BufferDesc.RefreshRate.Denominator = 1;
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
sd.OutputWindow = g_hWnd;
sd.SampleDesc.Count = 1;
sd.SampleDesc.Quality = 0;
sd.Windowed = TRUE;

for( UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++ )
{
g_driverType = driverTypes[driverTypeIndex];
hr = D3D10CreateDeviceAndSwapChain( NULL, g_driverType, NULL, createDeviceFlags,
D3D10_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice );
if( SUCCEEDED( hr ) )
break;
}
if( FAILED( hr ) )
return hr;

// Create a render target view
ID3D10Texture2D* pBuffer;
hr = g_pSwapChain->GetBuffer( 0, __uuidof( ID3D10Texture2D ), ( LPVOID* )&pBuffer );
if( FAILED( hr ) )
return hr;

hr = g_pd3dDevice->CreateRenderTargetView( pBuffer, NULL, &g_pRenderTargetView );
pBuffer->Release();
if( FAILED( hr ) )
return hr;

g_pd3dDevice->OMSetRenderTargets( 1, &g_pRenderTargetView, NULL );

// Setup the viewport
D3D10_VIEWPORT vp;
vp.Width = width;
vp.Height = height;
vp.MinDepth = 0.0f;
vp.MaxDepth = 1.0f;
vp.TopLeftX = 0;
vp.TopLeftY = 0;
g_pd3dDevice->RSSetViewports( 1, &vp );

// Create the effect
DWORD dwShaderFlags = D3D10_SHADER_ENABLE_STRICTNESS;
#if defined( DEBUG ) || defined( _DEBUG )
// Set the D3D10_SHADER_DEBUG flag to embed debug information in the shaders.
// Setting this flag improves the shader debugging experience, but still allows
// the shaders to be optimized and to run exactly the way they will run in
// the release configuration of this program.
dwShaderFlags |= D3D10_SHADER_DEBUG;
#endif
hr = D3DX10CreateEffectFromFile( L"Tutorial02.fx", NULL, NULL, "fx_4_0", dwShaderFlags, 0,
g_pd3dDevice, NULL, NULL, &g_pEffect, NULL, NULL );
if(FAILED(hr))
{
MessageBox( NULL,
L"The FX file cannot be located. Please run this executable from the directory that contains the FX file.", L"Error", MB_OK );
return hr;
}

// Obtain the technique
g_pTechnique = g_pEffect->GetTechniqueByName( "Render" );

// Define the input layout
D3D10_INPUT_ELEMENT_DESC layout[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 },
};
UINT numElements = sizeof( layout ) / sizeof( layout[0] );

// Create the input layout
D3D10_PASS_DESC PassDesc;
g_pTechnique->GetPassByIndex( 0 )->GetDesc( &PassDesc );
hr = g_pd3dDevice->CreateInputLayout( layout, numElements, PassDesc.pIAInputSignature,
PassDesc.IAInputSignatureSize, &g_pVertexLayout );
if( FAILED( hr ) )
return hr;

// Set the input layout
g_pd3dDevice->IASetInputLayout( g_pVertexLayout );

// Create vertex buffer
SimpleVertex vertices[] =
{
D3DXVECTOR3( 0.0f, 0.5f, 0.5f ),
D3DXVECTOR3( 0.5f, -0.5f, 0.5f ),
D3DXVECTOR3( -0.5f, -0.5f, 0.5f ),
};
D3D10_BUFFER_DESC bd;
bd.Usage = D3D10_USAGE_DEFAULT;
bd.ByteWidth = sizeof( SimpleVertex ) * 3;
bd.BindFlags = D3D10_BIND_VERTEX_BUFFER;
bd.CPUAccessFlags = 0;
bd.MiscFlags = 0;
D3D10_SUBRESOURCE_DATA InitData;
InitData.pSysMem = vertices;
hr = g_pd3dDevice->CreateBuffer( &bd, &InitData, &g_pVertexBuffer );
if( FAILED( hr ) )
return hr;

// Set vertex buffer
UINT stride = sizeof( SimpleVertex );
UINT offset = 0;
g_pd3dDevice->IASetVertexBuffers( 0, 1, &g_pVertexBuffer, &stride, &offset );

// Set primitive topology
g_pd3dDevice->IASetPrimitiveTopology( D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST );

return S_OK;
}


//--------------------------------------------------------------------------------------
// Clean up the objects we've created
//--------------------------------------------------------------------------------------
void CleanupDevice()
{
if( g_pd3dDevice ) g_pd3dDevice->ClearState();

if( g_pVertexBuffer ) g_pVertexBuffer->Release();
if( g_pVertexLayout ) g_pVertexLayout->Release();
if( g_pEffect ) g_pEffect->Release();
if( g_pRenderTargetView ) g_pRenderTargetView->Release();
if( g_pSwapChain ) g_pSwapChain->Release();
if( g_pd3dDevice ) g_pd3dDevice->Release();
}


//--------------------------------------------------------------------------------------
// Called every time the application receives a message
//--------------------------------------------------------------------------------------
LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
PAINTSTRUCT ps;
HDC hdc;

switch( message )
{
case WM_PAINT:
hdc = BeginPaint( hWnd, &ps );
EndPaint( hWnd, &ps );
break;

case WM_DESTROY:
PostQuitMessage( 0 );
break;

default:
return DefWindowProc( hWnd, message, wParam, lParam );
}

return 0;
}


//--------------------------------------------------------------------------------------
// Render a frame
//--------------------------------------------------------------------------------------
void Render()
{
// Clear the back buffer
float ClearColor[4] = { 0.0f, 0.125f, 0.3f, 1.0f }; // red,green,blue,alpha
g_pd3dDevice->ClearRenderTargetView( g_pRenderTargetView, ClearColor );

// Render a triangle
D3D10_TECHNIQUE_DESC techDesc;
g_pTechnique->GetDesc( &techDesc );
for( UINT p = 0; p < techDesc.Passes; ++p )
{
g_pTechnique->GetPassByIndex( p )->Apply( 0 );
g_pd3dDevice->Draw( 3, 0 );
}

// Present the information rendered to the back buffer to the front buffer (the screen)
g_pSwapChain->Present( 0, 0 );
}



And I think this is the part it's complaining about:
hr = D3DX10CreateEffectFromFile( L"Tutorial02.fx", NULL, NULL, "fx_4_0", dwShaderFlags, 0,
g_pd3dDevice, NULL, NULL, &g_pEffect, NULL, NULL );
if(FAILED(hr))
{
MessageBox( NULL,
L"The FX file cannot be located. Please run this executable from the directory that contains the FX file.", L"Error", MB_OK );
return hr;
}
Advertisement
I'm comparing your post to the June 2010 SDK. Perhaps the examples are different. I'm not a DX10 person, but does it compile/link without the changes you made to it (i.e., "out of the box")?

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

No,none of the examples worked before I added these two lines:
#pragma comment(lib, "d3d10.lib")
#pragma comment(lib, "d3dx10.lib")

I didn't change anything else and the first two were working after these changes.
And yes, that's the DirectX version I'm using.
Are d3d10.lib and d3dx10d.lib (and other libs) already included In Project->Properties->Configuration Properties->Linker->Input? Assuming Debug mode.

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

Yes, I already added them.
You added them. Okay, they're already there in the SDK example I compared it to. Looks like a different installation for some reason. Also, I'm using VS2008, so that may be all the help I can provide.

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

Well, thanks for trying.
What IDE are you using, and what steps did you take?

Here's what I just did, and it works for me:

  1. Open the sample browser (Start / Microsoft DirectX SDK (June 2010) / DirectX Sample Browser)
  2. Select "Direct3D 10" and sort by "Difficulty"
  3. Find "Tutorial 02: Rendering a Triangle" and click on "Install Project"
  4. Point it where you want it and click the "Install" button
  5. Select "Yes" when it asks you if you wish to view the contents of the folder
  6. Assuming you are using VC++ 2008 or 2010, open the appropriate SLN file for your IDE. (Other IDEs typically can convert to their project/solution format)
  7. Press F7 to build
  8. Press F5 to run.

All the dependency information is already set up in the project for you, so you shouldn't need to add anything.
Thank you, that worked. Turns out I was missing one more lib file. The dxguid.lib specifically. Thanks.
Not a problem ;)

This topic is closed to new replies.

Advertisement