Panda3D
computeNode.cxx
1 // Filename: computeNode.cxx
2 // Created by: rdb (19Jun14)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "pandabase.h"
16 #include "computeNode.h"
17 #include "cullTraverser.h"
18 #include "cullableObject.h"
19 #include "cullHandler.h"
20 #include "geomDrawCallbackData.h"
21 #include "omniBoundingVolume.h"
22 #include "config_pgraph.h"
23 
24 TypeHandle ComputeNode::_type_handle;
25 
26 ////////////////////////////////////////////////////////////////////
27 // Function: ComputeNode::Constructor
28 // Access: Published
29 // Description: Creates a ComputeNode with the given name. Use
30 // add_dispatch and also assign a shader using a
31 // ShaderAttrib.
32 ////////////////////////////////////////////////////////////////////
34 ComputeNode(const string &name) :
35  PandaNode(name),
36  _dispatcher(new ComputeNode::Dispatcher)
37 {
38  set_internal_bounds(new OmniBoundingVolume);
39 }
40 
41 ////////////////////////////////////////////////////////////////////
42 // Function: ComputeNode::Copy Constructor
43 // Access: Protected
44 // Description:
45 ////////////////////////////////////////////////////////////////////
47 ComputeNode(const ComputeNode &copy) :
48  PandaNode(copy),
49  _dispatcher(new ComputeNode::Dispatcher(*copy._dispatcher))
50 {
51 }
52 
53 ////////////////////////////////////////////////////////////////////
54 // Function: ComputeNode::make_copy
55 // Access: Public, Virtual
56 // Description: Returns a newly-allocated Node that is a shallow copy
57 // of this one. It will be a different Node pointer,
58 // but its internal data may or may not be shared with
59 // that of the original Node.
60 ////////////////////////////////////////////////////////////////////
62 make_copy() const {
63  return new ComputeNode(*this);
64 }
65 
66 ////////////////////////////////////////////////////////////////////
67 // Function: ComputeNode::safe_to_combine
68 // Access: Public, Virtual
69 // Description: Returns true if it is generally safe to combine this
70 // particular kind of PandaNode with other kinds of
71 // PandaNodes of compatible type, adding children or
72 // whatever. For instance, an LODNode should not be
73 // combined with any other PandaNode, because its set of
74 // children is meaningful.
75 ////////////////////////////////////////////////////////////////////
76 bool ComputeNode::
77 safe_to_combine() const {
78  return false;
79 }
80 
81 ////////////////////////////////////////////////////////////////////
82 // Function: ComputeNode::is_renderable
83 // Access: Public, Virtual
84 // Description: Returns true if there is some value to visiting this
85 // particular node during the cull traversal for any
86 // camera, false otherwise. This will be used to
87 // optimize the result of get_net_draw_show_mask(), so
88 // that any subtrees that contain only nodes for which
89 // is_renderable() is false need not be visited.
90 ////////////////////////////////////////////////////////////////////
91 bool ComputeNode::
92 is_renderable() const {
93  return true;
94 }
95 
96 ////////////////////////////////////////////////////////////////////
97 // Function: ComputeNode::add_for_draw
98 // Access: Public, Virtual
99 // Description: Adds the node's contents to the CullResult we are
100 // building up during the cull traversal, so that it
101 // will be drawn at render time. For most nodes other
102 // than GeomNodes, this is a do-nothing operation.
103 ////////////////////////////////////////////////////////////////////
104 void ComputeNode::
106  if (pgraph_cat.is_spam()) {
107  pgraph_cat.spam()
108  << "Found " << *this << " in state " << *data._state
109  << " draw_mask = " << data._draw_mask << "\n";
110  }
111 
112  // OK, render this node. Rendering this node means creating a
113  // CullableObject for the Dispatcher. We don't need to pass
114  // any Geoms, however.
115  CullableObject *object =
116  new CullableObject(NULL, data._state,
117  data.get_internal_transform(trav));
118  object->set_draw_callback(_dispatcher);
119  trav->get_cull_handler()->record_object(object, trav);
120 }
121 
122 ////////////////////////////////////////////////////////////////////
123 // Function: ComputeNode::output
124 // Access: Public, Virtual
125 // Description: Writes a brief description of the node to the
126 // indicated output stream. This is invoked by the <<
127 // operator. It may be overridden in derived classes to
128 // include some information relevant to the class.
129 ////////////////////////////////////////////////////////////////////
130 void ComputeNode::
131 output(ostream &out) const {
132  PandaNode::output(out);
133 }
134 
135 ////////////////////////////////////////////////////////////////////
136 // Function: ComputeNode::Dispatcher::Constructor
137 // Access: Public
138 // Description:
139 ////////////////////////////////////////////////////////////////////
140 ComputeNode::Dispatcher::
141 Dispatcher() {
142 }
143 
144 ////////////////////////////////////////////////////////////////////
145 // Function: ComputeNode::Dispatcher::Copy Constructor
146 // Access: Public
147 // Description:
148 ////////////////////////////////////////////////////////////////////
149 ComputeNode::Dispatcher::
150 Dispatcher(const Dispatcher &copy) :
151  _cycler(copy._cycler)
152 {
153 }
154 
155 ////////////////////////////////////////////////////////////////////
156 // Function: ComputeNode::Dispatcher::do_callback
157 // Access: Public, Virtual
158 // Description: Asks the GSG to dispatch the compute shader.
159 ////////////////////////////////////////////////////////////////////
162  GeomDrawCallbackData *data = (GeomDrawCallbackData *)cbdata;
163  GraphicsStateGuardianBase *gsg = data->get_gsg();
164 
165  CDReader cdata(_cycler);
166 
167  Dispatches::const_iterator it;
168  for (it = cdata->_dispatches.begin(); it != cdata->_dispatches.end(); ++it) {
169  gsg->dispatch_compute(it->get_x(), it->get_y(), it->get_z());
170  }
171 
172  // No need to upcall; we don't have any geometry, after all.
173 }
174 
175 ////////////////////////////////////////////////////////////////////
176 // Function: ComputeNode::register_with_read_factory
177 // Access: Public, Static
178 // Description: Tells the BamReader how to create objects of type
179 // ComputeNode.
180 ////////////////////////////////////////////////////////////////////
181 void ComputeNode::
183  BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
184 }
185 
186 ////////////////////////////////////////////////////////////////////
187 // Function: ComputeNode::write_datagram
188 // Access: Public, Virtual
189 // Description: Writes the contents of this object to the datagram
190 // for shipping out to a Bam file.
191 ////////////////////////////////////////////////////////////////////
192 void ComputeNode::
194  PandaNode::write_datagram(manager, dg);
195  manager->write_cdata(dg, _dispatcher->_cycler);
196 }
197 
198 ////////////////////////////////////////////////////////////////////
199 // Function: ComputeNode::make_from_bam
200 // Access: Protected, Static
201 // Description: This function is called by the BamReader's factory
202 // when a new object of type ComputeNode is encountered
203 // in the Bam file. It should create the ComputeNode
204 // and extract its information from the file.
205 ////////////////////////////////////////////////////////////////////
206 TypedWritable *ComputeNode::
207 make_from_bam(const FactoryParams &params) {
208  ComputeNode *node = new ComputeNode("");
209  DatagramIterator scan;
210  BamReader *manager;
211 
212  parse_params(params, scan, manager);
213  node->fillin(scan, manager);
214 
215  return node;
216 }
217 
218 ////////////////////////////////////////////////////////////////////
219 // Function: ComputeNode::fillin
220 // Access: Protected
221 // Description: This internal function is called by make_from_bam to
222 // read in all of the relevant data from the BamFile for
223 // the new ComputeNode.
224 ////////////////////////////////////////////////////////////////////
225 void ComputeNode::
226 fillin(DatagramIterator &scan, BamReader *manager) {
227  PandaNode::fillin(scan, manager);
228  manager->read_cdata(scan, _dispatcher->_cycler);
229 }
230 
231 ////////////////////////////////////////////////////////////////////
232 // Function: ComputeNode::Dispatcher::CData::make_copy
233 // Access: Public, Virtual
234 // Description:
235 ////////////////////////////////////////////////////////////////////
236 CycleData *ComputeNode::Dispatcher::CData::
237 make_copy() const {
238  return new CData(*this);
239 }
240 
241 ////////////////////////////////////////////////////////////////////
242 // Function: ComputeNode::Dispatcher::CData::write_datagram
243 // Access: Public, Virtual
244 // Description: Writes the contents of this object to the datagram
245 // for shipping out to a Bam file.
246 ////////////////////////////////////////////////////////////////////
248 write_datagram(BamWriter *manager, Datagram &dg) const {
249  dg.add_uint16(_dispatches.size());
250 
251  Dispatches::const_iterator it;
252  for (it = _dispatches.begin(); it != _dispatches.end(); ++it) {
253  generic_write_datagram(dg, *it);
254  }
255 }
256 
257 ////////////////////////////////////////////////////////////////////
258 // Function: ComputeNode::Dispatcher::CData::fillin
259 // Access: Public, Virtual
260 // Description: This internal function is called by make_from_bam to
261 // read in all of the relevant data from the BamFile for
262 // the new ComputeNode.
263 ////////////////////////////////////////////////////////////////////
266  int num_dispatches = scan.get_uint16();
267  _dispatches.resize(num_dispatches);
268 
269  for (int i = 0; i < num_dispatches; ++i) {
270  generic_read_datagram(_dispatches[i], scan);
271  }
272 }
GraphicsStateGuardianBase * get_gsg() const
Returns a pointer to the current GSG.
This specialization on CallbackData is passed when the callback is initiated from deep within the dra...
A basic node of the scene graph or data graph.
Definition: pandaNode.h:72
CullHandler * get_cull_handler() const
Returns the object that will receive the culled Geoms.
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
Definition: pandaNode.cxx:4164
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition: bamReader.h:122
void read_cdata(DatagramIterator &scan, PipelineCyclerBase &cycler)
Reads in the indicated CycleData object.
Definition: bamReader.cxx:753
A single page of data maintained by a PipelineCycler.
Definition: cycleData.h:50
virtual bool is_renderable() const
Returns true if there is some value to visiting this particular node during the cull traversal for an...
Definition: computeNode.cxx:92
Base class for objects that can be written to and read from Bam files.
Definition: typedWritable.h:37
void write_cdata(Datagram &packet, const PipelineCyclerBase &cycler)
Writes out the indicated CycleData object.
Definition: bamWriter.cxx:398
This collects together the pieces of data that are accumulated for each node while walking the scene ...
static void register_with_read_factory()
Tells the BamReader how to create objects of type ComputeNode.
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
Definition: bamWriter.h:73
This is a generic data block that is passed along to a CallbackObject when a callback is made...
Definition: callbackData.h:32
virtual PandaNode * make_copy() const
Returns a newly-allocated Node that is a shallow copy of this one.
Definition: computeNode.cxx:62
PN_uint16 get_uint16()
Extracts an unsigned 16-bit integer.
This template class calls PipelineCycler::read_unlocked(), and then provides a transparent read-only ...
virtual void output(ostream &out) const
Writes a brief description of the node to the indicated output stream.
The smallest atom of cull.
virtual void record_object(CullableObject *object, const CullTraverser *traverser)
This callback function is intended to be overridden by a derived class.
Definition: cullHandler.cxx:52
virtual void do_callback(CallbackData *cbdata)
Asks the GSG to dispatch the compute shader.
An instance of this class is passed to the Factory when requesting it to do its business and construc...
Definition: factoryParams.h:40
virtual void add_for_draw(CullTraverser *trav, CullTraverserData &data)
Adds the node&#39;s contents to the CullResult we are building up during the cull traversal, so that it will be drawn at render time.
A special node, the sole purpose of which is to invoke a dispatch operation on the assigned compute s...
Definition: computeNode.h:30
virtual void fillin(DatagramIterator &scan, BamReader *manager)
This internal function is called by make_from_bam to read in all of the relevant data from the BamFil...
virtual void write_datagram(BamWriter *manager, Datagram &dg) const
Writes the contents of this object to the datagram for shipping out to a Bam file.
void register_factory(TypeHandle handle, CreateFunc *func)
Registers a new kind of thing the Factory will be able to create.
Definition: factory.I:90
void add_uint16(PN_uint16 value)
Adds an unsigned 16-bit integer to the datagram.
Definition: datagram.I:181
void set_draw_callback(CallbackObject *draw_callback)
Specifies a CallbackObject that will be responsible for drawing this object.
This is a base class for the GraphicsStateGuardian class, which is itself a base class for the variou...
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
Definition: bamReader.I:213
ComputeNode(const string &name)
Creates a ComputeNode with the given name.
Definition: computeNode.cxx:34
This is a special kind of GeometricBoundingVolume that fills all of space.
A class to retrieve the individual data elements previously stored in a Datagram. ...
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:43
This object performs a depth-first traversal of the scene graph, with optional view-frustum culling...
Definition: cullTraverser.h:48
virtual bool safe_to_combine() const
Returns true if it is generally safe to combine this particular kind of PandaNode with other kinds of...
Definition: computeNode.cxx:77
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.