win_cam.c 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415
  1. /*
  2. ===========================================================================
  3. Copyright (C) 1997-2006 Id Software, Inc.
  4. This file is part of Quake 2 Tools source code.
  5. Quake 2 Tools source code is free software; you can redistribute it
  6. and/or modify it under the terms of the GNU General Public License as
  7. published by the Free Software Foundation; either version 2 of the License,
  8. or (at your option) any later version.
  9. Quake 2 Tools source code is distributed in the hope that it will be
  10. useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with Quake 2 Tools source code; if not, write to the Free Software
  15. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  16. ===========================================================================
  17. */
  18. #include "texpaint.h"
  19. #define CAMERA_WINDOW_CLASS "TPCamera"
  20. HDC camdc;
  21. HGLRC baseRC;
  22. float pitch, yaw, roll;
  23. qboolean model_lines = false;
  24. float cam_x, cam_y=-64, cam_z=32;
  25. int cam_width, cam_height;
  26. BINDTEXFUNCPTR BindTextureEXT;
  27. void InitIndexTexture (void)
  28. {
  29. int i;
  30. BindTextureEXT (GL_TEXTURE_2D, TEXTURE_INDEX);
  31. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  32. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  33. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  34. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  35. for (i=0 ; i<sizeof(index_texture)/4 ; i++)
  36. index_texture[i] = i+1;
  37. glTexImage2D (GL_TEXTURE_2D, 0, 3, width2, height2, 0, GL_RGBA, GL_UNSIGNED_BYTE, index_texture);
  38. BindTextureEXT (GL_TEXTURE_2D, TEXTURE_SKIN);
  39. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  40. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  41. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  42. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  43. }
  44. void CreateDisplaylist (void)
  45. {
  46. }
  47. void DrawModel (void)
  48. {
  49. int i, j;
  50. glColor4f (1,1,1,1);
  51. glBegin (GL_TRIANGLES);
  52. for (i=0 ; i<numfaces ; i++)
  53. {
  54. for (j=0 ; j<3 ; j++)
  55. {
  56. glTexCoord2f (tmcoords[i][j][0], tmcoords[i][j][1]);
  57. glVertex3fv (faces[i].verts[j]);
  58. }
  59. }
  60. glEnd ();
  61. }
  62. /*
  63. =============
  64. Cam_Click
  65. =============
  66. */
  67. int cam_last_index;
  68. void Cam_Click (int x, int y, qboolean shift)
  69. {
  70. int index;
  71. index = 0;
  72. glReadBuffer (GL_BACK);
  73. glReadPixels (x, y, 1,1, GL_RGB, GL_UNSIGNED_BYTE, &index);
  74. index--;
  75. if (index == -1)
  76. return;
  77. if (index >= width2*height2)
  78. return;
  79. if (index == cam_last_index)
  80. return; // in same pixel
  81. cam_last_index = index;
  82. if (shift)
  83. {
  84. Pal_SetIndex (pic[index]);
  85. return;
  86. }
  87. SetSkin (index, selected_rgb);
  88. UpdateWindow (camerawindow);
  89. }
  90. void Cam_DrawSetup (void)
  91. {
  92. glViewport (0,0,cam_width, cam_height);
  93. glMatrixMode (GL_PROJECTION);
  94. glLoadIdentity ();
  95. gluPerspective (90, (float)cam_width/cam_height, 2, 1024);
  96. gluLookAt (cam_x, cam_y, cam_z, cam_x, cam_y+1, cam_z, 0, 0, 1);
  97. glRotated (-roll*0.3, 0, 1, 0);
  98. glRotated (-pitch*0.3, 1, 0, 0);
  99. glRotated (yaw*0.3, 0, 0, 1);
  100. glMatrixMode (GL_MODELVIEW);
  101. glLoadIdentity ();
  102. glClear (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  103. glEnable (GL_DEPTH_TEST);
  104. glEnable (GL_CULL_FACE);
  105. glEnable (GL_TEXTURE_2D);
  106. glCullFace (GL_FRONT);
  107. glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  108. }
  109. void Cam_Draw (void)
  110. {
  111. if (!cam_width || !cam_height)
  112. return;
  113. glClearColor (0.3,0.3,0.3,1);
  114. Cam_DrawSetup ();
  115. BindTextureEXT (GL_TEXTURE_2D, TEXTURE_SKIN);
  116. DrawModel ();
  117. if (model_lines)
  118. {
  119. glDisable (GL_TEXTURE_2D);
  120. glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
  121. glDepthFunc (GL_LEQUAL);
  122. glDepthRange (0, 0.999); // nudge depth to avoid dropouts
  123. DrawModel ();
  124. glDepthRange (0, 1);
  125. glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
  126. glEnable (GL_TEXTURE_2D);
  127. }
  128. SwapBuffers(camdc);
  129. // now fill the back buffer with the index texture
  130. glClearColor (0,0,0,0);
  131. glClear (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  132. BindTextureEXT (GL_TEXTURE_2D, TEXTURE_INDEX);
  133. DrawModel ();
  134. BindTextureEXT (GL_TEXTURE_2D, TEXTURE_SKIN);
  135. }
  136. /*
  137. ============
  138. CameraWndProc
  139. ============
  140. */
  141. LONG WINAPI WCam_WndProc (
  142. HWND hWnd,
  143. UINT uMsg,
  144. WPARAM wParam,
  145. LPARAM lParam)
  146. {
  147. LONG lRet = 1;
  148. int fwKeys, xPos, yPos;
  149. RECT rect;
  150. static int oldx, oldy;
  151. POINT pt;
  152. GetClientRect(hWnd, &rect);
  153. cam_width = rect.right-rect.left;
  154. cam_height = rect.bottom-rect.top;
  155. switch (uMsg)
  156. {
  157. case WM_CREATE:
  158. camdc = GetDC(hWnd);
  159. bSetupPixelFormat(camdc);
  160. baseRC = wglCreateContext( camdc );
  161. if (!baseRC)
  162. Sys_Error ("wglCreateContext failed");
  163. if (!wglMakeCurrent( camdc, baseRC ))
  164. Sys_Error ("wglMakeCurrent failed");
  165. BindTextureEXT = (void *)wglGetProcAddress((LPCSTR) "glBindTextureEXT");
  166. if (!BindTextureEXT)
  167. Sys_Error ("GetProcAddress for BindTextureEXT failed");
  168. break;
  169. case WM_PAINT:
  170. {
  171. PAINTSTRUCT ps;
  172. BeginPaint(hWnd, &ps);
  173. if (!wglMakeCurrent( camdc, baseRC ))
  174. Sys_Error ("wglMakeCurrent failed");
  175. Cam_Draw ();
  176. EndPaint(hWnd, &ps);
  177. }
  178. break;
  179. case WM_MBUTTONDOWN:
  180. case WM_RBUTTONDOWN:
  181. if (GetTopWindow(mainwindow) != hWnd)
  182. BringWindowToTop(hWnd);
  183. SetFocus (camerawindow);
  184. SetCapture (camerawindow);
  185. GetCursorPos (&pt);
  186. xPos = pt.x;
  187. yPos = pt.y;
  188. oldx = xPos;
  189. oldy = yPos;
  190. break;
  191. case WM_LBUTTONDOWN:
  192. cam_last_index = -1;
  193. draw:
  194. if (GetTopWindow(mainwindow) != hWnd)
  195. BringWindowToTop(hWnd);
  196. SetFocus (camerawindow);
  197. SetCapture (camerawindow);
  198. fwKeys = wParam; // key flags
  199. xPos = (short)LOWORD(lParam); // horizontal position of cursor
  200. yPos = (short)HIWORD(lParam); // vertical position of cursor
  201. yPos = (int)rect.bottom - 1 - yPos;
  202. if (!wglMakeCurrent( camdc, baseRC ))
  203. Sys_Error ("wglMakeCurrent failed");
  204. Cam_Click (xPos, yPos, !!(wParam&(MK_SHIFT|MK_CONTROL)) );
  205. // Cam_MouseDown (xPos, yPos, fwKeys);
  206. break;
  207. case WM_MBUTTONUP:
  208. case WM_RBUTTONUP:
  209. case WM_LBUTTONUP:
  210. if (! (wParam & (MK_LBUTTON|MK_RBUTTON|MK_MBUTTON)))
  211. ReleaseCapture ();
  212. break;
  213. case WM_MOUSEMOVE:
  214. {
  215. int dx, dy;
  216. if (wParam & MK_LBUTTON)
  217. goto draw;
  218. GetCursorPos (&pt);
  219. xPos = pt.x;
  220. yPos = pt.y;
  221. if (!(wParam & (MK_RBUTTON|MK_MBUTTON)))
  222. {
  223. oldx = xPos;
  224. oldy = yPos;
  225. break;
  226. }
  227. dx = xPos-oldx;
  228. dy = oldy-yPos;
  229. if (!dx && !dy)
  230. break;
  231. SetCursorPos (oldx, oldy);
  232. if (wParam == (MK_RBUTTON|MK_CONTROL) )
  233. {
  234. if (abs(dx) > abs(dy))
  235. cam_y -= 0.1*dx;
  236. else
  237. cam_y -= 0.1*dy;
  238. InvalidateRect (camerawindow, NULL, false);
  239. }
  240. if (wParam == MK_RBUTTON)
  241. {
  242. cam_x -= 0.1*dx;
  243. cam_z -= 0.1*dy;
  244. InvalidateRect (camerawindow, NULL, false);
  245. }
  246. if (wParam == (MK_MBUTTON|MK_CONTROL) )
  247. {
  248. if (abs(dx) > abs(dy))
  249. roll -= dx;
  250. else
  251. roll -= dy;
  252. InvalidateRect (camerawindow, NULL, false);
  253. }
  254. if (wParam == MK_MBUTTON)
  255. {
  256. yaw += dx;
  257. pitch += dy;
  258. InvalidateRect (camerawindow, NULL, false);
  259. }
  260. }
  261. break;
  262. case WM_SIZE:
  263. // camera.width = rect.right;
  264. // camera.height = rect.bottom;
  265. InvalidateRect(camerawindow, NULL, false);
  266. break;
  267. case WM_NCCALCSIZE:// don't let windows copy pixels
  268. lRet = DefWindowProc (hWnd, uMsg, wParam, lParam);
  269. return WVR_REDRAW;
  270. case WM_CLOSE:
  271. /* call destroy window to cleanup and go away */
  272. DestroyWindow (hWnd);
  273. break;
  274. case WM_DESTROY:
  275. {
  276. HGLRC hRC;
  277. HDC hDC;
  278. /* release and free the device context and rendering context */
  279. hRC = wglGetCurrentContext();
  280. hDC = wglGetCurrentDC();
  281. wglMakeCurrent(NULL, NULL);
  282. if (hRC)
  283. wglDeleteContext(hRC);
  284. if (hDC)
  285. ReleaseDC(hWnd, hDC);
  286. }
  287. break;
  288. default:
  289. /* pass all unhandled messages to DefWindowProc */
  290. lRet = DefWindowProc (hWnd, uMsg, wParam, lParam);
  291. break;
  292. }
  293. /* return 1 if handled message, 0 if not */
  294. return lRet;
  295. }
  296. /*
  297. ==============
  298. WCam_Register
  299. ==============
  300. */
  301. void WCam_Register (HINSTANCE hInstance)
  302. {
  303. WNDCLASS wc;
  304. /* Register the camera class */
  305. memset (&wc, 0, sizeof(wc));
  306. wc.style = 0;
  307. wc.lpfnWndProc = (WNDPROC)WCam_WndProc;
  308. wc.cbClsExtra = 0;
  309. wc.cbWndExtra = 0;
  310. wc.hInstance = hInstance;
  311. wc.hIcon = 0;
  312. wc.hCursor = LoadCursor (NULL,IDC_ARROW);
  313. wc.hbrBackground = NULL;
  314. wc.lpszMenuName = 0;
  315. wc.lpszClassName = CAMERA_WINDOW_CLASS;
  316. if (!RegisterClass (&wc) )
  317. Sys_Error ("WCam_Register: failed");
  318. }
  319. void WCam_Create (HINSTANCE hInstance)
  320. {
  321. WCam_Register (hInstance);
  322. camerawindow = CreateWindow (CAMERA_WINDOW_CLASS ,
  323. "Camera View",
  324. QE3_STYLE,
  325. 0,
  326. 0,
  327. (int)(screen_width*0.5),
  328. (int)(screen_height-20), // size
  329. mainwindow, // parent window
  330. 0, // no menu
  331. hInstance,
  332. 0);
  333. if (!camerawindow)
  334. Sys_Error ("Couldn't create camerawindow");
  335. RestoreWindowState(camerawindow, "camerawindow");
  336. ShowWindow (camerawindow, SW_SHOWDEFAULT);
  337. }