Table Top Framework Example Application

Toolkits.TableTopFrameworkExampleApplication History

Hide minor edits - Show changes to output

April 10, 2006, at 09:49 AM by 141.44.27.190 -
Deleted lines 15-17:
>>redbox<<
>><<
Changed lines 34-35 from:
void
QTTabletopWidgetGL::OnXYDown(int x, int y, int z, int iPointerID)
to:
void QTTabletopWidgetGL::OnXYDown(int x, int y, int z, int iPointerID)
Changed lines 39-40 from:
void
QTTabletopWidgetGL::OnXYMove(int x, int y, int z, int iPointerID)
to:
void QTTabletopWidgetGL::OnXYMove(int x, int y, int z, int iPointerID)
Changed lines 44-45 from:
void
QTTabletopWidgetGL::OnXYUp(int x, int y, int z, int iPointerID)
to:
void QTTabletopWidgetGL::OnXYUp(int x, int y, int z, int iPointerID)
Changed lines 54-55 from:
unsigned int
QTTabletopWidgetGL::translateSmartIPointerId(int iPointerId)
to:
unsigned int QTTabletopWidgetGL::translateSmartIPointerId(int iPointerId)
Added line 121:
Added line 134:
Added line 147:
Added line 176:
Added line 214:
Deleted lines 221-222:
//GLubyte pixelColor[3];
Added line 246:
April 10, 2006, at 09:45 AM by 141.44.27.190 -
Changed lines 176-177 from:
to:
=]
Changed lines 186-187 from:
// this is important to do the expensive stuff not too
if (getVis()->getIsPicking(i)) often!!!
to:
// this is important to do the expensive operations not too often
if (getVis()->getIsPicking(i))
Changed line 190 from:
// render without the textures and only where the mouse is
to:
// render without the textures and only where the input is
Changed line 192 from:
// important so we won't see the other components moving without textures
to:
// important so we won't see the other Components moving without textures
Changed line 195 from:
// render objects for picking
to:
// render Components for picking
Changed lines 197-198 from:
// finish the rendering (is important on quite fast machines, otherwise we read wrong stuff from the cursor)
to:
// finish the rendering (is important on quite fast machines,
//
otherwise we read wrong stuff from the cursor)
Changed lines 201-202 from:
glReadPixels(getVis()->getPosXToPaint(i), getVis()->getPosYToPaint(i), 1, 1, GL_RGB, GL_UNSIGNED_BYTE, pixelColor);
to:
glReadPixels(getVis()->getPosXToPaint(i), getVis()->getPosYToPaint(i),
1, 1, GL_RGB, GL_UNSIGNED_BYTE, pixelColor);
Changed lines 209-210 from:
// we don't use the information "wasSuccessful" but we could (this is only a hint)
to:
// we don't use the information "wasSuccessful"
//
but we could (this is only a hint)
Changed lines 213-214 from:
to:
=]

The dropping of a Component is handled separately:
(:source lang=c++ tabwidth=2 :) [=
Changed line 227 from:
// render without the textures and only where the mouse is
to:
// render without the textures and only where the input is
Changed line 229 from:
// important so we won't see the other components moving without textures
to:
// important so we won't see the other Components moving without textures
Changed lines 246-249 from:
to:
=]

