home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 26 / AACD 26.iso / AACD / Graphics / sKulpt / skulpt-src / 3DWProc.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-08-30  |  12.3 KB  |  387 lines

  1. #define STRICT
  2.  
  3. // Includes standard Windows
  4. #include <windows.h>
  5. #include <windowsx.h>
  6. #include <time.h>
  7. #include <stdlib.h>
  8. #include <malloc.h>
  9. #include <memory.h>
  10. #include <stdio.h>
  11.  
  12. // Includes D3D
  13. #define  D3D_OVERLOADS
  14. #include <ddraw.h>
  15. #include <d3d.h>
  16.  
  17. // Includes utilitaires D3D
  18. #include "d3dmath.h"
  19. #include "d3dutil.h"
  20. #include "D3DEnum.h"
  21.  
  22. #include <d3dx.h>
  23.  
  24. // Ids Resources
  25. #include "resource.h"
  26.  
  27. // Constantes
  28. #include "const.h"
  29.  
  30. // Types
  31. #include "types.h"
  32.  
  33. // Variables globales projet
  34. #include "vars.h"
  35.  
  36. // Prototypes fonctions autres modules
  37. #include "proto.h"
  38.  
  39. // Macros
  40. #include "macros.h"
  41.  
  42. static W3D_Context *hWC3D;
  43. static HBITMAP hbDBuf3D;
  44. static DC dcDBuf3D, *hdcDBuf3D = &dcDBuf3D;
  45. static bZBuf = FALSE;
  46. static int iW, iH;
  47. static long lError;
  48. static BOOL bImage;
  49.  
  50. extern W3D_Texture *tex;
  51.  
  52. void vShow3DFrame(void)
  53. {
  54.     if (!bImage) return;
  55.  
  56.     int iLeftEdge = hWndPersp -> BorderLeft,
  57.         iTopEdge = hWndPersp -> BorderTop,
  58.         iW = hWndPersp -> Width - iLeftEdge - hWndPersp -> BorderRight,
  59.         iH = hWndPersp -> Height - iTopEdge - hWndPersp -> BorderBottom;
  60.  
  61.     ClipBlit(hdcDBuf3D, iLeftEdge, iTopEdge, hWndPersp -> RPort, iLeftEdge, iTopEdge, iW, iH, 0xc0);
  62. }
  63.  
  64. void vRender3DEnvironment(void)
  65. {
  66.     bImage = FALSE;
  67.  
  68.     // Verrouiller le bitmap en VRAM
  69.     lError = TAG_DONE;
  70. #if 0
  71.     APTR hBM = LockBitMapTagList(hbDBuf3D,(struct TagItem *) &lError);
  72.     if (!hBM)
  73.     {
  74.          vTrace("*** E0077 : vue 3D : lock bitmap (contexte @%08lX, code %ld)",  hWC3D, lError);
  75.          return;
  76.     }
  77. #endif
  78.     // Verrouiller le hardware 3D
  79.     if (!hWC3D || !hbDBuf3D || W3D_SUCCESS != (lError = W3D_LockHardware(hWC3D)))
  80.     {
  81. #if 0
  82.          // Déverrouiller le bitmap
  83.          UnLockBitMap(hBM);
  84. #endif
  85.          vTrace("*** E0067 : vue 3D : lock hardware (contexte @%08lX, code %ld, bm %08lX)", hWC3D, lError, hbDBuf3D);
  86.          return;
  87.     }
  88.  
  89.     W3D_Triangle sTriangle;
  90.     W3D_Double dZdepth = 1.;
  91.     W3D_Float   fLeftEdge = hWndPersp -> BorderLeft,
  92.                 fTopEdge = hWndPersp -> BorderTop,
  93.                 fW = hWndPersp -> Width - fLeftEdge - hWndPersp -> BorderRight,
  94.                 fH = hWndPersp -> Height - fTopEdge - hWndPersp -> BorderBottom,
  95.                 fXMed = fLeftEdge + fW / 2.,
  96.                 fYMed = fTopEdge + fH / 2.;
  97.     W3D_Vertex sV[4];
  98.     W3D_Triangles sTs; sTs.vertexcount = 4; sTs.v = sV;
  99.     W3D_Color sC = {0., 0., 0., 1.};
  100.  
  101.     // Clearer le zbuf
  102.     if (bZBuf) W3D_ClearZBuffer(hWC3D, &dZdepth);
  103.  
  104.     // Set Drawing region
  105.     sScissor.left   = (int) fLeftEdge;
  106.     sScissor.top    = (int) fTopEdge;
  107.     sScissor.width  = (int) fW;
  108.     sScissor.height = (int) fH;
  109.     W3D_SetDrawRegion(hWC3D, NULL, 0, &sScissor);
  110.  
  111.     // Calculer le produit des matrices view / proj
  112.     D3DMath_MatrixMultiply(matWorld, matView, matProj);
  113.  
  114.     // Gouraud shading & zbuffer off
  115.     W3D_SetState(hWC3D, W3D_GOURAUD, W3D_DISABLE);
  116.     W3D_SetState(hWC3D, W3D_ZBUFFER, W3D_DISABLE);
  117.  
  118.     // Remplir le fond
  119.     WSetPen(hWC3D, cBack);
  120.     WRectFill(hWC3D, 0, 0, fW - 1, fH - 1);
  121.  
  122.     // Gouraud shading & zBuffer on
  123.     W3D_SetState(hWC3D, W3D_GOURAUD, W3D_ENABLE);
  124.     if (bZBuf) W3D_SetState(hWC3D, W3D_ZBUFFER, W3D_ENABLE);
  125.  
  126.     // Calculer le vecteur normalisé observateur / cible (pour le lighting simpliste)
  127.     D3DVECTOR vObs = Normalize(Observer - Target);
  128.  
  129.     // Dessiner les triangles
  130.     for (register int iTriangles = 0 ; iTriangles <= iTriaLastUsed ; iTriangles++)
  131.     {
  132.         register gTri *hTri = &Triangles[iTriangles];
  133.  
  134.         if (!hTri -> bEnabled) continue;
  135.         if (hTri -> bHidden)   continue;
  136.         D3DVECTOR
  137.             // Déréférencer les 3 sommets du triangle
  138.             v0_UnT = Vertices[hTri -> iSommets[0]].vPoint,
  139.             v1_UnT = Vertices[hTri -> iSommets[1]].vPoint,
  140.             v2_UnT = Vertices[hTri -> iSommets[2]].vPoint,
  141.             // Transformés normalisés des 3 vecteurs ci-dessus
  142.             v0, v1, v2;
  143.  
  144.         // TRANSFORM, step 1 : Transformation coordonnées objets vers [-1..+1] en utilisant la concaténation des matrices View et Proj
  145.         D3DMath_VectorMatrixMultiply(v0, v0_UnT, matWorld);
  146.         D3DMath_VectorMatrixMultiply(v1, v1_UnT, matWorld);
  147.         D3DMath_VectorMatrixMultiply(v2, v2_UnT, matWorld);
  148.  
  149.         // TRANSFORM, step 2 : ajustement du span X/Y dans fenêtre 3D
  150.         sTriangle.v1.x = fXMed + v0.x * fW;
  151.         sTriangle.v1.y = fYMed + v0.y * fH;
  152.         sTriangle.v2.x = fXMed + v1.x * fW;
  153.         sTriangle.v2.y = fYMed + v1.y * fH;
  154.         sTriangle.v3.x = fXMed + v2.x * fW;
  155.         sTriangle.v3.y = fYMed + v2.y * fH;
  156.         sTriangle.v1.z = v0.z;
  157.         sTriangle.v2.z = v1.z;
  158.         sTriangle.v3.z = v2.z;
  159.  
  160.         // LIGHT, step 1 : calculer les vecteurs normaux sur les trois sommets et les facteurs de correction
  161.         D3DVECTOR
  162.             v01 = v1_UnT - v0_UnT,
  163.             v02 = v2_UnT - v0_UnT,
  164.             v12 = v2_UnT - v1_UnT,
  165.             vn0 = Normalize(CrossProduct(v01, v02)),
  166.             vn1 = Normalize(CrossProduct(v01, v12)),
  167.             vn2 = Normalize(CrossProduct(v02, v12));
  168.         FLOAT
  169.             f0 = fabs(DotProduct(vObs, vn0)),
  170.             f1 = fabs(DotProduct(vObs, vn1)),
  171.             f2 = fabs(DotProduct(vObs, vn2));
  172.  
  173.         // LIGHT, step 2 : moduler la couleur en fonction orientation
  174.         D3DMATERIAL7 *hMtrl = &Materials[hTri -> iMtrl].mtrl;
  175.         sC.r = hMtrl -> diffuse.r;
  176.         sC.g = hMtrl -> diffuse.g;
  177.         sC.b = hMtrl -> diffuse.b;
  178.         sTriangle.v1.color.r = sC.r * f0; sTriangle.v1.color.g = sC.g * f0; sTriangle.v1.color.b = sC.b * f0;
  179.         sTriangle.v2.color.r = sC.r * f1; sTriangle.v2.color.g = sC.g * f1; sTriangle.v2.color.b = sC.b * f1;
  180.         sTriangle.v3.color.r = sC.r * f2; sTriangle.v3.color.g = sC.g * f2; sTriangle.v3.color.b = sC.b * f2;
  181.  
  182.         if (Materials[hTri -> iMtrl].bTextured)
  183.         {
  184.             // Set Texture mapping on
  185.             W3D_SetState(hWC3D, W3D_TEXMAPPING, W3D_ENABLE);
  186.  
  187.             // Affecter les u & v
  188.             sTriangle.v1.u = hTri -> u[0];  sTriangle.v1.v = hTri -> v[0];
  189.             sTriangle.v2.u = hTri -> u[1];  sTriangle.v2.v = hTri -> v[1];
  190.             sTriangle.v3.u = hTri -> u[2];  sTriangle.v3.v = hTri -> v[2];
  191.  
  192.             // Affecter la texture
  193.             sTriangle.tex = Materials[hTri -> iMtrl].hTexture;
  194. /********/  sTriangle.tex = tex;
  195.  
  196.             // Dessiner le triangle
  197.             W3D_DrawTriangle(hWC3D, &sTriangle);
  198.  
  199.             // Set Texture mapping off
  200.             W3D_SetState(hWC3D, W3D_TEXMAPPING, W3D_DISABLE);
  201.         }
  202.         else
  203.             W3D_DrawTriangle(hWC3D, &sTriangle);
  204.     }
  205.  
  206.     // Déverrouiller le hardware 3D
  207.     W3D_UnLockHardware(hWC3D);
  208.  
  209. #if 0
  210.     // Déverrouiller le bitmap
  211.     UnLockBitMap(hBM);
  212. #endif
  213.  
  214.     // Mémoriser qu'on a bien créé une image dans le double buffer
  215.     bImage = TRUE;
  216.  
  217.     // Blitter le double dans la fenêtre
  218.     vShow3DFrame();
  219. }
  220.  
  221. void vForce3DRefresh(BOOL bFull)
  222. {
  223.     if (bFull == XDC_MODE_COMPLET)
  224.         vRender3DEnvironment();
  225.     else
  226.         vShow3DFrame();
  227. }
  228.  
  229. LRESULT CALLBACK lrPerspWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  230. {
  231.     switch( uMsg )
  232.     {
  233.         case WM_PAINT:
  234.             // If we get WM_PAINT messages, it usually means our window was
  235.             // covered up, so we need to refresh it by re-showing the contents
  236.             // of the current frame.
  237.             vForce3DRefresh(XDC_MODE_PARTIEL);
  238.             break;
  239.  
  240.         case WM_CREATE:
  241.             InitRastPort(hdcDBuf3D);
  242.         case WM_SIZE:
  243. #ifndef _AMIGA_
  244.             // Check to see if we are losing or gaining our window. Set the
  245.             // active flag to match.
  246.             if( SIZE_MAXHIDE==wParam || SIZE_MINIMIZED==wParam )
  247.                 bActive = FALSE;
  248.             else bActive = TRUE;
  249.             // A new window size will require a new backbuffer size. The
  250.             // easiest way to achieve this is to release and re-create
  251.             // everything.
  252.             if( bActive && bReady )
  253. #endif
  254.             {
  255.                 bReady = FALSE;
  256. #ifndef _AMIGA_
  257.                 if( FAILED( hrCloseD3D(FALSE) ) )
  258.                     DestroyWindow( hWnd );
  259.  
  260.                 if( FAILED( hrInitD3D( hWnd, &gDeviceGUID ) ) )
  261.                     DestroyWindow( hWnd );
  262.  
  263.                 if (FAILED(hrInitWorld( lpd3dDevice )))
  264.                 {
  265.                     hrCloseD3D(TRUE);
  266.                     DestroyWindow( hWnd );
  267.                 }
  268.  
  269.                 // Mettre à jour les variables d'état du pipe D3D
  270.                 vSetD3DState();
  271.  
  272.                 // Remettre en service les lampes
  273.                 for (int iCnt = 0 ; iCnt <= iLampLastUsed ; iCnt++)
  274.                     if (Lampes[iCnt].bEnabled)
  275.                         bUpdateLamp(iCnt);
  276.                 // Redessiner la scène
  277. #else
  278.                 // Si la taille n'a pas changé, ne rien faire
  279.                 if (iW == hWnd -> Width && iH == hWnd -> Height)
  280.                     break;
  281.                 iW = hWnd -> Width;
  282.                 iH = hWnd -> Height;
  283.  
  284.                 // Supprimer le contexte 3D s'il est déjà alloué
  285.                 if (hWC3D)
  286.                 {
  287.                     if (bZBuf)
  288.                     {
  289.                         W3D_FreeZBuffer(hWC3D);
  290.                         bZBuf = FALSE;
  291.                     }
  292.                     vCloseTextures(hWC3D);
  293.                     W3D_DestroyContext(hWC3D);
  294.                     hWC3D = NULL;
  295.                 }
  296.  
  297.                 // Supprimer le bitmap offscreen s'il est déjà alloué
  298.                 if (hbDBuf3D)
  299.                     FreeBitMap(hbDBuf3D);
  300.  
  301.                 // Créer le bitmap offscreen
  302.                 if (!(hbDBuf3D = AllocBitMap(hWnd -> Width, hWnd -> Height, 8, BMF_MINPLANES | BMF_DISPLAYABLE, hWnd -> RPort -> BitMap)))
  303.                 {
  304.                     vTrace("*** E0068 : vue 3D : allocation double buffer");
  305.                     break;
  306.                 }
  307.  
  308.                 // Attacher le bitmap au rastport
  309.                 dcDBuf3D.BitMap = hbDBuf3D;
  310.  
  311.                 // Créer le contexte W3D
  312.                 extern ULONG lModeID, lError;
  313.                 if (!(hWC3D = W3D_CreateContextTags(&lError,
  314.                     W3D_CC_MODEID,      lModeID,
  315.                     W3D_CC_BITMAP,      (ULONG) hbDBuf3D,
  316.                     W3D_CC_YOFFSET,     0,
  317.                     W3D_CC_DRIVERTYPE,  W3D_DRIVER_BEST,
  318.                     W3D_CC_FAST,        TRUE,
  319.                     TAG_DONE)))
  320.                 {
  321.                     vTrace("*** E0069 : vue 3D : crétion contexte Warp3D (code %ld)", lError);
  322.                     FreeBitMap(hbDBuf3D); hbDBuf3D = NULL;
  323.                     break;
  324.                 }
  325.  
  326.                 // Set dithering. This will look considerably better on 15 bit displays.
  327.                 W3D_SetState(hWC3D, W3D_DITHERING, W3D_ENABLE);
  328.  
  329.                 // Activer le clipping
  330.                 W3D_SetState(hWC3D, W3D_SCISSOR, W3D_ENABLE);
  331.  
  332.                 // Allouer le ZBuffer
  333.                    if (W3D_SUCCESS != W3D_AllocZBuffer(hWC3D))
  334.                 {
  335.                     bZBuf = FALSE;
  336.                     vTrace("*** E0047 : vue 3D : allocation ZBuffer -> pas de suppression faces cachées");
  337.                 }
  338.                 else
  339.                 {
  340.                     W3D_SetZCompareMode(hWC3D, W3D_Z_LESS);
  341.                     W3D_SetState(hWC3D, W3D_ZBUFFERUPDATE, W3D_ENABLE);
  342.                     bZBuf = TRUE;
  343.                     vTrace("Vue 3D : allocation double buffer / contexte Warp3D / z-buffer OK");
  344.                 }
  345.                 vInitTextures(hWC3D);
  346.  
  347. #endif
  348.                 // Redessiner la 3D dans le double buffer, Intuition va de de toute façon nous envoyer un REFRESH qui nous donnera un PAINT qui nous fera blitter le double buffer dans la fenêtre
  349.                 vRender3DEnvironment();
  350.  
  351.                 bReady = TRUE;
  352.             }
  353.             break;
  354.  
  355.         case WM_COMMAND: // Rediriger les frappes clavier et chois menus vers la fenêtre menus
  356.         case WM_CHAR :
  357.             PostMessage(hWndMenu, uMsg, wParam, lParam );
  358.             break;
  359.  
  360.         case WM_DESTROY:
  361.             // Supprimer le contexte 3D
  362.             if (hWC3D)
  363.             {
  364.                 if (bZBuf)
  365.                 {
  366.                     W3D_FreeZBuffer(hWC3D);
  367.                     bZBuf = FALSE;
  368.                 }
  369.                 vCloseTextures(hWC3D);
  370.                 W3D_DestroyContext(hWC3D);
  371.                 hWC3D = NULL;
  372.             }
  373.  
  374.             // Supprimer le bitmap offscreen
  375.             if (hbDBuf3D) FreeBitMap(hbDBuf3D);
  376.  
  377.             PostQuitMessage(0);
  378.             return 0L;
  379.     }
  380. #ifndef _AMIGA_
  381.     return DefWindowProc( hWnd, uMsg, wParam, lParam );
  382. #else
  383.     return 0;
  384. #endif
  385. }
  386.  
  387.