home *** CD-ROM | disk | FTP | other *** search
- // ============================================================
- // LeaRNWaRe code by CROM / Spanish Lords
- // - since 1993 -
- //
- // Objetivo : Ejemplillo de rotaciones.
- // Autor : Pedro Ant≤n Alonso. crom@ergos.es
- // Plataforma : Windows 95 / NT
- // Compilador : Visual C++ 6.0
- //
- // ============================================================
-
- #include <windows.h>
- #include <stdlib.h>
- #include <math.h>
-
- int cxClient; // Area cliente
- int cyClient;
-
- float fAngleA; // Angulos de giro sobre los ejes X,Y,Z
- float fAngleB;
- float fAngleC;
-
- typedef struct // Definicion de un punto en 3D.
- {
- float x;
- float y;
- float z;
- } tPunto3D;
-
- // Coordenadas del cubo que vamos a pintar.
- tPunto3D Punto1,Punto2,Punto3,Punto4;
- tPunto3D Punto5,Punto6,Punto7,Punto8;
-
- LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
- void DibujaTodo (HWND);
- void CalculaPuntos ();
- tPunto3D RotaPuntos (tPunto3D Punto);
-
- //
- // No comento nada de este trozo...
- // ... es siempre igual: Register, Create, Show y Update ;)
- //
- int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
- PSTR szCmdLine, int iCmdShow)
- {
- static char szAppName[] = "Algo de 3D" ;
- HWND hwnd ;
- MSG msg ;
- WNDCLASSEX wndclass ;
-
- wndclass.cbSize = sizeof (wndclass);
- wndclass.style = CS_HREDRAW | CS_VREDRAW;
- wndclass.lpfnWndProc = WndProc;
- wndclass.cbClsExtra = 0;
- wndclass.cbWndExtra = 0;
- wndclass.hInstance = hInstance;
- wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION);
- wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
- wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
- wndclass.lpszMenuName = NULL;
- wndclass.lpszClassName = szAppName;
- wndclass.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
-
- RegisterClassEx (&wndclass) ;
-
- hwnd = CreateWindow (szAppName, "Rotando un Cubo en 3D",
- WS_OVERLAPPEDWINDOW,
- CW_USEDEFAULT, CW_USEDEFAULT,
- CW_USEDEFAULT, CW_USEDEFAULT,
- NULL, NULL, hInstance, NULL);
-
- ShowWindow (hwnd, iCmdShow);
- UpdateWindow (hwnd);
- if(!SetTimer (hwnd,0x1010,20,NULL)) return FALSE;
-
- // Trata los mensajes... o pinta mis lineas.
- while (TRUE)
- {
- if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
- {
- if (msg.message == WM_QUIT) break;
- TranslateMessage (&msg);
- DispatchMessage (&msg);
- }
- }
- return msg.wParam;
- }
-
-
- //
- // El bucle procesador de mensajes.
- //
- LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
- {
- switch (iMsg)
- {
- case WM_SIZE: cxClient = LOWORD (lParam);
- cyClient = HIWORD (lParam);
- CalculaPuntos();
- return 0 ;
-
- case WM_DESTROY: PostQuitMessage (0);
- return 0;
- case WM_TIMER: DibujaTodo (hwnd);
- fAngleA=fAngleA+0.1;
- fAngleB=fAngleA+0.2;
- fAngleC=fAngleA+0.13;
- return 0;
- }
- return DefWindowProc (hwnd, iMsg, wParam, lParam);
- }
-
- //
- // Pintaaaaaaaaaaaaaaaaaa.
- //
- void DibujaTodo (HWND hwnd)
- {
- HPEN hLapiz;
- HPEN hLapizCubo;
- HDC hdc;
- HBRUSH hBrocha;
- tPunto3D Punto1R,Punto2R,Punto3R,Punto4R;
- tPunto3D Punto5R,Punto6R,Punto7R,Punto8R;
-
- // Comprueba el area cliente.
- if (cxClient == 0 || cyClient == 0) return;
-
- // Coje el contexto de dispositivo.
- hdc = GetDC (hwnd);
-
- // Crea la brocha.
- hBrocha= (HBRUSH) GetStockObject (WHITE_BRUSH);
- // Selecciona la brocha.
- SelectObject (hdc, hBrocha);
- // BORRA la pantalla.
- Rectangle (hdc, 0,0,cxClient,cyClient);
-
- // Crea un lapicero negro y otro verde
- hLapiz = CreatePen (PS_SOLID,3,RGB(0,0,0));
- hLapizCubo = CreatePen (PS_SOLID,3,RGB(0,128,0));
- // Selecciona el lapicero negro.
- SelectObject (hdc, hLapiz);
- // Pintamos los ejes
- MoveToEx (hdc, cxClient/2, cyClient/2, NULL);
- LineTo (hdc, cxClient, cyClient/2);
- MoveToEx (hdc, cxClient/2, cyClient/2, NULL);
- LineTo (hdc, cxClient/2, 0);
- MoveToEx (hdc, cxClient/2, cyClient/2, NULL);
- LineTo (hdc, 0, cyClient);
-
- // Rota el cubo alrededor de XYZ
- Punto1R=RotaPuntos (Punto1);
- Punto2R=RotaPuntos (Punto2);
- Punto3R=RotaPuntos (Punto3);
- Punto4R=RotaPuntos (Punto4);
- Punto5R=RotaPuntos (Punto5);
- Punto6R=RotaPuntos (Punto6);
- Punto7R=RotaPuntos (Punto7);
- Punto8R=RotaPuntos (Punto8);
-
- // Selecciona el lapicero verde.
- SelectObject (hdc, hLapizCubo);
- // El trozo de cubo que puedo pintar sin levantar el lapiz :)
- MoveToEx (hdc, (cxClient/2)+Punto1R.x, (cyClient/2)+Punto1R.y, NULL);
- LineTo (hdc, (cxClient/2)+Punto2R.x, (cyClient/2)+Punto2R.y);
- LineTo (hdc, (cxClient/2)+Punto3R.x, (cyClient/2)+Punto3R.y);
- LineTo (hdc, (cxClient/2)+Punto4R.x, (cyClient/2)+Punto4R.y);
- LineTo (hdc, (cxClient/2)+Punto1R.x, (cyClient/2)+Punto1R.y);
- LineTo (hdc, (cxClient/2)+Punto5R.x, (cyClient/2)+Punto5R.y);
- LineTo (hdc, (cxClient/2)+Punto6R.x, (cyClient/2)+Punto6R.y);
- LineTo (hdc, (cxClient/2)+Punto7R.x, (cyClient/2)+Punto7R.y);
- LineTo (hdc, (cxClient/2)+Punto8R.x, (cyClient/2)+Punto8R.y);
- LineTo (hdc, (cxClient/2)+Punto5R.x, (cyClient/2)+Punto5R.y);
- // ... y las diagonales.
- MoveToEx (hdc, (cxClient/2)+Punto2R.x, (cyClient/2)+Punto2R.y, NULL);
- LineTo (hdc, (cxClient/2)+Punto6R.x, (cyClient/2)+Punto6R.y);
- MoveToEx (hdc, (cxClient/2)+Punto3R.x, (cyClient/2)+Punto3R.y, NULL);
- LineTo (hdc, (cxClient/2)+Punto7R.x, (cyClient/2)+Punto7R.y);
- MoveToEx (hdc, (cxClient/2)+Punto4R.x, (cyClient/2)+Punto4R.y, NULL);
- LineTo (hdc, (cxClient/2)+Punto8R.x, (cyClient/2)+Punto8R.y);
-
- // Devuelve el contexto de dispositivo.
- ReleaseDC (hwnd, hdc);
- // Destruye el lapiz.
- DeleteObject (hBrocha);
- DeleteObject (hLapiz);
- DeleteObject (hLapizCubo);
- }
-
- //
- // Calcula mi cubo ;)
- //
- void CalculaPuntos ()
- {
- int iLadoCubo;
-
- // Vamos a los puntos:
- iLadoCubo= cxClient/8;
- // Delante izqda arriba
- Punto1.x = (float)-iLadoCubo;
- Punto1.y = (float) iLadoCubo;
- Punto1.z = (float) iLadoCubo;
- // Delante drcha arriba
- Punto2.x = (float) iLadoCubo;
- Punto2.y = (float) iLadoCubo;
- Punto2.z = (float) iLadoCubo;
- // Delante drcha abajo
- Punto3.x = (float) iLadoCubo;
- Punto3.y = (float)-iLadoCubo;
- Punto3.z = (float) iLadoCubo;
- // Delante izqda abajo
- Punto4.x = (float)-iLadoCubo;
- Punto4.y = (float)-iLadoCubo;
- Punto4.z = (float) iLadoCubo;
- // Detras izqda arriba
- Punto5.x = (float)-iLadoCubo;
- Punto5.y = (float) iLadoCubo;
- Punto5.z = (float)-iLadoCubo;
- // Detras drcha arriba
- Punto6.x = (float) iLadoCubo;
- Punto6.y = (float) iLadoCubo;
- Punto6.z = (float)-iLadoCubo;
- // Detras drcha abajo
- Punto7.x = (float) iLadoCubo;
- Punto7.y = (float)-iLadoCubo;
- Punto7.z = (float)-iLadoCubo;
- // Detras izqda abajo
- Punto8.x = (float)-iLadoCubo;
- Punto8.y = (float)-iLadoCubo;
- Punto8.z = (float)-iLadoCubo;
- }
-
- //
- // Rota los puntos alrededor de los ejes XYZ
- //
- tPunto3D RotaPuntos (tPunto3D Punto)
- {
- float x1;
- float y1;
- float z1;
- tPunto3D PuntoR;
-
- x1 = (Punto.x *cos(fAngleA)) - (Punto.z *sin(fAngleB));
- z1 = (Punto.x *sin(fAngleB)) + (Punto.z *cos(fAngleB));
- PuntoR.x = (x1*cos(fAngleC)) + (Punto.y *sin(fAngleC));
- y1 = (Punto.y *cos(fAngleC)) - (x1*sin(fAngleC));
- PuntoR.z = (z1*cos(fAngleA)) - (y1*sin(fAngleA));
- PuntoR.y = (z1*sin(fAngleA)) + (y1*cos(fAngleA));
- return (PuntoR);
- }