In the end, we move the cursors according to the interaction and render everything for real:
(:source lang=c++ tabwidth=2 :) [=
April 10, 2006, at 09:40 AM by 141.44.27.190 -
Added line 137:
Changed lines 159-161 from:

to do
to:
This part is described in greater detail in the thesis. Here just a brief look at important parts of the render loop.

The picking or dropping parts of the render loop have to be done for every user seperately. Therefore, we have to iterate over all users:
Changed lines 163-164 from:
void
QTTabletopWidgetGL::paintGL()
to:
void QTTabletopWidgetGL::paintGL()
Changed lines 166-167 from:
// \dots
to:
// ...
Changed line 169 from:
for (unsigned int i = 0; i < NUMBER_OF_USERS; ++i)
to:
for (unsigned int i = 0; i < config->NUMBER_OF_USERS; ++i)
Added lines 171-173:
// if there was an active component,
// make it the last active one (active then NULL)
getVis()->resetActiveComponent(i);
Deleted lines 174-175:
// \dots
Changed lines 176-178 from:

// \emph{Picking}
// do we really
need to draw?
to:
The color picking for Components starts here:
(:source lang=c++ tabwidth=2 :) [=
// COLOR PICKING
// do painting (or picking)
// do we
need to draw?
Changed lines 183-186 from:
{
// this is important to do the expensive
// operatios not too often!!!
if ( getVis()->getIsPicking(i) )
to:
{
GLubyte pixelColor[3];
// this is important to do the expensive stuff not too
if (getVis()->getIsPicking(i)) often!!!
Changed lines 191-194 from:
// important so we won't see the other Components
// moving without textures
glScissor(getVis()->getPosXToPaint(i),
getVis()->getPosYToPaint(i), 1, 1);
to:
// important so we won't see the other components moving without textures
glScissor(getVis()->getPosXToPaint(i), getVis()->getPosYToPaint(i), 1, 1);
Changed lines 196-197 from:
// finish the rendering (is important on quite fast
//
machines, otherwise we read wrong data from the cursor)
to:
// finish the rendering (is important on quite fast machines, otherwise we read wrong stuff from the cursor)
Changed lines 199-201 from:
glReadPixels(getVis()->getPosXToPaint(i),
getVis()->getPosYToPaint(i),
1, 1, GL_RGB, GL_UNSIGNED_BYTE, pixelColor);
to:
glReadPixels(getVis()->getPosXToPaint(i), getVis()->getPosYToPaint(i), 1, 1, GL_RGB, GL_UNSIGNED_BYTE, pixelColor);
//glDisable(GL_SCISSOR_TEST);
//glEnable(GL_TEXTURE_2D
);
Changed lines 203-216 from:
}
// cf. \autoref{fig:flowcharts}\ref{fig:processsingle} on page~\pageref{fig:flowcharts}
getVis()->processSingleComponent(i, pixelColor);
} // end of picking

// \emph{Dropping} part here

} // end of user iteration

// do the real rendering (not for picking etc.) here

// \dots

} // end of paintGL()
to:
}

// let the Vis do the processing
// we don't use the information "wasSuccessful" but we could (this is only a hint)
bool wasSuccessful = getVis()->processSingleComponent(i, pixelColor);
}


// handling where we dropped something
if( getVis()->checkWasDroppedByUser(i) )
{
// unfortunately, we have to render nearly all the stuff (actually, only the composites)
// but note: this should never happen the same time all the stuff above is rendered
// (because we already picked something) :-)

//GLubyte pixelColor[3];

glPushAttrib(GL_ALL_ATTRIB_BITS);
// render without the textures and only where the mouse is
glDisable(GL_TEXTURE_2D);
// important so we won't see the other components moving without textures
glScissor(getVis()->getPosXToPaint(i), getVis()->getPosYToPaint(i), 1, 1);
glEnable(GL_SCISSOR_TEST);
// render only the composites (components that can contain other components) for picking
// the user id is required here because we do not want to render the dropped component itself
getVis()->renderCompositesOnlyForPicking(i);
// finish the rendering (is important on quite fast machines, otherwise we read wrong stuff from the cursor)
glFinish();
// find pixel under mouse pointer
glReadPixels(getVis()->getPosXToPaint(i), getVis()->getPosYToPaint(i), 1, 1, GL_RGB, GL_UNSIGNED_BYTE, pixelColor);
//glDisable(GL_SCISSOR_TEST);
//glEnable(GL_TEXTURE_2D);
glPopAttrib();

// let the Vis do the processing
getVis()->processDroppedComponent(i, pixelColor);
}

// move the cursor to where we are
//(current position determined in Vis automatically based on code above)
getVis()->moveTouchIndicator(i);
}

