summaryrefslogtreecommitdiffstats
path: root/o3d/core
diff options
context:
space:
mode:
Diffstat (limited to 'o3d/core')
-rw-r--r--o3d/core/cross/client.cc27
-rw-r--r--o3d/core/cross/client.h12
-rw-r--r--o3d/core/cross/gl/render_surface_gl.cc12
-rw-r--r--o3d/core/cross/gl/render_surface_gl.h4
-rw-r--r--o3d/core/cross/gl/renderer_gl.cc3
-rw-r--r--o3d/core/cross/gl/texture_gl.cc1
-rw-r--r--o3d/core/cross/param_test.cc2
-rw-r--r--o3d/core/cross/render_surface.cc24
-rw-r--r--o3d/core/cross/render_surface.h11
-rw-r--r--o3d/core/win/d3d9/render_surface_d3d9.cc26
-rw-r--r--o3d/core/win/d3d9/render_surface_d3d9.h4
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_;