diff options
Diffstat (limited to 'o3d/core')
-rw-r--r-- | o3d/core/cross/client.cc | 27 | ||||
-rw-r--r-- | o3d/core/cross/client.h | 12 | ||||
-rw-r--r-- | o3d/core/cross/gl/render_surface_gl.cc | 12 | ||||
-rw-r--r-- | o3d/core/cross/gl/render_surface_gl.h | 4 | ||||
-rw-r--r-- | o3d/core/cross/gl/renderer_gl.cc | 3 | ||||
-rw-r--r-- | o3d/core/cross/gl/texture_gl.cc | 1 | ||||
-rw-r--r-- | o3d/core/cross/param_test.cc | 2 | ||||
-rw-r--r-- | o3d/core/cross/render_surface.cc | 24 | ||||
-rw-r--r-- | o3d/core/cross/render_surface.h | 11 | ||||
-rw-r--r-- | o3d/core/win/d3d9/render_surface_d3d9.cc | 26 | ||||
-rw-r--r-- | o3d/core/win/d3d9/render_surface_d3d9.h | 4 |
11 files changed, 96 insertions, 30 deletions
diff --git a/o3d/core/cross/client.cc b/o3d/core/cross/client.cc index a7f5924..c63c940 100644 --- a/o3d/core/cross/client.cc +++ b/o3d/core/cross/client.cc @@ -304,7 +304,25 @@ void Client::RenderClient(bool send_callback) { if (!renderer_.IsAvailable()) return; - RenderClientInner(true, send_callback); + bool have_offscreen_surfaces = + !(offscreen_render_surface_.IsNull() || + offscreen_depth_render_surface_.IsNull()); + + if (have_offscreen_surfaces) { + if (!renderer_->StartRendering()) { + return; + } + renderer_->SetRenderSurfaces(offscreen_render_surface_, + offscreen_depth_render_surface_, + true); + } + + RenderClientInner(!have_offscreen_surfaces, send_callback); + + if (have_offscreen_surfaces) { + renderer_->SetRenderSurfaces(NULL, NULL, false); + renderer_->FinishRendering(); + } } // Executes draw calls for all visible shapes in a subtree @@ -503,6 +521,13 @@ String Client::GetMessageQueueAddress() const { } } +void Client::SetOffscreenRenderingSurfaces( + RenderSurface::Ref surface, + RenderDepthStencilSurface::Ref depth_surface) { + offscreen_render_surface_ = surface; + offscreen_depth_render_surface_ = depth_surface; +} + // Error Related methods ------------------------------------------------------- void Client::SetErrorCallback(ErrorCallback* callback) { diff --git a/o3d/core/cross/client.h b/o3d/core/cross/client.h index 7347af4..003c6de 100644 --- a/o3d/core/cross/client.h +++ b/o3d/core/cross/client.h @@ -59,6 +59,7 @@ #include "core/cross/event_manager.h" #include "core/cross/lost_resource_callback.h" #include "core/cross/render_event.h" +#include "core/cross/render_surface.h" #include "core/cross/tick_event.h" #include "core/cross/timer.h" #include "core/cross/timingtable.h" @@ -429,6 +430,14 @@ class Client { DISALLOW_COPY_AND_ASSIGN(ScopedIncrement); }; + // Offscreen rendering methods ------------------- + + // Sets up this Client so that RenderClient will cause the rendering + // results to go into the given surfaces. + void SetOffscreenRenderingSurfaces( + RenderSurface::Ref surface, + RenderDepthStencilSurface::Ref depth_surface); + private: // Renders the client. void RenderClientInner(bool present, bool send_callback); @@ -499,6 +508,9 @@ class Client { int calls_; // Used to check reentrancy along with ScopedIncrement. + RenderSurface::Ref offscreen_render_surface_; + RenderDepthStencilSurface::Ref offscreen_depth_render_surface_; + DISALLOW_COPY_AND_ASSIGN(Client); }; // Client diff --git a/o3d/core/cross/gl/render_surface_gl.cc b/o3d/core/cross/gl/render_surface_gl.cc index 6570baa..f12718c 100644 --- a/o3d/core/cross/gl/render_surface_gl.cc +++ b/o3d/core/cross/gl/render_surface_gl.cc @@ -54,13 +54,13 @@ RenderSurfaceGL::RenderSurfaceGL(ServiceLocator *service_locator, RenderSurfaceGL::~RenderSurfaceGL() { } -Bitmap::Ref RenderSurfaceGL::PlatformSpecificGetBitmap() const { +bool RenderSurfaceGL::PlatformSpecificGetIntoBitmap(Bitmap::Ref bitmap) const { Renderer* renderer = service_locator()->GetService<Renderer>(); DCHECK(renderer); - - Bitmap::Ref bitmap = Bitmap::Ref(new Bitmap(service_locator())); - bitmap->Allocate( - Texture::ARGB8, clip_width(), clip_height(), 1, Bitmap::IMAGE); + DCHECK(bitmap->width() == static_cast<unsigned int>(clip_width()) && + bitmap->height() == static_cast<unsigned int>(clip_height()) && + bitmap->num_mipmaps() == 1 && + bitmap->format() == Texture::ARGB8); const RenderSurface* old_render_surface; const RenderDepthStencilSurface* old_depth_surface; @@ -76,7 +76,7 @@ Bitmap::Ref RenderSurfaceGL::PlatformSpecificGetBitmap() const { renderer->SetRenderSurfaces(old_render_surface, old_depth_surface, old_is_back_buffer); - return bitmap; + return true; } RenderDepthStencilSurfaceGL::RenderDepthStencilSurfaceGL( diff --git a/o3d/core/cross/gl/render_surface_gl.h b/o3d/core/cross/gl/render_surface_gl.h index 593b7994..254a142 100644 --- a/o3d/core/cross/gl/render_surface_gl.h +++ b/o3d/core/cross/gl/render_surface_gl.h @@ -73,8 +73,8 @@ class RenderSurfaceGL : public RenderSurface { } protected: - // The platform specific part of GetBitmap. - virtual Bitmap::Ref PlatformSpecificGetBitmap() const; + // The platform specific part of GetIntoBitmap. + virtual bool PlatformSpecificGetIntoBitmap(Bitmap::Ref bitmap) const; private: GLenum cube_face_; diff --git a/o3d/core/cross/gl/renderer_gl.cc b/o3d/core/cross/gl/renderer_gl.cc index e4de52f..378c74e 100644 --- a/o3d/core/cross/gl/renderer_gl.cc +++ b/o3d/core/cross/gl/renderer_gl.cc @@ -1317,7 +1317,8 @@ void RendererGL::SetRenderSurfacesPlatformSpecific( if (!InstallFramebufferObjects(surface, surface_depth)) { O3D_ERROR(service_locator()) << "Failed to bind OpenGL render target objects:" - << surface->name() <<", "<< surface_depth->name(); + << (surface ? surface->name() : "(no surface)") << ", " + << (surface_depth ? surface_depth->name() : "(no depth surface)"); } // RenderSurface rendering is performed with an inverted Y, so the front // face winding must be changed to clock-wise. See comments for diff --git a/o3d/core/cross/gl/texture_gl.cc b/o3d/core/cross/gl/texture_gl.cc index c168f41..f9a11e0 100644 --- a/o3d/core/cross/gl/texture_gl.cc +++ b/o3d/core/cross/gl/texture_gl.cc @@ -278,6 +278,7 @@ Texture2DGL* Texture2DGL::Create(ServiceLocator* service_locator, bool enable_render_surfaces) { DLOG(INFO) << "Texture2DGL Create"; DCHECK_NE(format, Texture::UNKNOWN_FORMAT); + DCHECK_GE(levels, 0); RendererGL *renderer = static_cast<RendererGL *>( service_locator->GetService<Renderer>()); renderer->MakeCurrentLazy(); diff --git a/o3d/core/cross/param_test.cc b/o3d/core/cross/param_test.cc index 82daa16..f4e7299 100644 --- a/o3d/core/cross/param_test.cc +++ b/o3d/core/cross/param_test.cc @@ -78,7 +78,7 @@ class TestRenderSurface : public RenderSurface { explicit TestRenderSurface(ServiceLocator* service_locator) : RenderSurface(service_locator, 1, 1, NULL) {} void* GetSurfaceHandle() const { return NULL; } - Bitmap::Ref PlatformSpecificGetBitmap() const { return Bitmap::Ref(); } + bool PlatformSpecificGetIntoBitmap(Bitmap::Ref bitmap) const { return true; } }; // TestSampler derives from o3d::Sampler and provides a public diff --git a/o3d/core/cross/render_surface.cc b/o3d/core/cross/render_surface.cc index 0e6a85a..8db8f01 100644 --- a/o3d/core/cross/render_surface.cc +++ b/o3d/core/cross/render_surface.cc @@ -72,7 +72,29 @@ RenderSurface::RenderSurface(ServiceLocator* service_locator, } Bitmap::Ref RenderSurface::GetBitmap() const { - return PlatformSpecificGetBitmap(); + Bitmap::Ref bitmap = Bitmap::Ref(new Bitmap(service_locator())); + bitmap->Allocate(Texture::ARGB8, + clip_width(), + clip_height(), + 1, + Bitmap::IMAGE); + if (!GetIntoBitmap(bitmap)) { + Bitmap::Ref empty; + return empty; + } + return bitmap; +} + +bool RenderSurface::GetIntoBitmap(Bitmap::Ref bitmap) const { + if (bitmap.IsNull() || + bitmap->width() != static_cast<unsigned int>(clip_width()) || + bitmap->height() != static_cast<unsigned int>(clip_height()) || + bitmap->num_mipmaps() != 1 || + bitmap->format() != Texture::ARGB8) { + return false; + } + + return PlatformSpecificGetIntoBitmap(bitmap); } RenderDepthStencilSurface::RenderDepthStencilSurface( diff --git a/o3d/core/cross/render_surface.h b/o3d/core/cross/render_surface.h index ba6db69..8ee3f01 100644 --- a/o3d/core/cross/render_surface.h +++ b/o3d/core/cross/render_surface.h @@ -138,9 +138,16 @@ class RenderSurface : public RenderSurfaceBase { // Only gets the clip_width/clip_height area. Bitmap::Ref GetBitmap() const; + // Gets a copy of the contents of the render surface into the given + // Bitmap. Only gets the clip_width/clip_height area. Returns true + // if the bitmap was appropriately sized, false if not or if an + // error occurred. + bool GetIntoBitmap(Bitmap::Ref bitmap) const; + protected: - // The platform specific part of GetBitmap. - virtual Bitmap::Ref PlatformSpecificGetBitmap() const = 0; + // The platform specific part of GetIntoBitmap. + virtual bool PlatformSpecificGetIntoBitmap( + Bitmap::Ref bitmap) const = 0; private: // Texture parameter of the texture in which this render surface is contained. diff --git a/o3d/core/win/d3d9/render_surface_d3d9.cc b/o3d/core/win/d3d9/render_surface_d3d9.cc index 5b7c9e4..c291887 100644 --- a/o3d/core/win/d3d9/render_surface_d3d9.cc +++ b/o3d/core/win/d3d9/render_surface_d3d9.cc @@ -75,11 +75,15 @@ void RenderSurfaceD3D9::Clear() { } } -Bitmap::Ref RenderSurfaceD3D9::PlatformSpecificGetBitmap() const { - Bitmap::Ref empty; +bool RenderSurfaceD3D9::PlatformSpecificGetIntoBitmap( + Bitmap::Ref bitmap) const { + DCHECK(bitmap->width() == static_cast<unsigned int>(clip_width()) && + bitmap->height() == static_cast<unsigned int>(clip_height()) && + bitmap->num_mipmaps() == 1 && + bitmap->format() == Texture::ARGB8); if (!direct3d_surface_) { - return empty; + return false; } RendererD3D9* renderer = @@ -89,7 +93,7 @@ Bitmap::Ref RenderSurfaceD3D9::PlatformSpecificGetBitmap() const { D3DSURFACE_DESC surface_description; if (!HR(direct3d_surface_->GetDesc(&surface_description))) { - return empty; + return false; } if (!HR(device->CreateOffscreenPlainSurface(surface_description.Width, @@ -98,25 +102,19 @@ Bitmap::Ref RenderSurfaceD3D9::PlatformSpecificGetBitmap() const { D3DPOOL_SYSTEMMEM, &system_surface, NULL))) { - return empty; + return false; } if (!HR(device->GetRenderTargetData(direct3d_surface_, system_surface))) - return empty; + return false; RECT rect = { 0, 0, clip_width(), clip_height() }; D3DLOCKED_RECT out_rect = {0}; if (!HR(system_surface->LockRect(&out_rect, &rect, D3DLOCK_READONLY))) { O3D_ERROR(service_locator()) << "Failed to Lock Surface (D3D9)"; - return empty; + return false; } - Bitmap::Ref bitmap = Bitmap::Ref(new Bitmap(service_locator())); - bitmap->Allocate(Texture::ARGB8, - clip_width(), - clip_height(), - 1, - Bitmap::IMAGE); bitmap->SetRect(0, 0, 0, clip_width(), clip_height(), @@ -125,7 +123,7 @@ Bitmap::Ref RenderSurfaceD3D9::PlatformSpecificGetBitmap() const { system_surface->UnlockRect(); - return bitmap; + return true; } RenderDepthStencilSurfaceD3D9::RenderDepthStencilSurfaceD3D9( diff --git a/o3d/core/win/d3d9/render_surface_d3d9.h b/o3d/core/win/d3d9/render_surface_d3d9.h index c708dab..f541e6f 100644 --- a/o3d/core/win/d3d9/render_surface_d3d9.h +++ b/o3d/core/win/d3d9/render_surface_d3d9.h @@ -79,8 +79,8 @@ class RenderSurfaceD3D9 : public RenderSurface { void Clear(); protected: - // The platform specific part of GetBitmap. - virtual Bitmap::Ref PlatformSpecificGetBitmap() const; + // The platform specific part of GetIntoBitmap. + virtual bool PlatformSpecificGetIntoBitmap(Bitmap::Ref bitmap) const; private: CComPtr<IDirect3DSurface9> direct3d_surface_; |