// THE REAL RENDERING

}
April 10, 2006, at 09:33 AM by 141.44.27.190 -
Deleted line 126:
Changed line 137 from:
to:
After that, we do some configuration for hardware acceleration:
Added line 149:
Last but not least, we setup the visualization for the specific rendering API and call the method we defined above:
Changed lines 154-155 from:
to:
The visualization is now set with the desired content and can be changed any time with a similar call.
April 10, 2006, at 09:26 AM by 141.44.27.190 -
Changed lines 125-127 from:
to:
!!! Using the Builder
After setting up, which content we want to create, this section deals with how to call the methods we just created. During initialization of the OpenGL widget we create the Builder and build an empty Vis for it.
Changed lines 129-131 from:
//--------------------------------------------------------------
// Build the TabletopVis and its objects
//--------------------------------------------------------------
to:
// create a renderer-specific Builder
// if a Builder for a different renderer would be required
// it has to be created here
// this enables changing the renderer at run
-time
// while still having access to the same Builder and Director methods
Added lines 137-139:
=]

(:source lang=c++ tabwidth=2 :) [=
Added lines 148-150:
=]

(:source lang=c++ tabwidth=2 :) [=
Deleted line 152:
//--------------------------------------------------------------
Deleted lines 155-156:
April 10, 2006, at 09:20 AM by 141.44.27.190 -
Changed lines 103-105 from:
The Build Director -- here @@TabletopVisBuildDirector@@ -- provides an interface to built complete visualizations with a single call of a method. This is achieved by accumulating multiple calls to the Builder interface. The example application can access this functionality by inheriting this
to:
The Build Director -- here @@TabletopVisBuildDirector@@ -- provides an interface to built complete visualizations with a single call of a method. This is achieved by accumulating multiple calls to the Builder interface. The example application can access this functionality by inheriting it from @@TabletopVisBuildDirector@@. Thus, @@TabletopVisBuildDirector@@ is the place where the content of an application gets defined. Even several different definition are possible to change the content dynamically at run-time. An example would be the following method that creates the content the example application starts with.
Changed lines 107-108 from:
TabletopVis*
TabletopVisBuildDirector::createFirstDemo(TabletopVisBuilder* builder)
to:
TabletopVis* TabletopVisBuildDirector::createFirstDemo(TabletopVisBuilder* builder)
Changed lines 109-111 from:
#ifdef _DEBUG
cout << endl << endl << "First Demo Created" << endl;
#endif
to:
// the builder needs to have a Vis
Changed lines 113-115 from:
builder->buildSimpleCurrentCreator(config->CREATORS_WIDTH, config->CREATORS_HEIGHT, config->CURRENT_GL_BASE_WIDTH, config->CURRENT_GL_BASE_HEIGHT, config->OBJECTS_IN_CURRENT_SIZE, config->OBJECTS_IN_CURRENT_SPEED);
builder->buildStorageBinCreator(config->CREATORS_WIDTH, config->CREATORS_HEIGHT, config->BIN_GL_BASE_WIDTH, config->BIN_GL_BASE_HEIGHT, config->OBJECTS_IN_BIN_SIZE);
builder->buildComponentDestroyer(config->CREATORS_WIDTH, config->CREATORS_HEIGHT);
to:
builder->buildComplexImages(config->IMAGE_LEAF_GL_BASE_WIDTH, config->IMAGE_LEAF_GL_BASE_HEIGHT, config->NUMBER_OF_OBJECTS, config->NUMBER_OF_TEXTURES);
Deleted lines 114-121:
//builder->buildPlainImages(config->IMAGE_LEAF_GL_BASE_WIDTH, config->IMAGE_LEAF_GL_BASE_HEIGHT, config->NUMBER_OF_OBJECTS, config->NUMBER_OF_TEXTURES);
//builder->buildComplexImages(config->IMAGE_LEAF_GL_BASE_WIDTH, config->IMAGE_LEAF_GL_BASE_HEIGHT, config->NUMBER_OF_OBJECTS, config->NUMBER_OF_TEXTURES);
//builder->buildSimpleCurrentWithImages(config->CURRENT_GL_BASE_WIDTH, config->CURRENT_GL_BASE_HEIGHT, config->OBJECTS_IN_CURRENT_SIZE, config->OBJECTS_IN_CURRENT_SPEED, config->IMAGE_LEAF_GL_BASE_WIDTH, config->IMAGE_LEAF_GL_BASE_HEIGHT, config->OBJECTS_IN_CURRENT, config->NUMBER_OF_TEXTURES);

// AJ
builder->buildComplexCurrentWithImages(config->CURRENT_GL_BASE_WIDTH, config->CURRENT_GL_BASE_HEIGHT, config->OBJECTS_IN_CURRENT_SIZE, config->OBJECTS_IN_COMPLEX_CURRENT_SPEED, config->IMAGE_LEAF_GL_BASE_WIDTH, config->IMAGE_LEAF_GL_BASE_HEIGHT, config->OBJECTS_IN_CURRENT, config->NUMBER_OF_TEXTURES, config->NUMBER_OF_CONTROL_POINTS, config->SPLINE_LEVEL, config->INSIDE_BOUNDARY_FLAG );

// builder->buildSimpleCurrent(config->CURRENT_GL_BASE_WIDTH, config->CURRENT_GL_BASE_HEIGHT, config->OBJECTS_IN_CURRENT_SIZE, config->OBJECTS_IN_CURRENT_SPEED);
Changed line 116 from:
//builder->buildStorageBinWithImages(config->BIN_GL_BASE_WIDTH, config->BIN_GL_BASE_HEIGHT, config->OBJECTS_IN_BIN_SIZE, config->IMAGE_LEAF_GL_BASE_WIDTH, config->IMAGE_LEAF_GL_BASE_HEIGHT, config->OBJECTS_IN_BIN, config->NUMBER_OF_TEXTURES);
to:
Changed lines 123-125 from:
to:
This method loads the textures, creates images, an Interface Current with images inside, and a Storage Bin. The resulting visualization is returned the calling client code for further processing (see below). (It is important to understand that all the parameters for the methods are set via the read configuration file. This enables changing details without recompilation of the project.)
April 10, 2006, at 09:07 AM by 141.44.27.190 -
Changed lines 100-101 from:

to do
to:
As described in the thesis on the buffer framework, the application content is created via the Builder design pattern.

!!! Build Director
The Build Director -- here @@TabletopVisBuildDirector@@ -- provides an interface to built complete visualizations with a single call of a method. This is achieved by accumulating multiple calls to the Builder interface. The example application can access this functionality by inheriting this
Deleted lines 106-126:
//--------------------------------------------------------------
// Build the TabletopVis and its objects
//--------------------------------------------------------------
glBuilder = new TabletopVisBuilderGL();
// Vis has to be built in advance to enable setup
glBuilder->buildVis(config->NUMBER_OF_USERS, config->BUFFER_WIDTH, config->BUFFER_HEIGHT, this->width(), this->height());
// hardware accelleration setup for the visualization
_mipMapping = _linearFiltering = _textureCompression = true;
_arbTextureCompression = false;
glBuilder->getVis()->enableHardwareOptimization(true);
glBuilder->getVis()->enableMipMapping(_mipMapping);
glBuilder->getVis()->enableLinearFiltering(_linearFiltering);
glBuilder->getVis()->enableTextureCompression(_textureCompression);
glBuilder->getVis()->enableARBTextureCompression(_arbTextureCompression);
glBuilder->getVis()->initializeRenderer();
setVis(createFirstDemo(glBuilder));
//--------------------------------------------------------------
=]


