1 // LDVLib.cpp : Defines the entry point for the DLL application.
2 //
3
4 #include <LDLib/LDrawModelViewer.h>
5 #include <LDLib/LDPreferences.h>
6 #include <LDLoader/LDLModel.h>
7 #include <LDLib/LDInputHandler.h>
8 //#include <TCFoundation/TCAlert.h>
9 #include <TCFoundation/TCAlertManager.h>
10 #include <TCFoundation/TCUserDefaults.h>
11 #include <TRE/TREMainModel.h>
12 #include <TRE/TREGLExtensions.h>
13 #include "LDVLib.h"
14 #include "resource.h"
15
16 struct ViewerInfo;
17
18 class AlertHandler : public TCObject
19 {
20 public:
21 AlertHandler(ViewerInfo *viewerInfo);
22 private:
23 void captureAlertCallback(TCAlert *alert);
24 void releaseAlertCallback(TCAlert *alert);
25 void redrawAlertCallback(TCAlert *alert);
26 void captureMouse(void);
27 void releaseMouse(void);
28
29 ViewerInfo *m_viewerInfo;
30 };
31
32 struct ViewerInfo
33 {
34 LDrawModelViewer *modelViewer;
35 HWND hwnd;
36 HDC hdc;
37 HWND hwndParent;
38 HGLRC hglrc;
39 int backgroundR;
40 int backgroundG;
41 int backgroundB;
42 BOOL inputEnabled;
43 AlertHandler *alertHandler;
44 };
45
46 static HINSTANCE g_hModule;
47 static int g_initCount = 0;
48 ViewerInfo *g_sharedViewerInfo;
49
50 #define OGL_WINDOW_CLASS_NAME "LDVLibOGLWindow"
51 #define REDRAW_TIMER 42
52
53 #define waitForDebugger() \
54 ::MessageBox(NULL, "Attach Debugger", "DEBUG LDVLib.dll", MB_OK);
55
DllMain(HANDLE hModule,DWORD,LPVOID)56 BOOL APIENTRY DllMain( HANDLE hModule,
57 DWORD /*ul_reason_for_call*/,
58 LPVOID /*lpReserved*/
59 )
60 {
61 g_hModule = (HINSTANCE)hModule;
62 return TRUE;
63 }
64
getViewerInfo(void * pLDV)65 static ViewerInfo *getViewerInfo(void *pLDV)
66 {
67 return (ViewerInfo *)pLDV;
68 }
69
requestRedraw(HWND hWnd)70 static void requestRedraw(HWND hWnd)
71 {
72 ::SetTimer(hWnd, REDRAW_TIMER, 0, NULL);
73 }
74
requestRedraw(void * pLDV)75 static void requestRedraw(void *pLDV)
76 {
77 requestRedraw(getViewerInfo(pLDV)->hwnd);
78 }
79
AlertHandler(ViewerInfo * viewerInfo)80 AlertHandler::AlertHandler(ViewerInfo *viewerInfo)
81 : m_viewerInfo(viewerInfo)
82 {
83 m_viewerInfo->alertHandler = this;
84 TCAlertManager::registerHandler(LDInputHandler::captureAlertClass(), this,
85 (TCAlertCallback)&AlertHandler::captureAlertCallback);
86 TCAlertManager::registerHandler(LDInputHandler::releaseAlertClass(), this,
87 (TCAlertCallback)&AlertHandler::releaseAlertCallback);
88 TCAlertManager::registerHandler(LDrawModelViewer::redrawAlertClass(), this,
89 (TCAlertCallback)&AlertHandler::redrawAlertCallback);
90 }
91
captureMouse(void)92 void AlertHandler::captureMouse(void)
93 {
94 SetCapture(m_viewerInfo->hwnd);
95 }
96
releaseMouse(void)97 void AlertHandler::releaseMouse(void)
98 {
99 ReleaseCapture();
100 }
101
captureAlertCallback(TCAlert * alert)102 void AlertHandler::captureAlertCallback(TCAlert *alert)
103 {
104 if (alert->getSender() == m_viewerInfo->modelViewer->getInputHandler())
105 {
106 captureMouse();
107 }
108 }
109
releaseAlertCallback(TCAlert * alert)110 void AlertHandler::releaseAlertCallback(TCAlert *alert)
111 {
112 if (alert->getSender() == m_viewerInfo->modelViewer->getInputHandler())
113 {
114 releaseMouse();
115 }
116 }
117
redrawAlertCallback(TCAlert * alert)118 void AlertHandler::redrawAlertCallback(TCAlert *alert)
119 {
120 if (alert->getSender() == m_viewerInfo->modelViewer)
121 {
122 requestRedraw(m_viewerInfo->hwnd);
123 }
124 }
125
getModelViewer(void * pLDV)126 static LDrawModelViewer *getModelViewer(void *pLDV)
127 {
128 return getViewerInfo(pLDV)->modelViewer;
129 }
130
makeCurrent(void * pLDV)131 static BOOL makeCurrent(void *pLDV)
132 {
133 ViewerInfo *viewerInfo = getViewerInfo(pLDV);
134 return wglMakeCurrent(viewerInfo->hdc, viewerInfo->hglrc);
135 }
136
doPaint(ViewerInfo * viewerInfo,HWND hWnd)137 static LRESULT doPaint(ViewerInfo *viewerInfo, HWND hWnd)
138 {
139 if (viewerInfo != NULL && viewerInfo->modelViewer != NULL)
140 {
141 PAINTSTRUCT paintStruct;
142
143 memset(&paintStruct, 0, sizeof(paintStruct));
144 if (::BeginPaint(hWnd, &paintStruct))
145 {
146 makeCurrent(viewerInfo);
147 viewerInfo->modelViewer->update();
148 SwapBuffers(viewerInfo->hdc);
149 ::EndPaint(hWnd, &paintStruct);
150 }
151 return 0;
152 }
153 return DefWindowProc(hWnd, WM_PAINT, 0, 0);
154 }
155
doEraseBackground(ViewerInfo * viewerInfo,HWND hWnd,HDC hdc)156 static LRESULT doEraseBackground(ViewerInfo *viewerInfo, HWND hWnd, HDC hdc)
157 {
158 int r = 0;
159 int g = 0;
160 int b = 0;
161
162 if (viewerInfo != NULL)
163 {
164 r = viewerInfo->backgroundR;
165 g = viewerInfo->backgroundG;
166 b = viewerInfo->backgroundB;
167 }
168 HBRUSH hBgBrush = ::CreateSolidBrush(RGB(r, g, b));
169 RECT updateRect;
170 ::GetUpdateRect(hWnd, &updateRect, FALSE);
171 ::FillRect(hdc, &updateRect, hBgBrush);
172 ::DeleteObject(hBgBrush);
173 return 1;
174 }
175
redraw(void * pLDV)176 static void redraw(void *pLDV)
177 {
178 ::RedrawWindow(getViewerInfo(pLDV)->hwnd, NULL, NULL,
179 RDW_ERASE | RDW_INVALIDATE | RDW_ERASENOW | RDW_UPDATENOW);
180 }
181
doTimer(ViewerInfo * viewerInfo,HWND hWnd,WPARAM timerID)182 static LRESULT doTimer(ViewerInfo *viewerInfo, HWND hWnd, WPARAM timerID)
183 {
184 if (timerID == REDRAW_TIMER)
185 {
186 ::KillTimer(hWnd, timerID);
187 redraw(viewerInfo);
188 }
189 return 0;
190 }
191
convertKeyModifiers(WPARAM osModifiers)192 static TCULong convertKeyModifiers(WPARAM osModifiers)
193 {
194 TCULong retValue = 0;
195
196 if (osModifiers & MK_SHIFT)
197 {
198 retValue |= LDInputHandler::MKShift;
199 }
200 if (osModifiers & MK_CONTROL)
201 {
202 retValue |= LDInputHandler::MKControl;
203 }
204 return retValue;
205 }
206
doButtonDown(ViewerInfo * viewerInfo,HWND hWnd,LDInputHandler::MouseButton button,WPARAM keyFlags,int xPos,int yPos)207 static LRESULT doButtonDown(
208 ViewerInfo *viewerInfo,
209 HWND hWnd,
210 LDInputHandler::MouseButton button,
211 WPARAM keyFlags,
212 int xPos,
213 int yPos)
214 {
215 if (viewerInfo->inputEnabled &&
216 viewerInfo->modelViewer->getInputHandler()->mouseDown(
217 convertKeyModifiers(keyFlags), button, xPos, yPos))
218 {
219 requestRedraw(hWnd);
220 ::SetFocus(hWnd);
221 return 0;
222 }
223 return 1;
224 }
225
doButtonUp(ViewerInfo * viewerInfo,HWND hWnd,LDInputHandler::MouseButton button,WPARAM keyFlags,int xPos,int yPos)226 static LRESULT doButtonUp(
227 ViewerInfo *viewerInfo,
228 HWND hWnd,
229 LDInputHandler::MouseButton button,
230 WPARAM keyFlags,
231 int xPos,
232 int yPos)
233 {
234 if (viewerInfo->inputEnabled &&
235 viewerInfo->modelViewer->getInputHandler()->mouseUp(
236 convertKeyModifiers(keyFlags), button, xPos, yPos))
237 {
238 requestRedraw(hWnd);
239 return 0;
240 }
241 return 1;
242 }
243
doMouseMove(ViewerInfo * viewerInfo,HWND hWnd,WPARAM keyFlags,int xPos,int yPos)244 static LRESULT doMouseMove(
245 ViewerInfo *viewerInfo,
246 HWND hWnd,
247 WPARAM keyFlags,
248 int xPos,
249 int yPos)
250 {
251 if (viewerInfo->inputEnabled &&
252 viewerInfo->modelViewer->getInputHandler()->mouseMove(
253 convertKeyModifiers(keyFlags), xPos, yPos))
254 {
255 requestRedraw(hWnd);
256 return 0;
257 }
258 return 1;
259 }
260
doMouseWheel(ViewerInfo * viewerInfo,HWND,short keyFlags,short zDelta,int,int)261 static LRESULT doMouseWheel(
262 ViewerInfo *viewerInfo,
263 HWND /*hWnd*/,
264 short keyFlags,
265 short zDelta,
266 int /*xPos*/,
267 int /*yPos*/)
268 {
269 if (viewerInfo->inputEnabled)
270 {
271 viewerInfo->modelViewer->getInputHandler()->mouseWheel(
272 convertKeyModifiers(keyFlags), (TCFloat)zDelta);
273 }
274 return 0;
275 }
276
doSetFocus(ViewerInfo *,HWND,HWND)277 static LRESULT doSetFocus(
278 ViewerInfo * /*viewerInfo*/,
279 HWND /*hWnd*/,
280 HWND /*hPrev*/)
281 {
282 return 0;
283 }
284
285
staticWindowProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)286 static LRESULT CALLBACK staticWindowProc(
287 HWND hWnd,
288 UINT message,
289 WPARAM wParam,
290 LPARAM lParam)
291 {
292 #pragma warning(push)
293 #pragma warning(disable:4312)
294 ViewerInfo *viewerInfo =
295 (ViewerInfo *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
296 #pragma warning(pop)
297
298 switch (message)
299 {
300 case WM_CREATE:
301 case WM_NCCREATE:
302 {
303 if (viewerInfo == NULL)
304 {
305 CREATESTRUCT *createStruct = (CREATESTRUCT *)lParam;
306
307 viewerInfo = (ViewerInfo *)createStruct->lpCreateParams;
308 if (viewerInfo != NULL)
309 {
310 #pragma warning(push)
311 #pragma warning(disable:4244)
312 SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)viewerInfo);
313 #pragma warning(pop)
314 viewerInfo->hdc = ::GetDC(hWnd);
315 }
316 }
317 }
318 break;
319 case WM_PAINT:
320 return doPaint(viewerInfo, hWnd);
321 case WM_TIMER:
322 if (lParam == 0)
323 {
324 return doTimer(viewerInfo, hWnd, wParam);
325 }
326 break;
327 case WM_ERASEBKGND:
328 return doEraseBackground(viewerInfo, hWnd, (HDC)wParam);
329 case WM_LBUTTONDOWN:
330 return doButtonDown(viewerInfo, hWnd, LDInputHandler::MBLeft, wParam,
331 (short)LOWORD(lParam), (short)HIWORD(lParam));
332 case WM_LBUTTONUP:
333 return doButtonUp(viewerInfo, hWnd, LDInputHandler::MBLeft, wParam,
334 (short)LOWORD(lParam), (short)HIWORD(lParam));
335 case WM_RBUTTONDOWN:
336 return doButtonDown(viewerInfo, hWnd, LDInputHandler::MBRight, wParam,
337 (short)LOWORD(lParam), (short)HIWORD(lParam));
338 case WM_RBUTTONUP:
339 return doButtonUp(viewerInfo, hWnd, LDInputHandler::MBRight, wParam,
340 (short)LOWORD(lParam), (short)HIWORD(lParam));
341 case WM_MBUTTONDOWN:
342 return doButtonDown(viewerInfo, hWnd, LDInputHandler::MBMiddle, wParam,
343 (short)LOWORD(lParam), (short)HIWORD(lParam));
344 case WM_MBUTTONUP:
345 return doButtonUp(viewerInfo, hWnd, LDInputHandler::MBMiddle, wParam,
346 (short)LOWORD(lParam), (short)HIWORD(lParam));
347 case WM_MOUSEMOVE:
348 return doMouseMove(viewerInfo, hWnd, wParam, (short)LOWORD(lParam),
349 (short)HIWORD(lParam));
350 case WM_MOUSEWHEEL:
351 return doMouseWheel(viewerInfo, hWnd, LOWORD(wParam), HIWORD(wParam),
352 (short)LOWORD(lParam), (short)HIWORD(lParam));
353 case WM_SETFOCUS:
354 return doSetFocus(viewerInfo, hWnd, (HWND)wParam);
355 }
356 return DefWindowProc(hWnd, message, wParam, lParam);
357 }
358
registerClass(void)359 static void registerClass(void)
360 {
361 WNDCLASSEX windowClass;
362
363 memset(&windowClass, 0, sizeof(windowClass));
364 // Set up and window class
365 windowClass.cbSize = sizeof(windowClass);
366 windowClass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_OWNDC;
367 windowClass.lpfnWndProc = staticWindowProc;
368 windowClass.cbClsExtra = 0;
369 windowClass.cbWndExtra = 0;
370 windowClass.hInstance = g_hModule;
371 windowClass.hIcon = NULL;
372 windowClass.hCursor = ::LoadCursor(NULL, IDC_ARROW);
373 windowClass.hbrBackground = NULL;
374 windowClass.lpszMenuName = NULL;
375 windowClass.lpszClassName = OGL_WINDOW_CLASS_NAME;
376 windowClass.hIconSm = NULL;
377 ::RegisterClassEx(&windowClass);
378 }
379
LDVInit(HWND hwnd)380 void *LDVInit(HWND hwnd)
381 {
382 ViewerInfo *viewerInfo = new ViewerInfo;
383 RECT clientRect;
384 HRSRC hFontResource = FindResource(g_hModule,
385 MAKEINTRESOURCE(IDR_SANS_FONT), RT_RCDATA);
386
387 if (++g_initCount == 1)
388 {
389 HRSRC hStudLogoResource = FindResource(g_hModule,
390 MAKEINTRESOURCE(IDR_STUDLOGO_PNG), RT_RCDATA);
391
392 if (hStudLogoResource)
393 {
394 HGLOBAL hStudLogo = LoadResource(g_hModule, hStudLogoResource);
395
396 if (hStudLogo)
397 {
398 TCByte *data = (TCByte *)LockResource(hStudLogo);
399
400 if (data)
401 {
402 DWORD length = SizeofResource(g_hModule, hStudLogoResource);
403
404 if (length)
405 {
406 TREMainModel::setStudTextureData(data, length);
407 }
408 }
409 }
410 }
411 registerClass();
412 g_sharedViewerInfo = new ViewerInfo;
413 memset(g_sharedViewerInfo, 0, sizeof(*g_sharedViewerInfo));
414 g_sharedViewerInfo->hwndParent = NULL;
415 g_sharedViewerInfo->hwnd = ::CreateWindowEx(
416 0, OGL_WINDOW_CLASS_NAME, "LDVLib Window",
417 WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
418 0, 0, 320, 240, hwnd, NULL, g_hModule, g_sharedViewerInfo);
419 LDVGLInit(g_sharedViewerInfo);
420 }
421 memset(viewerInfo, 0, sizeof(*viewerInfo));
422 viewerInfo->inputEnabled = TRUE;
423 viewerInfo->hwndParent = hwnd;
424 ::GetClientRect(hwnd, &clientRect);
425 int width = clientRect.right - clientRect.left;
426 int height = clientRect.bottom - clientRect.top;
427 viewerInfo->hwnd = ::CreateWindowEx(
428 0, OGL_WINDOW_CLASS_NAME, "LDVLib Window",
429 WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
430 0, 0, width, height, hwnd, NULL, g_hModule, viewerInfo);
431 viewerInfo->modelViewer = new LDrawModelViewer(width, height);
432 LDPreferences *prefs = new LDPreferences(viewerInfo->modelViewer);
433 prefs->loadSettings();
434 prefs->applySettings();
435 prefs->release();
436 if (hFontResource)
437 {
438 HGLOBAL hFont = LoadResource(g_hModule, hFontResource);
439
440 if (hFont)
441 {
442 TCByte *data = (TCByte *)LockResource(hFont);
443
444 if (data)
445 {
446 DWORD length = SizeofResource(g_hModule, hFontResource);
447
448 if (length)
449 {
450 viewerInfo->modelViewer->setFontData(data, length);
451 }
452 }
453 }
454 }
455 new AlertHandler(viewerInfo);
456 return viewerInfo;
457 }
458
SetRegistryAppName(const char * appName)459 void SetRegistryAppName(const char *appName)
460 {
461 LDVSetRegistryAppName(appName);
462 }
463
LDVSetRegistryAppName(const char * appName)464 void LDVSetRegistryAppName(const char *appName)
465 {
466 TCUserDefaults::setAppName(appName);
467 }
468
LDVSetCommandLine(const char * commandLine)469 void LDVSetCommandLine(const char *commandLine)
470 {
471 TCUserDefaults::setCommandLine(commandLine);
472 }
473
GLDeInit(ViewerInfo * viewerInfo)474 static void GLDeInit(ViewerInfo *viewerInfo)
475 {
476 if (viewerInfo->hglrc != NULL)
477 {
478 wglMakeCurrent(NULL, NULL);
479 wglDeleteContext(viewerInfo->hglrc);
480 viewerInfo->hglrc = NULL;
481 }
482 }
483
setPixelFormat(HDC hdc,int pfIndex)484 static BOOL setPixelFormat(HDC hdc, int pfIndex)
485 {
486 PIXELFORMATDESCRIPTOR pfd;
487
488 memset(&pfd, 0, sizeof(pfd));
489 pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
490 pfd.nVersion = 1;
491 if (SetPixelFormat(hdc, pfIndex, &pfd))
492 {
493 return TRUE;
494 }
495 return FALSE;
496 }
497
setupPFD(ViewerInfo * viewerInfo)498 static BOOL setupPFD(ViewerInfo *viewerInfo)
499 {
500 PIXELFORMATDESCRIPTOR pfd;
501 BOOL retValue = FALSE;
502
503 memset(&pfd, 0, sizeof(pfd));
504 pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
505 pfd.nVersion = 1;
506 pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER |
507 PFD_GENERIC_ACCELERATED;
508 pfd.iPixelType = PFD_TYPE_RGBA;
509 pfd.cColorBits = 12;
510 pfd.cDepthBits = 32;
511 pfd.cStencilBits = 1;
512 pfd.cAlphaBits = 4;
513 int pfIndex = ChoosePixelFormat(viewerInfo->hdc, &pfd);
514 if (pfIndex == 0)
515 { // Try with dest alpha but no stencil
516 pfd.cStencilBits = 0;
517 pfIndex = ChoosePixelFormat(viewerInfo->hdc, &pfd);
518 }
519 if (pfIndex == 0)
520 { // Try with stencil but no dest alpha
521 pfd.cStencilBits = 1;
522 pfd.cAlphaBits = 0;
523 pfIndex = ChoosePixelFormat(viewerInfo->hdc, &pfd);
524 }
525 if (pfIndex == 0)
526 { // Try with no stencil OR dest alpha
527 pfd.cStencilBits = 0;
528 pfIndex = ChoosePixelFormat(viewerInfo->hdc, &pfd);
529 }
530 if (pfIndex != 0)
531 {
532 retValue = setPixelFormat(viewerInfo->hdc, pfIndex);
533 }
534 return retValue;
535 }
536
LDVGLInit(void * pLDV)537 BOOL LDVGLInit(void *pLDV)
538 {
539 BOOL retValue = FALSE;
540 ViewerInfo *viewerInfo = getViewerInfo(pLDV);
541 GLDeInit(viewerInfo);
542 if (setupPFD(viewerInfo))
543 {
544 viewerInfo->hglrc = wglCreateContext(viewerInfo->hdc);
545 if (viewerInfo->hglrc != NULL)
546 {
547 retValue = wglMakeCurrent(viewerInfo->hdc, viewerInfo->hglrc);
548 if (retValue)
549 {
550 if (pLDV == g_sharedViewerInfo)
551 {
552 TREGLExtensions::setup();
553 }
554 else
555 {
556 wglShareLists(g_sharedViewerInfo->hglrc, viewerInfo->hglrc);
557 glDrawBuffer(GL_BACK);
558 }
559 }
560 }
561 }
562 return retValue;
563 }
564
LDVDeInit(void * pLDV)565 void LDVDeInit(void *pLDV)
566 {
567 GLDeInit(getViewerInfo(pLDV));
568 TCObject::release(getViewerInfo(pLDV)->alertHandler);
569 TCObject::release(getModelViewer(pLDV));
570 if (--g_initCount == 0)
571 {
572 ::UnregisterClass(OGL_WINDOW_CLASS_NAME, g_hModule);
573 }
574 }
575
LDVSetSize(void * pLDV,int width,int height)576 void LDVSetSize(void *pLDV, int width, int height)
577 {
578 ViewerInfo *viewerInfo = getViewerInfo(pLDV);
579
580 ::MoveWindow(viewerInfo->hwnd, 0, 0, width, height, FALSE);
581 makeCurrent(pLDV);
582 glViewport(0, 0, width, height);
583 viewerInfo->modelViewer->setWidth(width);
584 viewerInfo->modelViewer->setHeight(height);
585 redraw(pLDV);
586 }
587
LDVGetWidth(void * pLDV)588 int LDVGetWidth(void *pLDV)
589 {
590 return getModelViewer(pLDV)->getWidth();
591 }
592
LDVSetHeight(void * pLDV,int height)593 void LDVSetHeight(void *pLDV, int height)
594 {
595 getModelViewer(pLDV)->setHeight(height);
596 }
597
LDVGetHeight(void * pLDV)598 int LDVGetHeight(void *pLDV)
599 {
600 return getModelViewer(pLDV)->getHeight();
601 }
602
LDVSetFilename(void * pLDV,const char * filename)603 void LDVSetFilename(void *pLDV, const char *filename)
604 {
605 getModelViewer(pLDV)->setFilename(filename);
606 }
607
608
chDirFromFilename(const char * filename,char * outFilename)609 static bool chDirFromFilename(const char* filename, char* outFilename)
610 {
611 char buf[MAX_PATH];
612 char* fileSpot;
613 DWORD result = GetFullPathName(filename, MAX_PATH, buf, &fileSpot);
614
615 if (result <= MAX_PATH && result > 0)
616 {
617 // if (strlen(fileSpot) < strlen(filename))
618 {
619 strcpy(outFilename, buf);
620 }
621 *fileSpot = 0;
622 if (SetCurrentDirectory(buf))
623 {
624 return true;
625 }
626 }
627 return false;
628 }
629
LDVLoadModel(void * pLDV,BOOL resetViewpoint)630 BOOL LDVLoadModel(void *pLDV, BOOL resetViewpoint)
631 {
632 BOOL retValue = FALSE;
633 if (makeCurrent(pLDV))
634 {
635 LDrawModelViewer *modelViewer = getModelViewer(pLDV);
636 char origDir[1024];
637 char fullPath[1024];
638 bool dirChanged;
639
640 GetCurrentDirectory(sizeof(origDir), origDir);
641 dirChanged = chDirFromFilename(modelViewer->getFilename(),
642 fullPath);
643 if (dirChanged)
644 {
645 modelViewer->setFilename(fullPath);
646 }
647 if (modelViewer->loadModel(resetViewpoint ? true : false))
648 {
649 redraw(pLDV);
650 retValue = TRUE;
651 }
652 if (dirChanged)
653 {
654 SetCurrentDirectory(origDir);
655 }
656 }
657 return retValue;
658 }
659
LDVUpdate(void * pLDV)660 void LDVUpdate(void *pLDV)
661 {
662 requestRedraw(pLDV);
663 }
664
LDVSetBackgroundRGB(void * pLDV,int r,int g,int b)665 void LDVSetBackgroundRGB(void *pLDV, int r, int g, int b)
666 {
667 ViewerInfo *viewerInfo = getViewerInfo(pLDV);
668
669 viewerInfo->backgroundR = r;
670 viewerInfo->backgroundG = g;
671 viewerInfo->backgroundB = b;
672 getModelViewer(pLDV)->setBackgroundRGB(r, g, b);
673 requestRedraw(pLDV);
674 }
675
LDVGetBackgroundRGB(void * pLDV,int * r,int * g,int * b)676 void LDVGetBackgroundRGB(void *pLDV, int *r, int *g, int *b)
677 {
678 ViewerInfo *viewerInfo = getViewerInfo(pLDV);
679
680 *r = viewerInfo->backgroundR;
681 *g = viewerInfo->backgroundG;
682 *b = viewerInfo->backgroundB;
683 }
684
LDVSetDefaultRGB(void * pLDV,int r,int g,int b,BOOL transparent)685 void LDVSetDefaultRGB(void *pLDV, int r, int g, int b, BOOL transparent)
686 {
687 getModelViewer(pLDV)->setDefaultRGB(r, g, b, transparent ? true : false);
688 requestRedraw(pLDV);
689 }
690
LDVGetDefaultRGB(void * pLDV,int * r,int * g,int * b,BOOL * transparent)691 void LDVGetDefaultRGB(void *pLDV, int *r, int *g, int *b, BOOL *transparent)
692 {
693 TCByte rTemp, gTemp, bTemp;
694 bool transTemp;
695
696 getModelViewer(pLDV)->getDefaultRGB(rTemp, gTemp, bTemp, transTemp);
697 *r = rTemp;
698 *g = gTemp;
699 *b = bTemp;
700 *transparent = transTemp ? TRUE : FALSE;
701 }
702
LDVSetLDrawDir(const char * path)703 void LDVSetLDrawDir(const char *path)
704 {
705 LDLModel::setLDrawDir(path);
706 }
707
LDVResetView(void * pLDV,LDVViewingAngle viewingAngle)708 void LDVResetView(void *pLDV, LDVViewingAngle viewingAngle)
709 {
710 getModelViewer(pLDV)->resetView((LDVAngle)viewingAngle);
711 requestRedraw(pLDV);
712 }
713
LDVEnableInput(void * pLDV,BOOL enable)714 void LDVEnableInput(void *pLDV, BOOL enable)
715 {
716 getViewerInfo(pLDV)->inputEnabled = enable;
717 }
718
LDVIsInputEnabled(void * pLDV)719 BOOL LDVIsInputEnabled(void *pLDV)
720 {
721 return getViewerInfo(pLDV)->inputEnabled;
722 }
723
LDVZoomToFit(void * pLDV)724 void LDVZoomToFit(void *pLDV)
725 {
726 getModelViewer(pLDV)->zoomToFit();
727 requestRedraw(pLDV);
728 }
729
LDVHasFocus(void * pLDV)730 BOOL LDVHasFocus(void *pLDV)
731 {
732 return getViewerInfo(pLDV)->hwnd == ::GetFocus();
733 }
734
LDVGetUsesSpecular(void * pLDV)735 BOOL LDVGetUsesSpecular(void *pLDV)
736 {
737 return getModelViewer(pLDV)->getUsesSpecular() != false;
738 }
739
LDVSetUsesSpecular(void * pLDV,BOOL value)740 void LDVSetUsesSpecular(void *pLDV, BOOL value)
741 {
742 getModelViewer(pLDV)->setUsesSpecular(value ? true : false);
743 requestRedraw(pLDV);
744 }
745
LDVGetSeamWidth(void * pLDV)746 float LDVGetSeamWidth(void *pLDV)
747 {
748 return getModelViewer(pLDV)->getSeamWidth();
749 }
750
LDVSetSeamWidth(void * pLDV,float value)751 void LDVSetSeamWidth(void *pLDV, float value)
752 {
753 getModelViewer(pLDV)->setSeamWidth(value);
754 requestRedraw(pLDV);
755 }
756
LDVGetShowsEdges(void * pLDV)757 BOOL LDVGetShowsEdges(void *pLDV)
758 {
759 return getModelViewer(pLDV)->getShowsHighlightLines() != false;
760 }
761
LDVSetShowsEdges(void * pLDV,BOOL value)762 void LDVSetShowsEdges(void *pLDV, BOOL value)
763 {
764 getModelViewer(pLDV)->setShowsHighlightLines(value ? true : false);
765 requestRedraw(pLDV);
766 }
767
LDVGetBlackEdges(void * pLDV)768 BOOL LDVGetBlackEdges(void *pLDV)
769 {
770 return getModelViewer(pLDV)->getBlackHighlights() != false;
771 }
772
LDVSetBlackEdges(void * pLDV,BOOL value)773 void LDVSetBlackEdges(void *pLDV, BOOL value)
774 {
775 getModelViewer(pLDV)->setBlackHighlights(value ? true : false);
776 requestRedraw(pLDV);
777 }
778
LDVGetShowsConditionalEdges(void * pLDV)779 BOOL LDVGetShowsConditionalEdges(void *pLDV)
780 {
781 return getModelViewer(pLDV)->getDrawConditionalHighlights() != false;
782 }
783
LDVSetShowsConditionalEdges(void * pLDV,BOOL value)784 void LDVSetShowsConditionalEdges(void *pLDV, BOOL value)
785 {
786 getModelViewer(pLDV)->setDrawConditionalHighlights(value ? true : false);
787 requestRedraw(pLDV);
788 }
789
LDVGetLowQualityStuds(void * pLDV)790 BOOL LDVGetLowQualityStuds(void *pLDV)
791 {
792 return getModelViewer(pLDV)->getQualityStuds() == false;
793 }
794
LDVSetLowQualityStuds(void * pLDV,BOOL value)795 void LDVSetLowQualityStuds(void *pLDV, BOOL value)
796 {
797 getModelViewer(pLDV)->setQualityStuds(!value ? true : false);
798 requestRedraw(pLDV);
799 }
800
LDVGetLighting(void * pLDV)801 BOOL LDVGetLighting(void *pLDV)
802 {
803 return getModelViewer(pLDV)->getUseLighting() != false;
804 }
805
LDVSetLighting(void * pLDV,BOOL value)806 void LDVSetLighting(void *pLDV, BOOL value)
807 {
808 getModelViewer(pLDV)->setUseLighting(value ? true : false);
809 requestRedraw(pLDV);
810 }
811
LDVGetSubduedLighting(void * pLDV)812 BOOL LDVGetSubduedLighting(void *pLDV)
813 {
814 return getModelViewer(pLDV)->getSubduedLighting() != false;
815 }
816
LDVSetSubduedLighting(void * pLDV,BOOL value)817 void LDVSetSubduedLighting(void *pLDV, BOOL value)
818 {
819 getModelViewer(pLDV)->setSubduedLighting(value ? true : false);
820 requestRedraw(pLDV);
821 }
822
LDVGetTextureStuds(void * pLDV)823 BOOL LDVGetTextureStuds(void *pLDV)
824 {
825 return getModelViewer(pLDV)->getTextureStuds() != false;
826 }
827
LDVSetTextureStuds(void * pLDV,BOOL value)828 void LDVSetTextureStuds(void *pLDV, BOOL value)
829 {
830 getModelViewer(pLDV)->setTextureStuds(value ? true : false);
831 requestRedraw(pLDV);
832 }
833
LDVGetTextureFilterType(void * pLDV)834 LDVTextureFilterType LDVGetTextureFilterType(void *pLDV)
835 {
836 switch (getModelViewer(pLDV)->getTextureFilterType())
837 {
838 case GL_NEAREST_MIPMAP_NEAREST:
839 return LDVTFTNearest;
840 case GL_LINEAR_MIPMAP_NEAREST:
841 return LDVTFTBilinear;
842 case GL_LINEAR_MIPMAP_LINEAR:
843 return LDVTFTTrilinear;
844 default:
845 return LDVTFTBilinear;
846 }
847 }
848
LDVSetTextureFilterType(void * pLDV,LDVTextureFilterType value)849 void LDVSetTextureFilterType(void *pLDV, LDVTextureFilterType value)
850 {
851 int textureFilterType;
852
853 switch (value)
854 {
855 case LDVTFTNearest:
856 textureFilterType = GL_NEAREST_MIPMAP_NEAREST;
857 break;
858 case LDVTFTTrilinear:
859 textureFilterType = GL_LINEAR_MIPMAP_LINEAR;
860 break;
861 case LDVTFTBilinear:
862 default:
863 textureFilterType = GL_LINEAR_MIPMAP_NEAREST;
864 break;
865 }
866 getModelViewer(pLDV)->setTextureFilterType(textureFilterType);
867 requestRedraw(pLDV);
868 }
869
LDVGetAnisoLevel(void * pLDV)870 float LDVGetAnisoLevel(void *pLDV)
871 {
872 LDrawModelViewer *modelViewer = getModelViewer(pLDV);
873
874 if (modelViewer->getTextureFilterType() == GL_LINEAR_MIPMAP_LINEAR)
875 {
876 return modelViewer->getAnisoLevel();
877 }
878 else
879 {
880 return 1.0;
881 }
882 }
883
LDVSetAnisoLevel(void * pLDV,float value)884 void LDVSetAnisoLevel(void *pLDV, float value)
885 {
886 LDrawModelViewer *modelViewer = getModelViewer(pLDV);
887
888 if (modelViewer->getTextureFilterType() != GL_LINEAR_MIPMAP_LINEAR)
889 {
890 value = 1.0;
891 }
892 modelViewer->setAnisoLevel(value);
893 requestRedraw(pLDV);
894 }
895
LDVGetMaxAnisoLevel(void)896 float LDVGetMaxAnisoLevel(void)
897 {
898 return TREGLExtensions::getMaxAnisoLevel();
899 }
900
LDVGetDrawWireframe(void * pLDV)901 BOOL LDVGetDrawWireframe(void *pLDV)
902 {
903 return getModelViewer(pLDV)->getDrawWireframe() != false;
904 }
905
LDVSetDrawWireframe(void * pLDV,BOOL value)906 void LDVSetDrawWireframe(void *pLDV, BOOL value)
907 {
908 getModelViewer(pLDV)->setDrawWireframe(value ? true : false);
909 requestRedraw(pLDV);
910 }
911
LDVGetWireframeFog(void * pLDV)912 BOOL LDVGetWireframeFog(void *pLDV)
913 {
914 return getModelViewer(pLDV)->getUseWireframeFog() != false;
915 }
916
LDVSetWireframeFog(void * pLDV,BOOL value)917 void LDVSetWireframeFog(void *pLDV, BOOL value)
918 {
919 getModelViewer(pLDV)->setUseWireframeFog(value ? true : false);
920 requestRedraw(pLDV);
921 }
922
LDVGetRemoveHiddenLines(void * pLDV)923 BOOL LDVGetRemoveHiddenLines(void *pLDV)
924 {
925 return getModelViewer(pLDV)->getRemoveHiddenLines() != false;
926 }
927
LDVSetRemoveHiddenLines(void * pLDV,BOOL value)928 void LDVSetRemoveHiddenLines(void *pLDV, BOOL value)
929 {
930 getModelViewer(pLDV)->setRemoveHiddenLines(value ? true : false);
931 requestRedraw(pLDV);
932 }
933
LDVGetPrimitiveSubstitution(void * pLDV)934 BOOL LDVGetPrimitiveSubstitution(void *pLDV)
935 {
936 return getModelViewer(pLDV)->getAllowPrimitiveSubstitution() != false;
937 }
938
LDVSetPrimitiveSubstitution(void * pLDV,BOOL value)939 void LDVSetPrimitiveSubstitution(void *pLDV, BOOL value)
940 {
941 getModelViewer(pLDV)->setAllowPrimitiveSubstitution(value ? true : false);
942 requestRedraw(pLDV);
943 }
944
LDVGetSmoothing(void * pLDV)945 BOOL LDVGetSmoothing(void *pLDV)
946 {
947 return getModelViewer(pLDV)->getPerformSmoothing() != false;
948 }
949
LDVSetSmoothing(void * pLDV,BOOL value)950 void LDVSetSmoothing(void *pLDV, BOOL value)
951 {
952 getModelViewer(pLDV)->setPerformSmoothing(value ? true : false);
953 requestRedraw(pLDV);
954 }
955
LDVGetLineSmoothing(void * pLDV)956 BOOL LDVGetLineSmoothing(void *pLDV)
957 {
958 return getModelViewer(pLDV)->getLineSmoothing() != false;
959 }
960
LDVSetLineSmoothing(void * pLDV,BOOL value)961 void LDVSetLineSmoothing(void *pLDV, BOOL value)
962 {
963 getModelViewer(pLDV)->setLineSmoothing(value ? true : false);
964 requestRedraw(pLDV);
965 }
966
LDVGetEdgesOnly(void * pLDV)967 BOOL LDVGetEdgesOnly(void *pLDV)
968 {
969 return getModelViewer(pLDV)->getEdgesOnly() != false;
970 }
971
LDVSetEdgesOnly(void * pLDV,BOOL value)972 void LDVSetEdgesOnly(void *pLDV, BOOL value)
973 {
974 getModelViewer(pLDV)->setEdgesOnly(value ? true : false);
975 requestRedraw(pLDV);
976 }
977
LDVGetBFC(void * pLDV)978 BOOL LDVGetBFC(void *pLDV)
979 {
980 return getModelViewer(pLDV)->getBfc() != false;
981 }
982
LDVSetBFC(void * pLDV,BOOL value)983 void LDVSetBFC(void *pLDV, BOOL value)
984 {
985 getModelViewer(pLDV)->setBfc(value ? true : false);
986 requestRedraw(pLDV);
987 }
988
LDVGetRedBackFaces(void * pLDV)989 BOOL LDVGetRedBackFaces(void *pLDV)
990 {
991 return getModelViewer(pLDV)->getRedBackFaces() != false;
992 }
993
LDVSetRedBackFaces(void * pLDV,BOOL value)994 void LDVSetRedBackFaces(void *pLDV, BOOL value)
995 {
996 getModelViewer(pLDV)->setRedBackFaces(value ? true : false);
997 requestRedraw(pLDV);
998 }
999
LDVGetGreenFrontFaces(void * pLDV)1000 BOOL LDVGetGreenFrontFaces(void *pLDV)
1001 {
1002 return getModelViewer(pLDV)->getGreenFrontFaces() != false;
1003 }
1004
LDVSetGreenFrontFaces(void * pLDV,BOOL value)1005 void LDVSetGreenFrontFaces(void *pLDV, BOOL value)
1006 {
1007 getModelViewer(pLDV)->setGreenFrontFaces(value ? true : false);
1008 requestRedraw(pLDV);
1009 }
1010
LDVGetBlueNeutralFaces(void * pLDV)1011 BOOL LDVGetBlueNeutralFaces(void *pLDV)
1012 {
1013 return getModelViewer(pLDV)->getBlueNeutralFaces() != false;
1014 }
1015
LDVSetBlueNeutralFaces(void * pLDV,BOOL value)1016 void LDVSetBlueNeutralFaces(void *pLDV, BOOL value)
1017 {
1018 getModelViewer(pLDV)->setBlueNeutralFaces(value ? true : false);
1019 requestRedraw(pLDV);
1020 }
1021
LDVGetCheckPartsTracker(void * pLDV)1022 BOOL LDVGetCheckPartsTracker(void *pLDV)
1023 {
1024 return getModelViewer(pLDV)->getCheckPartTracker() != false;
1025 }
1026
LDVSetCheckPartsTracker(void * pLDV,BOOL value)1027 void LDVSetCheckPartsTracker(void *pLDV, BOOL value)
1028 {
1029 getModelViewer(pLDV)->setCheckPartTracker(value ? true : false);
1030 requestRedraw(pLDV);
1031 }
1032
LDVGetShowsAxes(void * pLDV)1033 BOOL LDVGetShowsAxes(void *pLDV)
1034 {
1035 return getModelViewer(pLDV)->getShowAxes() != false;
1036 }
1037
LDVSetShowsAxes(void * pLDV,BOOL value)1038 void LDVSetShowsAxes(void *pLDV, BOOL value)
1039 {
1040 getModelViewer(pLDV)->setShowAxes(value ? true : false);
1041 requestRedraw(pLDV);
1042 }
1043
LDVGetShowsBoundingBox(void * pLDV)1044 BOOL LDVGetShowsBoundingBox(void *pLDV)
1045 {
1046 return getModelViewer(pLDV)->getShowBoundingBox() != false;
1047 }
1048
LDVSetShowsBoundingBox(void * pLDV,BOOL value)1049 void LDVSetShowsBoundingBox(void *pLDV, BOOL value)
1050 {
1051 getModelViewer(pLDV)->setShowBoundingBox(value ? true : false);
1052 requestRedraw(pLDV);
1053 }
1054
LDVGetBoundingBoxesOnly(void * pLDV)1055 BOOL LDVGetBoundingBoxesOnly(void *pLDV)
1056 {
1057 return getModelViewer(pLDV)->getBoundingBoxesOnly() != false;
1058 }
1059
LDVSetBoundingBoxesOnly(void * pLDV,BOOL value)1060 void LDVSetBoundingBoxesOnly(void *pLDV, BOOL value)
1061 {
1062 getModelViewer(pLDV)->setBoundingBoxesOnly(value ? true : false);
1063 requestRedraw(pLDV);
1064 }
1065
LDVGetOBI(void * pLDV)1066 BOOL LDVGetOBI(void *pLDV)
1067 {
1068 return getModelViewer(pLDV)->getObi() != false;
1069 }
1070
LDVSetOBI(void * pLDV,BOOL value)1071 void LDVSetOBI(void *pLDV, BOOL value)
1072 {
1073 getModelViewer(pLDV)->setObi(value ? true : false);
1074 requestRedraw(pLDV);
1075 }
1076
LDVGetRandomColors(void * pLDV)1077 BOOL LDVGetRandomColors(void *pLDV)
1078 {
1079 return getModelViewer(pLDV)->getRandomColors() != false;
1080 }
1081
LDVSetRandomColors(void * pLDV,BOOL value)1082 void LDVSetRandomColors(void *pLDV, BOOL value)
1083 {
1084 getModelViewer(pLDV)->setRandomColors(value ? true : false);
1085 requestRedraw(pLDV);
1086 }
1087
LDVGetTexmaps(void * pLDV)1088 BOOL LDVGetTexmaps(void *pLDV)
1089 {
1090 return getModelViewer(pLDV)->getTexmaps() != false;
1091 }
1092
LDVSetTexmaps(void * pLDV,BOOL value)1093 void LDVSetTexmaps(void *pLDV, BOOL value)
1094 {
1095 getModelViewer(pLDV)->setTexmaps(value ? true : false);
1096 requestRedraw(pLDV);
1097 }
1098
LDVGetFOV(void * pLDV)1099 float LDVGetFOV(void *pLDV)
1100 {
1101 return getModelViewer(pLDV)->getFov();
1102 }
1103
LDVSetFOV(void * pLDV,float value)1104 void LDVSetFOV(void *pLDV, float value)
1105 {
1106 getModelViewer(pLDV)->setFov(value);
1107 requestRedraw(pLDV);
1108 }
1109
LDVGetShowsAllConditionalEdges(void * pLDV)1110 BOOL LDVGetShowsAllConditionalEdges(void *pLDV)
1111 {
1112 return getModelViewer(pLDV)->getShowAllConditionalLines() != false;
1113 }
1114
LDVSetShowsAllConditionalEdges(void * pLDV,BOOL value)1115 void LDVSetShowsAllConditionalEdges(void *pLDV, BOOL value)
1116 {
1117 getModelViewer(pLDV)->setShowAllConditionalLines(value ? true : false);
1118 requestRedraw(pLDV);
1119 }
1120