OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2009, Google Inc. | 2 * Copyright 2009, Google Inc. |
3 * All rights reserved. | 3 * All rights reserved. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions are | 6 * modification, are permitted provided that the following conditions are |
7 * met: | 7 * met: |
8 * | 8 * |
9 * * Redistributions of source code must retain the above copyright | 9 * * Redistributions of source code must retain the above copyright |
10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
(...skipping 1690 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1701 | 1701 |
1702 // Note that since the returned surface is not associated with a Texture | 1702 // Note that since the returned surface is not associated with a Texture |
1703 // mip-level, NULL is passed for the texture argument. | 1703 // mip-level, NULL is passed for the texture argument. |
1704 return RenderDepthStencilSurface::Ref( | 1704 return RenderDepthStencilSurface::Ref( |
1705 new RenderDepthStencilSurfaceD3D9(service_locator(), | 1705 new RenderDepthStencilSurfaceD3D9(service_locator(), |
1706 width, | 1706 width, |
1707 height, | 1707 height, |
1708 depth_constructor)); | 1708 depth_constructor)); |
1709 } | 1709 } |
1710 | 1710 |
1711 // Saves a png screenshot 'filename.png'. | 1711 Bitmap::Ref RendererD3D9::TakeScreenshot() { |
1712 // Returns true on success and false on failure. | 1712 Bitmap::Ref empty; |
1713 bool RendererD3D9::SaveScreen(const String& file_name) { | |
1714 #ifdef TESTING | |
1715 LPDIRECT3DDEVICE9 device = d3d_device(); | 1713 LPDIRECT3DDEVICE9 device = d3d_device(); |
1716 CComPtr<IDirect3DSurface9> system_surface; | 1714 CComPtr<IDirect3DSurface9> system_surface; |
1717 CComPtr<IDirect3DSurface9> current_surface; | 1715 CComPtr<IDirect3DSurface9> current_surface; |
1718 | 1716 |
1719 if (!HR(device->GetRenderTarget(0, ¤t_surface))) | 1717 if (!HR(device->GetRenderTarget(0, ¤t_surface))) |
1720 return false; | 1718 return empty; |
1721 | 1719 |
1722 D3DSURFACE_DESC surface_description; | 1720 D3DSURFACE_DESC surface_description; |
1723 if (!HR(current_surface->GetDesc(&surface_description))) | 1721 if (!HR(current_surface->GetDesc(&surface_description))) |
1724 return false; | 1722 return empty; |
1725 | 1723 |
1726 // Construct an intermediate surface with multi-sampling disabled. | 1724 // Construct an intermediate surface with multi-sampling disabled. |
1727 // This surface is required because GetRenderTargetData(...) will fail | 1725 // This surface is required because GetRenderTargetData(...) will fail |
1728 // for multi-sampled targets. One must first down-sample to a | 1726 // for multi-sampled targets. One must first down-sample to a |
1729 // non-multi-sample buffer, and then copy from that intermediate buffer | 1727 // non-multi-sample buffer, and then copy from that intermediate buffer |
1730 // to a main memory surface. | 1728 // to a main memory surface. |
1731 CComPtr<IDirect3DSurface9> intermediate_target; | 1729 CComPtr<IDirect3DSurface9> intermediate_target; |
1732 if (!HR(device->CreateRenderTarget(surface_description.Width, | 1730 if (!HR(device->CreateRenderTarget(surface_description.Width, |
1733 surface_description.Height, | 1731 surface_description.Height, |
1734 surface_description.Format, | 1732 surface_description.Format, |
1735 D3DMULTISAMPLE_NONE, | 1733 D3DMULTISAMPLE_NONE, |
1736 0, | 1734 0, |
1737 FALSE, | 1735 FALSE, |
1738 &intermediate_target, | 1736 &intermediate_target, |
1739 NULL))) { | 1737 NULL))) { |
1740 return false; | 1738 return empty; |
1741 } | 1739 } |
1742 | 1740 |
1743 if (!HR(device->StretchRect(current_surface, | 1741 if (!HR(device->StretchRect(current_surface, |
1744 NULL, | 1742 NULL, |
1745 intermediate_target, | 1743 intermediate_target, |
1746 NULL, | 1744 NULL, |
1747 D3DTEXF_NONE))) { | 1745 D3DTEXF_NONE))) { |
1748 return false; | 1746 return empty; |
1749 } | 1747 } |
1750 | 1748 |
1751 if (!HR(device->CreateOffscreenPlainSurface(surface_description.Width, | 1749 if (!HR(device->CreateOffscreenPlainSurface(surface_description.Width, |
1752 surface_description.Height, | 1750 surface_description.Height, |
1753 surface_description.Format, | 1751 surface_description.Format, |
1754 D3DPOOL_SYSTEMMEM, | 1752 D3DPOOL_SYSTEMMEM, |
1755 &system_surface, | 1753 &system_surface, |
1756 NULL))) { | 1754 NULL))) { |
1757 return false; | 1755 return empty; |
1758 } | 1756 } |
1759 | 1757 |
1760 if (!HR(device->GetRenderTargetData(intermediate_target, system_surface))) | 1758 if (!HR(device->GetRenderTargetData(intermediate_target, system_surface))) |
1761 return false; | 1759 return empty; |
1762 | 1760 |
1763 // append .png to the end of file_name | 1761 D3DLOCKED_RECT out_rect = {0}; |
1764 String png_file_name = file_name; | 1762 if (!HR(system_surface->LockRect(&out_rect, NULL, D3DLOCK_READONLY))) { |
1765 png_file_name.append(String(".png")); | 1763 O3D_ERROR(service_locator()) << "Failed to Lock Surface (D3D9)"; |
1766 // convert file name to utf16 | 1764 return empty; |
1767 std::wstring file_name_utf16 = UTF8ToWide(png_file_name); | 1765 } |
1768 | 1766 |
1769 return HR(o3d::D3DXSaveSurfaceToFile(file_name_utf16.c_str(), | 1767 Bitmap::Ref bitmap = Bitmap::Ref(new Bitmap(service_locator())); |
1770 D3DXIFF_PNG, | 1768 bitmap->Allocate(Texture::ARGB8, |
1771 system_surface, | 1769 surface_description.Width, |
1772 NULL, | 1770 surface_description.Height, |
1773 NULL)); | 1771 1, |
1774 #else | 1772 false); |
1775 // Not a test build, always return false. | 1773 bitmap->SetRect(0, 0, 0, |
1776 return false; | 1774 surface_description.Width, |
1777 #endif | 1775 surface_description.Height, |
| 1776 out_rect.pBits, |
| 1777 out_rect.Pitch); |
| 1778 // TODO(gman): Remove this when we get the D3D backbuffer to be RGBA |
| 1779 // Set the Alpha to 0xFF |
| 1780 uint8* data = bitmap->image_data(); |
| 1781 uint8* end = data + bitmap->width() * bitmap->height() * 4; |
| 1782 while (data != end) { |
| 1783 data[3] = 0xFF; |
| 1784 data += 4; |
| 1785 } |
| 1786 bitmap->FlipVertically(); |
| 1787 return bitmap; |
1778 } | 1788 } |
1779 | 1789 |
1780 const int* RendererD3D9::GetRGBAUByteNSwizzleTable() { | 1790 const int* RendererD3D9::GetRGBAUByteNSwizzleTable() { |
1781 static int swizzle_table[] = { 2, 1, 0, 3, }; | 1791 static int swizzle_table[] = { 2, 1, 0, 3, }; |
1782 return swizzle_table; | 1792 return swizzle_table; |
1783 } | 1793 } |
1784 | 1794 |
1785 // This is a factory function for creating Renderer objects. Since | 1795 // This is a factory function for creating Renderer objects. Since |
1786 // we're implementing D3D9, we only ever return a D3D9 renderer. | 1796 // we're implementing D3D9, we only ever return a D3D9 renderer. |
1787 Renderer* Renderer::CreateDefaultRenderer(ServiceLocator* service_locator) { | 1797 Renderer* Renderer::CreateDefaultRenderer(ServiceLocator* service_locator) { |
1788 return RendererD3D9::CreateDefault(service_locator); | 1798 return RendererD3D9::CreateDefault(service_locator); |
1789 } | 1799 } |
1790 } // namespace o3d | 1800 } // namespace o3d |
OLD | NEW |