(:source lang=c++ tabwidth=2 :) [=
Deleted lines 136-139:
!! The Render Loop

to do
Added lines 138-164:
//--------------------------------------------------------------
// Build the TabletopVis and its objects
//--------------------------------------------------------------
glBuilder = new TabletopVisBuilderGL();
// Vis has to be built in advance to enable setup
glBuilder->buildVis(config->NUMBER_OF_USERS, config->BUFFER_WIDTH, config->BUFFER_HEIGHT, this->width(), this->height());
// hardware accelleration setup for the visualization
_mipMapping = _linearFiltering = _textureCompression = true;
_arbTextureCompression = false;
glBuilder->getVis()->enableHardwareOptimization(true);
glBuilder->getVis()->enableMipMapping(_mipMapping);
glBuilder->getVis()->enableLinearFiltering(_linearFiltering);
glBuilder->getVis()->enableTextureCompression(_textureCompression);
glBuilder->getVis()->enableARBTextureCompression(_arbTextureCompression);
glBuilder->getVis()->initializeRenderer();
setVis(createFirstDemo(glBuilder));
//--------------------------------------------------------------
=]




!! The Render Loop

to do

(:source lang=c++ tabwidth=2 :) [=
April 10, 2006, at 08:55 AM by 141.44.27.190 -
Added line 34:
!!! SMART DViT
Changed lines 77-80 from:
And for Qt:
to:

!!! Trolltech
Qt
To have the application also running on regular computers without input from a SMART board, we have to implement the regular input methods Qt provides. As before, we just pass the information on the framework, but we do not care about the user id here as there is only one input (mouse) used in this context.
April 10, 2006, at 08:52 AM by 141.44.27.190 -
Changed lines 32-33 from:

For SMART DViT
to:
Forwarding input from the application or an input toolkit into the framework is an important taskt. The buffer framework provides a simple and powerful interface to achieve this.

The example application uses the SMART SDK to enable two touches on a SMART DViT display. Thus, we implement the following methods and pass the gathered information on to the framework:
Changed lines 53-58 from:
to:
=]

