//----------------------------------------------------------------------------- // Name: XBUtil_CreateNormalizationCubeMap() // Desc: Creates a cubemap and fills it with normalized RGBA vectors //----------------------------------------------------------------------------- HRESULT XBUtil_CreateNormalizationCubeMap( LPDIRECT3DDEVICE8 pd3dDevice, DWORD dwSize, LPDIRECT3DCUBETEXTURE8* ppCubeMap ) { HRESULT hr; // Create the cube map if( FAILED( hr = pd3dDevice->CreateCubeTexture( dwSize, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, ppCubeMap ) ) ) return E_FAIL; // Allocate temp space for swizzling the cubemap surfaces DWORD* pSourceBits = new DWORD[ dwSize * dwSize ]; // Fill all six sides of the cubemap for( DWORD i=0; i<6; i++ ) { // Lock the i'th cubemap surface LPDIRECT3DSURFACE8 pCubeMapFace; (*ppCubeMap)->GetCubeMapSurface( (D3DCUBEMAP_FACES)i, 0, &pCubeMapFace ); // Write the RGBA-encoded normals to the surface pixels DWORD* pPixel = pSourceBits; D3DXVECTOR3 n; FLOAT w, h; for( DWORD y = 0; y < dwSize; y++ ) { h = (FLOAT)y / (FLOAT)(dwSize-1); // 0 to 1 h = ( h * 2.0f ) - 1.0f; // -1 to 1 for( DWORD x = 0; x < dwSize; x++ ) { w = (FLOAT)x / (FLOAT)(dwSize-1); // 0 to 1 w = ( w * 2.0f ) - 1.0f; // -1 to 1 // Calc the normal for this texel switch( i ) { case D3DCUBEMAP_FACE_POSITIVE_X: // +x n.x = +1.0; n.y = -h; n.z = -w; break; case D3DCUBEMAP_FACE_NEGATIVE_X: // -x n.x = -1.0; n.y = -h; n.z = +w; break; case D3DCUBEMAP_FACE_POSITIVE_Y: // y n.x = +w; n.y = +1.0; n.z = +h; break; case D3DCUBEMAP_FACE_NEGATIVE_Y: // -y n.x = +w; n.y = -1.0; n.z = -h; break; case D3DCUBEMAP_FACE_POSITIVE_Z: // +z n.x = +w; n.y = -h; n.z = +1.0; break; case D3DCUBEMAP_FACE_NEGATIVE_Z: // -z n.x = -w; n.y = -h; n.z = -1.0; break; } // Store the normal as an RGBA color D3DXVec3Normalize( &n, &n ); *pPixel++ = XBUtil_VectorToRGBA( &n ); } } // Swizzle the result into the cubemap face surface D3DLOCKED_RECT lock; pCubeMapFace->LockRect( &lock, 0, 0L ); XGSwizzleRect( pSourceBits, 0, NULL, lock.pBits, dwSize, dwSize, NULL, sizeof(DWORD) ); pCubeMapFace->UnlockRect(); // Release the cubemap face pCubeMapFace->Release(); } // Free temp space SAFE_DELETE_ARRAY( pSourceBits ); return S_OK; }