PDA

View Full Version : loop with glutpostredisplay



bsperlin
09-02-2003, 12:16 PM
I'm missing a simple idea here:
I have a for-loop in which I change a global parameter for the viewing frustum and then call glutPostRedisplay(). In display() I end the function with glutSwapBuffers() since the picture is double buffered. However, only the last view, of the set of positions determined by the loop, is shown ( and it is correct ). I have put in a lot of delays and printf()s in the loop and, looking at the dos screen, values are being printed slowly enough to see each one. I am not on a network so I should not have to try glFlush() or glFinish(), though I have tried them with no effect. What am I forgetting when trying to render a sequence of pictures?

Bob
09-02-2003, 02:00 PM
glutPostRedisplay does not issue a redisplay immediately, it just sets a flag that the screen should be redrawn. The actual redraw does not occur until the message loop is entered again, which happens when your callback functions return. So basically, posting several redisplays won't do anything. Only one redisplay will be issued.

If you need some kind of animation, use the idle callback, perform your animation calculation in there, and end by posting a redisplay.

bsperlin
09-03-2003, 06:38 AM
Thanks Bob! glutIdleFunc did the job ( but it seems klutzy and I wish there was a more intuitive way ).

Deiussum
09-03-2003, 07:58 AM
If you understand how the Windows message pump works, that solution really doesn't seem that "klutzy" at all.

marcus256
09-03-2003, 10:26 PM
If you want a more intuitive solution, you should use an open event loop system (i.e. not GLUT). The answer could be freeglut (which has an addition that allows you to get control over the event loop, glutCheckLoop I believe), Rob Fletcher's GLUT patch (glutCheckLoop), pure Win32 coding, or GLFW, for instance.

bsperlin
09-04-2003, 10:48 AM
Thank you, Marcus, I have downloaded your GLFW and installed it. Your open message loop is what I wanted ( and intuitive, too ). My special problem is stereo , so I had to make sure that your implementation of stereo worked, and it did!
I am including the text of your example program: triangle.c, below, so people will have a reference implementation in stereo. Most of the stereo theory I got from some white papers at Stereographics.com several years ago.
Thanks again! Barry

//================================================== ======================
// This is a small test application for GLFW.
// The program opens a window (640x480), and renders a spinning colored
// triangle (it is controlled with both the GLFW timer and the mouse). It
// also calculates the rendering speed (FPS), which is displayed in the
// window title bar.
//================================================== ======================
// 9/4/03 REWRITTEN FOR STEREO, SPERLING, ANGLE INC.

#define GLFW_DLL
#include <stdio.h>
#include <glfw.h>

#define STEREO_MAGNITUDE_CONSTANT 0.07
#define LEFT_EYE_PROJECTION -1
#define RIGHT_EYE_PROJECTION 1

int SpinX = 0; // CHANGE INPUT IN keyboard, IMPLEMENTED AT START OF Draw_Figure
int SpinY = 0;
int SpinZ = 0;
double Zoom = 0.0; // CHANGE INPUT IN keyboard, IMPLEMENTED IN LAST LINE OF Stereo_Projection
GLfloat dist = 0.0; // USED IN INIT_SURFACE AND KEYBOARD FOR Z-DISPLACEMENT

double dfStereoMagnitudeAdj = 1.4; // CHANGE INPUT IN keyboard, IMPLEMENTED IN Stereo_Project.
double dfParallaxBalanceAdj = 1.0;