The last parameter of each method, @@translateSmartIPointerId(iPointerID)@@, is the id of the interacting user. The framework expects here a number between 0 and the number of users minus one.

On the DViT board, we cannot really identify the user, but we get an id from the SDK, which we have to translate. The numbers used here are due to the SDK specifications.
(:source lang=c++ tabwidth=2 :) [=
April 10, 2006, at 08:41 AM by 141.44.27.190 -
Changed lines 20-21 from:

UML diagram \\
to:
The application is built on Trolltech's Qt and, thus, the main body consists of three Qt objects:
* @@QApplication@@, which is the main application,
* A main window that contains all the window-related application logic, and
* A widget for rendering OpenGL content.
Certain information for both the main window and the rendering widget is defined in a configuration file which is read at run-time (this saves recompilation for minor changes).

The following figure gives an overview of the classes that are used in the example to built an application:
Changed lines 28-30 from:
to:
In the next sections, selected aspects of such an application are presented.
April 07, 2006, at 06:52 AM by 141.44.27.190 -
Changed lines 21-22 from:
UML diagram (to do)
to:
UML diagram \\
Attach:application_uml.png
April 07, 2006, at 02:24 AM by 141.44.27.190 -
Changed lines 25-34 from:
to do

!! Creating the Visualization Content via the Builder Design Pattern

to do

!! The Render Loop

to do
to:
For SMART DViT
Changed line 28 from:
QTTabletopWidgetGL::paintGL()
to:
QTTabletopWidgetGL::OnXYDown(int x, int y, int z, int iPointerID)
Changed lines 30-34 from:
// \dots

// iterate over all users
for
(unsigned int i = 0; i < NUMBER_OF_USERS; ++i)
to:
getVis()->devicePress(x, (this->height() - y -1), z, translateSmartIPointerId(iPointerID));
}

void
QTTabletopWidgetGL::OnXYMove(
int x, int y, int z, int iPointerID)
{
getVis()->deviceMove(x, (this->height() - y -1), z, translateSmartIPointerId(iPointerID));
}

void
QTTabletopWidgetGL::OnXYUp(int x, int y, int z, int iPointerID)
{
getVis()->deviceRelease(x, (this->height() - y -1), z, translateSmartIPointerId(iPointerID));
}

