Text archives Help
- From: abe@sci.utah.edu
- To: manta@sci.utah.edu
- Subject: [MANTA] r741 - in branches/itanium2: Core/Util Engine/Control Engine/Display Engine/ImageTraversers Engine/ImageTraversers/AFR Interface Model/Cameras StandAlone fox scenes
- Date: Thu, 1 Dec 2005 01:30:46 -0700 (MST)
Author: abe
Date: Thu Dec 1 01:30:42 2005
New Revision: 741
Added:
branches/itanium2/Core/Util/ThreadStorageAllocator.cc
branches/itanium2/Core/Util/ThreadStorageAllocator.h
Removed:
branches/itanium2/Engine/ImageTraversers/AFImageTraverser.cc
branches/itanium2/Engine/ImageTraversers/AFImageTraverser.h
branches/itanium2/Engine/ImageTraversers/AFR/
Modified:
branches/itanium2/Engine/Control/RTRT.cc
branches/itanium2/Engine/Control/RTRT.h
branches/itanium2/Engine/Control/RTRT_register.cc
branches/itanium2/Engine/Display/GLXImageDisplay.cc
branches/itanium2/Engine/Display/GLXImageDisplay.h
branches/itanium2/Engine/Display/XHelper.cc
branches/itanium2/Engine/ImageTraversers/CMakeLists.txt
branches/itanium2/Engine/ImageTraversers/FramelessImageTraverser.cc
branches/itanium2/Engine/ImageTraversers/TiledImageTraverser.cc
branches/itanium2/Engine/ImageTraversers/TiledImageTraverser.h
branches/itanium2/Interface/Context.h
branches/itanium2/Interface/Fragment.h
branches/itanium2/Interface/RTRTInterface.h
branches/itanium2/Model/Cameras/StereoPinholeCamera.cc
branches/itanium2/Model/Cameras/StereoPinholeCamera.h
branches/itanium2/StandAlone/CMakeLists.txt
branches/itanium2/StandAlone/frust-test.cc
branches/itanium2/StandAlone/manta_tile_size.pl
branches/itanium2/StandAlone/mf_stream_test.cc
branches/itanium2/fox/FMantaStereo.cc
branches/itanium2/fox/FMantaStereo.h
branches/itanium2/fox/FMantaWindow.cc
branches/itanium2/fox/FMantaWindow.h
branches/itanium2/scenes/boeing777.cc
Log:
Added ability for components on the rendering stack to request thread local
storage which is allocated by each thread instead of by the setup thread.
A Core/Util/ThreadStorageAllocator.cc
A Core/Util/ThreadStorageAllocator.h
M scenes/boeing777.cc
M StandAlone/mf_stream_test.cc
M StandAlone/manta_tile_size.pl
M StandAlone/frust-test.cc
M StandAlone/CMakeLists.txt
Fixed exit behavior, added "Safe Exit" and "Fast Exit" menu options.
M fox/FMantaWindow.cc
M fox/FMantaWindow.h
M fox/FMantaStereo.cc
M fox/FMantaStereo.h
M Interface/Fragment.h
M Interface/Context.h
M Interface/RTRTInterface.h
Hopefully fixed the stereo camera. Note that you have to use the -stereo
command line option AND specify a "stereo" camera (and have stereo hardware).
M Model/Cameras/StereoPinholeCamera.h
M Model/Cameras/StereoPinholeCamera.cc
M Engine/Control/RTRT.cc
M Engine/Control/RTRT.h
M Engine/Control/RTRT_register.cc
M Engine/ImageTraversers/TiledImageTraverser.cc
M Engine/ImageTraversers/TiledImageTraverser.h
M Engine/ImageTraversers/FramelessImageTraverser.cc
Removed AFR code since it has its own branch now
D Engine/ImageTraversers/AFR
D Engine/ImageTraversers/AFImageTraverser.cc
D Engine/ImageTraversers/AFImageTraverser.h
M Engine/ImageTraversers/CMakeLists.txt
Added fps output to glx image display
M Engine/Display/XHelper.cc
M Engine/Display/GLXImageDisplay.cc
M Engine/Display/GLXImageDisplay.h
Added: branches/itanium2/Core/Util/ThreadStorageAllocator.cc
==============================================================================
--- (empty file)
+++ branches/itanium2/Core/Util/ThreadStorageAllocator.cc Thu Dec 1
01:30:42 2005
@@ -0,0 +1,75 @@
+/*
+ For more information, please see:
http://software.sci.utah.edu
+
+ The MIT License
+
+ Copyright (c) 2005
+ Scientific Computing and Imaging Institute
+
+ License for the specific language governing rights and limitations under
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the "Software"),
+ to deal in the Software without restriction, including without limitation
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ and/or sell copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
+*/
+
+#include <Core/Util/ThreadStorageAllocator.h>
+
+#include <malloc.h>
+
+using namespace Manta;
+
+ThreadStorageAllocator::ThreadStorageAllocator( int num_procs_ ) :
+ requested( 0 ),
+ num_procs( num_procs_ )
+{
+ // Pad the array up to a cache line.
+ size_t bytes = (num_procs_*sizeof(char *));
+ bytes = (bytes % 128) ? ((bytes/128)+1)*128 : bytes;
+
+ // Allocate array of pointers.
+ storage = (char **)memalign( 128, bytes );
+
+ // Initialize all of the pointers to zero.
+ for (int i=0;i<num_procs;++i) {
+ storage[i] = 0;
+ }
+};
+
+ThreadStorageAllocator::~ThreadStorageAllocator() {
+
+ // Free the local memory for each thread.
+ for (int i=0;i<num_procs;++i) {
+ if (storage[i])
+ free( storage[i] );
+ }
+ free( storage );
+}
+
+// Called by each thread to allocate its memory. Will reallocate if
necessary.
+void ThreadStorageAllocator::allocateStorage( int proc ) {
+
+ // Delete the storage if it exists.
+ if (storage[proc])
+ free( storage[proc] );
+
+ // Allocate aligned storage.
+ storage[proc] = (char *)memalign( 128, requested );
+
+ if (storage[proc] == 0)
+ throw InternalError( "Could not allocate thread local memory", __FILE__,
__LINE__ );
+}
+
Added: branches/itanium2/Core/Util/ThreadStorageAllocator.h
==============================================================================
--- (empty file)
+++ branches/itanium2/Core/Util/ThreadStorageAllocator.h Thu Dec 1
01:30:42 2005
@@ -0,0 +1,117 @@
+/*
+ For more information, please see:
http://software.sci.utah.edu
+
+ The MIT License
+
+ Copyright (c) 2005
+ Scientific Computing and Imaging Institute
+
+ License for the specific language governing rights and limitations under
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the "Software"),
+ to deal in the Software without restriction, including without limitation
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ and/or sell copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
+*/
+
+// Abe Stephens
+
+#include <SCIRun/Core/Exceptions/InternalError.h>
+
+#include <vector>
+
+namespace Manta {
+
+ using SCIRun::InternalError;
+ using std::vector;
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Thread local storage allocation.
+ // Storage will be allocated after setupDisplayChannel but before the next
+ // call to setupFrame.
+ class ThreadStorageAllocator {
+ private:
+ // Actual storage.
+ char ** storage;
+ int num_procs;
+
+ // Requested storage.
+ size_t requested;
+
+ public:
+
+
///////////////////////////////////////////////////////////////////////////
+ // Token is returned by an allocation request.
+ class Token {
+ friend class ThreadStorageAllocator;
+ private:
+ size_t offset;
+
+ protected:
+ Token( size_t offset_ ) : offset( offset_ ) { };
+ };
+
+
///////////////////////////////////////////////////////////////////////////
+ // Accessor provides access to the memory allocated for a specific
request.
+ // Each request produces a token, which may be used to obtain an
Accessor after
+ // the memory is allocated.
+ class Accessor {
+ friend class ThreadStorageAllocator;
+ private:
+ char *storage;
+ public:
+ protected:
+ Accessor( void *storage_ ) :
+ storage( static_cast<char *>( storage_ ) ) { };
+
+ public:
+ Accessor() { };
+ };
+
+
///////////////////////////////////////////////////////////////////////////
+ // Constructor.
+ ThreadStorageAllocator( int num_procs_ );
+ ThreadStorageAllocator( );
+ ~ThreadStorageAllocator();
+
+ Token requestStorage( size_t size, size_t aligned ) {
+
+ // Determine how many bytes needed.
+ size_t bytes = size;
+
+ // Find the next aligned offset.
+ size_t offset = requested +
+ ((requested % aligned) ? ((requested/aligned)+1)*aligned : 0);
+
+ requested = offset + bytes;
+
+ return Token( offset );
+ }
+
+ // Obtain an accessor to the storage. This is only possible after it has
been allocated.
+ template< typename StorageType >
+ StorageType getStorage( int proc, const Token &token ) {
+ if (storage[proc]) {
+ return static_cast<StorageType>(storage[proc]);
+ }
+ throw InternalError( "Attempt to access unallocated thread local
storage.", __FILE__, __LINE__ );
+ }
+
+ // Called by each thread to allocate its memory. Will reallocate if
necessary.
+ void allocateStorage( int proc );
+
+ };
+};
+
Modified: branches/itanium2/Engine/Control/RTRT.cc
==============================================================================
--- branches/itanium2/Engine/Control/RTRT.cc (original)
+++ branches/itanium2/Engine/Control/RTRT.cc Thu Dec 1 01:30:42 2005
@@ -61,13 +61,14 @@
}
RTRT::RTRT()
-: runningLock("RTRT running mutex"),
-callbackLock("RTRT callback r/w lock"),
-barrier1("RTRT frame barrier #1"),
-barrier2("RTRT frame barrier #2"),
-barrier3("RTRT frame barrier #3"),
-transaction_lock("RTRT transaction lock"),
-ids("RTRT id counter", 1)
+ : runningLock("RTRT running mutex"),
+ callbackLock("RTRT callback r/w lock"),
+ barrier1("RTRT frame barrier #1"),
+ barrier2("RTRT frame barrier #2"),
+ barrier3("RTRT frame barrier #3"),
+ transaction_lock("RTRT transaction lock"),
+ ids("RTRT id counter", 1),
+ thread_storage( 0 )
{
workersWanted=0;
workersRendering=0;
@@ -92,7 +93,7 @@
Channel* channel = *iter;
delete channel->display;
for(vector<Image*>::iterator iter = channel->images.begin();
- iter != channel->images.end(); iter++)
+ iter != channel->images.end(); iter++)
delete *iter;
}
delete currentImageTraverser;
@@ -103,7 +104,7 @@
void RTRT::changeNumWorkers(int newNumWorkers)
{
- if(newNumWorkers <= 0)
+ if(newNumWorkers < 0)
throw IllegalValue<int>("RTRT::changeNumWorkers, number of workers
should be > 0", newNumWorkers);
workersWanted=newNumWorkers;
@@ -121,19 +122,19 @@
// What about adding callbacks during anim cycle?
#endif
callbackLock.writeLock();
-// #if NOTFINISHED
+ // #if NOTFINISHED
if(whence == RTRTInterface::Relative) {
frame += animFrameState.frameNumber;
}
-// #endif
+ // #endif
oneShots.insert(OneShotMapType::value_type(frame, callback));
callbackLock.writeUnlock();
}
void RTRT::addParallelOneShotCallback(Whence whence, long frame,
- CallbackBase_2Data<int, int>* callback)
+ CallbackBase_2Data<int, int>* callback)
{
callbackLock.writeLock();
@@ -165,6 +166,13 @@
callbackLock.writeUnlock();
}
+void RTRT::registerTerminationCallback( CallbackBase_1Data< RTRTInterface *>
*cb ) {
+ callbackLock.writeLock();
+ terminationCallbacks.push_back(cb);
+ callbackLock.writeUnlock();
+}
+
+
void RTRT::setTimeMode(TimeMode /*tm*/, double /*rate*/)
{
NOT_FINISHED("RTRT::setTimeMode");
@@ -192,10 +200,10 @@
check for existence of other components;
#endif
- if(workersWanted <= 0){
- runningLock.unlock();
- throw IllegalValue<int>("workersWanted should be
positive", workersWanted);
- }
+ if(workersWanted <= 0){
+ runningLock.unlock();
+ throw IllegalValue<int>("workersWanted should be positive",
workersWanted);
+ }
if(workersRendering != 0){
runningLock.unlock();
@@ -212,14 +220,17 @@
ostringstream name;
name << "RTRT Worker " << i;
Thread* t = new Thread(new Worker(this, i, false), name.str().c_str(),
-
0, Thread::NotActivated);
+ 0, Thread::NotActivated);
t->setStackSize(RENDER_THREAD_STACKSIZE);
t->activate(false);
workers[i] = t;
}
}
+
+ // Block until finished is set while running in bin/manta
if(blockUntilFinished)
internalRenderLoop(0, false);
+
}
void RTRT::blockUntilFinished()
@@ -242,14 +253,14 @@
if(proc == 0){
animFrameState.frameNumber++;
switch(timeMode){
- case RealTime:
- animFrameState.frameTime =
Time::currentSeconds() * timeScale;
- break;
- case FixedRate:
- animFrameState.frameTime =
static_cast<double>(animFrameState.frameNumber) / frameRate;
- break;
- case Static:
- break;
+ case RealTime:
+ animFrameState.frameTime = Time::currentSeconds() * timeScale;
+ break;
+ case FixedRate:
+ animFrameState.frameTime =
static_cast<double>(animFrameState.frameNumber) / frameRate;
+ break;
+ case Static:
+ break;
}
// Update the number of workers to be used for the animation and
@@ -276,13 +287,13 @@
if(!firstFrame){
for(int index = 0;index < static_cast<int>(channels.size());index++){
- Channel* channel = channels[index];
- RenderContext myContext(this, index, proc,
workersAnimAndImage,
-
&animFrameState,
-
currentLoadBalancer,
currentPixelSampler,
-
currentRenderer,
currentShadowAlgorithm,
-
channel->camera, scene);
- currentImageTraverser->setupFrame(myContext);
+ Channel* channel = channels[index];
+ RenderContext myContext(this, index, proc, workersAnimAndImage,
+ &animFrameState,
+ currentLoadBalancer, currentPixelSampler,
+ currentRenderer, currentShadowAlgorithm,
+ channel->camera, scene, thread_storage );
+ currentImageTraverser->setupFrame(myContext);
}
}
//callbackLock.readUnlock();
@@ -297,29 +308,29 @@
// in case it changes
int newWorkers = workersWanted;
if(newWorkers > workersRendering){
- // We must start new threads, if the number
increased. Mark
- // these threads as "latecomers", which will
skip to the rendering
- // section of this loop for the first frame
- workersChanged = true;
- workers.resize(newWorkers);
- int oldworkers = workersRendering;
- workersRendering = workersWanted;
- for(int i=oldworkers;i<newWorkers;i++){
- ostringstream name;
- name << "RTRT Worker " << i;
- workers[i] = new Thread(new
Worker(this, i, true), name.str().c_str(),
-
0,
Thread::NotActivated);
-
workers[i]->setStackSize(RENDER_THREAD_STACKSIZE);
- workers[i]->activate(false);
- }
+ // We must start new threads, if the number increased. Mark
+ // these threads as "latecomers", which will skip to the rendering
+ // section of this loop for the first frame
+ workersChanged = true;
+ workers.resize(newWorkers);
+ int oldworkers = workersRendering;
+ workersRendering = workersWanted;
+ for(int i=oldworkers;i<newWorkers;i++){
+ ostringstream name;
+ name << "RTRT Worker " << i;
+ workers[i] = new Thread(new Worker(this, i, true),
name.str().c_str(),
+ 0, Thread::NotActivated);
+ workers[i]->setStackSize(RENDER_THREAD_STACKSIZE);
+ workers[i]->activate(false);
+ }
} else if(newWorkers < workersRendering) {
- workersChanged = true;
- workersRendering = workersWanted;
+ workersChanged = true;
+ workersRendering = workersWanted;
} else {
- // Don't set it to false if it is already
false - avoids
- // flushing the other caches
- if(workersChanged)
- workersChanged = false;
+ // Don't set it to false if it is already false - avoids
+ // flushing the other caches
+ if(workersChanged)
+ workersChanged = false;
}
}
@@ -333,17 +344,17 @@
barrier2.wait(numProcs);
changed=false;
for(int i=0;i<numProcs;i++){
- if(changedFlags[i].changed){
- changed=true;
- break;
- }
+ if(changedFlags[i].changed){
+ changed=true;
+ break;
+ }
}
if(changed != lastChanged || firstFrame){
if(proc == 0)
doIdleModeCallbacks(changed, firstFrame, pipelineNeedsSetup,
proc, numProcs);
- barrier2.wait(numProcs);
+ barrier2.wait(numProcs);
lastChanged = changed;
}
if(firstFrame)
@@ -351,95 +362,116 @@
// P0 process deletions
if(proc == 0){
- //callbackLock.readLock();
- processDeletions();
- //callbackLock.readUnlock();
+ //callbackLock.readLock();
+ processDeletions();
+ //callbackLock.readUnlock();
}
if(pipelineNeedsSetup){
- // Negotiate the image pipeline for each
channel
- if(proc == 0){
- setupPipelines(numProcs);
-
resizeImages(renderFrameState.frameNumber);
- }
- for(int index = 0;index <
static_cast<int>(channels.size());index++){
- Channel* channel = channels[index];
- RenderContext myContext(this, index,
proc, workersAnimAndImage,
-
&animFrameState,
-
currentLoadBalancer, currentPixelSampler,
-
currentRenderer,
currentShadowAlgorithm,
-
channel->camera,
scene);
-
currentImageTraverser->setupFrame(myContext);
- }
- barrier3.wait(numProcs);
- pipelineNeedsSetup = false;
+
+ // Negotiate the image pipeline for each channel
+ if(proc == 0){
+ setupPipelines(numProcs);
+ resizeImages(renderFrameState.frameNumber);
+ }
+
+ // Wait for processor zero to setup the image pipeline
+ barrier3.wait(numProcs);
+
+ // Allocate thread local storage for each thread.
+ thread_storage->allocateStorage( proc );
+
+ for(int index = 0;index < static_cast<int>(channels.size());index++){
+ Channel* channel = channels[index];
+ RenderContext myContext(this, index, proc, workersAnimAndImage,
+ &animFrameState,
+ currentLoadBalancer,
+ currentPixelSampler,
+ currentRenderer,
+ currentShadowAlgorithm,
+ channel->camera,
+ scene,
+ thread_storage );
+
+ currentImageTraverser->setupFrame(myContext);
+ }
+ barrier3.wait(numProcs);
+ pipelineNeedsSetup = false;
}
// Image display, if image is valid
for(ChannelListType::iterator iter = channels.begin();
- iter != channels.end(); iter++){
- Channel* channel = *iter;
- long displayFrame =
(renderFrameState.frameNumber-1)%channel->pipelineDepth;
- Image* image = channel->images[displayFrame];
- if(image && image->isValid()){
- DisplayContext myContext(proc,
workersAnimAndImage);
-
channel->display->displayImage(myContext, image);
- }
+ iter != channels.end(); iter++){
+ Channel* channel = *iter;
+ long displayFrame =
(renderFrameState.frameNumber-1)%channel->pipelineDepth;
+ Image* image = channel->images[displayFrame];
+ if(image && image->isValid()){
+ DisplayContext myContext(proc, workersAnimAndImage);
+ channel->display->displayImage(myContext, image);
+ }
}
// Possibly change # of workers
if(proc == 0 && workersRendering < numProcs){
- for(int i = workersRendering; i<numProcs;
i++){
- // Clean up after worker. Don't
attempt to join with self
- if(i != 0)
- workers[i]->join();
- }
- workers.resize(workersRendering ==
0?1:workersRendering);
+ for(int i = workersRendering; i<numProcs; i++){
+ // Clean up after worker. Don't attempt to join with self
+ if(i != 0)
+ workers[i]->join();
+ }
+ workers.resize(workersRendering == 0?1:workersRendering);
+ }
+
+ if(proc >= workersRendering) {
+
+ // If proc 0 is exiting invoke the termination callbacks.
+ if (proc == 0) {
+ doTerminationCallbacks();
+ }
+
+ break;
}
- if(proc >= workersRendering)
- break;
}
-skipToRendering:
- // Pre-render callbacks
- //callbackLock.readLock();
- doParallelPreRenderCallbacks(proc, workersRendering);
+ skipToRendering:
+ // Pre-render callbacks
+ //callbackLock.readLock();
+ doParallelPreRenderCallbacks(proc, workersRendering);
doSerialPreRenderCallbacks(proc, workersRendering);
//callbackLock.readUnlock();
if(workersChanged){
barrier3.wait(workersRendering);
if(proc == 0)
- changedFlags.resize(workersRendering);
+ changedFlags.resize(workersRendering);
}
-#if NOTFINISHED
+ // #if NOTFINISHED
//if(!idle){
-#endif
+ // #endif
{
for(int index = 0;index < static_cast<int>(channels.size());index++){
- Channel* channel = channels[index];
- long renderFrame =
renderFrameState.frameNumber%channel->pipelineDepth;
- Image* image = channel->images[renderFrame];
- RenderContext myContext(this, index, proc,
workersRendering, &renderFrameState,
-
currentLoadBalancer,
currentPixelSampler,
-
currentRenderer,
currentShadowAlgorithm,
-
channel->camera, scene);
-
currentImageTraverser->renderImage(myContext, image);
+ Channel* channel = channels[index];
+ long renderFrame =
renderFrameState.frameNumber%channel->pipelineDepth;
+ Image* image = channel->images[renderFrame];
+ RenderContext myContext(this, index, proc, workersRendering,
&renderFrameState,
+ currentLoadBalancer, currentPixelSampler,
+ currentRenderer, currentShadowAlgorithm,
+ channel->camera, scene, thread_storage );
+ currentImageTraverser->renderImage(myContext, image);
}
}
-#if NOTFINISHED
- how to set rendering complete flag?;
- } else {
- //callbackLock.readLock();
- idle callbacks;
- //callbackLock.readUnlock();
- }
-#endif
+ // #if NOTFINISHED
+ // how to set rendering complete flag?;
+ // } else {
+ //callbackLock.readLock();
+ // idle callbacks;
+ //callbackLock.readUnlock();
+ // }
+ //#endif
}
}
void RTRT::doParallelAnimationCallbacks(bool& changed, int proc, int
numProcs) {
-
+
// Parallel one shot callbacks.
ParallelOneShotMapType::iterator iter = parallelOneShots.begin();
while(iter != parallelOneShots.end() && iter->first <
animFrameState.frameNumber){
@@ -478,25 +510,37 @@
(*iter)->call(proc, numProcs, changed);
}
+void RTRT::doTerminationCallbacks() {
+
+ // All threads have terminated.
+ TCallbackMapType::iterator iter = terminationCallbacks.begin();
+ while (iter != terminationCallbacks.end()) {
+
+ // Invoke the callback and pass in the RTRTInterface.
+ (*iter)->call( this );
+ ++iter;
+ }
+}
+
void RTRT::postTransactions(bool& changed)
{
if(transactions.size() > 0){
transaction_lock.lock();
changed = true;
for(TransactionListType::iterator iter = transactions.begin();
- iter != transactions.end(); iter++){
+ iter != transactions.end(); iter++){
TransactionBase* transaction = *iter;
if(verbose_transactions){
- cerr << "Apply transaction: " <<
transaction->getName() << " : ";
- transaction->printValue(cerr);
- cerr << " : ";
- transaction->printOp(cerr);
- cerr << " : ";
+ cerr << "Apply transaction: " << transaction->getName() << " : ";
+ transaction->printValue(cerr);
+ cerr << " : ";
+ transaction->printOp(cerr);
+ cerr << " : ";
}
transaction->apply();
if(verbose_transactions){
- transaction->printValue(cerr);
- cerr << '\n';
+ transaction->printValue(cerr);
+ cerr << '\n';
}
delete transaction;
}
@@ -560,16 +604,16 @@
string name;
vector<string> args;
- // Parse the arg string.
+ // Parse the arg string.
parseSpec(spec, name, args);
- // Search for an image display with the name.
+ // Search for an image display with the name.
ImageDisplayMapType::iterator iter = imageDisplays.find(name);
if(iter == imageDisplays.end())
return 0;
- // Create the channel with the image display.
- return createChannel( (*iter->second)(args), camera, stereo, xres,
yres );
+ // Create the channel with the image display.
+ return createChannel( (*iter->second)(args), camera, stereo, xres, yres );
}
int RTRT::createChannel(ImageDisplay *image_display, Camera* camera, bool
stereo, int xres, int yres)
@@ -588,14 +632,14 @@
channel->images.resize(channel->pipelineDepth);
channel->camera = camera;
- // Setup images for pipeline.
+ // Setup images for pipeline.
for(int i=0;i<channel->pipelineDepth;i++)
channel->images[i] = 0;
- pipelineNeedsSetup = true;
+ pipelineNeedsSetup = true;
- // Add the channel to the renderer.
- channels.push_back(channel);
+ // Add the channel to the renderer.
+ channels.push_back(channel);
return channel->id;
}
@@ -623,7 +667,7 @@
void RTRT::setCamera(int channel, Camera *camera ) {
- channels[channel]->camera = camera;
+ channels[channel]->camera = camera;
}
void RTRT::getResolution(int channel, bool& stereo, int& xres, int& yres)
@@ -644,53 +688,61 @@
void RTRT::setupPipelines(int numProcs)
{
- // Total number of channels.
+ // Total number of channels.
int numChannels = static_cast<int>(channels.size());
- // Create a setup context.
- SetupContext globalcontext(this, numChannels, 0, numProcs,
+ // Create a setup context.
+ SetupContext globalcontext(this, numChannels, 0, numProcs,
currentLoadBalancer, currentPixelSampler,
currentRenderer);
- // Setup the image traverser.
+ // Setup the image traverser.
currentImageTraverser->setupBegin(globalcontext, numChannels);
- // Proceess setup callbacks.
+ // Proceess setup callbacks.
for(vector<SetupCallback*>::iterator iter = setupCallbacks.begin(); iter
!= setupCallbacks.end(); iter++)
- (*iter)->setupBegin(globalcontext, numChannels);
+ (*iter)->setupBegin(globalcontext, numChannels);
- // Setup each channel.
+ // Allocate/resize per thread local storage.
+ if (thread_storage != 0)
+ delete thread_storage;
+ thread_storage = new ThreadStorageAllocator( numProcs );
+
+ // Setup each channel.
for(int index = 0;index < static_cast<int>(channels.size());index++){
Channel* channel = channels[index];
SetupContext context(this, index, numChannels, 0, numProcs,
channel->stereo, channel->xres, channel->yres,
-
currentLoadBalancer, currentPixelSampler,
- currentRenderer);
+ currentLoadBalancer,
+ currentPixelSampler,
+ currentRenderer,
+ thread_storage );
- // Setup the channel iteratively, until context.isChanged()
is false.
+ // Setup the channel iteratively, until context.isChanged() is false.
int iteration = 100;
+
do {
context.setChanged(false);
context.clearMasterWindow();
- // Call setup callbacks.
+ // Call setup callbacks.
for(vector<SetupCallback*>::iterator iter = setupCallbacks.begin();
iter != setupCallbacks.end(); iter++)
- (*iter)->setupDisplayChannel(context);
+ (*iter)->setupDisplayChannel(context);
- // Setup the image display.
+ // Setup the image display.
channel->display->setupDisplayChannel(context);
- // Setup the image traverser.
+ // Setup the image traverser.
currentImageTraverser->setupDisplayChannel(context);
} while(context.isChanged() && --iteration > 0);
- // Check to for errors.
+ // Check to for errors.
if(!iteration)
throw InternalError("Pipeline/resolution negotiation failed",
__FILE__, __LINE__ );
context.getResolution(channel->stereo, channel->xres, channel->yres);
- if(channel->xres <= 0)
+ if(channel->xres <= 0)
throw IllegalValue<int>("Resolution should be positive",
channel->xres);
if(channel->yres <= 0)
throw IllegalValue<int>("Resolution should be positive",
channel->yres);
@@ -701,19 +753,19 @@
if(depth == 1 && context.getMaxDepth() > 1)
depth = 2; // Prefer double-buffering
- //cerr << "RTRT::setupPipelines:: depth = "<< depth << "\n";
+ //cerr << "RTRT::setupPipelines:: depth = "<< depth << "\n";
- // Set the pipeline depth.
- channel->pipelineDepth = depth;
+ // Set the pipeline depth.
+ channel->pipelineDepth = depth;
unsigned long osize = channel->images.size();
for(unsigned long i=depth;i<osize;i++)
delete channel->images[i];
- // Zero pointers to images.
+ // Zero pointers to images.
for(unsigned long i=osize;i<static_cast<unsigned long>(depth);i++)
channel->images[i]=0;
- // Specify the number of frames needed for the entire
pipeline.
+ // Specify the number of frames needed for the entire pipeline.
channel->images.resize(depth);
}
}
@@ -734,10 +786,10 @@
if(!channel->images[which] || channel->stereo != stereo
|| channel->xres != xres || channel->yres != yres){
if(channel->images[which])
- delete channel->images[which];
+ delete channel->images[which];
ImageCreator creator = channel->imageCreator;
if(!creator)
- creator = currentImageCreator;
+ creator = currentImageCreator;
channel->images[which] = (creator)(currentImageCreatorArgs,
channel->stereo,
channel->xres, channel->yres);
@@ -842,7 +894,7 @@
}
void RTRT::setPixelSampler( PixelSampler *sampler_ ) {
- currentPixelSampler = sampler_;
+ currentPixelSampler = sampler_;
}
bool RTRT::selectPixelSampler(const string& spec)
@@ -854,7 +906,7 @@
if(iter == pixelSamplers.end())
return false;
currentPixelSampler = (*iter->second)(args);
- pipelineNeedsSetup = true;
+ pipelineNeedsSetup = true;
return true;
}
@@ -1003,7 +1055,7 @@
Scene *RTRT::getScene() {
- return scene;
+ return scene;
}
bool RTRT::readScene(const string& spec)
@@ -1084,7 +1136,7 @@
}
Scene* RTRT::readMOScene(const string& name, const vector<string>& args,
-
bool printErrors)
+ bool printErrors)
{
vector<string> dirs = split_string(scenePath, ':');
for(vector<string>::iterator dir = dirs.begin(); dir != dirs.end(); dir++){
@@ -1092,22 +1144,22 @@
struct stat statbuf;
if(stat(fullname.c_str(), &statbuf) != 0){
if(printErrors){
- cerr << "Error reading " << fullname << ": "
<< strerror(errno) << '\n';
+ cerr << "Error reading " << fullname << ": " << strerror(errno) <<
'\n';
}
continue;
}
void* handle=dlopen(fullname.c_str(), RTLD_NOW);
if(!handle){
if(printErrors){
- cerr << "Error opening scene: " << fullname
<< '\n';
- cerr << dlerror() << '\n';
+ cerr << "Error opening scene: " << fullname << '\n';
+ cerr << dlerror() << '\n';
}
continue;
}
void* scene_fn=dlsym(handle, "make_scene");
if(!scene_fn){
if(printErrors){
- cerr << "Scene file found, but make_scene()
function not found\n";
+ cerr << "Scene file found, but make_scene() function not found\n";
}
// If we get here, we fail so that we don't keep searching the path
// for another scene
@@ -1120,7 +1172,7 @@
Scene* scene=(*make_scene)(context, args);
if(!scene){
if(printErrors)
- cerr << "scene " << name << " did not
produce a scene\n";
+ cerr << "scene " << name << " did not produce a scene\n";
return 0;
}
return scene;
@@ -1193,37 +1245,37 @@
void RTRT::shootOneRay( Color &result_color, RayPacket &result_rays, Real
image_x, Real image_y, int channel_index ) {
- // Only shoot one ray.
- result_rays.resize( 1 );
+ // Only shoot one ray.
+ result_rays.resize( 1 );
- // Set the image space coordinates of the pixel.
- result_rays.setPixel(0, 0, image_x, image_y, &result_color );
- result_rays.setFlag ( RayPacket::HaveImageCoordinates );
+ // Set the image space coordinates of the pixel.
+ result_rays.setPixel(0, 0, image_x, image_y, &result_color );
+ result_rays.setFlag ( RayPacket::HaveImageCoordinates );
- // Get a pointer to the channel.
- Channel *channel = channels[ channel_index ];
+ // Get a pointer to the channel.
+ Channel *channel = channels[ channel_index ];
- // Create a render context.
- RenderContext render_context(this, channel_index, workersRendering,
workersRendering+1, 0,
-
currentLoadBalancer, currentPixelSampler,
-
currentRenderer,
currentShadowAlgorithm,
-
channel->camera, scene );
+ // Create a render context.
+ RenderContext render_context(this, channel_index, workersRendering, 0, 0,
+ currentLoadBalancer, currentPixelSampler,
+ currentRenderer, currentShadowAlgorithm,
+ channel->camera, scene, thread_storage );
- // Send this to the renderer.
- currentRenderer->traceEyeRays( render_context, result_rays );
+ // Send this to the renderer.
+ currentRenderer->traceEyeRays( render_context, result_rays );
- // Check to see if the ray hit anything.
- if (result_rays.hitInfo(0).wasHit()) {
+ // Check to see if the ray hit anything.
+ if (result_rays.hitInfo(0).wasHit()) {
- // Compute hit positions.
- result_rays.computeHitPositions();
+ // Compute hit positions.
+ result_rays.computeHitPositions();
- // Compute the normal.
- result_rays.computeNormals( render_context );
+ // Compute the normal.
+ result_rays.computeNormals( render_context );
- // Shade.
- result_rays.hitInfo(0).hitMaterial()->shade( render_context,
result_rays );
- }
+ // Shade.
+ result_rays.hitInfo(0).hitMaterial()->shade( render_context, result_rays
);
+ }
}
Modified: branches/itanium2/Engine/Control/RTRT.h
==============================================================================
--- branches/itanium2/Engine/Control/RTRT.h (original)
+++ branches/itanium2/Engine/Control/RTRT.h Thu Dec 1 01:30:42 2005
@@ -10,6 +10,7 @@
#include <Core/Thread/CrowdMonitor.h>
#include <Core/Thread/Mutex.h>
#include <Core/Thread/Semaphore.h>
+#include <Core/Util/ThreadStorageAllocator.h>
#include <map>
#include <set>
#include <vector>
@@ -111,6 +112,7 @@
virtual void registerSetupCallback(SetupCallback*);
virtual void registerSerialAnimationCallback(CallbackBase_3Data<int,
int, bool&>*);
virtual void registerParallelAnimationCallback(CallbackBase_3Data<int,
int, bool&>*);
+ virtual void registerTerminationCallback( CallbackBase_1Data<
RTRTInterface *> *);
// Control of time/animation
virtual void setTimeMode(TimeMode tm, double rate);
@@ -164,7 +166,8 @@
void doIdleModeCallbacks(bool changed, bool firstFrame,
bool& pipelineNeedsSetup,
int proc, int numProcs);
-
+ void doTerminationCallbacks();
+
void resizeImages(long frameNumber);
void setupPipelines(int numProcs);
TValue<int> workersWanted;
@@ -202,6 +205,10 @@
ACallbackMapType serialAnimationCallbacks;
vector<SetupCallback*> setupCallbacks;
+ typedef vector<CallbackBase_1Data<RTRTInterface *>*> TCallbackMapType;
+ TCallbackMapType terminationCallbacks;
+
+
// Transactions
typedef vector<TransactionBase*> TransactionListType;
TransactionListType transactions;
@@ -280,6 +287,9 @@
typedef vector<Channel*> ChannelListType;
ChannelListType channels;
+ // Thread local storage allocator.
+ ThreadStorageAllocator *thread_storage;
+
Scene* scene;
string scenePath;
Modified: branches/itanium2/Engine/Control/RTRT_register.cc
==============================================================================
--- branches/itanium2/Engine/Control/RTRT_register.cc (original)
+++ branches/itanium2/Engine/Control/RTRT_register.cc Thu Dec 1 01:30:42
2005
@@ -6,8 +6,7 @@
#include <Engine/IdleModes/ZoomIdleMode.h>
#include <Engine/ImageTraversers/NullImageTraverser.h>
#include <Engine/ImageTraversers/TiledImageTraverser.h>
-#include <Engine/ImageTraversers/FramelessImageTraverser.h>
-#include <Engine/ImageTraversers/AFImageTraverser.h>
+// #include <Engine/ImageTraversers/FramelessImageTraverser.h>
#include <Engine/ImageTraversers/DissolveImageTraverser.h>
#include <Engine/ImageTraversers/DissolveTiledImageTraverser.h>
#include <Engine/LoadBalancers/CyclicLoadBalancer.h>
@@ -60,8 +59,8 @@
// Register image traversers
rtrt->registerComponent("null", &NullImageTraverser::create);
rtrt->registerComponent("tiled", &TiledImageTraverser::create);
- rtrt->registerComponent("frameless", &FramelessImageTraverser::create);
- rtrt->registerComponent("afr", &AFImageTraverser::create);
+ // rtrt->registerComponent("frameless",
&FramelessImageTraverser::create);
+ // rtrt->registerComponent("afr", &AFImageTraverser::create);
rtrt->registerComponent("dissolve", &DissolveImageTraverser::create);
rtrt->registerComponent("dissolvetiled",
&DissolveTiledImageTraverser::create);
Modified: branches/itanium2/Engine/Display/GLXImageDisplay.cc
==============================================================================
--- branches/itanium2/Engine/Display/GLXImageDisplay.cc (original)
+++ branches/itanium2/Engine/Display/GLXImageDisplay.cc Thu Dec 1 01:30:42
2005
@@ -9,6 +9,7 @@
#include <Image/Pixel.h>
#include <Interface/Image.h>
#include <Interface/Context.h>
+#include <Engine/Display/XHelper.h>
#include <iostream>
#include <vector>
@@ -118,6 +119,22 @@
// Copy out the manta channel.
manta_channel = context.channelIndex;
+
+ // Get the fonts. You need to call this with a current GL context.
+ if (!(font_info = XHelper::getX11Font( x_display )))
+ throw new InternalError("getX11Font failed!\n", __FILE__, __LINE__ );
+
+ if (!(fontbase = XHelper::getGLFont(font_info)))
+ throw new InternalError("getGLFont failed!\n", __FILE__, __LINE__ );
+
+ // Setup opengl.
+ glDisable( GL_DEPTH_TEST );
+
+ // Clear the screen.
+ glClearColor(.05, .1, .2, 0);
+ glClear(GL_COLOR_BUFFER_BIT);
+ glXSwapBuffers( x_display, glx_drawable );
+ glFinish();
}
void GLXImageDisplay::displayImage( const DisplayContext &context, const
Image* image ) {
@@ -225,6 +242,9 @@
}
}
+ // Output fps.
+ // display_frame_rate( 1.0 );
+
// Swap buffers.
glXSwapBuffers( x_display, glx_drawable );
@@ -236,3 +256,25 @@
}
}
+void GLXImageDisplay::display_frame_rate(double framerate) {
+
+ // Display textual information on the screen:
+ char buf[200];
+ if (framerate > 1)
+ sprintf( buf, "%3.1lf fps", framerate);
+ else
+ sprintf( buf, "%2.2lf fps - %3.1lf spf", framerate , 1.0f/framerate);
+
+ // Figure out how wide the string is
+ int width = XHelper::calc_width(font_info, buf);
+
+ // Now we want to draw a gray box beneth the font using blending. :)
+ glRasterPos2i(0,0);
+ glEnable(GL_BLEND);
+ glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
+ glColor4f(0.5,0.5,0.5,0.5);
+ glRecti(8,3-font_info->descent-2,12+width,font_info->ascent+3);
+ glDisable(GL_BLEND);
+
+ XHelper::printString(fontbase, 10, 3, buf, RGBColor(1,1,1));
+}
Modified: branches/itanium2/Engine/Display/GLXImageDisplay.h
==============================================================================
--- branches/itanium2/Engine/Display/GLXImageDisplay.h (original)
+++ branches/itanium2/Engine/Display/GLXImageDisplay.h Thu Dec 1 01:30:42
2005
@@ -21,11 +21,16 @@
Display *x_display;
XVisualInfo *x_visual_info;
+ // Font info
+ XFontStruct* font_info;
+ GLuint fontbase;
+
bool use_stereo; // Setup parameter used when creating the visual
int manta_channel; // The last channel number to call
setupDisplayChannel.
static void createVisual( bool stereo_ );
-
+ void display_frame_rate(double framerate);
+
public:
// Note that the GLXImage display must be passed a GLX
context by the
// application it is embedded inside of.
Modified: branches/itanium2/Engine/Display/XHelper.cc
==============================================================================
--- branches/itanium2/Engine/Display/XHelper.cc (original)
+++ branches/itanium2/Engine/Display/XHelper.cc Thu Dec 1 01:30:42 2005
@@ -16,8 +16,8 @@
XFontStruct* XHelper::getX11Font(Display* dpy,
const char* fontstring) {
// Should we lock X?
- cerr << "XHelper::getX11Font: Trying to load in font:\n"
- << fontstring << "\n";
+ // cerr << "XHelper::getX11Font: Trying to load in font:\n"
+ // << fontstring << "\n";
return XLoadQueryFont(dpy, fontstring);
}
Modified: branches/itanium2/Engine/ImageTraversers/CMakeLists.txt
==============================================================================
--- branches/itanium2/Engine/ImageTraversers/CMakeLists.txt (original)
+++ branches/itanium2/Engine/ImageTraversers/CMakeLists.txt Thu Dec 1
01:30:42 2005
@@ -4,18 +4,10 @@
ImageTraversers/NullImageTraverser.cc
ImageTraversers/TiledImageTraverser.h
ImageTraversers/TiledImageTraverser.cc
- ImageTraversers/FramelessImageTraverser.h
- ImageTraversers/FramelessImageTraverser.cc
+ # ImageTraversers/FramelessImageTraverser.h
+ # ImageTraversers/FramelessImageTraverser.cc
ImageTraversers/DissolveImageTraverser.h
ImageTraversers/DissolveImageTraverser.cc
ImageTraversers/DissolveTiledImageTraverser.h
ImageTraversers/DissolveTiledImageTraverser.cc
- ImageTraversers/AFImageTraverser.h
- ImageTraversers/AFImageTraverser.cc
- ImageTraversers/AFR/stats.h
- ImageTraversers/AFR/stats.cc
- ImageTraversers/AFR/tiles.h
- ImageTraversers/AFR/tiles.cc
- ImageTraversers/AFR/kdtree.h
- ImageTraversers/AFR/kdtree.cc
)
Modified: branches/itanium2/Engine/ImageTraversers/FramelessImageTraverser.cc
==============================================================================
--- branches/itanium2/Engine/ImageTraversers/FramelessImageTraverser.cc
(original)
+++ branches/itanium2/Engine/ImageTraversers/FramelessImageTraverser.cc Thu
Dec 1 01:30:42 2005
@@ -219,27 +219,66 @@
bool stereo;
int xres, yres;
image->getResolution(stereo, xres, yres);
- int s,e;
+
// this is what every thread does: gets the next assignment and render it.
+ int s,e;
while(context.loadBalancer->getNextAssignment(context, s, e)) {
+
for(int assignment = s; assignment < e; assignment++) {
int size = 8;
+
Fragment fragment;
- fragment.createRandom(size, shuffledTiles[assignment].xstart,
+
+ // Set size and flags.
+ fragment.setSize ( size );
+ fragment.setFlags( Fragment::ConstantEye );
+
+
+fragment.createRandom(size, shuffledTiles[assignment].xstart,
shuffledTiles[assignment].ystart,
shuffledTiles[assignment].xend,
shuffledTiles[assignment].yend,
0, myRandomNumber[context.proc]);
+
+ // Set individual pixel locations.
+ for (int i=0;i<size;++i) {
+
+ int x = (int)(xstart+myRandomNumber[context.proc].genfrand()*(xend -
xstart));
+ int y = (int)(ystart+myRandomNumber[context.proc].genfrand()*(yend -
ystart));
+
+ if (x >= xend) x = (xend - 1);
+ if (y >= yend) y = (yend - 1);
+ }
+
+ // Render the fragment.
renderFragment(context, fragment, xres, yres);
- /*for(int i = 0; i < fragment.getSize(); i++) {
- Fragment::Element& e = fragment.get(i);
- //printf("%d,%d\n", e.x, e.y);
- float val = ((float)e.x/xres)*((float)e.y/yres);
- e.color = Color(GrayColor(val));
- }*/
+
image->set(fragment);
}
}
if(context.proc == 0)
image->setValid(true);
}
+
+// This code was moved over from Fragment where it really didn't belong.
+void createRandom( Fragment &fragment,
+ int size,
+ int xstart, int ystart,
+ int xend, int yend, int which_eye,
+ MT_RNG &myRandomNumber)
+{
+ size = numElements;
+ flags = ConstantEye;
+
+ int
+
+ for(int i=0;i<size;i++) {
+ data[i].x = (int)(xstart+myRandomNumber.genfrand()*(xend - xstart));
+ data[i].y = (int)(ystart+myRandomNumber.genfrand()*(yend - ystart));
+
+
+
+ data[i].which_eye = which_eye;
+ }
+}
+
Modified: branches/itanium2/Engine/ImageTraversers/TiledImageTraverser.cc
==============================================================================
--- branches/itanium2/Engine/ImageTraversers/TiledImageTraverser.cc
(original)
+++ branches/itanium2/Engine/ImageTraversers/TiledImageTraverser.cc Thu
Dec 1 01:30:42 2005
@@ -26,7 +26,7 @@
string arg = args[i];
if(arg == "-tilesize"){
if(!getResolutionArg(i, args, xtilesize, ytilesize))
- throw IllegalArgument("TiledImageTraverser -tilesize", i, args);
+ throw IllegalArgument("TiledImageTraverser -tilesize", i, args);
} else {
throw IllegalArgument("TiledImageTraverser", i, args);
}
@@ -45,13 +45,20 @@
void TiledImageTraverser::setupDisplayChannel(SetupContext& context)
{
+ // Determine the resolution.
bool stereo;
int xres, yres;
context.getResolution(stereo, xres, yres);
- int xtiles = (xres + xtilesize-1)/xtilesize;
- int ytiles = (yres + ytilesize-1)/ytilesize;
+
+ // Determine how many tiles are needed.
+ xtiles = (xres + xtilesize-1)/xtilesize;
+ ytiles = (yres + ytilesize-1)/ytilesize;
+
+ // Tell the load balancer how much work to assign.
int numAssignments = xtiles * ytiles;
context.loadBalancer->setupDisplayChannel(context, numAssignments);
+
+ // Continue setting up the rendering stack.
context.pixelSampler->setupDisplayChannel(context);
}
@@ -63,35 +70,47 @@
void TiledImageTraverser::renderImage(const RenderContext& context, Image*
image)
{
+
+ // Determine number of tiles.
bool stereo;
int xres, yres;
image->getResolution(stereo, xres, yres);
- int ytiles = (yres + ytilesize-1)/ytilesize;
+
int s,e;
while(context.loadBalancer->getNextAssignment(context, s, e)){
+
for(int assignment = s; assignment < e; assignment++){
+
int xtile = assignment/ytiles;
int ytile = assignment%ytiles;
int xstart = xtile * xtilesize;
int xend = (xtile+1) * xtilesize;
+
if(xend > xres)
- xend = xres;
+ xend = xres;
+
int ystart = ytile * ytilesize;
int yend = (ytile+1) * ytilesize;
+
if(yend > yres)
- yend = yres;
+ yend = yres;
+
for(int y = ystart; y<yend; y++){
- for(int x = xstart; x<xend; x+= Fragment::MaxFragmentSize){
- // Create a Fragment that is consecutive in X pixels
- Fragment frag(0, x, xend, y);
- context.pixelSampler->renderFragment(context, frag);
- image->set(frag);
- if(stereo){
- Fragment frag(1, x, xend, y);
- context.pixelSampler->renderFragment(context, frag);
- image->set(frag);
- }
- }
+ for(int x = xstart; x<xend; x+= Fragment::MaxFragmentSize){
+
+ // Create a Fragment that is consecutive in X pixels
+ Fragment frag(0, x, xend, y);
+ context.pixelSampler->renderFragment(context, frag);
+ image->set(frag);
+
+ // Check to see if we need to render another copy in setero.
+ if(stereo){
+ Fragment frag(1, x, xend, y);
+ context.pixelSampler->renderFragment(context, frag);
+ image->set(frag);
+ }
+
+ }
}
}
}
Modified: branches/itanium2/Engine/ImageTraversers/TiledImageTraverser.h
==============================================================================
--- branches/itanium2/Engine/ImageTraversers/TiledImageTraverser.h
(original)
+++ branches/itanium2/Engine/ImageTraversers/TiledImageTraverser.h Thu
Dec 1 01:30:42 2005
@@ -26,6 +26,9 @@
int xtilesize;
int ytilesize;
+
+ int xtiles;
+ int ytiles;
};
}
Modified: branches/itanium2/Interface/Context.h
==============================================================================
--- branches/itanium2/Interface/Context.h (original)
+++ branches/itanium2/Interface/Context.h Thu Dec 1 01:30:42 2005
@@ -14,45 +14,57 @@
class Scene;
class ShadowAlgorithm;
class XWindow;
-
+ class ThreadStorageAllocator;
+
class ReadContext {
public:
ReadContext(RTRTInterface* rtrt_int)
: rtrt_int(rtrt_int)
{
}
- RTRTInterface* rtrt_int;
+ mutable RTRTInterface* rtrt_int;
private:
ReadContext(const ReadContext&);
ReadContext& operator=(const ReadContext&);
};
+
+
+
+
/////////////////////////////////////////////////////////////////////////////
+ // Setup context is used to configure rendering stack components.
+
+
+
class SetupContext {
public:
SetupContext(RTRTInterface* rtrt_int,
int channelIndex, int numChannels, int proc, int numProcs,
- bool stereo, int xres, int yres,
- LoadBalancer* loadBalancer, PixelSampler* pixelSampler,
- Renderer* renderer)
+ bool stereo, int xres, int yres,
+ LoadBalancer* loadBalancer, PixelSampler* pixelSampler,
+ Renderer* renderer,
+ ThreadStorageAllocator *storage_allocator_ )
+
: rtrt_int(rtrt_int),
channelIndex(channelIndex), numChannels(numChannels),
proc(proc), numProcs(numProcs),
- loadBalancer(loadBalancer), pixelSampler(pixelSampler),
- renderer(renderer),
- stereo(stereo), xres(xres), yres(yres)
+ loadBalancer(loadBalancer), pixelSampler(pixelSampler),
+ renderer(renderer),
+ stereo(stereo), xres(xres), yres(yres),
+ storage_allocator( storage_allocator_ )
{
init();
}
SetupContext(RTRTInterface* rtrt_int, int numChannels,
int proc, int numProcs,
- LoadBalancer* loadBalancer, PixelSampler* pixelSampler,
- Renderer* renderer)
+ LoadBalancer* loadBalancer, PixelSampler* pixelSampler,
+ Renderer* renderer)
: rtrt_int(rtrt_int), channelIndex(-1), numChannels(numChannels),
proc(proc), numProcs(numProcs),
- loadBalancer(loadBalancer), pixelSampler(pixelSampler),
- renderer(renderer),
- stereo(false), xres(-1), yres(-1)
+ loadBalancer(loadBalancer), pixelSampler(pixelSampler),
+ renderer(renderer),
+ stereo(false), xres(-1), yres(-1)
{
init();
}
@@ -71,14 +83,16 @@
LoadBalancer* loadBalancer;
PixelSampler* pixelSampler;
Renderer* renderer;
+
+ ThreadStorageAllocator *storage_allocator;
mutable XWindow* masterWindow;
void changeResolution(bool new_stereo, int new_xres, int new_yres) {
if(new_stereo != stereo || new_xres != xres || new_yres != yres){
- stereo = new_stereo;
- xres = new_xres;
- yres = new_yres;
- changed=true;
+ stereo = new_stereo;
+ xres = new_xres;
+ yres = new_yres;
+ changed=true;
}
}
void getResolution(bool& out_stereo, int& out_xres, int& out_yres) const
{
@@ -89,9 +103,9 @@
void constrainPipelineDepth(int newmin, int newmax) {
if(newmin > minPipelineDepth)
- minPipelineDepth = newmin;
+ minPipelineDepth = newmin;
if(newmax < maxPipelineDepth)
- maxPipelineDepth = newmax;
+ maxPipelineDepth = newmax;
}
int getMinDepth() const {
return minPipelineDepth;
@@ -118,6 +132,7 @@
bool getMultipleGLWindows() {
return multipleGLWindows;
}
+
private:
SetupContext(const SetupContext&);
SetupContext& operator=(const SetupContext&);
@@ -145,16 +160,18 @@
public:
RenderContext(RTRTInterface* rtrt_int,
int channelIndex, int proc, int numProcs,
- const FrameState* frameState,
- LoadBalancer* loadBalancer, PixelSampler* pixelSampler,
- Renderer* renderer, ShadowAlgorithm* shadowAlgorithm,
- const Camera* camera, const Scene* scene)
+ const FrameState* frameState,
+ LoadBalancer* loadBalancer, PixelSampler* pixelSampler,
+ Renderer* renderer, ShadowAlgorithm* shadowAlgorithm,
+ const Camera* camera, const Scene* scene,
+ ThreadStorageAllocator *storage_allocator_ )
: rtrt_int(rtrt_int), channelIndex(channelIndex),
proc(proc), numProcs(numProcs),
frameState(frameState),
loadBalancer(loadBalancer), pixelSampler(pixelSampler),
renderer(renderer), shadowAlgorithm(shadowAlgorithm),
- camera(camera), scene(scene)
+ camera(camera), scene(scene),
+ storage_allocator( storage_allocator_ )
{
}
RTRTInterface* rtrt_int;
@@ -168,6 +185,9 @@
ShadowAlgorithm* shadowAlgorithm;
const Camera* camera;
const Scene* scene;
+
+ mutable ThreadStorageAllocator *storage_allocator;
+
private:
RenderContext(const RenderContext&);
RenderContext& operator=(const RenderContext&);
Modified: branches/itanium2/Interface/Fragment.h
==============================================================================
--- branches/itanium2/Interface/Fragment.h (original)
+++ branches/itanium2/Interface/Fragment.h Thu Dec 1 01:30:42 2005
@@ -36,7 +36,10 @@
static const int ConsecutiveX = 0x01; // Implies a constant Y:
static const int ConstantEye = 0x02;
+
///////////////////////////////////////////////////////////////////////////
+ // 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);
@@ -52,34 +55,24 @@
~Fragment() {}
+
///////////////////////////////////////////////////////////////////////////
+ // Element Accessors.
void addElement(int x, int y, int which_eye) {
- ASSERT(size < MaxFragmentSize);
+ // 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,
- const int xend, const int yend, const int which_eye,
- MT_RNG &myRandomNumber)
- {
- size = numElements;
- flags = ConstantEye;
- for(int i=0;i<size;i++)
- {
- data[i].x = (int)(xstart+myRandomNumber.genfrand()*(xend - xstart));
- data[i].y = (int)(ystart+myRandomNumber.genfrand()*(yend - ystart));
-
- if (data[i].x >= xend) data[i].x = (xend - 1);
- if (data[i].y >= yend) data[i].y = (yend - 1);
-
- data[i].which_eye = which_eye;
- }
+
+ void setElement( int i, int x, int y, int which_eye ) {
+ data[i].x = x;
+ data[i].y = y;
+ data[i].which_eye = which_eye;
}
-
+
+
///////////////////////////////////////////////////////////////////////////
+ // Accessors.
int getFlags() const {
return flags;
}
@@ -133,6 +126,9 @@
data[which].color = color;
}
+
///////////////////////////////////////////////////////////////////////////
+ // Fragment Element Structure.
+
// Constant number of Elements so that we do not have to
// dynamically allocate them.
static const int MaxFragmentSize = 32;
@@ -159,6 +155,10 @@
// Number of Elements that are currently being used.
int size;
};
+
+
+ // Fragment with a dynamic size.
+
}
#endif
Modified: branches/itanium2/Interface/RTRTInterface.h
==============================================================================
--- branches/itanium2/Interface/RTRTInterface.h (original)
+++ branches/itanium2/Interface/RTRTInterface.h Thu Dec 1 01:30:42 2005
@@ -125,6 +125,7 @@
virtual void registerSetupCallback(SetupCallback*) = 0;
virtual void registerSerialAnimationCallback(CallbackBase_3Data<int,
int, bool&>*) = 0;
virtual void registerParallelAnimationCallback(CallbackBase_3Data<int,
int, bool&>*) = 0;
+ virtual void registerTerminationCallback( CallbackBase_1Data<
RTRTInterface *> *) = 0;
// Settings
enum TimeMode {
Modified: branches/itanium2/Model/Cameras/StereoPinholeCamera.cc
==============================================================================
--- branches/itanium2/Model/Cameras/StereoPinholeCamera.cc (original)
+++ branches/itanium2/Model/Cameras/StereoPinholeCamera.cc Thu Dec 1
01:30:42 2005
@@ -108,20 +108,24 @@
stereo_eye[0] = eye + right;
stereo_eye[1] = eye - right;
- // Compute the focus point.
- Point focus_point = eye + (camera_direction * focus_distance);
+ // Compute focus point for each eye.
+ right.normalize();
+ right *= focus_eye_distance;
- for (int i=0;i<2;++i) {
+ Point focus_point[2];
+ focus_point[0] = eye + (camera_direction * focus_distance) + right;
+ focus_point[1] = eye + (camera_direction * focus_distance) - right;
+ for (int i=0;i<2;++i) {
+
// Compute direction for either eye.
- direction[i] = focus_point - stereo_eye[i];
+ direction[i] = focus_point[i] - stereo_eye[i];
// Compute v
v[i] = Cross( direction[i], up );
v[i].normalize();
v[i] *= width;
-
-
+
// Compute u
u[i] = Cross( v[i], direction[i] );
u[i].normalize();
Modified: branches/itanium2/Model/Cameras/StereoPinholeCamera.h
==============================================================================
--- branches/itanium2/Model/Cameras/StereoPinholeCamera.h (original)
+++ branches/itanium2/Model/Cameras/StereoPinholeCamera.h Thu Dec 1
01:30:42 2005
@@ -23,13 +23,15 @@
hfov( fov_ ),
eye_distance( 1 ),
- focus_distance( 10 ) { setup(); }
+ focus_distance( 10 ),
+ focus_eye_distance( 0.5 ) { setup(); }
StereoPinholeCamera( const Point &eye_, const Point &lookat_, const
Vector &up_, Real fov_,
- Real eye_distance_, Real focus_distance_ ) :
+ Real eye_distance_, Real focus_distance_, Real
focus_eye_distance_ ) :
eye( eye_ ), lookat( lookat_ ), up( up_ ), hfov( fov_
),
- eye_distance( eye_distance_ ), focus_distance( focus_distance_ ) {
setup(); }
+ eye_distance( eye_distance_ ), focus_distance( focus_distance_ ),
+ focus_eye_distance( focus_eye_distance_ ) { setup(); }
StereoPinholeCamera(const vector<string>& args);
static Camera* create(const vector<string>& args);
@@ -47,12 +49,13 @@
virtual void output( std::ostream &os );
virtual Point project(const Point &point) const; // project a 3D
point to the camera image plane
- void set_eye_distance ( Real eye_distance_ ) { eye_distance =
eye_distance_; setup(); }
- void set_focus_distance( Real focus_distance_ ) { focus_distance =
focus_distance_; setup(); }
+ void set_eye_distance ( Real eye_distance_ ) { eye_distance =
eye_distance_; setup(); }
+ void set_focus_distance( Real focus_distance_ ) { focus_distance =
focus_distance_; setup(); }
+ void set_focus_eye_distance( Real eye_distance_ ) { focus_eye_distance =
eye_distance_; setup(); }
virtual Point getPosition() const { return eye; }
virtual Point getLookAt() const { return lookat; };
- virtual Vector getUp() const { return up; };
+ virtual Vector getUp() const { return up; };
virtual void reset( const Point &eye_, const Vector &up_,
const Point &lookat_ ) {
@@ -76,6 +79,7 @@
Real eye_distance; // Distance between eyes.
Real focus_distance; // Distance from camera point that view from both
eyes cross.
+ Real focus_eye_distance; // Distance between the point each eye is
focusing on..?
// Assume that fov is the same for both eyes.
Modified: branches/itanium2/StandAlone/CMakeLists.txt
==============================================================================
--- branches/itanium2/StandAlone/CMakeLists.txt (original)
+++ branches/itanium2/StandAlone/CMakeLists.txt Thu Dec 1 01:30:42 2005
@@ -10,7 +10,7 @@
TARGET_LINK_LIBRARIES(manta ${CMAKE_THREAD_LIBS_INIT}
${OPENGL_LIBRARIES}
- ${X11_LIBRARIES}
+ ${X11_LIBRARIES}
-lm)
@@ -40,7 +40,8 @@
ENDIF(BUILD_V3C1_TOOLS)
IF(SGI_LINUX)
- ADD_EXECUTABLE(mf_stream_test mf_stream_test.cc)
+ ADD_EXECUTABLE(mf_stream_test mf_stream_test.cc
+ ../fox/MediaFusionBridge.cc)
TARGET_LINK_LIBRARIES(mf_stream_test Manta_Engine
Manta_UserInterface
Manta_Model
Modified: branches/itanium2/StandAlone/frust-test.cc
==============================================================================
--- branches/itanium2/StandAlone/frust-test.cc (original)
+++ branches/itanium2/StandAlone/frust-test.cc Thu Dec 1 01:30:42 2005
@@ -55,7 +55,7 @@
NULL,
NULL, NULL,
NULL, NULL,
- NULL,NULL );
+ NULL,NULL,NULL );
// Ah, the ray packet
Point ray_origin(20, 0, 20);
Point Pn(19,1,2), Pf(2,1,2);
Modified: branches/itanium2/StandAlone/manta_tile_size.pl
==============================================================================
--- branches/itanium2/StandAlone/manta_tile_size.pl (original)
+++ branches/itanium2/StandAlone/manta_tile_size.pl Thu Dec 1 01:30:42
2005
@@ -220,9 +220,10 @@
}
}
-print MANTA_IN "-quit\n";
-close MANTA_IN;
+# print MANTA_IN "-quit\n";
close MANTA_OUT;
+close MANTA_IN;
+
# Produce a plot.
if ($file ne "-") {
@@ -268,6 +269,7 @@
"unu save -f nrrd | " .
"unu reshape -s $size_x $size_y | ".
"unu rmap -m $colormap | " .
+ "unu flip -a 2 | " .
"unu resample -s = 512 512 -k box | ".
"unu quantize -b 8 | unu save -f png -o $file_png\n";
@@ -280,7 +282,8 @@
$colormap_png = "$file-colormap.png";
$command = "cat $colormap | " .
"unu save -f nrrd | " .
- "unu reshape -s 3 1 12 |" .
+ "unu reshape -s 3 1 12 | " .
+ "unu flip -a 2 | " .
"unu quantize -b 8 | unu save -f png -o $colormap_png\n";
print $command;
Modified: branches/itanium2/StandAlone/mf_stream_test.cc
==============================================================================
--- branches/itanium2/StandAlone/mf_stream_test.cc (original)
+++ branches/itanium2/StandAlone/mf_stream_test.cc Thu Dec 1 01:30:42
2005
@@ -1,34 +1,79 @@
#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/keysym.h>
#include <GL/glx.h>
#include <GL/glu.h>
+#include <unistd.h>
+#include <errno.h>
#include <vector>
#include <string>
#include <iostream>
#include <Core/Shm/MFStreamData.h>
+#include <fox/MediaFusionBridge.h>
#include <SCIRun/Core/Exceptions/Exception.h>
#include <SCIRun/Core/Exceptions/InternalError.h>
+#include <SCIRun/Core/Exceptions/ErrnoException.h>
#include <SCIRun/Core/Thread/Time.h>
using namespace std;
using namespace Manta;
using namespace SCIRun;
-
+using namespace fox_manta;
static Window parent;
static Window win;
static Display* dpy;
static GLXContext cx;
+static int xpipe[2];
+static vector<int> xfds;
+
+static void connection_watch(Display*, XPointer data, int fd, Bool opening,
XPointer*) {
+
+ // Check to see if a connection is being opened or closed.
+ if(opening) {
+ xfds.push_back( fd );
+ }
+ else {
+ for (vector<int>::iterator i = xfds.begin();i!=xfds.end();++i) {
+ if ((*i) == fd) {
+ xfds.erase( i );
+ }
+ }
+ }
+}
+
static void createWindow( MFStreamData *stream_data ) {
+ // Create the xpipe.
+ if (pipe(xpipe) == -1)
+ throw ErrnoException( "Error obtaining xpipe", errno, __FILE__, __LINE__
);
+
// Open the display and make sure it has opengl
dpy = XOpenDisplay(NULL);
if(!dpy)
throw new InternalError("Error opening display", __FILE__, __LINE__ );
+ // Add a connection watch callback to obtain the file descriptor.
+ if (XAddConnectionWatch( dpy, connection_watch, 0 ) == 0)
+ throw InternalError("XAddConnectionWatch failed", __FILE__, __LINE__ );
+
+ // Check to see if XAddConnectionWatch already executed the callback????
+ if (xfds.size() == 0) {
+ // throw InternalError("XAddConnectionWatch broken", __FILE__, __LINE__
);
+
+ int tmp_pipe[2];
+ if(pipe(tmp_pipe) == -1)
+ throw ErrnoException("tmp_pipe", errno, __FILE__, __LINE__ );
+
+ for(int i=xpipe[1]+1; i<tmp_pipe[0];i++)
+ xfds.push_back( i );
+ }
+
+ // Check to make sure opengl is available.
int error, event;
if ( !glXQueryExtension( dpy, &error, &event) ) {
XCloseDisplay(dpy);
@@ -71,8 +116,15 @@
atts.background_pixmap = None;
atts.border_pixmap = None;
atts.border_pixel = 0;
- atts.colormap=cmap;
- atts.event_mask=StructureNotifyMask;
+ atts.colormap = cmap;
+ atts.event_mask =
+ StructureNotifyMask |
+ ExposureMask |
+ ButtonPressMask |
+ ButtonReleaseMask |
+ ButtonMotionMask |
+ KeyPressMask |
+ KeyReleaseMask;
parent = RootWindow(dpy, screen);
@@ -95,8 +147,8 @@
}
// Turn off events from this window
- atts.event_mask = 0;
- XChangeWindowAttributes(dpy, win, CWEventMask, &atts);
+ // atts.event_mask = 0;
+ // XChangeWindowAttributes(dpy, win, CWEventMask, &atts);
cx = glXCreateContext(dpy, vi, NULL, True);
XFree(vi);
@@ -167,6 +219,120 @@
}
+#define TOKEN_NOOP 1
+#define TOKEN_LOCK 2
+
+void handle_events() {
+
+ // Setup a file handle for reading.
+ fd_set readfds;
+
+ FD_ZERO( &readfds );
+ FD_SET ( xpipe[0], &readfds );
+
+ // Determine the max file descriptor.
+ int max = xpipe[0];
+ for(vector<int>::iterator iter = xfds.begin(); iter != xfds.end(); iter++){
+
+ // Setup each descriptor for reading.
+ FD_SET(*iter, &readfds);
+
+ if(*iter > max) {
+ max = *iter;
+ }
+ }
+#if 0
+ // Wait for something to happen.
+ // int s;
+ // if ((s = select( max+1, &readfds, 0, 0, 0 )) == -1) {
+ // throw ErrnoException("select", errno, __FILE__, __LINE__ );
+ // }
+
+ // std::cout << "Past select" << std::endl;
+
+ // Do I have to do that TOKEN stuff?
+ if(FD_ISSET(xpipe[0], &readfds)){
+
+ std::cout << "Token stuff" << std::endl;
+
+ // Process the pipe...
+ int token;
+ ssize_t s = read(xpipe[0], &token, sizeof(token));
+ if(s != sizeof(token))
+ throw ErrnoException("read pipe", errno, __FILE__, __LINE__ );
+
+ switch(token){
+ case TOKEN_NOOP:
+ break;
+
+ case TOKEN_LOCK:
+ // xlock.unlock();
+ // xsema.down();
+ // xlock.lock();
+ break;
+
+ default:
+ throw InternalError("Unknown token in pipe", __FILE__, __LINE__ );
+ }
+ }
+
+ // Process xlib events.
+ bool have_events = false;
+ for(vector<int>::iterator iter = xfds.begin(); iter != xfds.end(); iter++){
+ if(FD_ISSET(*iter, &readfds)){
+ XProcessInternalConnection(dpy, *iter);
+ have_events = true;
+ }
+ }
+
+ // If there are no events waiting, return;
+ if (have_events == false) {
+ return;
+ }
+#endif
+ XEvent e;
+ while (XEventsQueued( dpy, QueuedAfterReading )) {
+
+ // Get the next event.
+ XNextEvent( dpy, &e );
+
+ // Check to see if the event is for our window.
+ if (e.xany.window == win) {
+
+ // Decide what to do based on the event type.
+ switch (e.type) {
+ case KeyPress:
+ std::cerr << "KeyPress" << std::endl;
+ break;
+ case KeyRelease:
+ std::cerr << "KeyRelease" << std::endl;
+ break;
+ case ButtonPress:
+ std::cerr << "ButtonPress" << std::endl;
+ break;
+ case ButtonRelease:
+ std::cerr << "ButtonRelease" << std::endl;
+ break;
+ case MotionNotify:
+ std::cerr << "MotionNotify" << std::endl;
+ break;
+ case ConfigureNotify:
+ std::cerr << "ConfigureNotify" << std::endl;
+ break;
+ case Expose:
+ std::cerr << "Expose" << std::endl;
+ break;
+ default:
+ std::cerr << "Unknown x event: " << e.type << std::endl;
+ }
+ }
+ else {
+ std::cout << "Received event for unknown windows: " << e.xany.window
<< std::endl;
+ }
+
+ }
+};
+
int main( int argc, char **argv ) {
int key = 0;
@@ -203,8 +369,16 @@
if (use_x) {
createWindow( stream_data );
+ // Start a media fusion event thread.
+ MediaFusionBridge mf_events( win,
+ parent,
+ dpy,
+ key );
+ mf_events.startup();
+
for(;;) {
- display( stream_data );
+ handle_events();
+ // display( stream_data );
SCIRun::Time::waitUntil( SCIRun::Time::currentSeconds()+0.05 );
};
@@ -226,6 +400,9 @@
// Catch any exceptions.
catch (SCIRun::Exception *e) {
std::cerr << "Caught Exception: " << e->message() << std::endl;
+ }
+ catch (SCIRun::Exception &e) {
+ std::cerr << "Caught Exception: " << e.message() << std::endl;
}
return 1;
Modified: branches/itanium2/fox/FMantaStereo.cc
==============================================================================
--- branches/itanium2/fox/FMantaStereo.cc (original)
+++ branches/itanium2/fox/FMantaStereo.cc Thu Dec 1 01:30:42 2005
@@ -43,6 +43,7 @@
// Message_Type ID Message_Handler
FXMAPFUNC(SEL_COMMAND, FMantaStereoDialog::ID_DISTANCE,
FMantaStereoDialog::onDistance ),
FXMAPFUNC(SEL_COMMAND, FMantaStereoDialog::ID_FOCUS,
FMantaStereoDialog::onFocus ),
+ FXMAPFUNC(SEL_COMMAND, FMantaStereoDialog::ID_FOCUS_EYE,
FMantaStereoDialog::onFocusEye ),
};
@@ -62,12 +63,14 @@
{
FXHorizontalFrame *frame = new FXHorizontalFrame( this );
-
+ new FXLabel( frame, "The \"stereo\" camera must be specified to use stereo
mode." );
+
+ frame = new FXHorizontalFrame( this );
new FXLabel( frame, "Eye distance" );
distance_spinner = new FXRealSpinner( frame, 5, this, ID_DISTANCE );
distance_spinner->setRange( 0, 999 );
- distance_spinner->setIncrement( 0.05 );
- distance_spinner->setValue( 0.1 );
+ distance_spinner->setIncrement( 0.001 );
+ distance_spinner->setValue( 0.01 );
frame = new FXHorizontalFrame( this );
new FXLabel( frame, "Focus distance" );
@@ -75,6 +78,13 @@
focus_spinner->setRange( 0, 999 );
focus_spinner->setIncrement( 0.05 );
focus_spinner->setValue( 10.0 );
+
+ frame = new FXHorizontalFrame( this );
+ new FXLabel( frame, "Focus separation" );
+ focus_eye_spinner = new FXRealSpinner( frame, 5, this, ID_FOCUS_EYE );
+ focus_eye_spinner->setRange( 0, 999 );
+ focus_eye_spinner->setIncrement( 0.001 );
+ focus_eye_spinner->setValue( 0.01 );
}
@@ -98,6 +108,16 @@
return 1;
}
+long FMantaStereoDialog::onFocusEye( FXObject *sender, FXSelector key, void
*data ) {
+
+ Real focus = focus_spinner->getValue();
+ manta_window->getMantaInterface()->addTransaction("stereo focus eye",
+ Callback::create(this,
&FMantaStereoDialog::mantaSetFocusEye,
+ focus ));
+
+ return 1;
+}
+
void FMantaStereoDialog::mantaSetDistance( Real distance_ ) {
int channel = 0;
@@ -119,3 +139,14 @@
camera->set_focus_distance( focus_ );
}
}
+
+void FMantaStereoDialog::mantaSetFocusEye( Real distance_ ) {
+
+ int channel = 0;
+
+ // Check to make sure that the camera is a stereo camera.
+ StereoPinholeCamera *camera = dynamic_cast<StereoPinholeCamera
*>(manta_window->getMantaInterface()->getCamera( channel ));
+ if (camera) {
+ camera->set_focus_eye_distance( distance_ );
+ }
+}
Modified: branches/itanium2/fox/FMantaStereo.h
==============================================================================
--- branches/itanium2/fox/FMantaStereo.h (original)
+++ branches/itanium2/fox/FMantaStereo.h Thu Dec 1 01:30:42 2005
@@ -60,11 +60,13 @@
FXRealSpinner *distance_spinner;
FXRealSpinner *focus_spinner;
+ FXRealSpinner *focus_eye_spinner;
public:
enum {
ID_DISTANCE = FXDialogBox::ID_LAST,
ID_FOCUS,
+ ID_FOCUS_EYE,
ID_LAST
};
@@ -78,9 +80,11 @@
long onDistance( FXObject *sender, FXSelector key, void *data );
long onFocus ( FXObject *sender, FXSelector key, void *data );
+ long onFocusEye( FXObject *sender, FXSelector key, void *data );
void mantaSetDistance( Real distance_ );
void mantaSetFocus ( Real focus_ );
+ void mantaSetFocusEye( Real distance_ );
};
};
Modified: branches/itanium2/fox/FMantaWindow.cc
==============================================================================
--- branches/itanium2/fox/FMantaWindow.cc (original)
+++ branches/itanium2/fox/FMantaWindow.cc Thu Dec 1 01:30:42 2005
@@ -29,8 +29,9 @@
//////////////////////////////////////////////////////////////////////////////
// Message_Type ID Message_Handler
FXMAPFUNC(SEL_COMMAND, FMantaWindow::ID_QUIT,
FMantaWindow::onQuit ),
+ FXMAPFUNC(SEL_COMMAND, FMantaWindow::ID_FAST_QUIT,
FMantaWindow::onFastQuit ),
FXMAPFUNC(SEL_COMMAND,
FMantaWindow::ID_SAVE_BOOKMARKS,FMantaWindow::onSaveBookmarks ),
- FXMAPFUNC(SEL_COMMAND, FXApp::ID_QUIT,
FMantaWindow::onQuit ),
+ FXMAPFUNC(SEL_CLOSE, 0,
FMantaWindow::onFastQuit ),
// Control options
FXMAPFUNC(SEL_CHANGED, FMantaWindow::ID_SPEED_SLIDER,
FMantaWindow::onSpeedSlider ),
@@ -101,7 +102,9 @@
// File Menu.
file_menu = new FXMenuPane( this );
new FXMenuCommand( file_menu, "Save Bookmarks", 0, this, ID_SAVE_BOOKMARKS
);
- new FXMenuCommand( file_menu, "Quit", 0, this, ID_QUIT );
+ new FXMenuSeparator( file_menu );
+ new FXMenuCommand( file_menu, "Safe Quit", 0, this, ID_QUIT );
+ new FXMenuCommand( file_menu, "Fast Quit", 0, this, ID_FAST_QUIT );
new FXMenuTitle ( menu_bar, "File", 0, file_menu );
// Camera menu.
@@ -231,18 +234,30 @@
// Quit the program.
long FMantaWindow::onQuit( FXObject *sender, FXSelector key, void *data ) {
- // Hard quit.
- // if (fast_quit) {
- SCIRun::Thread::exitAll( 0 );
- //}
-
+ // Register termination callback.
+ manta_interface->registerTerminationCallback(
+ Callback::create( this, &FMantaWindow::mantaTerminate ) );
+
// Add a quit command to manta.
- //
manta_interface->addTransaction("Quit",Callback::create(manta_interface,&RTRTInterface::finish));
- // fast_quit = true;
-
+ manta_interface->addTransaction("Quit",Callback::create(manta_interface,
+
&RTRTInterface::changeNumWorkers, 0 ));
+ // Wait until manta terminates.
+ manta_interface->blockUntilFinished();
+
+ // Quit the fox application.
+ getApp()->exit();
+
return 1;
};
+long FMantaWindow::onFastQuit( FXObject *sender, FXSelector key, void *data
) {
+
+ // Hard quit all threads.
+ SCIRun::Thread::exitAll( 0 );
+
+ return 1;
+}
+
long FMantaWindow::onSpeedSlider( FXObject *sender, FXSelector key, void
*data ) {
// Set the control speed for interaction.
@@ -1146,5 +1161,8 @@
}
+void FMantaWindow::mantaTerminate( RTRTInterface *manta_interface ) {
+
+}
Modified: branches/itanium2/fox/FMantaWindow.h
==============================================================================
--- branches/itanium2/fox/FMantaWindow.h (original)
+++ branches/itanium2/fox/FMantaWindow.h Thu Dec 1 01:30:42 2005
@@ -75,6 +75,7 @@
// Commands for the main window.
enum {
ID_QUIT = FXMainWindow::ID_LAST, // Sent when the application must
quit.
+ ID_FAST_QUIT, // Terminate ALL threads immediately
ID_SPEED_SLIDER, // Control speed slider was changed.
ID_CUTTING_SLIDER, // Cutting plane slider was changed.
ID_CUTTING_FLIP,
@@ -151,6 +152,7 @@
// Message handlers.
long onQuit ( FXObject *sender, FXSelector key, void *data );
+ long onFastQuit ( FXObject *sender, FXSelector key, void *data );
long onSpeedSlider ( FXObject *sender, FXSelector key, void *data );
long onCuttingSlider ( FXObject *sender, FXSelector key, void *data );
long onCuttingFlip ( FXObject *sender, FXSelector key, void *data );
@@ -220,6 +222,9 @@
// Unhide all hidden parts.
void mantaUnHideAll();
+
+ // This methid is called by manta when the last rendering thread exits.
+ void mantaTerminate( RTRTInterface *manta_interface );
};
};
Modified: branches/itanium2/scenes/boeing777.cc
==============================================================================
--- branches/itanium2/scenes/boeing777.cc (original)
+++ branches/itanium2/scenes/boeing777.cc Thu Dec 1 01:30:42 2005
@@ -184,7 +184,7 @@
kd_material = new Phong( new KDTreeTexture,
new Constant<Color>(Color::white()),
phong_exp,
- new Constant<ColorComponent>(phong_reflect) );
+ new Constant<float>(phong_reflect) );
break;
};
- [MANTA] r741 - in branches/itanium2: Core/Util Engine/Control Engine/Display Engine/ImageTraversers Engine/ImageTraversers/AFR Interface Model/Cameras StandAlone fox scenes, abe, 12/01/2005
Archive powered by MHonArc 2.6.16.