1 //-----------------------------------------------------------------------------
2 //
3 // ImageLib Windows (GDI) Test Source
4 // Copyright (C) 2000 by Denton Woods
5 // Last modified: 08/26/2001 <--Y2K Compliant! =]
6 //
7 // Filename: testil/animtest/animtest.c
8 //
9 // Description: Animation test application for DevIL.
10 //
11 //-----------------------------------------------------------------------------
12
13 #include <windows.h>
14 #ifdef _DEBUG
15 #define IL_DEBUG
16 #endif
17 #include <il/il.h>
18 #include <il/ilu.h>
19 #include <il/ilut.h>
20 #include "resource.h"
21
22
23 // Evil globals!
24 HINSTANCE hInstance;
25 HDC hDC, hMemDC = NULL;
26 HWND HWnd;
27
28 #define BORDER_W 8
29 #define MENU_H 46
30 #define MIN_W 205 // Accomodate the menu bar.
31 #define MAX_W 400
32 #define MAX_H 400
33 #define TITLE "DevIL Animation Test"
34
35 ILuint FilterType;
36 ILuint FilterParamInt;
37 ILfloat FilterParamFloat;
38 char FilterEditString[255];
39 char NewTitle[512];
40
41 BITMAPINFOHEADER *BmpInfo = NULL;
42 HBITMAP *Bitmaps = NULL;
43 ILuint *Durations = NULL;
44 ILuint NumImages = 0, CurImage = 0;
45
46 __int64 StartTime, TimerFreq;
47 double TimerRes;
48 bool IsPaused = false;
49
50
51 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
52 void GenFilterString(char *Out, char **Strings);
53 void DisplayImage(void);
54 void LoadImages(char *FileName);
55
56
WinMain(HINSTANCE hInst,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)57 int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
58 {
59 MSG msg;
60 WNDCLASSEX wcex;
61 HACCEL hAccelTable;
62
63 hInstance = hInst;
64
65 wcex.cbSize = sizeof(WNDCLASSEX);
66
67 wcex.style = CS_HREDRAW | CS_VREDRAW;
68 wcex.lpfnWndProc = (WNDPROC)WndProc;
69 wcex.cbClsExtra = 0;
70 wcex.cbWndExtra = 0;
71 wcex.hInstance = hInstance;
72 wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1));
73 wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
74 wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
75 wcex.lpszMenuName = (LPCSTR)IDR_MENU1;
76 wcex.lpszClassName = TITLE;
77 wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_ICON1);
78
79 RegisterClassEx(&wcex);
80
81 HWnd = CreateWindow(TITLE, TITLE, WS_OVERLAPPEDWINDOW | WS_VISIBLE,
82 50, 50, 400, 300, NULL, NULL, hInstance, NULL);
83 if (HWnd == NULL)
84 return FALSE;
85
86 // Display the window
87 ShowWindow(HWnd, nCmdShow);
88 UpdateWindow(HWnd);
89
90 ilInit();
91 ilEnable(IL_ORIGIN_SET);
92 ilEnable(IL_TYPE_SET);
93 ilEnable(IL_FORMAT_SET);
94
95 ilOriginFunc(IL_ORIGIN_LOWER_LEFT);
96 ilTypeFunc(IL_UNSIGNED_BYTE);
97 ilFormatFunc(IL_BGR);
98
99 // Is there a file to load from the command-line?
100 if (__argc > 1) {
101 LoadImages(__argv[1]);
102 }
103
104 hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDR_MENU1);
105
106 while (GetMessage(&msg, NULL, 0, 0)) {
107 if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) {
108 TranslateMessage(&msg);
109 DispatchMessage(&msg);
110 }
111 }
112
113 return msg.wParam;
114 }
115
116
LoadImages(char * FileName)117 void LoadImages(char *FileName)
118 {
119 ILuint Image, i;
120
121 hDC = GetDC(HWnd);
122 hMemDC = CreateCompatibleDC(hDC);
123
124 ilGenImages(1, &Image);
125 ilBindImage(Image);
126 if (!ilLoadImage(FileName)) {
127 ilDeleteImages(1, &Image);
128 return;
129 }
130
131 ilEnable(IL_ORIGIN_SET);
132 ilEnable(IL_FORMAT_SET);
133 ilOriginFunc(IL_ORIGIN_LOWER_LEFT);
134 //ilFormatFunc(IL_BGRA);
135 ilConvertImage(IL_BGR, IL_UNSIGNED_BYTE);
136 ilutRenderer(ILUT_WIN32);
137
138 CurImage = 0;
139 NumImages = ilGetInteger(IL_NUM_IMAGES) + 1;
140 Bitmaps = new HBITMAP[NumImages];
141 BmpInfo = new BITMAPINFOHEADER[NumImages];
142 Durations = new ILuint[NumImages];
143 if (Bitmaps == NULL || BmpInfo == NULL || Durations == NULL) {
144 ilDeleteImages(1, &Image);
145 return;
146 }
147
148 for (i = 0; i < NumImages; i++) {
149 ilActiveImage(0);
150 ilActiveImage(i);
151 Durations[i] = ilGetInteger(IL_IMAGE_DURATION);
152 *(Bitmaps + i) = ilutConvertToHBitmap(hDC);
153 ilutGetBmpInfo((BITMAPINFO*)(BmpInfo + i));
154 }
155
156 SelectObject(hMemDC, Bitmaps[0]);
157
158 ilDeleteImages(1, &Image);
159
160 sprintf(NewTitle, "%s - %s", TITLE, FileName);
161 SetWindowText(HWnd, NewTitle);
162
163 QueryPerformanceFrequency((LARGE_INTEGER*)&TimerFreq);
164 TimerRes = 1.0 / TimerFreq;
165 QueryPerformanceCounter((LARGE_INTEGER*)&StartTime);
166
167 return;
168 }
169
170
DestroyGDI()171 void DestroyGDI()
172 {
173 ILuint i;
174
175 if (Bitmaps) {
176 for (i = 0; i < NumImages; i++) {
177 DeleteObject(*(Bitmaps + i));
178 }
179 }
180
181 if (hMemDC)
182 DeleteDC(hMemDC);
183
184 if (Bitmaps)
185 delete []Bitmaps;
186 if (BmpInfo)
187 delete []BmpInfo;
188
189 Bitmaps = NULL;
190 BmpInfo = NULL;
191 hMemDC = NULL;
192
193 return;
194 }
195
196
DisplayImage()197 void DisplayImage()
198 {
199 static PAINTSTRUCT ps;
200 static __int64 CurTime;
201 static double TimeElapsed;
202
203 // Not created yet.
204 if (Durations == NULL || BmpInfo == NULL || Bitmaps == NULL)
205 return;
206
207 if (!IsPaused) {
208 QueryPerformanceCounter((LARGE_INTEGER*)&CurTime);
209 TimeElapsed = (CurTime - StartTime) * TimerRes;
210 if (TimeElapsed * 1000 > Durations[CurImage]) {
211 StartTime = CurTime;
212 CurImage++;
213 if (CurImage >= NumImages) {
214 CurImage = 0;
215 }
216 SelectObject(hMemDC, Bitmaps[CurImage]);
217 }
218 }
219
220 hDC = BeginPaint(HWnd, &ps);
221 BitBlt(hDC, 0, 0, (WORD)BmpInfo[CurImage].biWidth, (WORD)BmpInfo[CurImage].biHeight,
222 hMemDC, 0, 0, SRCCOPY);
223 EndPaint(HWnd, &ps);
224
225 return;
226 }
227
228
229 // Window procedure, handles all messages for this program
WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)230 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
231 {
232 static HMENU hMenu;
233 static ILuint Colours;
234 static RECT Rect;
235 static HDROP hDrop;
236
237 static char OpenFileName[2048];
238 static char OpenFilter[2048];
239 static char *OFilter[] = {
240 "All Files (*.*)", "*.*",
241 "Half-Life Model Files (*.mdl)", "*.mdl",
242 "Homeworld Image Files (*.lif)", "*.lif",
243 "Image Files (All Supported Types)", "*.jpe;*.jpg;*.jpeg;*.lif;*.bmp;*.ico;*.pbm;*.pgm;*.pnm;*.ppm;*.png;*.bw;*.rgb;*.rgba;*.sgi;*.tga;*.tif;*.tiff;*.pcx",
244 "Jpeg Files (*.jpe, *.jpg, *.jpeg)", "*.jpe;*.jpg;*.jpeg",
245 "Microsoft Bitmap Files (*.bmp)", "*.bmp",
246 "Microsoft Icon Files (*.ico)", "*.ico",
247 "OpenIL Files (*.oil)", "*.oil",
248 "Portable AnyMap Files (*.pbm, *.pgm, *.pnm, *.ppm)", "*.pbm;*.pgm;*.pnm;*.ppm",
249 "Portable Network Graphics Files (*.png)", "*.png",
250 "Sgi Files (*.sgi)", "*.bw;*.rgb;*.rgba;*.sgi",
251 "Targa Files (*.tga)", "*.tga",
252 "Tiff Files (*.tif)", "*.tif;*.tiff",
253 "Quake Wal Files (*.wal)", "*.wal",
254 "ZSoft Pcx Files (*.pcx)", "*.pcx",
255 "\0\0"
256 };
257
258 static OPENFILENAME Ofn = {
259 sizeof(OPENFILENAME),
260 hWnd,
261 NULL,
262 OpenFilter,
263 NULL,
264 0,
265 0,
266 OpenFileName,
267 512,
268 NULL,
269 0,
270 NULL,
271 NULL,
272 OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST,
273 0,
274 0,
275 NULL,
276 NULL,
277 NULL,
278 NULL
279 };
280
281 switch (message)
282 {
283 case WM_CREATE:
284 GenFilterString(OpenFilter, OFilter);
285
286 hDC = GetDC(hWnd);
287 DragAcceptFiles(hWnd, TRUE);
288
289 break;
290
291 case WM_CLOSE:
292 DestroyGDI();
293 ReleaseDC(hWnd, hDC);
294 DestroyWindow(hWnd);
295 UnregisterClass(TITLE, hInstance);
296 break;
297
298 case WM_DESTROY:
299 PostQuitMessage(0);
300 break;
301
302 case WM_PAINT:
303 DisplayImage();
304 InvalidateRect(hWnd, NULL, FALSE);
305 break;
306
307 case WM_KEYDOWN:
308 if (wParam == VK_ESCAPE)
309 PostQuitMessage(0);
310 InvalidateRect(hWnd, NULL, FALSE);
311 break;
312
313 case WM_DROPFILES:
314 hDrop = (HDROP)wParam;
315 DragQueryFile(hDrop, 0, OpenFileName, 512);
316
317 DestroyGDI();
318 LoadImages(OpenFileName);
319
320 DragFinish (hDrop);
321 return 0;
322
323 case WM_COMMAND:
324 FilterType = LOWORD(wParam);
325
326 switch (LOWORD(wParam))
327 {
328 case ID_FILE_EXIT:
329 PostMessage(hWnd, WM_CLOSE, 0, 0);
330 return (0L);
331
332 case ID_FILE_LOAD:
333 sprintf(OpenFileName, "*.*");
334 Ofn.lpstrFilter = OpenFilter;
335 Ofn.lpstrFile = OpenFileName;
336 Ofn.lpstrTitle = "Open File";
337 Ofn.nFilterIndex = 1;
338 Ofn.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST;
339
340 if (!GetOpenFileName(&Ofn))
341 return (0L);
342
343 DestroyGDI();
344 LoadImages(OpenFileName);
345
346 return (0L);
347
348 case ID_EDIT_PAUSE:
349 IsPaused = true;
350 return 0;
351
352 case ID_EDIT_RESUME:
353 IsPaused = false;
354 QueryPerformanceCounter((LARGE_INTEGER*)&StartTime);
355 return 0;
356 }
357
358 default:
359 return (DefWindowProc(hWnd, message, wParam, lParam));
360 }
361
362 return (0L);
363 }
364
365
GenFilterString(char * Out,char ** Strings)366 void GenFilterString(char *Out, char **Strings)
367 {
368 int OutPos = 0, StringPos = 0;
369
370 while (Strings[StringPos][0] != 0) {
371 sprintf(Out + OutPos, Strings[StringPos]);
372 OutPos += strlen(Strings[StringPos++]) + 1;
373 }
374
375 Out[OutPos++] = 0;
376 Out[OutPos] = 0;
377
378 return;
379 }
380