|
|
@@ -0,0 +1,274 @@
|
|
|
+// Filename: computeNode.cxx
|
|
|
+// Created by: rdb (19Jun14)
|
|
|
+//
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+//
|
|
|
+// PANDA 3D SOFTWARE
|
|
|
+// Copyright (c) Carnegie Mellon University. All rights reserved.
|
|
|
+//
|
|
|
+// All use of this software is subject to the terms of the revised BSD
|
|
|
+// license. You should have received a copy of this license along
|
|
|
+// with this source code in a file named "LICENSE."
|
|
|
+//
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+
|
|
|
+#include "pandabase.h"
|
|
|
+#include "computeNode.h"
|
|
|
+#include "cullTraverser.h"
|
|
|
+#include "cullableObject.h"
|
|
|
+#include "cullHandler.h"
|
|
|
+#include "geomDrawCallbackData.h"
|
|
|
+#include "omniBoundingVolume.h"
|
|
|
+#include "config_pgraph.h"
|
|
|
+
|
|
|
+TypeHandle ComputeNode::_type_handle;
|
|
|
+
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+// Function: ComputeNode::Constructor
|
|
|
+// Access: Published
|
|
|
+// Description: Creates a ComputeNode with the given name. Use
|
|
|
+// add_dispatch and also assign a shader using a
|
|
|
+// ShaderAttrib.
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+ComputeNode::
|
|
|
+ComputeNode(const string &name) :
|
|
|
+ PandaNode(name),
|
|
|
+ _dispatcher(new ComputeNode::Dispatcher)
|
|
|
+{
|
|
|
+ set_internal_bounds(new OmniBoundingVolume);
|
|
|
+}
|
|
|
+
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+// Function: ComputeNode::Copy Constructor
|
|
|
+// Access: Protected
|
|
|
+// Description:
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+ComputeNode::
|
|
|
+ComputeNode(const ComputeNode ©) :
|
|
|
+ PandaNode(copy),
|
|
|
+ _dispatcher(new ComputeNode::Dispatcher(*copy._dispatcher))
|
|
|
+{
|
|
|
+}
|
|
|
+
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+// Function: ComputeNode::make_copy
|
|
|
+// Access: Public, Virtual
|
|
|
+// Description: Returns a newly-allocated Node that is a shallow copy
|
|
|
+// of this one. It will be a different Node pointer,
|
|
|
+// but its internal data may or may not be shared with
|
|
|
+// that of the original Node.
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+PandaNode *ComputeNode::
|
|
|
+make_copy() const {
|
|
|
+ return new ComputeNode(*this);
|
|
|
+}
|
|
|
+
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+// Function: ComputeNode::safe_to_combine
|
|
|
+// Access: Public, Virtual
|
|
|
+// Description: Returns true if it is generally safe to combine this
|
|
|
+// particular kind of PandaNode with other kinds of
|
|
|
+// PandaNodes of compatible type, adding children or
|
|
|
+// whatever. For instance, an LODNode should not be
|
|
|
+// combined with any other PandaNode, because its set of
|
|
|
+// children is meaningful.
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+bool ComputeNode::
|
|
|
+safe_to_combine() const {
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+// Function: ComputeNode::is_renderable
|
|
|
+// Access: Public, Virtual
|
|
|
+// Description: Returns true if there is some value to visiting this
|
|
|
+// particular node during the cull traversal for any
|
|
|
+// camera, false otherwise. This will be used to
|
|
|
+// optimize the result of get_net_draw_show_mask(), so
|
|
|
+// that any subtrees that contain only nodes for which
|
|
|
+// is_renderable() is false need not be visited.
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+bool ComputeNode::
|
|
|
+is_renderable() const {
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+// Function: ComputeNode::add_for_draw
|
|
|
+// Access: Public, Virtual
|
|
|
+// Description: Adds the node's contents to the CullResult we are
|
|
|
+// building up during the cull traversal, so that it
|
|
|
+// will be drawn at render time. For most nodes other
|
|
|
+// than GeomNodes, this is a do-nothing operation.
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+void ComputeNode::
|
|
|
+add_for_draw(CullTraverser *trav, CullTraverserData &data) {
|
|
|
+ if (pgraph_cat.is_spam()) {
|
|
|
+ pgraph_cat.spam()
|
|
|
+ << "Found " << *this << " in state " << *data._state
|
|
|
+ << " draw_mask = " << data._draw_mask << "\n";
|
|
|
+ }
|
|
|
+
|
|
|
+ // OK, render this node. Rendering this node means creating a
|
|
|
+ // CullableObject for the Dispatcher. We don't need to pass
|
|
|
+ // any Geoms, however.
|
|
|
+ CullableObject *object =
|
|
|
+ new CullableObject(NULL, data._state,
|
|
|
+ data.get_net_transform(trav),
|
|
|
+ data.get_modelview_transform(trav),
|
|
|
+ trav->get_scene());
|
|
|
+ object->set_draw_callback(_dispatcher);
|
|
|
+ trav->get_cull_handler()->record_object(object, trav);
|
|
|
+}
|
|
|
+
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+// Function: ComputeNode::output
|
|
|
+// Access: Public, Virtual
|
|
|
+// Description: Writes a brief description of the node to the
|
|
|
+// indicated output stream. This is invoked by the <<
|
|
|
+// operator. It may be overridden in derived classes to
|
|
|
+// include some information relevant to the class.
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+void ComputeNode::
|
|
|
+output(ostream &out) const {
|
|
|
+ PandaNode::output(out);
|
|
|
+}
|
|
|
+
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+// Function: ComputeNode::Dispatcher::Constructor
|
|
|
+// Access: Public
|
|
|
+// Description:
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+ComputeNode::Dispatcher::
|
|
|
+Dispatcher() {
|
|
|
+}
|
|
|
+
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+// Function: ComputeNode::Dispatcher::Copy Constructor
|
|
|
+// Access: Public
|
|
|
+// Description:
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+ComputeNode::Dispatcher::
|
|
|
+Dispatcher(const Dispatcher ©) :
|
|
|
+ _cycler(copy._cycler)
|
|
|
+{
|
|
|
+}
|
|
|
+
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+// Function: ComputeNode::Dispatcher::do_callback
|
|
|
+// Access: Public, Virtual
|
|
|
+// Description: Asks the GSG to dispatch the compute shader.
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+void ComputeNode::Dispatcher::
|
|
|
+do_callback(CallbackData *cbdata) {
|
|
|
+ GeomDrawCallbackData *data = (GeomDrawCallbackData *)cbdata;
|
|
|
+ GraphicsStateGuardianBase *gsg = data->get_gsg();
|
|
|
+
|
|
|
+ CDReader cdata(_cycler);
|
|
|
+
|
|
|
+ Dispatches::const_iterator it;
|
|
|
+ for (it = cdata->_dispatches.begin(); it != cdata->_dispatches.end(); ++it) {
|
|
|
+ gsg->dispatch_compute(it->get_x(), it->get_y(), it->get_z());
|
|
|
+ }
|
|
|
+
|
|
|
+ // No need to upcall; we don't have any geometry, after all.
|
|
|
+}
|
|
|
+
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+// Function: ComputeNode::register_with_read_factory
|
|
|
+// Access: Public, Static
|
|
|
+// Description: Tells the BamReader how to create objects of type
|
|
|
+// ComputeNode.
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+void ComputeNode::
|
|
|
+register_with_read_factory() {
|
|
|
+ BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
|
|
|
+}
|
|
|
+
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+// Function: ComputeNode::write_datagram
|
|
|
+// Access: Public, Virtual
|
|
|
+// Description: Writes the contents of this object to the datagram
|
|
|
+// for shipping out to a Bam file.
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+void ComputeNode::
|
|
|
+write_datagram(BamWriter *manager, Datagram &dg) {
|
|
|
+ PandaNode::write_datagram(manager, dg);
|
|
|
+ manager->write_cdata(dg, _dispatcher->_cycler);
|
|
|
+}
|
|
|
+
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+// Function: ComputeNode::make_from_bam
|
|
|
+// Access: Protected, Static
|
|
|
+// Description: This function is called by the BamReader's factory
|
|
|
+// when a new object of type ComputeNode is encountered
|
|
|
+// in the Bam file. It should create the ComputeNode
|
|
|
+// and extract its information from the file.
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+TypedWritable *ComputeNode::
|
|
|
+make_from_bam(const FactoryParams ¶ms) {
|
|
|
+ ComputeNode *node = new ComputeNode("");
|
|
|
+ DatagramIterator scan;
|
|
|
+ BamReader *manager;
|
|
|
+
|
|
|
+ parse_params(params, scan, manager);
|
|
|
+ node->fillin(scan, manager);
|
|
|
+
|
|
|
+ return node;
|
|
|
+}
|
|
|
+
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+// Function: ComputeNode::fillin
|
|
|
+// Access: Protected
|
|
|
+// Description: This internal function is called by make_from_bam to
|
|
|
+// read in all of the relevant data from the BamFile for
|
|
|
+// the new ComputeNode.
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+void ComputeNode::
|
|
|
+fillin(DatagramIterator &scan, BamReader *manager) {
|
|
|
+ PandaNode::fillin(scan, manager);
|
|
|
+ manager->read_cdata(scan, _dispatcher->_cycler);
|
|
|
+}
|
|
|
+
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+// Function: ComputeNode::Dispatcher::CData::make_copy
|
|
|
+// Access: Public, Virtual
|
|
|
+// Description:
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+CycleData *ComputeNode::Dispatcher::CData::
|
|
|
+make_copy() const {
|
|
|
+ return new CData(*this);
|
|
|
+}
|
|
|
+
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+// Function: ComputeNode::Dispatcher::CData::write_datagram
|
|
|
+// Access: Public, Virtual
|
|
|
+// Description: Writes the contents of this object to the datagram
|
|
|
+// for shipping out to a Bam file.
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+void ComputeNode::Dispatcher::CData::
|
|
|
+write_datagram(BamWriter *manager, Datagram &dg) const {
|
|
|
+ dg.add_uint16(_dispatches.size());
|
|
|
+
|
|
|
+ Dispatches::const_iterator it;
|
|
|
+ for (it = _dispatches.begin(); it != _dispatches.end(); ++it) {
|
|
|
+ generic_write_datagram(dg, *it);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+// Function: ComputeNode::Dispatcher::CData::fillin
|
|
|
+// Access: Public, Virtual
|
|
|
+// Description: This internal function is called by make_from_bam to
|
|
|
+// read in all of the relevant data from the BamFile for
|
|
|
+// the new ComputeNode.
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+void ComputeNode::Dispatcher::CData::
|
|
|
+fillin(DatagramIterator &scan, BamReader *manager) {
|
|
|
+ int num_dispatches = scan.get_uint16();
|
|
|
+ _dispatches.resize(num_dispatches);
|
|
|
+
|
|
|
+ for (int i = 0; i < num_dispatches; ++i) {
|
|
|
+ generic_read_datagram(_dispatches[i], scan);
|
|
|
+ }
|
|
|
+}
|