 /* '02 Main.cpp' */

 /* Nagłówek szkieletu okna Mirus */
#include "mrWindow.h"
 /* Nagłówek Direct3D */
#include <d3d8.h>
 /* Nagłówek funkcji matematycznych C++ */
#include <math.h>

 /* Własna klasa potomna */
class D3DWindow : public mrWindow
{
  /* Interfejsy Direct 3D  */
 LPDIRECT3D8             m_pD3D;
 LPDIRECT3DDEVICE8       m_pD3DDevice;

  /* Interfejs powierzchni Direct3D */
 LPDIRECT3DSURFACE8      m_pD3DSurface;
  /* Bieżący format Direct3D */
 mrUInt32                m_iD3DFormat;

public:
  /* Konstruktor / Destruktor */
 D3DWindow (void) {};
 ~D3DWindow (void) {};

  /* Inicjalizacja i zamknięcie Direct3D */
 HRESULT SetupDirect3D (void);
 HRESULT KillDirect3D (void);

  /* Funkcje obsługi okna */
 mrBool32 Frame (void);
};

 /* Inicjalizuje Direct3D */
HRESULT D3DWindow::SetupDirect3D (void)
{
  /* Tworzy obiekt Direct3D */
 if (NULL == (m_pD3D = Direct3DCreate8 (D3D_SDK_VERSION) ) )
 {
  return E_FAIL;
 }
 
  /* Pobiera bieżący tryb graficzny, abyśmy poznali bieżącą
  głębię kolorów */
 D3DDISPLAYMODE d3ddm;
 if (FAILED (m_pD3D->GetAdapterDisplayMode (D3DADAPTER_DEFAULT, 
                                            &d3ddm) ) )
 {
  return E_FAIL;
 }
 
  /* Wprowadzenie paramterów prezentacji */
 D3DPRESENT_PARAMETERS d3dpp; 
 ZeroMemory( &d3dpp, sizeof(d3dpp) );
  /* Tryb niepełnoekranowy */
 d3dpp.Windowed   = TRUE;
  /* Odrzuć to */
 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
  /* Zapisz format jako format bieżący 
     (pobieramy go z g_pD3D->GetAdapterDisplayMode)  */
 d3dpp.BackBufferFormat = d3ddm.Format;
  /* Zapisz format */
 m_iD3DFormat = d3ddm.Format;
 
  /* Utwórz urządzenie */
 if (FAILED (m_pD3D->CreateDevice (D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
                                   m_hWindow, 
                                   D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                                   &d3dpp, 
                                   &m_pD3DDevice ) ) )
 {
  return E_FAIL;
 }

  /* Utwórz powierchnię */  
 if (FAILED (m_pD3DDevice->CreateImageSurface (256, 256, 
                                               (D3DFORMAT) m_iD3DFormat,
                                               &m_pD3DSurface ) ) )

 {
  return E_FAIL;
 }

  /* Zablokuj powierchnię */
 D3DLOCKED_RECT kLockedRect;
 m_pD3DSurface->LockRect (&kLockedRect, NULL, 0);

  /* Rzutuj wskaźnik aby wskazywał pierwszy piksel */
 DWORD * piSurfaceBuffer = (DWORD *) kLockedRect.pBits;

  /* Wypełnij powierchnię */
 int iX, iY;
 for (iY=0; iY<256; iY++)
 {
  for (iX=0; iX<256; iX++)
  {
    /* Utwórz wzór */
   int iPower = (int)(sin (iY * iX) * 128 + cos (iY * -iX) * 128);
   piSurfaceBuffer [iX + iY* (kLockedRect.Pitch >> 2)] = 
                    D3DCOLOR_XRGB (iPower, iPower, iPower);
  }
 }
  
  /* Odblokuj */
 m_pD3DSurface->UnlockRect ();

 return D3D_OK;
}

 /* Zamyka Direct3D */
HRESULT D3DWindow::KillDirect3D (void)
{
   /* Jeżeli istnieją jakiekolwiek obiekty Direct3D, uwolnij je */
 if (NULL != m_pD3D)
 {
  m_pD3D->Release ();
 }
 if (NULL != m_pD3DDevice)
 {
  m_pD3DDevice->Release ();
 }

 if (NULL != m_pD3DSurface)
 {
  m_pD3DSurface->Release ();
 }

 return D3D_OK;

}

 /* Narysuj powierchnię */
mrBool32 D3DWindow::Frame (void)
{
  /* Wyzeruj okno na kolor niebieski */
 m_pD3DDevice->Clear (0, NULL, D3DCLEAR_TARGET, 
                      D3DCOLOR_XRGB (0,0,255), 1.0f, 0);
 
  /* Pobierz bufor tylny */
 LPDIRECT3DSURFACE8 pBackBuffer;
 m_pD3DDevice->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer);

  /* Rozpocznij renderowanie */
 m_pD3DDevice->BeginScene();
  /* Kopiuj powierchnię na ekran */
 m_pD3DDevice->CopyRects (m_pD3DSurface, NULL, 0, pBackBuffer, NULL);
  /* Zakończ renderowanie */
 m_pD3DDevice->EndScene();

  /* Uwolnij bufor tylny */
 pBackBuffer->Release ();

  /* Wyświetl zrenderowany obraz na ekranie */
 m_pD3DDevice->Present (NULL, NULL, NULL, NULL);

 return mrTrue;
}

 /* "WinMain kontra main" */
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInst, 
                    LPSTR lpCmdLine, int nShowCmd)
{
  /* Nasze okno */
 D3DWindow  kWindow;

  /* Utwórz ukno */
 kWindow.Create (hInstance, "Surfaces");

  /* Zainicjalizuj Direct3D */
 kWindow.SetupDirect3D ();

  /* Wejdź w pętlę komunikatów */
 kWindow.Run ();

  /* Zamknij Direct3D */
 kWindow.KillDirect3D ();

 return 0;
}