// Skybox implementation

 #include <d3d8.h>
 #include <d3dx8.h>

 #include "D3DFuncs.h"
 #include "Skybox.h"
 #include "resource.h"

 // =====================================================================================
 // Constructor/Destructor
 // =====================================================================================

 CSkyBox::CSkyBox()
 {

 }

 CSkyBox::~CSkyBox()
 {
     if(m_pTextureTop)
         m_pTextureTop->Release();

     if(m_pTextureFront)
         m_pTextureFront->Release();

     if(m_pTextureBack)
         m_pTextureBack->Release();

     if(m_pTextureLeft)
         m_pTextureLeft->Release();

     if(m_pTextureRight)
         m_pTextureRight->Release();

     if(m_pVertexBuffer)
         m_pVertexBuffer->Release();
 }

 // =====================================================================================
 // Initialisation
 // =====================================================================================

 HRESULT CSkyBox::Initialise(LPDIRECT3DDEVICE8& pDevice)
 {
     HRESULT rslt;

     rslt=D3DXCreateTextureFromResourceEx(pDevice, GetModuleHandle( NULL ), MAKEINTRESOURCE(IDB_BITMAP_TOP),
                                          D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0,
                                          D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT,
                                          D3DCOLOR_XRGB(0,0,0), NULL, NULL, &m_pTextureTop);
     if(FAILED(rslt)) { return D3DError(rslt, __LINE__, __FILE__, "Could not load texmap"); }

     rslt=D3DXCreateTextureFromResourceEx(pDevice, GetModuleHandle( NULL ), MAKEINTRESOURCE(IDB_BITMAP_LEFT),
                                          D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0,
                                          D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT,
                                          D3DCOLOR_XRGB(0,0,0), NULL, NULL, &m_pTextureLeft);
     if(FAILED(rslt)) { return D3DError(rslt, __LINE__, __FILE__, "Could not load texmap"); }

     rslt=D3DXCreateTextureFromResourceEx(pDevice, GetModuleHandle( NULL ), MAKEINTRESOURCE(IDB_BITMAP_RIGHT),
                                          D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0,
                                          D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT,
                                          D3DCOLOR_XRGB(0,0,0), NULL, NULL, &m_pTextureRight);
     if(FAILED(rslt)) { return D3DError(rslt, __LINE__, __FILE__, "Could not load texmap"); }

     rslt=D3DXCreateTextureFromResourceEx(pDevice, GetModuleHandle( NULL ), MAKEINTRESOURCE(IDB_BITMAP_FRONT),
                                          D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0,
                                          D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT,
                                          D3DCOLOR_XRGB(0,0,0), NULL, NULL, &m_pTextureFront);
     if(FAILED(rslt)) { return D3DError(rslt, __LINE__, __FILE__, "Could not load texmap"); }

     rslt=D3DXCreateTextureFromResourceEx(pDevice, GetModuleHandle( NULL ), MAKEINTRESOURCE(IDB_BITMAP_BACK),
                                          D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0,
                                          D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT,
                                          D3DCOLOR_XRGB(0,0,0), NULL, NULL, &m_pTextureBack);
     if(FAILED(rslt)) { return D3DError(rslt, __LINE__, __FILE__, "Could not load texmap"); }

     // FRONT
     m_vSkyBox[0].x=-128.0f;
     m_vSkyBox[0].y= 100.0f;
     m_vSkyBox[0].z=-128.0f;
     m_vSkyBox[0].tu=1.0f;
     m_vSkyBox[0].tv=0.0f;

     m_vSkyBox[1].x= 128.0f;
     m_vSkyBox[1].y= 100.0f;
     m_vSkyBox[1].z=-128.0f;
     m_vSkyBox[1].tu=0.0f;
     m_vSkyBox[1].tv=0.0f;

     m_vSkyBox[2].x=-128.0f;
     m_vSkyBox[2].y=   0.0f;
     m_vSkyBox[2].z=-128.0f;
     m_vSkyBox[2].tu=1.0f;
     m_vSkyBox[2].tv=1.0f;

     m_vSkyBox[3].x=-128.0f;
     m_vSkyBox[3].y=   0.0f;
     m_vSkyBox[3].z=-128.0f;
     m_vSkyBox[3].tu=1.0f;
     m_vSkyBox[3].tv=1.0f;

     m_vSkyBox[4].x= 128.0f;
     m_vSkyBox[4].y= 100.0f;
     m_vSkyBox[4].z=-128.0f;
     m_vSkyBox[4].tu=0.0f;
     m_vSkyBox[4].tv=0.0f;

     m_vSkyBox[5].x= 128.0f;
     m_vSkyBox[5].y=   0.0f;
     m_vSkyBox[5].z=-128.0f;
     m_vSkyBox[5].tu=0.0f;
     m_vSkyBox[5].tv=1.0f;

     // LEFT

     m_vSkyBox[6].x=-128.0f;
     m_vSkyBox[6].y= 100.0f;
     m_vSkyBox[6].z=-128.0f;
     m_vSkyBox[6].tu=0.0f;
     m_vSkyBox[6].tv=0.0f;

     m_vSkyBox[7].x=-128.0f;
     m_vSkyBox[7].y= 100.0f;
     m_vSkyBox[7].z= 128.0f;
     m_vSkyBox[7].tu=1.0f;
     m_vSkyBox[7].tv=0.0f;

     m_vSkyBox[8].x=-128.0f;
     m_vSkyBox[8].y=   0.0f;
     m_vSkyBox[8].z=-128.0f;
     m_vSkyBox[8].tu=0.0f;
     m_vSkyBox[8].tv=1.0f;

     m_vSkyBox[9].x=-128.0f;
     m_vSkyBox[9].y=   0.0f;
     m_vSkyBox[9].z=-128.0f;
     m_vSkyBox[9].tu=0.0f;
     m_vSkyBox[9].tv=1.0f;

     m_vSkyBox[10].x=-128.0f;
     m_vSkyBox[10].y= 100.0f;
     m_vSkyBox[10].z= 128.0f;
     m_vSkyBox[10].tu=1.0f;
     m_vSkyBox[10].tv=0.0f;

     m_vSkyBox[11].x=-128.0f;
     m_vSkyBox[11].y=   0.0f;
     m_vSkyBox[11].z= 128.0f;
     m_vSkyBox[11].tu=1.0f;
     m_vSkyBox[11].tv=1.0f;


     // BACK

     m_vSkyBox[12].x=-128.0f;
     m_vSkyBox[12].y= 100.0f;
     m_vSkyBox[12].z= 128.0f;
     m_vSkyBox[12].tu=0.0f;
     m_vSkyBox[12].tv=0.0f;

     m_vSkyBox[13].x= 128.0f;
     m_vSkyBox[13].y= 100.0f;
     m_vSkyBox[13].z= 128.0f;
     m_vSkyBox[13].tu=1.0f;
     m_vSkyBox[13].tv=0.0f;

     m_vSkyBox[14].x=-128.0f;
     m_vSkyBox[14].y=   0.0f;
     m_vSkyBox[14].z= 128.0f;
     m_vSkyBox[14].tu=0.0f;
     m_vSkyBox[14].tv=1.0f;

     m_vSkyBox[15].x=-128.0f;
     m_vSkyBox[15].y=   0.0f;
     m_vSkyBox[15].z= 128.0f;
     m_vSkyBox[15].tu=0.0f;
     m_vSkyBox[15].tv=1.0f;

     m_vSkyBox[16].x= 128.0f;
     m_vSkyBox[16].y= 100.0f;
     m_vSkyBox[16].z= 128.0f;
     m_vSkyBox[16].tu=1.0f;
     m_vSkyBox[16].tv=0.0f;

     m_vSkyBox[17].x= 128.0f;
     m_vSkyBox[17].y=   0.0f;
     m_vSkyBox[17].z= 128.0f;
     m_vSkyBox[17].tu=1.0f;
     m_vSkyBox[17].tv=1.0f;


     // RIGHT

     m_vSkyBox[18].x= 128.0f;
     m_vSkyBox[18].y= 100.0f;
     m_vSkyBox[18].z= 128.0f;
     m_vSkyBox[18].tu=0.0f;
     m_vSkyBox[18].tv=0.0f;

     m_vSkyBox[19].x= 128.0f;
     m_vSkyBox[19].y= 100.0f;
     m_vSkyBox[19].z=-128.0f;
     m_vSkyBox[19].tu=1.0f;
     m_vSkyBox[19].tv=0.0f;

     m_vSkyBox[20].x= 128.0f;
     m_vSkyBox[20].y=   0.0f;
     m_vSkyBox[20].z= 128.0f;
     m_vSkyBox[20].tu=0.0f;
     m_vSkyBox[20].tv=1.0f;

     m_vSkyBox[21].x= 128.0f;
     m_vSkyBox[21].y=   0.0f;
     m_vSkyBox[21].z= 128.0f;
     m_vSkyBox[21].tu=0.0f;
     m_vSkyBox[21].tv=1.0f;

     m_vSkyBox[22].x= 128.0f;
     m_vSkyBox[22].y= 100.0f;
     m_vSkyBox[22].z=-128.0f;
     m_vSkyBox[22].tu=1.0f;
     m_vSkyBox[22].tv=0.0f;

     m_vSkyBox[23].x= 128.0f;
     m_vSkyBox[23].y=   0.0f;
     m_vSkyBox[23].z=-128.0f;
     m_vSkyBox[23].tu=1.0f;
     m_vSkyBox[23].tv=1.0f;


     // TOP

     m_vSkyBox[24].x=-128.0f;
     m_vSkyBox[24].y= 100.0f;
     m_vSkyBox[24].z=-128.0f;
     m_vSkyBox[24].tu=1.0f;
     m_vSkyBox[24].tv=1.0f;

     m_vSkyBox[25].x= 128.0f;
     m_vSkyBox[25].y= 100.0f;
     m_vSkyBox[25].z=-128.0f;
     m_vSkyBox[25].tu=0.0f;
     m_vSkyBox[25].tv=1.0f;

     m_vSkyBox[26].x=-128.0f;
     m_vSkyBox[26].y= 100.0f;
     m_vSkyBox[26].z= 128.0f;
     m_vSkyBox[26].tu=1.0f;
     m_vSkyBox[26].tv=0.0f;

     m_vSkyBox[27].x=-128.0f;
     m_vSkyBox[27].y= 100.0f;
     m_vSkyBox[27].z= 128.0f;
     m_vSkyBox[27].tu=1.0f;
     m_vSkyBox[27].tv=0.0f;

     m_vSkyBox[28].x= 128.0f;
     m_vSkyBox[28].y= 100.0f;
     m_vSkyBox[28].z=-128.0f;
     m_vSkyBox[28].tu=0.0f;
     m_vSkyBox[28].tv=1.0f;

     m_vSkyBox[29].x= 128.0f;
     m_vSkyBox[29].y= 100.0f;
     m_vSkyBox[29].z= 128.0f;
     m_vSkyBox[29].tu=0.0f;
     m_vSkyBox[29].tv=0.0f;


     rslt=pDevice->CreateVertexBuffer(sizeof(m_vSkyBox), 0, D3DFVF_SKYBOX, D3DPOOL_MANAGED,
                                      &m_pVertexBuffer);
     if(FAILED(rslt)) { return D3DError(rslt, __LINE__, __FILE__, "CreateVertexBuffer() failed."); }

     // Now lock the vertex buffer...
     BYTE* pVerticeLock=0;
     rslt=m_pVertexBuffer->Lock(0, sizeof(m_vSkyBox), &pVerticeLock, 0);
     if(FAILED(rslt)) { return D3DError(rslt, __LINE__, __FILE__, "Failed to lock Vertex Buffer."); }

     // ...and copy our array of vertices straight into it
     CopyMemory(pVerticeLock, &m_vSkyBox, sizeof(m_vSkyBox));

     // Remember to unlock the vertex buffer once we're done.
     m_pVertexBuffer->Unlock();

     return S_OK;

 }

 // =====================================================================================
 // Rendering
 // =====================================================================================

 HRESULT CSkyBox::Render(LPDIRECT3DDEVICE8& pDevice, LPDIRECT3DSURFACE8& pBackBuffer)
 {
     HRESULT rslt;

     rslt=pDevice->SetVertexShader(D3DFVF_SKYBOX);
     if(FAILED(rslt)) { return D3DError(rslt, __LINE__, __FILE__, "Failed to set vertex shader."); }

     rslt=pDevice->SetStreamSource(0, m_pVertexBuffer, sizeof(SKYBOXVERTEX));
     if(FAILED(rslt)) { return D3DError(rslt, __LINE__, __FILE__, "Failed to set stream source."); }

     rslt=pDevice->SetTexture(0, m_pTextureFront);
     if(FAILED(rslt)) { return D3DError(rslt, __LINE__, __FILE__, "Failed to set texture."); }

     rslt=pDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);
     if(FAILED(rslt)) { return D3DError(rslt, __LINE__, __FILE__, "Failed to draw primitives"); }


     rslt=pDevice->SetTexture(0, m_pTextureLeft);
     if(FAILED(rslt)) { return D3DError(rslt, __LINE__, __FILE__, "Failed to set texture."); }

     rslt=pDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 6, 2);
     if(FAILED(rslt)) { return D3DError(rslt, __LINE__, __FILE__, "Failed to draw primitives"); }


     rslt=pDevice->SetTexture(0, m_pTextureBack);
     if(FAILED(rslt)) { return D3DError(rslt, __LINE__, __FILE__, "Failed to set texture."); }

     rslt=pDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 12, 2);
     if(FAILED(rslt)) { return D3DError(rslt, __LINE__, __FILE__, "Failed to draw primitives"); }


     rslt=pDevice->SetTexture(0, m_pTextureRight);
     if(FAILED(rslt)) { return D3DError(rslt, __LINE__, __FILE__, "Failed to set texture."); }

     rslt=pDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 18, 2);
     if(FAILED(rslt)) { return D3DError(rslt, __LINE__, __FILE__, "Failed to draw primitives"); }

     rslt=pDevice->SetTexture(0, m_pTextureTop);
     if(FAILED(rslt)) { return D3DError(rslt, __LINE__, __FILE__, "Failed to set texture."); }

     rslt=pDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 24, 2);
     if(FAILED(rslt)) { return D3DError(rslt, __LINE__, __FILE__, "Failed to draw primitives"); }

     rslt=pDevice->SetTexture(0, NULL);

     return S_OK;

 }