// TRYING TO PUT AS LITTLE AS POSSIBLE INTO DISPLAY AND STEREO_PROJECTION
double dfStereoCameraOffset;
double FrustumTop, FrustumBottom, n_over_d;
double dfXRange;
double dfNearClipDistance, dfFarClipDistance;
double dfXMidpoint, dfYMidpoint;
double dfCameraPlane;
//-----------------------------------------------
void Frustum_Common() { // CALLED FROM INIT, ABSTRACTING FROM DISPLAY AND STEREO_PROJECTION
double dfLeftBorder = -3.0;
double dfRightBorder = 3.0;
double dfBottomBorder = -2.0;
double dfTopBorder = 2.0;
double dfNearBorder = 4.0;
double dfFarBorder = -40.0;
double dfTargetPlane = -1.5; // Z-POSITION OF ZERO PARALLAX PLANE
double dfCameraToTargetDistance = 7.5;

double dfYRange = dfTopBorder - dfBottomBorder;

// midpoints of the X & Y axis ranges
dfCameraPlane = dfTargetPlane + dfCameraToTargetDistance;
dfXMidpoint = (dfRightBorder + dfLeftBorder) / 2.0;
dfYMidpoint = (dfTopBorder + dfBottomBorder) / 2.0;

// convert clipping plane positions to distances in front of camera
dfNearClipDistance = dfCameraPlane - dfNearBorder;
dfFarClipDistance = dfCameraPlane - dfFarBorder;
dfXRange = dfRightBorder - dfLeftBorder;

n_over_d = dfNearClipDistance / dfCameraToTargetDistance;
dfXRange *= n_over_d;
dfYRange *= n_over_d;

FrustumTop = dfYRange / 2.0;
FrustumBottom = -dfYRange / 2.0;
} // FRUSTUM_COMMON
//-----------------------------------
void Stereo_Projection ( int WhichEyeProjection )
{
// CALLED FROM DISPLAY
// COPIED FROM BOB AKKA'S OGLPLANE.CPP DEMO
// EXPLANATION FROM WWW.STEREOGRAPHICS.COM/HTML/PCSDK.HTM (http://WWW.STEREOGRAPHICS.COM/HTML/PCSDK.HTM)
//
// Perform the asymmetric frustum perspective projection for one eye's
// subfield.
// The projection is in the direction of the negative z axis.
// the X & Y axis ranges, in the target Z plane
// SOME CODE PULLED OUT TO GLOBAL AND FRUSTUM_COMMON
double dfFrustumAsymmetry;
double FrustumRight;
double FrustumLeft;

double dfStereoCameraOffset = dfXRange * STEREO_MAGNITUDE_CONSTANT *
dfStereoMagnitudeAdj;
dfStereoCameraOffset /= 2.0; // offset each camera by half the overall sep

if ( WhichEyeProjection == LEFT_EYE_PROJECTION ) // left cam has neg offset
dfStereoCameraOffset = -dfStereoCameraOffset;

dfFrustumAsymmetry = -dfStereoCameraOffset * dfParallaxBalanceAdj;

dfFrustumAsymmetry *= n_over_d;

FrustumRight = (dfXRange / 2.0) + dfFrustumAsymmetry;
FrustumLeft = (-dfXRange / 2.0) + dfFrustumAsymmetry;

glMatrixMode(GL_PROJECTION);
glLoadIdentity();

// this matrix transformation performs the actual persp projection
glFrustum ( FrustumLeft, FrustumRight, FrustumBottom, FrustumTop,
dfNearClipDistance, dfFarClipDistance );

glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glTranslated ( -dfXMidpoint - dfStereoCameraOffset, -dfYMidpoint,
-dfCameraPlane + Zoom );
glRotatef( SpinX, 1.0, 0.0, 0.0 );
glRotatef( SpinY, 0.0, 1.0, 0.0 );
glRotatef( SpinZ, 0.0, 0.0, 1.0 );
} // STEREO_PROJECTION
//-----------------------------------------------------------------------
void Draw_Triangle( int x, double t )
{
// Draw a rotating colorful triangle
glRotatef( 0.3*(GLfloat)x + (GLfloat)t*100.0f, 0.0f, 1.0f, 0.0f );
glBegin( GL_TRIANGLES );
glColor3f( 1.0f, 0.0f, 0.0f );
glVertex3f( -1.0f, 0.0f, 1.0f );
glColor3f( 0.0f, 1.0f, 0.0f );
glVertex3f( 1.0f, 0.0f, 1.0f );
glColor3f( 0.0f, 0.0f, 1.0f );
glVertex3f( 0.0f, 1.0f, 1.0f );
glEnd();

}
//---------------------------
int main( void )
{
int width, height, running, frames, x, y;
double t, t0, fps;
char titlestr[ 200 ];

// Initialise GLFW
glfwInit();

glfwOpenWindowHint( GLFW_STEREO, GL_TRUE );

// Open OpenGL window
if( !glfwOpenWindow( 640, 480, 0,0,0,0, 0,0, GLFW_WINDOW ) ) {
glfwTerminate();
return 0;
}

// Enable sticky keys
glfwEnable( GLFW_STICKY_KEYS );

// Disable vertical sync (on cards that support it)
glfwSwapInterval( 0 );

// Main loop
running = GL_TRUE;
frames = 0;

Frustum_Common();

t0 = glfwGetTime();
while( running ) {
// Get time and mouse position
t = glfwGetTime();
glfwGetMousePos( &x, &y );

// Calculate and display FPS (frames per second)
if( (t-t0) > 1.0 &#0124; &#0124; frames == 0 ) {
fps = (double)frames / (t-t0);
sprintf( titlestr, "Spinning Triangle (%.1f FPS)", fps );
glfwSetWindowTitle( titlestr );
t0 = t;
frames = 0;
}
frames ++;

// Get window size (may be different than the requested size)
glfwGetWindowSize( &width, &height );
height = height > 0 ? height : 1;

// Set viewport
glViewport( 0, 0, width, height );

glDrawBuffer( GL_BACK );
// Clear color buffer
glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

glDrawBuffer( GL_BACK_LEFT );
Stereo_Projection( LEFT_EYE_PROJECTION );
Draw_Triangle( x, t );

glClear( GL_DEPTH_BUFFER_BIT );

glDrawBuffer( GL_BACK_RIGHT );
Stereo_Projection( RIGHT_EYE_PROJECTION );
Draw_Triangle( x, t );

// Swap buffers
glfwSwapBuffers();

// Check if the ESC key was pressed or the window was closed
running = !glfwGetKey( GLFW_KEY_ESC ) &&
glfwGetWindowParam( GLFW_OPENED );
}

// Close OpenGL window and terminate GLFW
glfwTerminate();

return 0;
}

marcus256
09-07-2003, 09:27 PM
Thank you bsperlin!

I never got SoftQuadro to work on my system, so I never got around to testing any stereo myself. I will see what I can do with your stereo code. http://www.opengl.org/discussion_boards/ubb/smile.gif