summaryrefslogtreecommitdiffstats
path: root/o3d/import
diff options
context:
space:
mode:
authorgman@google.com <gman@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-07 04:24:21 +0000
committergman@google.com <gman@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-07 04:24:21 +0000
commit34f464fb752432829a22a30767b66eb5c24a2242 (patch)
tree93545e6e6f56e7151ae8bc5100accf0998c262ad /o3d/import
parente8b80d819b7d1888e10f5cfef75bfeff0f5d3b03 (diff)
downloadchromium_src-34f464fb752432829a22a30767b66eb5c24a2242.zip
chromium_src-34f464fb752432829a22a30767b66eb5c24a2242.tar.gz
chromium_src-34f464fb752432829a22a30767b66eb5c24a2242.tar.bz2
Add o3djs.DestinationBuffer to converter.
I named it o3djs.DestinationBuffer because it has nothing to do with O3D. It's purely part of our sample serialization example. Review URL: http://codereview.chromium.org/149236 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@20013 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'o3d/import')
-rw-r--r--o3d/import/build.scons1
-rw-r--r--o3d/import/cross/collada.cc152
-rw-r--r--o3d/import/cross/collada.h8
-rw-r--r--o3d/import/cross/destination_buffer.cc79
-rw-r--r--o3d/import/cross/destination_buffer.h83
-rw-r--r--o3d/import/cross/destination_buffer_test.cc104
6 files changed, 389 insertions, 38 deletions
diff --git a/o3d/import/build.scons b/o3d/import/build.scons
index 554750b..a695a0a 100644
--- a/o3d/import/build.scons
+++ b/o3d/import/build.scons
@@ -64,6 +64,7 @@ else:
collada_inputs = [
'cross/collada.cc',
'cross/collada_zip_archive.cc',
+ 'cross/destination_buffer.cc',
'cross/zip_archive.cc',
'cross/gz_compressor.cc',
'cross/file_output_stream_processor.cc',
diff --git a/o3d/import/cross/collada.cc b/o3d/import/cross/collada.cc
index e2041e86..6379274 100644
--- a/o3d/import/cross/collada.cc
+++ b/o3d/import/cross/collada.cc
@@ -36,6 +36,7 @@
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/string_util.h"
+#include "core/cross/class_manager.h"
#include "core/cross/curve.h"
#include "core/cross/error.h"
#include "core/cross/function.h"
@@ -53,6 +54,7 @@
#include "import/cross/collada.h"
#include "import/cross/collada_conditioner.h"
#include "import/cross/collada_zip_archive.h"
+#include "import/cross/destination_buffer.h"
#include "utils/cross/file_path_utils.h"
#define COLLADA_NAMESPACE "collada"
@@ -147,6 +149,12 @@ bool Collada::Import(Pack* pack,
options);
}
+void Collada::Init(ServiceLocator* service_locator) {
+ ClassManager* class_manager=
+ service_locator->GetService<o3d::ClassManager>();
+ class_manager->AddTypedClass<DestinationBuffer>();
+}
+
// Parameters:
// pack: The pack into which the scene objects will be placed.
// Returns true on success.
@@ -391,11 +399,13 @@ bool Collada::ImportDAEDocument(FCDocument* doc,
FCDSceneNode* scene = doc->GetVisualSceneInstance();
if (scene) {
instance_root_ = CreateInstanceTree(scene);
- ImportTree(instance_root_, parent, animation_input);
- ImportTreeInstances(doc, instance_root_);
+ if (ImportTree(instance_root_, parent, animation_input)) {
+ if (ImportTreeInstances(doc, instance_root_)) {
+ status = true;
+ }
+ }
delete instance_root_;
instance_root_ = NULL;
- status = true;
}
}
}
@@ -796,7 +806,7 @@ NodeInstance *Collada::FindNodeInstanceFast(FCDSceneNode *node) {
// animation_input: The float parameter used as the input to the animation
// (if present). This is usually time. This can be null
// if there is no animation.
-void Collada::ImportTree(NodeInstance *instance,
+bool Collada::ImportTree(NodeInstance *instance,
Transform* parent_transform,
ParamFloat* animation_input) {
FCDSceneNode *node = instance->node();
@@ -807,17 +817,22 @@ void Collada::ImportTree(NodeInstance *instance,
// recursively import the rest of the nodes in the tree
const NodeInstance::NodeInstanceList &children = instance->children();
for (size_t i = 0; i < children.size(); ++i) {
- ImportTree(children[i], transform, animation_input);
+ if (!ImportTree(children[i], transform, animation_input)) {
+ return false;
+ }
}
+ return true;
}
-void Collada::ImportTreeInstances(FCDocument* doc,
+bool Collada::ImportTreeInstances(FCDocument* doc,
NodeInstance *node_instance) {
FCDSceneNode *node = node_instance->node();
// recursively import the rest of the nodes in the tree
const NodeInstance::NodeInstanceList &children = node_instance->children();
for (size_t i = 0; i < children.size(); ++i) {
- ImportTreeInstances(doc, children[i]);
+ if (!ImportTreeInstances(doc, children[i])) {
+ return false;
+ }
}
Transform* transform = node_instance->transform();
@@ -847,9 +862,19 @@ void Collada::ImportTreeInstances(FCDocument* doc,
case FCDEntity::CONTROLLER: {
FCDControllerInstance* controller_instance =
static_cast<FCDControllerInstance*> (instance);
- Shape* shape = GetSkinnedShape(doc, controller_instance, node_instance);
- if (shape) {
- transform->AddShape(shape);
+ FCDController* controller =
+ static_cast<FCDController*>(controller_instance->GetEntity());
+ if (controller) {
+ if (controller->IsSkin()) {
+ Shape* shape = GetSkinnedShape(doc,
+ controller_instance,
+ node_instance);
+ if (shape) {
+ transform->AddShape(shape);
+ } else {
+ return false;
+ }
+ }
}
break;
}
@@ -858,6 +883,7 @@ void Collada::ImportTreeInstances(FCDocument* doc,
break;
}
}
+ return true;
}
// Converts an FCollada vertex attribute semantic into an O3D
@@ -1318,9 +1344,23 @@ Shape* Collada::BuildSkinnedShape(FCDocument* doc,
// skin everything. This is actually what was BuildShape was doing at the
// time this code was written.
const ElementRefArray& elements = shape->GetElementRefs();
- if (elements.empty() || !elements[0]->IsA(Primitive::GetApparentClass())) {
+ if (elements.empty()) {
return NULL;
}
+ // check that they all use the same StreamBank and are all Primitives
+ for (unsigned ii = 0; ii < elements.size(); ++ii) {
+ if (!elements[ii]->IsA(Primitive::GetApparentClass())) {
+ O3D_ERROR(service_locator_)
+ << "Element in Shape '" << shape->name() << "' is not a Primitive.";
+ return NULL;
+ }
+ if (down_cast<Primitive*>(elements[ii].Get())->stream_bank() !=
+ down_cast<Primitive*>(elements[0].Get())->stream_bank()) {
+ O3D_ERROR(service_locator_)
+ << "More than one StreamBank in Shape '" << shape->name() << "'.";
+ return NULL;
+ }
+ }
Primitive* primitive = down_cast<Primitive*>(elements[0].Get());
String controller_name = WideToUTF8(controller->GetName().c_str());
@@ -1412,16 +1452,29 @@ Shape* Collada::BuildSkinnedShape(FCDocument* doc,
// so we can store the skinned vertices for the second instance. But we'd
// like to share the COLOR and TEXCOORDS. To do that they need to be in
// a separate VertexBuffer.
- StreamBank* stream_bank = primitive->stream_bank();
- SourceBuffer* buffer = pack_->Create<SourceBuffer>();
+ StreamBank* old_stream_bank = primitive->stream_bank();
+ StreamBank* new_stream_bank = pack_->Create<StreamBank>();
+ new_stream_bank->set_name(String("skinned_") + old_stream_bank->name());
+ Buffer* old_buffer = NULL;
+ SourceBuffer* source_buffer = pack_->Create<SourceBuffer>();
VertexBuffer* shared_buffer = pack_->Create<VertexBuffer>();
+ DestinationBuffer* dest_buffer = pack_->Create<DestinationBuffer>();
const StreamParamVector& source_stream_params =
- stream_bank->vertex_stream_params();
- std::vector<Field*> new_fields(source_stream_params.size(), NULL);
+ old_stream_bank->vertex_stream_params();
+ std::vector<Field*> source_fields(source_stream_params.size(), NULL);
+ std::vector<Field*> dest_fields(source_stream_params.size(), NULL);
// first make all the fields.
for (unsigned ii = 0; ii < source_stream_params.size(); ++ii) {
const Stream& source_stream = source_stream_params[ii]->stream();
const Field& field = source_stream.field();
+ if (old_buffer == NULL) {
+ old_buffer = field.buffer();
+ } else if (old_buffer != field.buffer()) {
+ O3D_ERROR(service_locator_)
+ << "More than 1 buffer used by StreamBank '"
+ << old_stream_bank->name().c_str()
+ << "' which the collada importer does not currently support";
+ }
bool copied = false;
if (field.IsA(FloatField::GetApparentClass()) &&
(field.num_components() == 3 ||
@@ -1437,25 +1490,44 @@ Shape* Collada::BuildSkinnedShape(FCDocument* doc,
if (num_source_vertices != num_vertices) {
O3D_ERROR(service_locator_)
<< "Number of vertices in stream_bank '"
- << stream_bank->name().c_str()
+ << old_stream_bank->name().c_str()
<< "' does not equal the number of vertices in the Skin '"
<< skin->name().c_str() << "'";
return NULL;
}
- new_fields[ii] = buffer->CreateField(FloatField::GetApparentClass(),
- num_source_components);
+ source_fields[ii] = source_buffer->CreateField(
+ FloatField::GetApparentClass(), num_source_components);
+ DCHECK(source_fields[ii]);
+ dest_fields[ii] = dest_buffer->CreateField(
+ FloatField::GetApparentClass(), num_source_components);
+ DCHECK(dest_fields[ii]);
+ if (!new_stream_bank->SetVertexStream(
+ source_stream.semantic(),
+ source_stream.semantic_index(),
+ dest_fields[ii],
+ 0)) {
+ O3D_ERROR(service_locator_)
+ << "could not SetVertexStream on StreamBank '"
+ << new_stream_bank->name() << "'";
+ return NULL;
+ }
}
}
}
if (!copied) {
// It's a shared field, copy it to the shared buffer.
- new_fields[ii] = shared_buffer->CreateField(field.GetClass(),
- field.num_components());
+ source_fields[ii] = shared_buffer->CreateField(field.GetClass(),
+ field.num_components());
+ new_stream_bank->SetVertexStream(source_stream.semantic(),
+ source_stream.semantic_index(),
+ source_fields[ii],
+ 0);
}
}
- if (!buffer->AllocateElements(num_vertices) ||
- !shared_buffer->AllocateElements(num_vertices)) {
+ if (!source_buffer->AllocateElements(num_vertices) ||
+ !shared_buffer->AllocateElements(num_vertices) ||
+ !dest_buffer->AllocateElements(num_vertices)) {
O3D_ERROR(service_locator_)
<< "Failed to allocate destination vertex buffer";
return NULL;
@@ -1475,7 +1547,7 @@ Shape* Collada::BuildSkinnedShape(FCDocument* doc,
case Stream::TANGENT: {
copied = true;
unsigned num_source_components = field.num_components();
- Field* new_field = new_fields[ii];
+ Field* source_field = source_fields[ii];
std::vector<float> data(num_vertices * num_source_components);
field.GetAsFloats(0, &data[0], num_source_components,
@@ -1516,30 +1588,38 @@ Shape* Collada::BuildSkinnedShape(FCDocument* doc,
}
}
}
- new_field->SetFromFloats(&data[0], num_source_components, 0,
- num_vertices);
+ source_field->SetFromFloats(&data[0], num_source_components, 0,
+ num_vertices);
// Bind streams
skin_eval->SetVertexStream(source_stream.semantic(),
source_stream.semantic_index(),
- new_field,
+ source_field,
0);
- stream_bank->BindStream(skin_eval,
- source_stream.semantic(),
- source_stream.semantic_index());
+ new_stream_bank->BindStream(skin_eval,
+ source_stream.semantic(),
+ source_stream.semantic_index());
break;
}
}
}
if (!copied) {
- Field* new_field = new_fields[ii];
- new_field->Copy(field);
- field.buffer()->RemoveField(&source_stream.field());
- stream_bank->SetVertexStream(source_stream.semantic(),
- source_stream.semantic_index(),
- new_field,
- 0);
+ Field* source_field = source_fields[ii];
+ source_field->Copy(field);
}
}
+
+ // Set all primitives to use new stream bank.
+ for (unsigned ii = 0; ii < elements.size(); ++ii) {
+ down_cast<Primitive*>(elements[ii].Get())->set_stream_bank(
+ new_stream_bank);
+ }
+ pack_->RemoveObject(old_stream_bank);
+ if (old_buffer) {
+ source_buffer->set_name(String("source_") + old_buffer->name());
+ dest_buffer->set_name(String("skinned_") + old_buffer->name());
+ shared_buffer->set_name(String("shared_") + old_buffer->name());
+ pack_->RemoveObject(old_buffer);
+ }
}
return shape;
}
diff --git a/o3d/import/cross/collada.h b/o3d/import/cross/collada.h
index a3aa963..77382d8 100644
--- a/o3d/import/cross/collada.h
+++ b/o3d/import/cross/collada.h
@@ -66,6 +66,7 @@ class FilePath;
namespace o3d {
+class ClassManager;
class ColladaZipArchive;
class Effect;
class IErrorStatus;
@@ -221,6 +222,9 @@ class Collada {
std::vector<FilePath> GetOriginalDataFilenames() const;
const std::string& GetOriginalData(const FilePath& filename) const;
+ // Init the Collada Importer.
+ static void Init(ServiceLocator* service_locator);
+
private:
// Imports the given ZIP file into the given pack.
bool ImportZIP(const FilePath& filename, Transform* parent,
@@ -244,7 +248,7 @@ class Collada {
// Recursively imports a tree of nodes from FCollada, rooted at the
// given node, into the O3D scene.
- void ImportTree(NodeInstance *instance,
+ bool ImportTree(NodeInstance *instance,
Transform* parent,
ParamFloat* animation_input);
@@ -252,7 +256,7 @@ class Collada {
// rooted at the given node, into the O3D scene. This is a separate step
// from ImportTree because various kinds of instances can reference other
// parts of the tree.
- void ImportTreeInstances(FCDocument* doc,
+ bool ImportTreeInstances(FCDocument* doc,
NodeInstance* instance);
bool BuildFloatAnimation(ParamFloat* result,
diff --git a/o3d/import/cross/destination_buffer.cc b/o3d/import/cross/destination_buffer.cc
new file mode 100644
index 0000000..5aa3124
--- /dev/null
+++ b/o3d/import/cross/destination_buffer.cc
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2009, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "import/cross/destination_buffer.h"
+
+namespace o3d {
+
+O3D_OBJECT_BASE_DEFN_CLASS(
+ "o3djs.DestinationBuffer", DestinationBuffer, VertexBuffer);
+
+DestinationBuffer::DestinationBuffer(ServiceLocator* service_locator)
+ : VertexBuffer(service_locator),
+ buffer_() {
+}
+
+DestinationBuffer::~DestinationBuffer() {
+ ConcreteFree();
+}
+
+void DestinationBuffer::ConcreteFree() {
+ buffer_.reset();
+}
+
+bool DestinationBuffer::ConcreteAllocate(size_t size_in_bytes) {
+ ConcreteFree();
+
+ buffer_.reset(new char[size_in_bytes]);
+
+ return true;
+}
+
+bool DestinationBuffer::ConcreteLock(AccessMode access_mode,
+ void **buffer_data) {
+ if (!buffer_.get()) {
+ return false;
+ }
+
+ *buffer_data = reinterpret_cast<void*>(buffer_.get());
+ return true;
+}
+
+bool DestinationBuffer::ConcreteUnlock() {
+ return buffer_.get() != NULL;
+}
+
+ObjectBase::Ref DestinationBuffer::Create(ServiceLocator* service_locator) {
+ return ObjectBase::Ref(new DestinationBuffer(service_locator));
+}
+
+} // namespace o3d
+
diff --git a/o3d/import/cross/destination_buffer.h b/o3d/import/cross/destination_buffer.h
new file mode 100644
index 0000000..5b12e34
--- /dev/null
+++ b/o3d/import/cross/destination_buffer.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2009, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+// This file declares the DestinationBuffer class.
+
+#ifndef O3D_IMPORT_CROSS_DESTINATION_BUFFER_H_
+#define O3D_IMPORT_CROSS_DESTINATION_BUFFER_H_
+
+#include "core/cross/buffer.h"
+
+namespace o3d {
+
+// DestinationBuffer is a used for serialization only and is not part of the
+// normal O3D plugin. It is used for Skinning to distinguish between a normal
+// VertexBuffer that needs to have its contents serialized and a
+// DestinationBuffer that only needs to know its structure but not its
+// contents.
+class DestinationBuffer : public VertexBuffer {
+ public:
+ typedef SmartPointer<DestinationBuffer> Ref;
+
+ ~DestinationBuffer();
+
+ protected:
+ // Overridden from Buffer.
+ virtual bool ConcreteAllocate(size_t size_in_bytes);
+
+ // Overridden from Buffer.
+ virtual bool ConcreteLock(AccessMode access_mode, void **buffer_data);
+
+ // Overridden from Buffer.
+ virtual bool ConcreteUnlock();
+
+ explicit DestinationBuffer(ServiceLocator* service_locator);
+
+ protected:
+ // Frees the buffer if it exists.
+ void ConcreteFree();
+
+ private:
+ friend class IClassManager;
+ static ObjectBase::Ref Create(ServiceLocator* service_locator);
+
+ scoped_array<char> buffer_; // The actual data for this buffer.
+
+ O3D_OBJECT_BASE_DECL_CLASS(DestinationBuffer, VertexBuffer);
+ DISALLOW_COPY_AND_ASSIGN(DestinationBuffer);
+};
+
+
+} // namespace o3d
+
+#endif // O3D_IMPORT_CROSS_DESTINATION_BUFFER_H_
+
diff --git a/o3d/import/cross/destination_buffer_test.cc b/o3d/import/cross/destination_buffer_test.cc
new file mode 100644
index 0000000..c7f69d3
--- /dev/null
+++ b/o3d/import/cross/destination_buffer_test.cc
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2009, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "tests/common/win/testing_common.h"
+#include "import/cross/destination_buffer.h"
+#include "core/cross/class_manager.h"
+#include "core/cross/object_manager.h"
+#include "core/cross/pack.h"
+#include "core/cross/service_dependency.h"
+
+namespace o3d {
+
+class DestinationBufferTest : public testing::Test {
+ protected:
+ DestinationBufferTest()
+ : class_manager_(g_service_locator),
+ object_manager_(g_service_locator) {
+ class_manager_->AddTypedClass<DestinationBuffer>();
+ }
+
+ virtual void SetUp();
+ virtual void TearDown();
+
+ Pack* pack() { return pack_; }
+
+ private:
+ ServiceDependency<ClassManager> class_manager_;
+ ServiceDependency<ObjectManager> object_manager_;
+ Pack* pack_;
+};
+
+void DestinationBufferTest::SetUp() {
+ pack_ = object_manager_->CreatePack();
+}
+
+void DestinationBufferTest::TearDown() {
+ object_manager_->DestroyPack(pack_);
+}
+
+
+// Creates a Destination buffer, tests basic properties, and checks that writing
+// then reading data works.
+TEST_F(DestinationBufferTest, TestDestinationBuffer) {
+ Buffer *buffer = pack()->Create<DestinationBuffer>();
+ EXPECT_TRUE(buffer->IsA(DestinationBuffer::GetApparentClass()));
+ EXPECT_TRUE(buffer->IsA(VertexBuffer::GetApparentClass()));
+ EXPECT_TRUE(buffer->IsA(Buffer::GetApparentClass()));
+
+ const size_t kSize = 100;
+ Field* field = buffer->CreateField(UInt32Field::GetApparentClass(), 1);
+ ASSERT_TRUE(field != NULL);
+ ASSERT_TRUE(buffer->AllocateElements(kSize));
+ EXPECT_EQ(kSize * sizeof(uint32), buffer->GetSizeInBytes()); // NOLINT
+
+ // Put some data into the buffer.
+ uint32 *data = NULL;
+ ASSERT_TRUE(buffer->LockAs(Buffer::WRITE_ONLY, &data));
+ ASSERT_TRUE(data != NULL);
+ for (uint32 i = 0; i < kSize; ++i) {
+ data[i] = i;
+ }
+ ASSERT_TRUE(buffer->Unlock());
+
+ data = NULL;
+ // Read the data from the buffer, checks that it's the expected values.
+ ASSERT_TRUE(buffer->LockAs(Buffer::READ_ONLY, &data));
+ ASSERT_TRUE(data != NULL);
+ for (uint32 i = 0; i < kSize; ++i) {
+ EXPECT_EQ(i, data[i]);
+ }
+ ASSERT_TRUE(buffer->Unlock());
+}
+
+
+} // namespace o3d
+