home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 45 / cda45.iso / VNULabs / CursoProg / test.c next >
Encoding:
C/C++ Source or Header  |  2000-03-30  |  7.6 KB  |  250 lines

  1. // ============================================================
  2. //   LeaRNWaRe code by CROM / Spanish  Lords 
  3. //                            - since 1993 -
  4. //
  5. //   Objetivo   : Ejemplillo de rotaciones.
  6. //   Autor      : Pedro Ant≤n Alonso. crom@ergos.es
  7. //   Plataforma : Windows 95 / NT
  8. //   Compilador : Visual C++ 6.0
  9. //   
  10. // ============================================================
  11.  
  12. #include <windows.h>
  13. #include <stdlib.h>
  14. #include <math.h>
  15.  
  16. int cxClient; // Area cliente
  17. int cyClient;
  18.  
  19. float fAngleA; // Angulos de giro sobre los ejes X,Y,Z
  20. float fAngleB;
  21. float fAngleC;
  22.  
  23. typedef struct // Definicion de un punto en 3D.
  24.   float x;
  25.   float y;
  26.   float z;
  27. } tPunto3D;
  28.  
  29. // Coordenadas del cubo que vamos a pintar.
  30. tPunto3D Punto1,Punto2,Punto3,Punto4;
  31. tPunto3D Punto5,Punto6,Punto7,Punto8;
  32.  
  33. LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
  34. void             DibujaTodo (HWND);
  35. void             CalculaPuntos ();
  36. tPunto3D         RotaPuntos (tPunto3D Punto);
  37.  
  38. //
  39. // No comento nada de este trozo... 
  40. // ... es siempre igual: Register, Create, Show y Update ;)
  41. //
  42. int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
  43.                     PSTR szCmdLine, int iCmdShow)
  44. {
  45.   static char szAppName[] = "Algo de 3D" ;
  46.   HWND        hwnd ;
  47.   MSG         msg ;
  48.   WNDCLASSEX  wndclass ;
  49.  
  50.   wndclass.cbSize        = sizeof (wndclass);
  51.   wndclass.style         = CS_HREDRAW | CS_VREDRAW;
  52.   wndclass.lpfnWndProc   = WndProc;
  53.   wndclass.cbClsExtra    = 0;
  54.   wndclass.cbWndExtra    = 0;
  55.   wndclass.hInstance     = hInstance;
  56.   wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION);
  57.   wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW);
  58.   wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
  59.   wndclass.lpszMenuName  = NULL;
  60.   wndclass.lpszClassName = szAppName;
  61.   wndclass.hIconSm       = LoadIcon (NULL, IDI_APPLICATION);
  62.  
  63.   RegisterClassEx (&wndclass) ;
  64.  
  65.   hwnd = CreateWindow (szAppName, "Rotando un Cubo en 3D",
  66.                        WS_OVERLAPPEDWINDOW,
  67.                        CW_USEDEFAULT, CW_USEDEFAULT,
  68.                        CW_USEDEFAULT, CW_USEDEFAULT,
  69.                        NULL, NULL, hInstance, NULL);
  70.  
  71.   ShowWindow (hwnd, iCmdShow);
  72.   UpdateWindow (hwnd);
  73.   if(!SetTimer (hwnd,0x1010,20,NULL)) return FALSE;
  74.  
  75.   // Trata  los mensajes... o pinta mis lineas.
  76.   while (TRUE)
  77.   {
  78.     if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
  79.     {
  80.       if (msg.message == WM_QUIT) break;
  81.       TranslateMessage (&msg);
  82.       DispatchMessage (&msg);
  83.     }
  84.   }
  85.   return msg.wParam;
  86. }
  87.  
  88.  
  89. //
  90. // El bucle procesador de mensajes.
  91. //
  92. LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
  93. {
  94.   switch (iMsg)
  95.   {
  96.     case WM_SIZE:    cxClient = LOWORD (lParam);
  97.                      cyClient = HIWORD (lParam);
  98.                      CalculaPuntos();
  99.                      return 0 ;
  100.  
  101.     case WM_DESTROY: PostQuitMessage (0);
  102.                      return 0;
  103.     case WM_TIMER:   DibujaTodo (hwnd);
  104.                      fAngleA=fAngleA+0.1;
  105.                      fAngleB=fAngleA+0.2;
  106.                      fAngleC=fAngleA+0.13;
  107.                      return 0;
  108.   }
  109.   return DefWindowProc (hwnd, iMsg, wParam, lParam);
  110. }
  111.  
  112. //
  113. // Pintaaaaaaaaaaaaaaaaaa.
  114. //
  115. void DibujaTodo (HWND hwnd)
  116. {
  117.   HPEN     hLapiz;
  118.   HPEN     hLapizCubo;
  119.   HDC      hdc;
  120.   HBRUSH   hBrocha;
  121.   tPunto3D Punto1R,Punto2R,Punto3R,Punto4R;
  122.   tPunto3D Punto5R,Punto6R,Punto7R,Punto8R;
  123.   
  124.   // Comprueba el area cliente.
  125.   if (cxClient == 0 || cyClient == 0) return;
  126.  
  127.   // Coje el contexto de dispositivo.
  128.   hdc = GetDC (hwnd);
  129.  
  130.   // Crea la brocha.
  131.   hBrocha= (HBRUSH) GetStockObject (WHITE_BRUSH);
  132.   // Selecciona la brocha.
  133.   SelectObject (hdc, hBrocha);
  134.   // BORRA la pantalla.
  135.   Rectangle (hdc, 0,0,cxClient,cyClient);
  136.  
  137.   // Crea un lapicero negro y otro verde
  138.   hLapiz     = CreatePen (PS_SOLID,3,RGB(0,0,0));
  139.   hLapizCubo = CreatePen (PS_SOLID,3,RGB(0,128,0));
  140.   // Selecciona el lapicero negro.
  141.   SelectObject (hdc, hLapiz);
  142.   // Pintamos los ejes
  143.   MoveToEx (hdc, cxClient/2, cyClient/2, NULL);
  144.   LineTo   (hdc, cxClient, cyClient/2);
  145.   MoveToEx (hdc, cxClient/2, cyClient/2, NULL);
  146.   LineTo   (hdc, cxClient/2, 0);
  147.   MoveToEx (hdc, cxClient/2, cyClient/2, NULL);
  148.   LineTo   (hdc, 0, cyClient);
  149.  
  150.   // Rota el cubo alrededor de XYZ
  151.   Punto1R=RotaPuntos (Punto1);
  152.   Punto2R=RotaPuntos (Punto2);
  153.   Punto3R=RotaPuntos (Punto3);
  154.   Punto4R=RotaPuntos (Punto4);
  155.   Punto5R=RotaPuntos (Punto5);
  156.   Punto6R=RotaPuntos (Punto6);
  157.   Punto7R=RotaPuntos (Punto7);
  158.   Punto8R=RotaPuntos (Punto8);
  159.   
  160.   // Selecciona el lapicero verde.
  161.   SelectObject (hdc, hLapizCubo);
  162.   // El trozo de cubo que puedo pintar sin levantar el lapiz :)
  163.   MoveToEx (hdc, (cxClient/2)+Punto1R.x, (cyClient/2)+Punto1R.y, NULL);
  164.   LineTo   (hdc, (cxClient/2)+Punto2R.x, (cyClient/2)+Punto2R.y);
  165.   LineTo   (hdc, (cxClient/2)+Punto3R.x, (cyClient/2)+Punto3R.y);
  166.   LineTo   (hdc, (cxClient/2)+Punto4R.x, (cyClient/2)+Punto4R.y);
  167.   LineTo   (hdc, (cxClient/2)+Punto1R.x, (cyClient/2)+Punto1R.y);
  168.   LineTo   (hdc, (cxClient/2)+Punto5R.x, (cyClient/2)+Punto5R.y);
  169.   LineTo   (hdc, (cxClient/2)+Punto6R.x, (cyClient/2)+Punto6R.y);
  170.   LineTo   (hdc, (cxClient/2)+Punto7R.x, (cyClient/2)+Punto7R.y);
  171.   LineTo   (hdc, (cxClient/2)+Punto8R.x, (cyClient/2)+Punto8R.y);
  172.   LineTo   (hdc, (cxClient/2)+Punto5R.x, (cyClient/2)+Punto5R.y);
  173.   // ... y las diagonales.
  174.   MoveToEx (hdc, (cxClient/2)+Punto2R.x, (cyClient/2)+Punto2R.y, NULL);
  175.   LineTo   (hdc, (cxClient/2)+Punto6R.x, (cyClient/2)+Punto6R.y);
  176.   MoveToEx (hdc, (cxClient/2)+Punto3R.x, (cyClient/2)+Punto3R.y, NULL);
  177.   LineTo   (hdc, (cxClient/2)+Punto7R.x, (cyClient/2)+Punto7R.y);
  178.   MoveToEx (hdc, (cxClient/2)+Punto4R.x, (cyClient/2)+Punto4R.y, NULL);
  179.   LineTo   (hdc, (cxClient/2)+Punto8R.x, (cyClient/2)+Punto8R.y);
  180.   
  181.   // Devuelve el contexto de dispositivo.
  182.   ReleaseDC (hwnd, hdc);
  183.   // Destruye el lapiz.
  184.   DeleteObject (hBrocha);
  185.   DeleteObject (hLapiz);
  186.   DeleteObject (hLapizCubo);
  187. }     
  188.  
  189. //
  190. // Calcula mi cubo ;)
  191. //
  192. void CalculaPuntos ()
  193. {
  194.   int      iLadoCubo;
  195.  
  196.   // Vamos a los puntos:
  197.   iLadoCubo= cxClient/8;
  198.   // Delante izqda arriba
  199.   Punto1.x = (float)-iLadoCubo;
  200.   Punto1.y = (float) iLadoCubo;
  201.   Punto1.z = (float) iLadoCubo;
  202.     // Delante drcha arriba
  203.   Punto2.x = (float) iLadoCubo;
  204.   Punto2.y = (float) iLadoCubo;
  205.   Punto2.z = (float) iLadoCubo;
  206.   // Delante drcha abajo
  207.   Punto3.x = (float) iLadoCubo;
  208.   Punto3.y = (float)-iLadoCubo;
  209.   Punto3.z = (float) iLadoCubo;
  210.   // Delante izqda abajo
  211.   Punto4.x = (float)-iLadoCubo;
  212.   Punto4.y = (float)-iLadoCubo;
  213.   Punto4.z = (float) iLadoCubo;
  214.   // Detras izqda arriba
  215.   Punto5.x = (float)-iLadoCubo;
  216.   Punto5.y = (float) iLadoCubo;
  217.   Punto5.z = (float)-iLadoCubo;
  218.   // Detras drcha arriba
  219.   Punto6.x = (float) iLadoCubo;
  220.   Punto6.y = (float) iLadoCubo;
  221.   Punto6.z = (float)-iLadoCubo;
  222.   // Detras drcha abajo
  223.   Punto7.x = (float) iLadoCubo;
  224.   Punto7.y = (float)-iLadoCubo;
  225.   Punto7.z = (float)-iLadoCubo;
  226.   // Detras izqda abajo
  227.   Punto8.x = (float)-iLadoCubo;
  228.   Punto8.y = (float)-iLadoCubo;
  229.   Punto8.z = (float)-iLadoCubo;
  230. }
  231.  
  232. //
  233. // Rota los puntos alrededor de los ejes XYZ
  234. //
  235. tPunto3D RotaPuntos (tPunto3D Punto)
  236. {
  237.   float    x1;
  238.   float    y1;
  239.   float    z1;
  240.   tPunto3D PuntoR;
  241.  
  242.   x1        = (Punto.x *cos(fAngleA))  - (Punto.z *sin(fAngleB));
  243.   z1        = (Punto.x *sin(fAngleB))  + (Punto.z *cos(fAngleB));
  244.   PuntoR.x  = (x1*cos(fAngleC))        + (Punto.y *sin(fAngleC));
  245.   y1        = (Punto.y *cos(fAngleC))  - (x1*sin(fAngleC));
  246.   PuntoR.z  = (z1*cos(fAngleA))        - (y1*sin(fAngleA));
  247.   PuntoR.y  = (z1*sin(fAngleA))        + (y1*cos(fAngleA));
  248.   return (PuntoR);
  249. }