unsigned int
QTTabletopWidgetGL::translateSmartIPointerId(int iPointerId)
{
switch (iPointerId
)
Changed lines 50-94 from:

// \dots

GLubyte pixelColor[3] = {0,0,0};

// \emph{Picking}
// do we really need to draw?
if ( getVis()->checkDoDrawingForUser(i) )
{
// this is important to do the expensive
// operatios not too often!!!
if ( getVis()->getIsPicking(i) )
{
glPushAttrib(GL_ALL_ATTRIB_BITS);
// render without the textures and only where the mouse is
glDisable(GL_TEXTURE_2D);
// important so we won't see the other Components
// moving without textures
glScissor(getVis()->getPosXToPaint(i),
getVis()->getPosYToPaint(i), 1, 1);
glEnable(GL_SCISSOR_TEST);
// render objects for picking
getVis()->renderAllComponentsForPicking();
// finish the rendering (is important on quite fast
// machines, otherwise we read wrong data from the cursor)
glFinish();
// find pixel under mouse pointer
glReadPixels(getVis()->getPosXToPaint(i),
getVis()->getPosYToPaint(i),
1, 1, GL_RGB, GL_UNSIGNED_BYTE, pixelColor);
glPopAttrib();
}
// cf. \autoref{fig:flowcharts}\ref{fig:processsingle} on page~\pageref{fig:flowcharts}
getVis()->processSingleComponent(i, pixelColor);
} // end of picking

// \emph{Dropping} part here

} // end of user iteration

// do the real rendering (not for picking etc.) here

// \dots

} // end of paintGL()
to:
case 1:
return 0;
break;
case 257:
return 1;
break;
default:
return 0;
}
}
Added lines 62-196:
And for Qt:
(:source lang=c++ tabwidth=2 :) [=
void QTTabletopWidgetGL::mousePressEvent(QMouseEvent *e)
{
getVis()->devicePress(e->x(), (this->height() - e->y() - 1), 0, 0);
}

void QTTabletopWidgetGL::mouseReleaseEvent(QMouseEvent *e)
{
getVis()->deviceRelease(e->x(), (this->height() - e->y() - 1), 0, 0);
}

void QTTabletopWidgetGL::mouseMoveEvent(QMouseEvent *e)
{
getVis()->deviceMove(e->x(), (this->height() - e->y() - 1), 0, 0);
}
=]


!! Creating the Visualization Content via the Builder Design Pattern

to do
(:source lang=c++ tabwidth=2 :) [=
//--------------------------------------------------------------
// Build the TabletopVis and its objects
//--------------------------------------------------------------
glBuilder = new TabletopVisBuilderGL();
// Vis has to be built in advance to enable setup
glBuilder->buildVis(config->NUMBER_OF_USERS, config->BUFFER_WIDTH, config->BUFFER_HEIGHT, this->width(), this->height());
// hardware accelleration setup for the visualization
_mipMapping = _linearFiltering = _textureCompression = true;
_arbTextureCompression = false;
glBuilder->getVis()->enableHardwareOptimization(true);
glBuilder->getVis()->enableMipMapping(_mipMapping);
glBuilder->getVis()->enableLinearFiltering(_linearFiltering);
glBuilder->getVis()->enableTextureCompression(_textureCompression);
glBuilder->getVis()->enableARBTextureCompression(_arbTextureCompression);
glBuilder->getVis()->initializeRenderer();
setVis(createFirstDemo(glBuilder));
//--------------------------------------------------------------
=]


