Ошибка при линковке
31.07.2010, 19:07. Показов 5184. Ответов 5
Разбираю пример с 3 главы книги "Введение в программирование трехмерных игр с DX9" Ф. Луна.
Выдаёт ошибку:
| Code | 1
2
| 1>d3dUtility.obj : error LNK2019: ссылка на неразрешенный внешний символ __imp__timeGetTime@0 в функции "int __cdecl d3d::EnterMsgLoop(bool (__cdecl*)(float))" (?EnterMsgLoop@d3d@@YAHP6A_NM@Z@Z)
1>C:\Projects-C++\DX9\Cube\Debug\Cube.exe : fatal error LNK1120: 1 неразрешенных внешних элементов |
|
d3dUtility.h
| C++ | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
| // Включение основного заголовочного файла Direct3DX. В нем осуществляется
// включение других, необходимых нам заголовочных файлов Direct3D.
//
// Помните, что для построения данного приложения компоновщику
// необходимы библиотеки d3d9.lib, d3dx9.lib и winmm.lib.
//
#ifndef __d3dUtilityH__
#define __d3dUtilityH__
#include <d3d9.h>
#include <string>
namespace d3d
{
bool InitD3D(
HINSTANCE hInstance, // [in] Экземпляр приложения
int width, int height, // [in] Размер вторичного буфера
bool windowed, // [in] Оконный(true) или
// полноэкранный(false) режим
D3DDEVTYPE deviceType, // [in] HAL или REF
IDirect3DDevice9** device); // [out] Созданное устройство
int EnterMsgLoop(
bool (*ptr_display)(float timeDelta));
LRESULT CALLBACK WndProc(
HWND hwnd,
UINT msg,
WPARAM wParam,
LPARAM lParam);
template<class T> void Release(T t)
{
if(t)
{
t->Release();
t = 0;
}
}
template<class T> void Delete(T t)
{
if(t)
{
delete t;
t = 0;
}
}
}
#endif // __d3dUtilityH__ |
|
d3dUtility.cpp
| C++ | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
| #include "d3dUtility.h"
bool d3d::InitD3D(
HINSTANCE hInstance,
int width, int height,
bool windowed,
D3DDEVTYPE deviceType,
IDirect3DDevice9** device)
{
//
// Создание главного окна приложения
//
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC)d3d::WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = ::LoadIcon(0, IDI_APPLICATION);
wc.hCursor = ::LoadCursor(0, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = 0;
wc.lpszClassName = TEXT("Direct3DApp");
if( !RegisterClass(&wc))
{
::MessageBox(0, TEXT("RegisterClas() - FAILED"), 0, 0);
return false;
}
HWND hwnd = 0;
hwnd = ::CreateWindow(TEXT("Direct3DApp"), TEXT("Direct3DApp"),
WS_EX_TOPMOST,
0, 0, width, height,
0 /*parent hwnd*/, 0 /*menu*/, hInstance, 0 /*extra*/);
if( !hwnd)
{
::MessageBox(0, TEXT("CreateWindow() - FAILED"), 0, 0);
return false;
}
::ShowWindow(hwnd, SW_SHOW);
::UpdateWindow(hwnd);
//
// Init D3D
//
HRESULT hr = 0;
// Шаг 1: Создаем обьект IDIrect3D9
IDirect3D9* d3d9 = 0;
d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
if( !d3d9)
{
::MessageBox(0, TEXT("Direct3dCreare() - FAILED"), 0, 0);
return false;
}
// Шаг 2: Проверка аппаратной поддержки обработки вершин
// Заполняем структуру D3DCAPS9 информацией о
// возможностях первичного видеоадаптера
D3DCAPS9 caps;
d3d9->GetDeviceCaps(
D3DADAPTER_DEFAULT, // Означает первичный видеоадаптер
deviceType, // Задает тип устройства, обыяно D3DDEVICE_HAL
&caps); // Возвращает заполненую структуру D3DCAPS9, которая содержит
// информацию о возможностях первичного видеоадаптера
// Поддерживается аппаратноая обработка вершин?
int vp = 0;
if( caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)
{
// да, сохраняем в vp флаг поддержки аппаратной
// обработки вершин
vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;
}
else
{
// нет, сохраняем в vp флаг использования программной
// обработки вершин
vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
}
// Шаг 3: Заполняем структуру D3DPRESENT_PARAMETERS
D3DPRESENT_PARAMETERS d3dpp;
d3dpp.BackBufferWidth = width;
d3dpp.BackBufferHeight = height;
d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8; // Формат пикселей
d3dpp.BackBufferCount = 1;
d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE/*D3DMULTISAMPLE_4_SAMPLES*/;
d3dpp.MultiSampleQuality = 0;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.hDeviceWindow = hwnd;
d3dpp.Windowed = windowed; // режим экрана
d3dpp.EnableAutoDepthStencil = true;
d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8; // формат буфера глубины
d3dpp.Flags = 0;
d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
// Шаг 4: Создаем устройство
hr = d3d9->CreateDevice(
D3DADAPTER_DEFAULT, // первичный видеоадаптер
deviceType, // тип устройства
hwnd, // окно, связанное с устройством
vp, // тип обработки вершин
&d3dpp, // параметры показа
device); // возвращает созданное устройство
if( FAILED(hr))
{
d3d9->Release();
::MessageBox(0, TEXT("CreateDevice() - FAILED"), 0, 0);
return false;
}
d3d9->Release();
return true;
}
int d3d::EnterMsgLoop( bool (*ptr_display)(float timeDelta) )
{
MSG msg;
::ZeroMemory(&msg, sizeof(MSG));
static float lastTime = (float)timeGetTime();
while(msg.message != WM_QUIT)
{
if(::PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
else
{
float currTime = (float)timeGetTime();
float timeDelta = (currTime - lastTime)*0.001f;
ptr_display(timeDelta);
lastTime = currTime;
}
}
return msg.wParam;
} |
|
Cube.cpp
| C++ | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
| #include "d3dUtility.h"
#include <d3dx9math.h>
#pragma comment (lib, "d3d9.lib")
#pragma comment (lib, "d3dx9.lib")
//
// Глобальные
//
IDirect3DDevice9* Device = 0;
// Разрешение экрана
const int Width = 800;
const int Height = 600;
IDirect3DVertexBuffer9* VB = 0; // буфер вершин
IDirect3DIndexBuffer9* IB = 0; // буфер индексов
//
// Классы и Структуры
//
struct Vertex
{
// Описывает структуру для хранения данных о вершинах
// и приводит описание настраимаемого формата вершин для этой структуры
// Структура вершин содержит только информацию о местоположении вершин
Vertex(){}
Vertex(float x, float y, float z)
{
_x = x; _y = y; _z = z;
}
float _x, _y, _z;
static const DWORD FVF;
};
const DWORD Vertex::FVF = D3DFVF_XYZ;
//
// Фреймовые функции
//
bool Setup()
{
//
// Создание буфера вершин и буфера индексов
//
Device->CreateVertexBuffer(
8 * sizeof(Vertex), // Количестов байт, выделяемых под буфер
D3DUSAGE_WRITEONLY, // Флаг - может только записывать данные в буфер
Vertex::FVF, // Формат вершин
D3DPOOL_MANAGED, // Пул памяти, в котором будет хранится буфер
&VB, // Возвращает созданный буфер вершин
0);
Device->CreateIndexBuffer(
36 * sizeof(WORD), // Количество байт, выделеных для хранения буфера
D3DUSAGE_WRITEONLY, // флаг - может только записывать в буфер
D3DFMT_INDEX16, // Размер индексов
D3DPOOL_MANAGED,
&IB, // Возвращает созданный буфер инфексов
0);
//
// Заполняем буферов данными о кубе
//
// определение уникальных вершин
Vertex* vertices;
VB->Lock(0, 0, (void**)&vertices, 0);
// Вершины эдиничного куба
vertices[0] = Vertex(-1.0f, -1.0f, -1.0f);
vertices[1] = Vertex(-1.0f, 1.0f, -1.0f);
vertices[2] = Vertex( 1.0f, 1.0f, -1.0f);
vertices[3] = Vertex( 1.0f, -1.0f, -1.0f);
vertices[4] = Vertex(-1.0f, -1.0f, 1.0f);
vertices[5] = Vertex(-1.0f, 1.0f, 1.0f);
vertices[6] = Vertex( 1.0f, 1.0f, 1.0f);
vertices[7] = Vertex( 1.0f, -1.0f, 1.0f);
VB->Unlock();
// Описание образующих куб треугольниковж
WORD* indices = 0;
IB->Lock(0, 0, (void**)&indices, 0);
// Передняя грань
indices[0] = 0; indices[1] = 1; indices[2] = 2;
indices[3] = 0; indices[4] = 2; indices[5] = 3;
// Задняя грань
indices[6] = 4; indices[7] = 6; indices[8] = 5;
indices[9] = 4; indices[10] = 7; indices[11] = 6;
// Левая грань
indices[12] = 4; indices[13] = 5; indices[14] = 1;
indices[15] = 4; indices[16] = 1; indices[17] = 0;
// Правая грань
indices[18] = 3; indices[19] = 2; indices[20] = 6;
indices[21] = 3; indices[22] = 6; indices[23] = 7;
// Верх
indices[24] = 1; indices[25] = 5; indices[26] = 6;
indices[27] = 1; indices[28] = 6; indices[29] = 2;
// Низ
indices[30] = 4; indices[31] = 0; indices[32] = 3;
indices[33] = 4; indices[34] = 3; indices[35] = 7;
IB->Unlock();
//
// Размещение и ориентация камеры
//
D3DXVECTOR3 position(0.0f, 0.0f, -5.0f);
D3DXVECTOR3 target(0.0f , 0.0f, 0.0f);
D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);
D3DXMATRIX v;
D3DXMatrixLookAtLH(&v, &position, &target, &up);
Device->SetTransform(D3DTS_VIEW, &v);
// Установка матрицы проекции
D3DXMATRIX proj;
D3DXMatrixPerspectiveFovLH(
&proj,
D3DX_PI * 0.5f,
(float)Width / (float) Height,
1.0f,
1000.0f);
Device->SetTransform(D3DTS_PROJECTION, &proj);
// установка режима визуализации
Device->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
return true;
}
void Cleanup()
{
d3d::Release<IDirect3DVertexBuffer9*>(VB);
d3d::Release<IDirect3DIndexBuffer9*>(IB);
}
bool Display(float timeDelta)
{
if( Device)
{
//
// Вращение куба
//
D3DXMATRIX Rx, Ry;
// поворот на 45 градусов вокрус оси Х
D3DXMatrixRotationX(&Rx, D3DX_PI / 4.0f);
// увеличение угла поворота вокруг оси Y в каждом кадре
static float y = 0.0f;
D3DXMatrixRotationY(&Ry, y);
y += timeDelta;
// сброс угла поворота, если он достих 2*PI
if( y >= 2*D3DX_PI)
y = 0.0f;
// комбинация поворотов
D3DXMATRIX p = Rx * Ry;
Device->SetTransform(D3DTS_WORLD, &p);
//
// рисование сцены
//
Device->Clear( 0, 0,
D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
0xffffffff, 1.0f, 0);
Device->BeginScene();
Device->SetStreamSource(0, VB, 0, sizeof(Vertex));
Device->SetIndices(IB);
Device->SetFVF(Vertex::FVF);
Device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,
0, 0, 8, 0, 12);
Device->EndScene();
Device->Present(0, 0, 0, 0);
}
return true;
}
//
// WndProc
//
LRESULT CALLBACK d3d::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_DESTROY:
::PostQuitMessage(0);
break;
case WM_KEYDOWN:
if( wParam == VK_ESCAPE)
::DestroyWindow(hwnd);
break;
}
return ::DefWindowProc(hwnd, msg, wParam, lParam);
}
//
// WinMAin
//
int WINAPI WinMain(HINSTANCE hinstance,
HINSTANCE prevInstance,
PSTR cmdLine,
int showCmd)
{
if(!d3d::InitD3D(hinstance,
Width, Height, true, D3DDEVTYPE_HAL, &Device))
{
::MessageBox(0, TEXT("Init3D() - FAILED"), 0, 0);
return 0;
}
if(Setup())
{
::MessageBox(0, TEXT("Setup() - FAILED"), 0, 0);
return 0;
}
d3d::EnterMsgLoop( Display );
Cleanup();
Device->Release();
return 0;
} |
|
d3dUtility.cpp d3dUtility.h просто копировал с старых проектов.
Добавлено через 1 час 37 минут
Нужно было вручную в настройках подключить либы)
А можно как-то в коде все либы подключать?
Добавлено через 6 минут
Но при сборке в Release все равно осталась ошибка(((
| Code | 1
2
| 1>d3dUtility.obj : error LNK2001: неразрешенный внешний символ "__imp__timeGetTime@0"
1>C:\Projects-C++\DX9\Cube\Release\Cube.exe : fatal error LNK1120: 1 неразрешенных внешних элементов |
|
0
|