diff options
author | gman@google.com <gman@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-08-08 19:50:29 +0000 |
---|---|---|
committer | gman@google.com <gman@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-08-08 19:50:29 +0000 |
commit | 16f5c4de8b926dc889859cfff03c9328edb60a5c (patch) | |
tree | c6d7a6f51973164ae28ff3157f0cf6356736c1d7 /o3d/core/cross | |
parent | c890e98205d97b57534f2eac00618a2864d61bb5 (diff) | |
download | chromium_src-16f5c4de8b926dc889859cfff03c9328edb60a5c.zip chromium_src-16f5c4de8b926dc889859cfff03c9328edb60a5c.tar.gz chromium_src-16f5c4de8b926dc889859cfff03c9328edb60a5c.tar.bz2 |
This CL adds client.toDataURL which gets the contents
of the client area as a data url (which is a base64
encoded string of a png file)
data urls are part of the HTML5 standard and supported
by firefox, safari and chrome.
http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-canvas-todataurl
That means you can now do this
var dataURL = client.toDataURL();
// make an IMG tag display the screenshot
someImgTag.src = dataURL;
// use the IMG tag to draw into a canvas
someCanvasContext.drawImage(someImageTag, ...);
It also means there is no need for the test builds
anymore "test-dbg-d3d", "test-opt-d3d" etc as
toDataURL is part of the public API and can
therefore always be used to take screenshots
in any build.
I updated the selenium code to use it.
There are a few issues:
1) The GL version has the same limitations as taking
a screenshot before. Namely that the client area
must be on screen. We need to fix this.
2) We need to add support for origin-clean. See
https://tracker.corp.google.com/story/show/180334
Review URL: http://codereview.chromium.org/164130
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@22869 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'o3d/core/cross')
-rw-r--r-- | o3d/core/cross/bitmap.cc | 4 | ||||
-rw-r--r-- | o3d/core/cross/bitmap.h | 9 | ||||
-rw-r--r-- | o3d/core/cross/bitmap_png.cc | 87 | ||||
-rw-r--r-- | o3d/core/cross/client.cc | 12 | ||||
-rw-r--r-- | o3d/core/cross/client.h | 5 | ||||
-rw-r--r-- | o3d/core/cross/command_buffer/renderer_cb.cc | 5 | ||||
-rw-r--r-- | o3d/core/cross/command_buffer/renderer_cb.h | 5 | ||||
-rw-r--r-- | o3d/core/cross/command_buffer/texture_cb.h | 6 | ||||
-rw-r--r-- | o3d/core/cross/gl/renderer_gl.cc | 16 | ||||
-rw-r--r-- | o3d/core/cross/gl/renderer_gl.h | 5 | ||||
-rw-r--r-- | o3d/core/cross/gl/texture_gl.h | 6 | ||||
-rw-r--r-- | o3d/core/cross/gl/utils_gl.h | 6 | ||||
-rw-r--r-- | o3d/core/cross/image_utils.h | 3 | ||||
-rw-r--r-- | o3d/core/cross/image_utils_test.cc | 19 | ||||
-rw-r--r-- | o3d/core/cross/object_base.h | 6 | ||||
-rw-r--r-- | o3d/core/cross/precompile.h | 6 | ||||
-rw-r--r-- | o3d/core/cross/renderer.h | 5 | ||||
-rw-r--r-- | o3d/core/cross/sampler.h | 6 |
18 files changed, 111 insertions, 100 deletions
diff --git a/o3d/core/cross/bitmap.cc b/o3d/core/cross/bitmap.cc index 8069451..cdccc66 100644 --- a/o3d/core/cross/bitmap.cc +++ b/o3d/core/cross/bitmap.cc @@ -146,8 +146,8 @@ void Bitmap::SetRect( uint8* dst = GetMipData(level) + - image::ComputeMipChainSize(mip_width, dst_top, format(), 1) + - image::ComputeMipChainSize(dst_left, 1, format(), 1); + image::ComputePitch(format(), mip_width) * dst_top + + image::ComputePitch(format(), dst_left); const uint8* src = static_cast<const uint8*>(src_data); if (!compressed) { diff --git a/o3d/core/cross/bitmap.h b/o3d/core/cross/bitmap.h index 5bd3687..a86b76a 100644 --- a/o3d/core/cross/bitmap.h +++ b/o3d/core/cross/bitmap.h @@ -242,13 +242,10 @@ class Bitmap : public ParamObject { // from a flippable format back to a DXT format.
void FlipVertically();
- // Saves to a PNG file. The image must be of the ARGB8 format, be a 2D image
- // with no mip-maps (only the base level).
- // Parameters:
- // filename: the name of the file to into.
+ // Returns the contents of the bitmap as a data URL
// Returns:
- // true if successful.
- bool SaveToPNGFile(const char* filename);
+ // A data url that represents the content of the bitmap.
+ String ToDataURL();
// Checks that the alpha channel for the entire bitmap is 1.0
bool CheckAlphaIsOne() const;
diff --git a/o3d/core/cross/bitmap_png.cc b/o3d/core/cross/bitmap_png.cc index 770ced0..047f585 100644 --- a/o3d/core/cross/bitmap_png.cc +++ b/o3d/core/cross/bitmap_png.cc @@ -37,6 +37,7 @@ #include <fstream> #include "core/cross/bitmap.h" +#include "core/cross/error.h" #include "core/cross/types.h" #include "utils/cross/file_path_utils.h" #include "base/file_path.h" @@ -44,22 +45,38 @@ #include "import/cross/memory_buffer.h" #include "import/cross/memory_stream.h" #include "png.h" +#include "utils/cross/dataurl.h" using file_util::OpenFile; using file_util::CloseFile; namespace o3d { +namespace { + // Helper function for LoadFromPNGFile that converts a stream into the // necessary abstract byte reading function. -static void stream_read_data(png_structp png_ptr, - png_bytep data, - png_size_t length) { +void StreamReadData(png_structp png_ptr, png_bytep data, png_size_t length) { MemoryReadStream *stream = static_cast<MemoryReadStream*>(png_get_io_ptr(png_ptr)); stream->Read(data, length); } +// Helper function for ToDataURL that converts a stream into the necessary +// abstract byte writing function. +void StreamWriteData(png_structp png_ptr, png_bytep data, png_size_t length) { + std::vector<uint8>* stream = + static_cast<std::vector<uint8>*>(png_get_io_ptr(png_ptr)); + stream->insert(stream->end(), + static_cast<uint8*>(data), + static_cast<uint8*>(data) + length); +} + +// Because libpng requires a flush function according to the docs. +void StreamFlush(png_structp png_ptr) { +} + +} // anonymous namespace // Loads the raw RGB data from a compressed PNG file. bool Bitmap::LoadFromPNGStream(MemoryReadStream *stream, @@ -117,7 +134,7 @@ bool Bitmap::LoadFromPNGStream(MemoryReadStream *stream, } // Set up our STL stream input control - png_set_read_fn(png_ptr, stream, &stream_read_data); + png_set_read_fn(png_ptr, stream, &StreamReadData); // We have already read some of the signature, advance the pointer. png_set_sig_bytes(png_ptr, sizeof(magic)); @@ -263,27 +280,17 @@ bool Bitmap::LoadFromPNGStream(MemoryReadStream *stream, return true; } -// Saves the BGRA data from a compressed PNG file. -bool Bitmap::SaveToPNGFile(const char* filename) { - if (format_ != Texture::ARGB8) { - DLOG(ERROR) << "Can only save ARGB8 images."; - return false; - } - if (num_mipmaps_ != 1 || is_cubemap_) { - DLOG(ERROR) << "Only 2D images with only the base level can be saved."; - return false; - } - FILE *fp = fopen(filename, "wb"); - if (!fp) { - DLOG(ERROR) << "Could not open file " << filename << " for writing."; - return false; - } +namespace { + +bool CreatePNGInUInt8Vector(const Bitmap& bitmap, std::vector<uint8>* buffer) { + DCHECK(bitmap.format() == Texture::ARGB8); + DCHECK(bitmap.num_mipmaps() == 1); + DCHECK(!bitmap.is_cubemap()); png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) { DLOG(ERROR) << "Could not create PNG structure."; - fclose(fp); return false; } @@ -291,26 +298,27 @@ bool Bitmap::SaveToPNGFile(const char* filename) { if (!info_ptr) { DLOG(ERROR) << "Could not create PNG info structure."; png_destroy_write_struct(&png_ptr, png_infopp_NULL); - fclose(fp); return false; } - scoped_array<png_bytep> row_pointers(new png_bytep[height_]); - for (int i = 0; i < height_; ++i) { - row_pointers[height_-1-i] = image_data_.get() + i * width_ * 4; + unsigned width = bitmap.width(); + unsigned height = bitmap.height(); + scoped_array<png_bytep> row_pointers(new png_bytep[height]); + for (int i = 0; i < height; ++i) { + row_pointers[height - 1 - i] = bitmap.GetMipData(0) + i * width * 4; } if (setjmp(png_jmpbuf(png_ptr))) { // If we get here, we had a problem reading the file. - DLOG(ERROR) << "Error while writing file " << filename << "."; + DLOG(ERROR) << "Error while getting dataURL."; png_destroy_write_struct(&png_ptr, &info_ptr); - fclose(fp); return false; } - png_init_io(png_ptr, fp); + // Set up our STL stream output. + png_set_write_fn(png_ptr, buffer, &StreamWriteData, &StreamFlush); - png_set_IHDR(png_ptr, info_ptr, width_, height_, 8, + png_set_IHDR(png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); png_set_bgr(png_ptr); @@ -318,8 +326,27 @@ bool Bitmap::SaveToPNGFile(const char* filename) { png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, png_voidp_NULL); png_destroy_write_struct(&png_ptr, &info_ptr); - fclose(fp); - return true; +} + +} // anonymous namespace + +String Bitmap::ToDataURL() { + if (format_ != Texture::ARGB8) { + O3D_ERROR(service_locator()) << "Can only get data URL from ARGB8 images."; + return dataurl::kEmptyDataURL; + } + if (num_mipmaps_ != 1 || is_cubemap_) { + O3D_ERROR(service_locator()) << + "Can only get data URL from 2d images with no mips."; + return dataurl::kEmptyDataURL; + } + + std::vector<uint8> stream; + if (!CreatePNGInUInt8Vector(*this, &stream)) { + return dataurl::kEmptyDataURL; + } + + return dataurl::ToDataURL("image/png", &stream[0], stream.size()); } } // namespace o3d diff --git a/o3d/core/cross/client.cc b/o3d/core/cross/client.cc index 7b70496..cfbce23 100644 --- a/o3d/core/cross/client.cc +++ b/o3d/core/cross/client.cc @@ -55,6 +55,7 @@ #include "core/cross/profiler.h" #include "utils/cross/string_writer.h" #include "utils/cross/json_writer.h" +#include "utils/cross/dataurl.h" #ifdef OS_WIN #include "core/cross/core_metrics.h" @@ -401,12 +402,17 @@ void Client::InvalidateAllParameters() { evaluation_counter_->InvalidateAllParameters(); } -bool Client::SaveScreen(const String& file_name) { +String Client::ToDataURL() { if (!renderer_.IsAvailable()) { O3D_ERROR(service_locator_) << "No Render Device Available"; - return false; + return dataurl::kEmptyDataURL; } else { - return renderer_->SaveScreen(file_name); + Bitmap::Ref bitmap(renderer_->TakeScreenshot()); + if (bitmap.IsNull()) { + return dataurl::kEmptyDataURL; + } else { + return bitmap->ToDataURL(); + } } } diff --git a/o3d/core/cross/client.h b/o3d/core/cross/client.h index b7de85c..153e354 100644 --- a/o3d/core/cross/client.h +++ b/o3d/core/cross/client.h @@ -395,9 +395,8 @@ class Client { // Dumps all profiler state to a string. String ProfileToString(); - // Saves a png screenshot of the display buffer. - // Returns true on success and false on failure. - bool SaveScreen(const String& file_name); + // Reutrns a data: URL of the client area in png format. + String ToDataURL(); // This class is intended to be used on the stack, such that the variable gets // incremented on scope entry and decremented on scope exit. It's currently diff --git a/o3d/core/cross/command_buffer/renderer_cb.cc b/o3d/core/cross/command_buffer/renderer_cb.cc index 493da78..9de0617 100644 --- a/o3d/core/cross/command_buffer/renderer_cb.cc +++ b/o3d/core/cross/command_buffer/renderer_cb.cc @@ -368,9 +368,8 @@ void RendererCB::SetViewportInPixels(int left, helper_->AddCommand(command_buffer::SET_VIEWPORT, 6, args); } -bool RendererCB::SaveScreen(const String& file_name) { - // TODO - return false; +Bitmap::Ref RendererCB::TakeScreenshot() { + return Bitmap::Ref(); } const int* RendererCB::GetRGBAUByteNSwizzleTable() { diff --git a/o3d/core/cross/command_buffer/renderer_cb.h b/o3d/core/cross/command_buffer/renderer_cb.h index df13f9b..e7f8963 100644 --- a/o3d/core/cross/command_buffer/renderer_cb.h +++ b/o3d/core/cross/command_buffer/renderer_cb.h @@ -141,9 +141,8 @@ class RendererCB : public Renderer { return RenderDepthStencilSurface::Ref(); } - // Saves a png screenshot. - // Returns true on success and false on failure. - virtual bool SaveScreen(const String& file_name); + // Overridden from Renderer. + virtual Bitmap::Ref TakeScreenshot(); // Gets the allocator for vertex buffer IDs. IdAllocator &vertex_buffer_ids() { return vertex_buffer_ids_; } diff --git a/o3d/core/cross/command_buffer/texture_cb.h b/o3d/core/cross/command_buffer/texture_cb.h index e000a8e..c08cfcd 100644 --- a/o3d/core/cross/command_buffer/texture_cb.h +++ b/o3d/core/cross/command_buffer/texture_cb.h @@ -32,8 +32,8 @@ // This file contains the declarations for Texture2DCB and TextureCUBECB. -#ifndef O3D_CORE_CROSS_COMMAND_BUFFER_TEXTURE_CB_H__ -#define O3D_CORE_CROSS_COMMAND_BUFFER_TEXTURE_CB_H__ +#ifndef O3D_CORE_CROSS_COMMAND_BUFFER_TEXTURE_CB_H_ +#define O3D_CORE_CROSS_COMMAND_BUFFER_TEXTURE_CB_H_ // Precompiled header comes before everything else. #include "core/cross/precompile.h" @@ -212,4 +212,4 @@ class TextureCUBECB : public TextureCUBE { } // namespace o3d -#endif // O3D_CORE_CROSS_COMMAND_BUFFER_TEXTURE_CB_H__ +#endif // O3D_CORE_CROSS_COMMAND_BUFFER_TEXTURE_CB_H_ diff --git a/o3d/core/cross/gl/renderer_gl.cc b/o3d/core/cross/gl/renderer_gl.cc index c22cda3..4a8b215 100644 --- a/o3d/core/cross/gl/renderer_gl.cc +++ b/o3d/core/cross/gl/renderer_gl.cc @@ -1560,10 +1560,7 @@ RenderDepthStencilSurface::Ref RendererGL::CreateDepthStencilSurface( height)); } -// Saves a png screenshot 'file_name.png'. -// Returns true on success and false on failure. -bool RendererGL::SaveScreen(const String& file_name) { -#ifdef TESTING +Bitmap::Ref RendererGL::TakeScreenshot() {; MakeCurrentLazy(); Bitmap::Ref bitmap = Bitmap::Ref(new Bitmap(service_locator())); bitmap->Allocate(Texture::ARGB8, width(), height(), 1, false); @@ -1574,16 +1571,7 @@ bool RendererGL::SaveScreen(const String& file_name) { // might exhibit suprise translucency. ::glReadPixels(0, 0, width(), height(), GL_BGRA, GL_UNSIGNED_BYTE, bitmap->image_data()); - bool result = bitmap->SaveToPNGFile((file_name + ".png").c_str()); - if (!result) { - O3D_ERROR(service_locator()) - << "Failed to save screen into " << file_name; - } - return result; -#else - // Not a test build, always return false. - return false; -#endif + return bitmap; } const int* RendererGL::GetRGBAUByteNSwizzleTable() { diff --git a/o3d/core/cross/gl/renderer_gl.h b/o3d/core/cross/gl/renderer_gl.h index 24d8d01..534ea9c 100644 --- a/o3d/core/cross/gl/renderer_gl.h +++ b/o3d/core/cross/gl/renderer_gl.h @@ -144,9 +144,8 @@ class RendererGL : public Renderer { int width, int height); - // Saves a png screenshot 'file_name.png'. - // Returns true on success and false on failure. - virtual bool SaveScreen(const String& file_name); + // Overridden from Renderer. + virtual Bitmap::Ref TakeScreenshot(); // Overridden from Renderer. virtual const int* GetRGBAUByteNSwizzleTable(); diff --git a/o3d/core/cross/gl/texture_gl.h b/o3d/core/cross/gl/texture_gl.h index 6b97b7f..567bf2b 100644 --- a/o3d/core/cross/gl/texture_gl.h +++ b/o3d/core/cross/gl/texture_gl.h @@ -32,8 +32,8 @@ // This file contains the declarations for Texture2DGL and TextureCUBEGL. -#ifndef O3D_CORE_CROSS_GL_TEXTURE_GL_H__ -#define O3D_CORE_CROSS_GL_TEXTURE_GL_H__ +#ifndef O3D_CORE_CROSS_GL_TEXTURE_GL_H_ +#define O3D_CORE_CROSS_GL_TEXTURE_GL_H_ // Precompiled header comes before everything else. #include "core/cross/precompile.h" @@ -235,4 +235,4 @@ class TextureCUBEGL : public TextureCUBE { } // namespace o3d -#endif // O3D_CORE_CROSS_GL_TEXTURE_GL_H__ +#endif // O3D_CORE_CROSS_GL_TEXTURE_GL_H_ diff --git a/o3d/core/cross/gl/utils_gl.h b/o3d/core/cross/gl/utils_gl.h index b6b87ff..a7af934 100644 --- a/o3d/core/cross/gl/utils_gl.h +++ b/o3d/core/cross/gl/utils_gl.h @@ -30,8 +30,8 @@ */ -#ifndef O3D_CORE_CROSS_GL_UTILS_GL_H__ -#define O3D_CORE_CROSS_GL_UTILS_GL_H__ +#ifndef O3D_CORE_CROSS_GL_UTILS_GL_H_ +#define O3D_CORE_CROSS_GL_UTILS_GL_H_ #include "base/basictypes.h" #include "core/cross/stream.h" @@ -44,4 +44,4 @@ Stream::Semantic GLVertexAttributeToStream(const unsigned int attr, int *index); } // namespace o3d -#endif // O3D_CORE_CROSS_GL_UTILS_GL_H__ +#endif // O3D_CORE_CROSS_GL_UTILS_GL_H_ diff --git a/o3d/core/cross/image_utils.h b/o3d/core/cross/image_utils.h index 12f29b8..2b6212e 100644 --- a/o3d/core/cross/image_utils.h +++ b/o3d/core/cross/image_utils.h @@ -59,8 +59,7 @@ enum ImageFileType { unsigned int GetNumComponentsForFormat(Texture::Format format);
inline bool CheckImageDimensions(unsigned int width, unsigned int height) {
- return width > 0 && height > 0 &&
- width <= kMaxImageDimension && height <= kMaxImageDimension;
+ return width <= kMaxImageDimension && height <= kMaxImageDimension;
}
// Gets the number of mip-maps required for a full chain starting at
diff --git a/o3d/core/cross/image_utils_test.cc b/o3d/core/cross/image_utils_test.cc index 99edc489..4f6a1c3 100644 --- a/o3d/core/cross/image_utils_test.cc +++ b/o3d/core/cross/image_utils_test.cc @@ -41,16 +41,14 @@ namespace o3d { class ImageTest : public testing::Test { }; -TEST_F(ImageTest, CheckImageDimensions) { - EXPECT_TRUE(image::CheckImageDimensions(1u, 1u)); - EXPECT_FALSE(image::CheckImageDimensions(0u, 1u)); - EXPECT_FALSE(image::CheckImageDimensions(1u, 0u)); - EXPECT_TRUE(image::CheckImageDimensions(image::kMaxImageDimension, - image::kMaxImageDimension)); - EXPECT_FALSE(image::CheckImageDimensions(0u, image::kMaxImageDimension)); - EXPECT_FALSE(image::CheckImageDimensions(image::kMaxImageDimension, 0u)); -} - +TEST_F(ImageTest, CheckImageDimensions) {
+ EXPECT_TRUE(image::CheckImageDimensions(1u, 1u));
+ EXPECT_TRUE(image::CheckImageDimensions(image::kMaxImageDimension,
+ image::kMaxImageDimension));
+ EXPECT_FALSE(image::CheckImageDimensions(0u, image::kMaxImageDimension + 1));
+ EXPECT_FALSE(image::CheckImageDimensions(image::kMaxImageDimension + 1, 0u));
+}
+
TEST_F(ImageTest, ComputeMipMapCount) { EXPECT_EQ(image::ComputeMipMapCount(1, 1), 1u); EXPECT_EQ(image::ComputeMipMapCount(2, 2), 2u); @@ -301,3 +299,4 @@ TEST_F(ImageTest, GetFileTypeFromMimeType) { } // namespace +
diff --git a/o3d/core/cross/object_base.h b/o3d/core/cross/object_base.h index 9a174c0..b4939c1 100644 --- a/o3d/core/cross/object_base.h +++ b/o3d/core/cross/object_base.h @@ -33,8 +33,8 @@ // This file contains the declaration of the ObjectBase class and definitions // for the macros used to define the O3D object classes. -#ifndef O3D_CORE_CROSS_OBJECT_BASE_H__ -#define O3D_CORE_CROSS_OBJECT_BASE_H__ +#ifndef O3D_CORE_CROSS_OBJECT_BASE_H_ +#define O3D_CORE_CROSS_OBJECT_BASE_H_ #include <vector> @@ -240,4 +240,4 @@ typedef std::vector<ObjectBase*> ObjectBaseArray; } // namespace o3d -#endif // O3D_CORE_CROSS_OBJECT_BASE_H__ +#endif // O3D_CORE_CROSS_OBJECT_BASE_H_ diff --git a/o3d/core/cross/precompile.h b/o3d/core/cross/precompile.h index bc9ba64..3e11e99 100644 --- a/o3d/core/cross/precompile.h +++ b/o3d/core/cross/precompile.h @@ -33,8 +33,8 @@ // This file contains includes for common headers used by O3D files. It // is used for pre-compiled header support. -#ifndef O3D_CORE_CROSS_PRECOMPILE_H__ -#define O3D_CORE_CROSS_PRECOMPILE_H__ +#ifndef O3D_CORE_CROSS_PRECOMPILE_H_ +#define O3D_CORE_CROSS_PRECOMPILE_H_ #include <build/build_config.h> @@ -63,4 +63,4 @@ #include <map> #include <vector> -#endif // O3D_CORE_CROSS_PRECOMPILE_H__ +#endif // O3D_CORE_CROSS_PRECOMPILE_H_ diff --git a/o3d/core/cross/renderer.h b/o3d/core/cross/renderer.h index 15717ed..d766b24 100644 --- a/o3d/core/cross/renderer.h +++ b/o3d/core/cross/renderer.h @@ -364,9 +364,8 @@ class Renderer { int width, int height) = 0; - // Saves a png screenshot. - // Returns true on success and false on failure. - virtual bool SaveScreen(const String& file_name) = 0; + // Returns the screen as a Bitmap. Will return a null reference on error. + virtual Bitmap::Ref TakeScreenshot() = 0; ServiceLocator* service_locator() const { return service_locator_; } diff --git a/o3d/core/cross/sampler.h b/o3d/core/cross/sampler.h index 20ead52..c6dcf54 100644 --- a/o3d/core/cross/sampler.h +++ b/o3d/core/cross/sampler.h @@ -32,8 +32,8 @@ // This file contains the declaration for the Sampler class. -#ifndef O3D_CORE_CROSS_SAMPLER_H__ -#define O3D_CORE_CROSS_SAMPLER_H__ +#ifndef O3D_CORE_CROSS_SAMPLER_H_ +#define O3D_CORE_CROSS_SAMPLER_H_ #include "core/cross/param_object.h" #include "core/cross/param.h" @@ -204,4 +204,4 @@ class ParamSampler : public TypedRefParam<Sampler> { } // namespace o3d -#endif // O3D_CORE_CROSS_SAMPLER_H__ +#endif // O3D_CORE_CROSS_SAMPLER_H_ |