(:source lang=c++ tabwidth=2 :) [=
TabletopVis*
TabletopVisBuildDirector::createFirstDemo(TabletopVisBuilder* builder)
{
#ifdef _DEBUG
cout << endl << endl << "First Demo Created" << endl;
#endif
if(builder->getVis())
{
builder->buildTextures(config->NUMBER_OF_TEXTURES, config->TEXTURES_SOURCE);
builder->buildSimpleCurrentCreator(config->CREATORS_WIDTH, config->CREATORS_HEIGHT, config->CURRENT_GL_BASE_WIDTH, config->CURRENT_GL_BASE_HEIGHT, config->OBJECTS_IN_CURRENT_SIZE, config->OBJECTS_IN_CURRENT_SPEED);
builder->buildStorageBinCreator(config->CREATORS_WIDTH, config->CREATORS_HEIGHT, config->BIN_GL_BASE_WIDTH, config->BIN_GL_BASE_HEIGHT, config->OBJECTS_IN_BIN_SIZE);
builder->buildComponentDestroyer(config->CREATORS_WIDTH, config->CREATORS_HEIGHT);
builder->buildSimpleCurrentWithImages(config->CURRENT_GL_BASE_WIDTH, config->CURRENT_GL_BASE_HEIGHT, config->OBJECTS_IN_CURRENT_SIZE, config->OBJECTS_IN_CURRENT_SPEED, config->IMAGE_LEAF_GL_BASE_WIDTH, config->IMAGE_LEAF_GL_BASE_HEIGHT, config->OBJECTS_IN_CURRENT, config->NUMBER_OF_TEXTURES);
//builder->buildPlainImages(config->IMAGE_LEAF_GL_BASE_WIDTH, config->IMAGE_LEAF_GL_BASE_HEIGHT, config->NUMBER_OF_OBJECTS, config->NUMBER_OF_TEXTURES);
//builder->buildComplexImages(config->IMAGE_LEAF_GL_BASE_WIDTH, config->IMAGE_LEAF_GL_BASE_HEIGHT, config->NUMBER_OF_OBJECTS, config->NUMBER_OF_TEXTURES);
//builder->buildSimpleCurrentWithImages(config->CURRENT_GL_BASE_WIDTH, config->CURRENT_GL_BASE_HEIGHT, config->OBJECTS_IN_CURRENT_SIZE, config->OBJECTS_IN_CURRENT_SPEED, config->IMAGE_LEAF_GL_BASE_WIDTH, config->IMAGE_LEAF_GL_BASE_HEIGHT, config->OBJECTS_IN_CURRENT, config->NUMBER_OF_TEXTURES);

// AJ
builder->buildComplexCurrentWithImages(config->CURRENT_GL_BASE_WIDTH, config->CURRENT_GL_BASE_HEIGHT, config->OBJECTS_IN_CURRENT_SIZE, config->OBJECTS_IN_COMPLEX_CURRENT_SPEED, config->IMAGE_LEAF_GL_BASE_WIDTH, config->IMAGE_LEAF_GL_BASE_HEIGHT, config->OBJECTS_IN_CURRENT, config->NUMBER_OF_TEXTURES, config->NUMBER_OF_CONTROL_POINTS, config->SPLINE_LEVEL, config->INSIDE_BOUNDARY_FLAG );

// builder->buildSimpleCurrent(config->CURRENT_GL_BASE_WIDTH, config->CURRENT_GL_BASE_HEIGHT, config->OBJECTS_IN_CURRENT_SIZE, config->OBJECTS_IN_CURRENT_SPEED);
builder->buildStorageBin(config->BIN_GL_BASE_WIDTH, config->BIN_GL_BASE_HEIGHT, config->OBJECTS_IN_BIN_SIZE);
//builder->buildStorageBinWithImages(config->BIN_GL_BASE_WIDTH, config->BIN_GL_BASE_HEIGHT, config->OBJECTS_IN_BIN_SIZE, config->IMAGE_LEAF_GL_BASE_WIDTH, config->IMAGE_LEAF_GL_BASE_HEIGHT, config->OBJECTS_IN_BIN, config->NUMBER_OF_TEXTURES);
return builder->getVis();
} else {
return NULL;
}
}
=]

!! The Render Loop

to do

