Text archives Help
- From: bigler@sci.utah.edu
- To: manta@sci.utah.edu
- Subject: [MANTA] r465 - in trunk: Core/Util Engine/Control Engine/ImageTraversers Engine/PixelSamplers Interface
- Date: Wed, 3 Aug 2005 17:42:44 -0600 (MDT)
Author: bigler
Date: Wed Aug 3 17:42:43 2005
New Revision: 465
Modified:
trunk/Core/Util/Args.h
trunk/Engine/Control/RTRT_register.cc
trunk/Engine/ImageTraversers/CMakeLists.txt
trunk/Engine/ImageTraversers/DissolveImageTraverser.cc
trunk/Engine/ImageTraversers/DissolveImageTraverser.h
trunk/Engine/PixelSamplers/JitterSampler.cc
trunk/Interface/Fragment.h
trunk/Interface/RayPacket.h
Log:
Core/Util/Args.h
Added getArgs function that is templated on the type of argument.
Engine/Control/RTRT_register.cc
Added dissolve pixel sampler.
Engine/ImageTraversers/CMakeLists.txt
Added compilation of DissolveImageTraverser class.
Engine/ImageTraversers/DissolveImageTraverser.cc
Engine/ImageTraversers/DissolveImageTraverser.h
Fleshed out the class into something that seems to work. I will
need to perform additional tests to make sure that it is doing what
I want it to. For now with more than one processor it fills the
screen eventually (albeit with a weird delay).
Engine/PixelSamplers/JitterSampler.cc
Call setFlags while resetting the RayPacket. This is in the
itanium2 branch (don't know which version, though).
Interface/Fragment.h
Empty constructor needs to initialize size and flags to zero.
Fixed indentations and comment spacings.
Added addElement, resetSize, and resetAll functions.
setFlags now correctly returns void.
Interface/RayPacket.h
Added setFlags function.
Modified: trunk/Core/Util/Args.h
==============================================================================
--- trunk/Core/Util/Args.h (original)
+++ trunk/Core/Util/Args.h Wed Aug 3 17:42:43 2005
@@ -6,6 +6,7 @@
#include <sgi_stl_warnings_off.h>
#include <string>
#include <vector>
+#include <sstream>
#include <sgi_stl_warnings_on.h>
namespace Manta {
@@ -18,6 +19,30 @@
bool getPointArg(int& i, const vector<string>&, Point& p);
bool getVectorArg(int& i, const vector<string>&, Vector& p);
void parseSpec(const string& spec, string& name, vector<string>& args);
+
+ // Generic version that grabs an argument of type T.
+ template<typename T>
+ bool getArg(int& i, const vector<string>& args, T& result) {
+ // Check to make sure args[i] exists.
+ if(++i >= static_cast<int>(args.size())) {
+ i--;
+ return false;
+ }
+
+ istringstream in(args[i]);
+ T temp;
+ // Attempt to pull in the value
+ in >> temp;
+ if (!in.fail()) {
+ // Everything was OK, so assign it to the return parameter.
+ result = temp;
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+
// This will separate input into whitespace separated arguments. If
// you want a single argument to contain whitespace you must
Modified: trunk/Engine/Control/RTRT_register.cc
==============================================================================
--- trunk/Engine/Control/RTRT_register.cc (original)
+++ trunk/Engine/Control/RTRT_register.cc Wed Aug 3 17:42:43 2005
@@ -7,6 +7,7 @@
#include <Engine/ImageTraversers/TiledImageTraverser.h>
#include <Engine/ImageTraversers/FramelessImageTraverser.h>
#include <Engine/ImageTraversers/AFImageTraverser.h>
+#include <Engine/ImageTraversers/DissolveImageTraverser.h>
#include <Engine/LoadBalancers/CyclicLoadBalancer.h>
#include <Engine/LoadBalancers/SimpleLoadBalancer.h>
#include <Engine/LoadBalancers/WQLoadBalancer.h>
@@ -53,6 +54,7 @@
rtrt->registerComponent("tiled", &TiledImageTraverser::create);
rtrt->registerComponent("frameless", &FramelessImageTraverser::create);
rtrt->registerComponent("afr", &AFImageTraverser::create);
+ rtrt->registerComponent("dissolve", &DissolveImageTraverser::create);
// Register image types
rtrt->registerComponent("null", &NullImage::create);
Modified: trunk/Engine/ImageTraversers/CMakeLists.txt
==============================================================================
--- trunk/Engine/ImageTraversers/CMakeLists.txt (original)
+++ trunk/Engine/ImageTraversers/CMakeLists.txt Wed Aug 3 17:42:43 2005
@@ -3,6 +3,7 @@
ImageTraversers/NullImageTraverser.cc
ImageTraversers/TiledImageTraverser.cc
ImageTraversers/FramelessImageTraverser.cc
+ ImageTraversers/DissolveImageTraverser.cc
ImageTraversers/AFImageTraverser.cc
ImageTraversers/AFR/stats.cc
ImageTraversers/AFR/tiles.cc
Modified: trunk/Engine/ImageTraversers/DissolveImageTraverser.cc
==============================================================================
--- trunk/Engine/ImageTraversers/DissolveImageTraverser.cc (original)
+++ trunk/Engine/ImageTraversers/DissolveImageTraverser.cc Wed Aug 3
17:42:43 2005
@@ -1,3 +1,19 @@
+
+#include <Engine/ImageTraversers/DissolveImageTraverser.h>
+#include <Core/Exceptions/IllegalArgument.h>
+#include <Core/Exceptions/InternalError.h>
+#include <Core/Util/Args.h>
+#include <Interface/Context.h>
+#include <Interface/Fragment.h>
+#include <Interface/Image.h>
+#include <Interface/LoadBalancer.h>
+#include <Interface/PixelSampler.h>
+#include <Core/Thread/Mutex.h>
+#include <Core/Util/NotFinished.h>
+
+using namespace Manta;
+using SCIRun::InternalError;
+
// Use this mask to produce values from 1 to N (in the comments)
unsigned int MaskValues[] = {
/* 00 */ 0x00, // 0
@@ -35,3 +51,144 @@
/* 32 */ 0xA3000000 // 4,294,967,295
};
+ImageTraverser* DissolveImageTraverser::create(const vector<string>& args)
+{
+ return new DissolveImageTraverser(args);
+}
+
+DissolveImageTraverser::DissolveImageTraverser(const vector<string>& args)
+{
+ pixels_per_pass = 4096;
+ int argc = static_cast<int>(args.size());
+ for(int i = 0; i<argc;i++){
+ string arg = args[i];
+ if(arg == "-pixelsPerPass"){
+ if(!getArg<unsigned int>(i, args, pixels_per_pass))
+ throw IllegalArgument("DissolveImageTraverser -pixelsPerPass",
+ i, args);
+ if (pixels_per_pass < 1)
+ throw IllegalArgument("-pixelsPerPass must be greater than 0",
+ i, args);
+ } else {
+ throw IllegalArgument("DissolveImageTraverser", i, args);
+ }
+ }
+}
+
+DissolveImageTraverser::~DissolveImageTraverser()
+{
+}
+
+void DissolveImageTraverser::setupBegin(SetupContext& context, int
numChannels)
+{
+ per_thread_data.resize(context.numProcs);
+ for(size_t i = 0; i < per_thread_data.size(); i++)
+ per_thread_data[i].next_pixel.resize(numChannels);
+ channel_data.resize(numChannels);
+
+ // context.loadBalancer->setupBegin(context, numChannels);
+ context.pixelSampler->setupBegin(context, numChannels);
+}
+
+void DissolveImageTraverser::setupDisplayChannel(SetupContext& context)
+{
+ bool stereo;
+ int xres, yres;
+ context.getResolution(stereo, xres, yres);
+
+ // Compute the mask
+ unsigned int num_x_bits = numBinaryDigits(xres-1);
+ unsigned int num_y_bits = numBinaryDigits(yres-1);
+ unsigned int num_all_bits = num_x_bits + num_y_bits;
+ if (num_all_bits > 32)
+ throw InternalError("DissolveImageTraverser::setupDisplayChannel::number
of bits needed for random number exceeds 32", __FILE__, __LINE__);
+
+ ChannelContext& cdata = channel_data[context.channelIndex];
+ cdata.mask = MaskValues[num_all_bits];
+ cdata.num_y_bits = num_y_bits;
+ cdata.y_bit_mask = (1 << num_y_bits) - 1;
+
+ // Reset the starting pixel
+ unsigned int next_pixel = 1;
+ per_thread_data[0].next_pixel[context.channelIndex] = next_pixel;
+ for(size_t i = 1; i < per_thread_data.size(); i++) {
+ int x,y;
+ do {
+ computeNextSample(next_pixel, cdata.mask);
+ x = next_pixel >> cdata.num_y_bits;
+ y = next_pixel & cdata.y_bit_mask;
+ } while (x >= xres || y >= yres);
+ per_thread_data[i].next_pixel[context.channelIndex] = next_pixel;
+ }
+
+ // Single bufferd, please.
+ context.constrainPipelineDepth(1,1);
+
+ // context.loadBalancer->setupDisplayChannel(context, numAssignments);
+ context.pixelSampler->setupDisplayChannel(context);
+}
+
+void DissolveImageTraverser::setupFrame(const RenderContext& context)
+{
+ // context.loadBalancer->setupFrame(context);
+ context.pixelSampler->setupFrame(context);
+}
+
+void DissolveImageTraverser::renderImage(const RenderContext& context,
+ Image* image)
+{
+ bool stereo;
+ int xres, yres;
+ image->getResolution(stereo, xres, yres);
+
+ unsigned int next_pixel =
per_thread_data[context.proc].next_pixel[context.channelIndex];
+ ChannelContext& cdata = channel_data[context.channelIndex];
+
+ Fragment frag;
+ frag.setFlags(Fragment::ConstantEye);
+ unsigned int pixel = 0;
+ // Catch the first fragment
+ if (next_pixel == 1) {
+ frag.addElement(0,0,0);
+ pixel++;
+ }
+ int x, y;
+ while ( pixel < pixels_per_pass ) {
+ int x = next_pixel >> cdata.num_y_bits;
+ int y = next_pixel & cdata.y_bit_mask;
+ if (x < xres && y < yres) {
+ pixel++;
+ frag.addElement(x, y, 0);
+ if(stereo){
+ }
+ if (frag.getSize() == Fragment::MaxFragmentSize) {
+ context.pixelSampler->renderFragment(context, frag);
+ image->set(frag);
+ // Reset the Fragment
+ frag.resetSize();
+ }
+ }
+ // Generate the next pixel
+ for(int i = 0; i < context.numProcs;) {
+ computeNextSample(next_pixel, cdata.mask);
+ int x = next_pixel >> cdata.num_y_bits;
+ int y = next_pixel & cdata.y_bit_mask;
+ if (x < xres && y < yres) i++;
+ }
+ }
+ // Pick up strays
+ if (frag.getSize()) {
+ context.pixelSampler->renderFragment(context, frag);
+ image->set(frag);
+ }
+
+ per_thread_data[context.proc].next_pixel[context.channelIndex] =
next_pixel;
+
+
+
+ // This can potentially happen before the other procesors are finished
+ // rendering, but that is okay because it won't get displayed until
+ // everyone enters the barrier anyway
+ if(context.proc == 0)
+ image->setValid(true);
+}
Modified: trunk/Engine/ImageTraversers/DissolveImageTraverser.h
==============================================================================
--- trunk/Engine/ImageTraversers/DissolveImageTraverser.h (original)
+++ trunk/Engine/ImageTraversers/DissolveImageTraverser.h Wed Aug 3
17:42:43 2005
@@ -25,13 +25,43 @@
DissolveImageTraverser& operator=(const DissolveImageTraverser&);
struct ThreadContext {
- unsigned int current_x, current_y;
+ // next_pixel.size() == numChannels. We'll store both x and y
+ // in this single variable, where x uses the higher order bits
+ // and y uses the lower order.
+ vector<unsigned int> next_pixel;
};
- unsigned int mask;
- vector<ThreadContext> current_pixels;
+ vector<ThreadContext> per_thread_data;
+
+ struct ChannelContext {
+ unsigned int mask;
+ unsigned int num_y_bits;
+ unsigned int y_bit_mask;
+ };
+ // channel_masks.size() == numChannels
+ vector<ChannelContext> channel_data;
+
// This is how many pixels to render on a call to renderImage.
unsigned int pixels_per_pass;
+
+ inline void computeNextSample(unsigned int& val, unsigned int mask) {
+ if (val & 1)
+ val = (val >> 1) ^ mask;
+ else
+ val = val >> 1;
+ }
+
+ // Returns the number of binary digits needed to represent val.
+ unsigned int numBinaryDigits(unsigned int val) {
+ unsigned int num_digits = 0;
+ while (val) {
+ num_digits++;
+ val>>=1;
+ }
+ return num_digits;
+ }
+
+
};
}
Modified: trunk/Engine/PixelSamplers/JitterSampler.cc
==============================================================================
--- trunk/Engine/PixelSamplers/JitterSampler.cc (original)
+++ trunk/Engine/PixelSamplers/JitterSampler.cc Wed Aug 3 17:42:43 2005
@@ -207,6 +207,7 @@
sample_count = 0;
// Make sure we start with a fresh slate
rays.resetHit();
+ rays.setFlags(flags);
}
} // end sample filling loops
} // end fragment loop
Modified: trunk/Interface/Fragment.h
==============================================================================
--- trunk/Interface/Fragment.h (original)
+++ trunk/Interface/Fragment.h Wed Aug 3 17:42:43 2005
@@ -18,6 +18,7 @@
#include <Core/Color/Color.h>
#include <Core/Util/FancyAssert.h>
+#include <Core/Util/Assert.h>
#include <Core/Math/MT_RNG.h>
// TODO:
@@ -35,7 +36,7 @@
static const int ConsecutiveX = 0x01; // Implies a constant Y:
static const int ConstantEye = 0x02;
- Fragment() {} // empty constructor
+ Fragment(): flags(0), size(0) {} // empty constructor
// Creates a "Scan-line" fragment.
Fragment(int which_eye, int xstart, int xend, int y) {
ASSERTRANGE(xend-xstart, 0, MaxFragmentSize+1);
@@ -49,12 +50,19 @@
size = nx;
}
- ~Fragment() {
+ ~Fragment() {}
+
+ void addElement(int x, int y, int which_eye) {
+ ASSERT(size < MaxFragmentSize);
+ data[size].x = x;
+ data[size].y = y;
+ data[size].which_eye = which_eye;
+ size++;
}
-
// input: a rectangular tile and number of sample locations to generate
// output: creates randomly oriented sample locations in given range
- void createRandom(const int numElements, const int xstart, const int
ystart,
+ void createRandom(const int numElements,
+ const int xstart, const int ystart,
const int xend, const int yend, const int which_eye,
MT_RNG &myRandomNumber)
{
@@ -68,8 +76,8 @@
}
}
- // add a sample location to the fragment and return if fragment has more
space
- // left or not
+ // Add a sample location to the fragment and return if fragment
+ // has more space left or not.
bool addItem(const int x, const int y, const int which_eye, int index) {
data[index].x = x;
data[index].y = y;
@@ -80,15 +88,25 @@
int getFlags() const {
return flags;
}
- int setFlags(const int newflags) {
+ void setFlags(const int newflags) {
flags = newflags;
}
+
int getSize() const {
return size;
}
void setSize(const int newSize) {
size = newSize;
}
+
+ void resetSize() {
+ size = 0;
+ }
+ void resetAll() {
+ size = 0;
+ flags = 0;
+ }
+
void setColor(int which, const Color& color) {
data[which].color = color;
}
Modified: trunk/Interface/RayPacket.h
==============================================================================
--- trunk/Interface/RayPacket.h (original)
+++ trunk/Interface/RayPacket.h Wed Aug 3 17:42:43 2005
@@ -46,6 +46,9 @@
void setFlag(int flag) {
flags |= flag;
}
+ void setFlags(int new_flags) {
+ flags = new_flags;
+ }
void resetFlag(int flag) {
flags &= ~flag;
}
- [MANTA] r465 - in trunk: Core/Util Engine/Control Engine/ImageTraversers Engine/PixelSamplers Interface, bigler, 08/03/2005
Archive powered by MHonArc 2.6.16.