Ion
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
renderutils.cc
Go to the documentation of this file.
1 
18 #include "ion/image/renderutils.h"
19 
20 #include <string>
21 
22 #include "base/integral_types.h"
24 #include "ion/base/datacontainer.h"
26 #include "ion/gfx/node.h"
27 #include "ion/gfx/sampler.h"
28 #include "ion/gfx/shader.h"
30 #include "ion/gfx/shaderprogram.h"
31 #include "ion/gfx/shape.h"
32 #include "ion/gfx/statetable.h"
33 #include "ion/gfx/texture.h"
35 #include "ion/math/range.h"
36 #include "ion/math/vector.h"
37 
38 namespace ion {
39 namespace image {
40 
41 namespace {
42 
44 
49 
50 
51 static const char kVertexShaderString[] =
52  "attribute vec3 aVertex;\n"
53  "attribute vec2 aTexCoords;\n"
54  "varying vec2 vTextureCoords;\n"
55  "\n"
56  "void main(void) {\n"
57  " vTextureCoords = aTexCoords;\n"
58  " gl_Position = vec4(aVertex, 1.);\n"
59  "}\n";
60 
61 static const char kTextureFragmentShaderString[] =
62  "#ifdef GL_ES\n"
63  "#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
64  "precision highp float;\n"
65  "#else\n"
66  "precision mediump float;\n"
67  "#endif\n"
68  "#endif\n"
69  "\n"
70  "uniform sampler2D uTexture;\n"
71  "varying vec2 vTextureCoords;\n"
72  "\n"
73  "void main(void) {\n"
74  " gl_FragColor = texture2D(uTexture, vTextureCoords);\n"
75  "}\n";
76 
77 static const char kCubeMapFragmentShaderString[] =
78  "#ifdef GL_ES\n"
79  "#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
80  "precision highp float;\n"
81  "#else\n"
82  "precision mediump float;\n"
83  "#endif\n"
84  "#endif\n"
85  "\n"
86  "uniform int uCubeMapFace;\n"
87  "uniform samplerCube uCubeMap;\n"
88  "varying vec2 vTextureCoords;\n"
89  "\n"
90  "void main(void) {\n"
91  " /* Put coords in range (-1, 1). */\n"
92  " float s = -1. + 2. * vTextureCoords.s;\n"
93  " float t = -1. + 2. * vTextureCoords.t;\n"
94  " vec3 tc;\n"
95  " if (uCubeMapFace == 0) { /* Left */\n"
96  " tc = vec3(-1., t, s);\n"
97  " } else if (uCubeMapFace == 1) { /* Bottom */\n"
98  " tc = vec3(s, -1., t);\n"
99  " } else if (uCubeMapFace == 2) { /* Back */\n"
100  " tc = vec3(s, -t, -1.);\n"
101  " } else if (uCubeMapFace == 3) { /* Right */\n"
102  " tc = vec3(1., t, -s);\n"
103  " } else if (uCubeMapFace == 4) { /* Top */\n"
104  " tc = vec3(s, 1., -t);\n"
105  " } else { /* Front */\n"
106  " tc = vec3(s, t, 1.);\n"
107  " }\n"
108  " gl_FragColor = textureCube(uCubeMap, tc);\n"
109  "}\n";
110 
112 
117 
118 
120 static const base::AllocatorPtr& GetShortTermAllocator(
121  const base::AllocatorPtr& allocator) {
122  return allocator.Get() ?
126 }
127 
129 static const gfx::ShaderInputRegistryPtr BuildRegistry(
130  bool is_cubemap, const base::AllocatorPtr& allocator) {
131  gfx::ShaderInputRegistryPtr reg(new(allocator) gfx::ShaderInputRegistry);
132  reg->IncludeGlobalRegistry();
133  if (is_cubemap) {
135  "uCubeMap", gfx::kCubeMapTextureUniform, "CubeMapTexture"));
137  "uCubeMapFace", gfx::kIntUniform, "Face of cubemap"));
138  } else {
140  "uTexture", gfx::kTextureUniform, "Texture"));
141  }
142  return reg;
143 }
144 
149 static const gfx::NodePtr BuildNode(
150  const gfx::TexturePtr& texture,
151  const gfx::CubeMapTexturePtr& cubemap, int face,
152  const math::Vector2i& viewport_size, const base::AllocatorPtr& allocator) {
153  gfx::NodePtr node(new(allocator) gfx::Node);
154 
155  const bool is_cubemap = cubemap.Get();
156 
159  gfx::StateTablePtr state_table(
160  new(allocator) gfx::StateTable(viewport_size[0], viewport_size[1]));
161  state_table->SetViewport(
162  math::Range2i::BuildWithSize(math::Point2i::Zero(), viewport_size));
163  node->SetStateTable(state_table);
164 
166  gfxutils::RectangleSpec rect_spec;
167  rect_spec.allocator = allocator;
168  rect_spec.size.Set(2.f, 2.f); // -1 to +1.
169  rect_spec.vertex_type = gfxutils::ShapeSpec::kPositionTexCoords;
170  gfx::ShapePtr rect_shape = gfxutils::BuildRectangleShape(rect_spec);
171  node->AddShape(rect_shape);
172 
174  gfx::ShaderInputRegistryPtr reg = BuildRegistry(is_cubemap, allocator);
175  node->SetShaderProgram(
177  "Ion image renderutils", reg, kVertexShaderString,
178  is_cubemap ? kCubeMapFragmentShaderString : kTextureFragmentShaderString,
179  allocator));
180 
182  if (is_cubemap) {
183  node->AddUniform(reg->Create<gfx::Uniform>("uCubeMap", cubemap));
184  node->AddUniform(reg->Create<gfx::Uniform>("uCubeMapFace",
185  static_cast<int>(face)));
186  } else {
187  node->AddUniform(reg->Create<gfx::Uniform>("uTexture", texture));
188  }
189 
190  return node;
191 }
192 
195 static const gfx::ImagePtr RenderToImage(
196  const gfx::RendererPtr& renderer, const gfx::NodePtr& node,
197  const math::Vector2i& image_size, const base::AllocatorPtr& allocator) {
198  DCHECK(renderer.Get());
199  DCHECK(node.Get());
200  DCHECK_GT(image_size[0], 0);
201  DCHECK_GT(image_size[1], 0);
202 
205  DCHECK(renderer->GetGraphicsManager().Get());
206  const gfx::GraphicsManager& gm = *renderer->GetGraphicsManager();
207  const gfx::Image::Format target_format =
208  (gm.GetGlApiStandard() == gfx::GraphicsManager::kEs &&
209  gm.GetGlVersion() == 20) ? gfx::Image::kRgb565Byte : gfx::Image::kRgb8;
210 
212  const base::AllocatorPtr& st_alloc = GetShortTermAllocator(allocator);
213  const gfx::FramebufferObjectPtr fbo(
214  new (st_alloc) gfx::FramebufferObject(image_size[0], image_size[1]));
215  fbo->SetColorAttachment(0U,
216  gfx::FramebufferObject::Attachment(target_format));
217  renderer->BindFramebuffer(fbo);
218  renderer->DrawScene(node);
219 
221  gfx::ImagePtr image = renderer->ReadImage(
222  math::Range2i::BuildWithSize(math::Point2i::Zero(), image_size),
223  gfx::Image::kRgb888, allocator);
224 
226  renderer->BindFramebuffer(gfx::FramebufferObjectPtr());
227 
228  return image;
229 }
230 
233 static const gfx::ImagePtr RenderTextureOrCubeMapTextureToImage(
234  const gfx::TexturePtr& texture,
236  const math::Vector2i& size, const gfx::RendererPtr& renderer,
237  const base::AllocatorPtr& allocator) {
238  gfx::ImagePtr output_image;
239  if ((texture.Get() || cubemap.Get()) &&
240  renderer.Get() && size[0] && size[1]) {
241  gfx::NodePtr node = BuildNode(texture, cubemap, face, size,
242  GetShortTermAllocator(allocator));
243  output_image = RenderToImage(renderer, node, size, allocator);
244  }
245  return output_image;
246 }
247 
248 } // anonymous namespace
249 
251 
256 
257 
259  const gfx::TexturePtr& texture, uint32 width, uint32 height,
260  const gfx::RendererPtr& renderer, const base::AllocatorPtr& allocator) {
262  return RenderTextureOrCubeMapTextureToImage(
264  math::Vector2i(width, height), renderer, allocator);
265 }
266 
269  uint32 width, uint32 height,
270  const gfx::RendererPtr& renderer, const base::AllocatorPtr& allocator) {
271  return RenderTextureOrCubeMapTextureToImage(
272  gfx::TexturePtr(), cubemap, face,
273  math::Vector2i(width, height), renderer, allocator);
274 }
275 
276 } // namespace image
277 } // namespace ion
kShortTerm is used for objects that are very transient in nature, such as scratch memory used to comp...
Definition: allocator.h:36
base::ReferentPtr< Node >::Type NodePtr
Definition: node.h:33
base::ReferentPtr< FramebufferObject >::Type FramebufferObjectPtr
Convenience typedef for shared pointer to a FramebufferObject.
const gfx::ImagePtr RenderTextureImage(const gfx::TexturePtr &texture, uint32 width, uint32 height, const gfx::RendererPtr &renderer, const base::AllocatorPtr &allocator)
Public functions.
Definition: renderutils.cc:258
Format
Supported image formats.
Definition: image.h:38
base::ReferentPtr< Image >::Type ImagePtr
Definition: image.h:29
base::ReferentPtr< Shape >::Type ShapePtr
Convenience typedef for shared pointer to a Shape.
Definition: shape.h:167
#define DCHECK(expr)
Definition: logging.h:331
base::ReferentPtr< CubeMapTexture >::Type CubeMapTexturePtr
Convenience typedef for shared pointer to a CubeMapTexture.
CubeFace
The names of faces of the cube map.
#define DCHECK_GT(val1, val2)
Definition: logging.h:337
virtual const AllocatorPtr & GetAllocatorForLifetime(AllocationLifetime lifetime) const
Returns the correct Allocator to use to allocate memory with a specific lifetime. ...
Definition: allocator.cc:27
base::ReferentPtr< StateTable >::Type StateTablePtr
Convenience typedef for shared pointer to a StateTable.
Definition: statetable.h:705
SharedPtr< Allocator > AllocatorPtr
Definition: allocator.h:51
Three channel RGB images.
Definition: image.h:79
T * Get() const
Returns a raw pointer to the instance, which may be NULL.
Definition: sharedptr.h:89
const Grid & image
The original monochrome image data, as doubles (0 - 1).
Definition: sdfutils.cc:90
bits blue, packed half float data.
Definition: image.h:145
int width
TexturePtr texture
The Texture to add sub-image data to.
Definition: fontimage.cc:107
static const ShaderProgramPtr BuildFromStrings(const std::string &id_string, const ShaderInputRegistryPtr &registry_ptr, const std::string &vertex_shader_string, const std::string &fragment_shader_string, const base::AllocatorPtr &allocator)
Convenience function that builds and returns a new ShaderProgram instance that uses the given ShaderI...
base::ReferentPtr< ShaderInputRegistry >::Type ShaderInputRegistryPtr
Convenience typedef for shared pointer to a ShaderInputRegistry.
base::ReferentPtr< Renderer >::Type RendererPtr
Convenience typedef for shared pointer to a Renderer.
Definition: renderer.h:428
A SharedPtr is a smart shared pointer to an instance of some class that implements reference counting...
Definition: sharedptr.h:60
const gfx::ShapePtr BuildRectangleShape(const RectangleSpec &spec)
Builds and returns a Shape representing a rectangle in one of the principal Cartesian planes...
Definition: shapeutils.cc:1290
base::ReferentPtr< Texture >::Type TexturePtr
Convenience typedef for shared pointer to a Texture.
Definition: texture.h:333
static const AllocatorPtr & GetDefaultAllocatorForLifetime(AllocationLifetime lifetime)
const gfx::ImagePtr RenderCubeMapTextureFaceImage(const gfx::CubeMapTexturePtr &cubemap, gfx::CubeMapTexture::CubeFace face, uint32 width, uint32 height, const gfx::RendererPtr &renderer, const base::AllocatorPtr &allocator)
This is similar to RenderTextureImage(), but instead operates on one face of a CubeMapTexture.
Definition: renderutils.cc:267