(:source lang=c++ tabwidth=2 :) [=
void
QTTabletopWidgetGL::paintGL()
{

// \dots

// iterate over all users
for (unsigned int i = 0; i < NUMBER_OF_USERS; ++i)
{

// \dots

GLubyte pixelColor[3] = {0,0,0};

// \emph{Picking}
// do we really need to draw?
if ( getVis()->checkDoDrawingForUser(i) )
{
// this is important to do the expensive
// operatios not too often!!!
if ( getVis()->getIsPicking(i) )
{
glPushAttrib(GL_ALL_ATTRIB_BITS);
// render without the textures and only where the mouse is
glDisable(GL_TEXTURE_2D);
// important so we won't see the other Components
// moving without textures
glScissor(getVis()->getPosXToPaint(i),
getVis()->getPosYToPaint(i), 1, 1);
glEnable(GL_SCISSOR_TEST);
// render objects for picking
getVis()->renderAllComponentsForPicking();
// finish the rendering (is important on quite fast
// machines, otherwise we read wrong data from the cursor)
glFinish();
// find pixel under mouse pointer
glReadPixels(getVis()->getPosXToPaint(i),
getVis()->getPosYToPaint(i),
1, 1, GL_RGB, GL_UNSIGNED_BYTE, pixelColor);
glPopAttrib();
}
// cf. \autoref{fig:flowcharts}\ref{fig:processsingle} on page~\pageref{fig:flowcharts}
getVis()->processSingleComponent(i, pixelColor);
} // end of picking

// \emph{Dropping} part here

} // end of user iteration

// do the real rendering (not for picking etc.) here

// \dots

} // end of paintGL()
=]
April 06, 2006, at 12:43 AM by 141.44.27.190 -
Added lines 1-4:
[[Toolkits.TableTopFramework | << Back to the Tabletop Framework page]]
\\
\\
April 05, 2006, at 10:28 AM by 217.86.52.242 -
Added lines 5-11:
(:table border=1 cellpadding=17 cellspacing=0 align=centre bgcolor=#eeeeee :)
(:cell:) It is ''very'' useful (if not even necessary) to have a good understanding \\
of the framework architecture from reading the information provided in the
'''Getting Started''' section.
(:tableend:)
Deleted line 12:
It is ''very'' useful (if not even necessary) to have a good understanding of the framework architecture from reading the information provided in the '''Getting Started''' section.
Added line 20:
Added line 24:
Changed lines 28-29 from:
to
to:

to do

(:source lang=c++ tabwidth=2 :) [=
void
QTTabletopWidgetGL::paintGL()
{

// \dots

// iterate over all users
for (unsigned int i = 0; i < NUMBER_OF_USERS; ++i)
{

// \dots

GLubyte pixelColor[3] = {0,0,0};

// \emph{Picking}
// do we really need to draw?
if ( getVis()->checkDoDrawingForUser(i) )
{
// this is important to do the expensive
// operatios not too often!!!
if ( getVis()->getIsPicking(i) )
{
glPushAttrib(GL_ALL_ATTRIB_BITS);
// render without the textures and only where the mouse is
glDisable(GL_TEXTURE_2D);
// important so we won't see the other Components
// moving without textures
glScissor(getVis()->getPosXToPaint(i),
getVis()->getPosYToPaint(i), 1, 1);
glEnable(GL_SCISSOR_TEST);
// render objects for picking
getVis()->renderAllComponentsForPicking();
// finish the rendering (is important on quite fast
// machines, otherwise we read wrong data from the cursor)
glFinish();
// find pixel under mouse pointer
glReadPixels(getVis()->getPosXToPaint(i),
getVis()->getPosYToPaint(i),
1, 1, GL_RGB, GL_UNSIGNED_BYTE, pixelColor);
glPopAttrib();
}
// cf. \autoref{fig:flowcharts}\ref{fig:processsingle} on page~\pageref{fig:flowcharts}
getVis()->processSingleComponent(i, pixelColor);
} // end of picking

// \emph{Dropping} part here

} // end of user iteration

// do the real rendering (not for picking etc.) here

// \dots

} // end of paintGL()
=]
April 05, 2006, at 10:05 AM by 217.86.52.242 -
Added line 5:
>>redbox<<
Changed lines 7-8 from:
to:
>><<
Changed lines 14-15 from:
to:
to do
Changed lines 17-19 from:


!!
The Render Loop
to:
to do

!!
The Render Loop
to
April 05, 2006, at 10:03 AM by 217.86.52.242 -
Added lines 1-17:
! Building an Example Application

This tutorial gives a brief overview how to build the example application that comes with the buffer framework. It can also be used as a guideline to build other applications with the buffer framework.

It is ''very'' useful (if not even necessary) to have a good understanding of the framework architecture from reading the information provided in the '''Getting Started''' section.

!! Application Overview

UML diagram (to do)

!! Feeding Input from the Application and/or an Input Toolkit into the Buffer Framework


!! Creating the Visualization Content via the Builder Design Pattern


!! The Render Loop