问题
i have tried to implement the data transfer between usb and cpu in this project. The data transfer is being shown as a small rectangle moving from one component of the computer to another.
In the code below, the GlutPostRedisplay does not work.
Also, can someone tell me if sleep() used is correct because the functions called in display do not work in sync. casing() is never executed. After fisrtscreen(), it directly jumps to opened() and operate() does not work.
what is the error with this code ??
void operate()
{
URLTEXTX = 200;
URLTEXTY = 950;
displayString(READUSB,1);
//southbrigde to northbrigde
bottom(488.0,425.0,380.0);
back(488.0,188.0,380.0);
top(188.0,380.0,550.0);
//northbridge to cpu
front(230.0,350.0,595.0);
top(345.0,600.0,650.0);
//read from usb
back(700.0,625.0,465.0);
bottom(625.0,460.0,385.0);
back(620.0,525.0,390.0);
sleep(1);
URLTEXTX = 200;
URLTEXTY = 950;
displayString(WRITEUSB,1);
//cpu to northbridge
bottom(350.0,650.0,595.0);
back(350.0,230.0,600.0);
//northbridge to southbridge
bottom(188.0,550.0,380.0);
front(188.0,488.0,380.0);
top(483.0,380.0,425.0);
//write to usb
front(525.0,625.0,385.0);
top(625.0,385.0,460.0);
front(620.0,700.0,460.0);
sleep(1);
URLTEXTX = 200;
URLTEXTY = 950;
displayString(READDVD,1);
//read from dvd
back(600.0,560.0,810.0);
bottom(570.0,810.0,600.0);
back(560.0,525.0,610.0);
//ram to northbridge
back(450.0,230.0,580.0);
//northbridge to cpu
front(230.0,350.0,595.0);
top(345.0,600.0,650.0);
sleep(1);
URLTEXTX = 200;
URLTEXTY = 950;
displayString(WRITEDVD,1);
//cpu to northbridge
bottom(350.0,650.0,595.0);
back(350.0,230.0,600.0);
//northbridge to ram
front(230.0,450.0,580.0);
//write to dvd
front(525.0,570.0,600.0);
top(570.0,600.0,800.0);
front(560.0,600.0,800.0);
sleep(1);
URLTEXTX = 200;
URLTEXTY = 950;
displayString(READHD,1);
//read from hard disc
back(640.0,560.0,300.0);
top(560.0,300.0,530.0);
back(560.0,525.0,530.0);
//ram to northbridge
back(450.0,230.0,580.0);
//northbridge to cpu
front(230.0,350.0,595.0);
top(345.0,600.0,650.0);
sleep(1);
URLTEXTX = 200;
URLTEXTY = 950;
displayString(WRITEHD,1);
//cpu to northbridge
bottom(350.0,650.0,595.0);
back(350.0,230.0,600.0);
//northbridge to ram
front(230.0,450.0,580.0);
//write to hard disc
front(525.0,560.0,530.0);
bottom(560.0,530.0,300.0);
front(560.0,640.0,300.0);
sleep(1);
}
void front(GLfloat x1,GLfloat x2,GLfloat y1)//to move in forward direction
{
GLfloat i;
for(i=x1;i<=x2;i++)
{
drawbit(i,x1+5,y1,y1-5);
glutPostRedisplay();
}
}
void back(GLfloat x1,GLfloat x2,GLfloat y1)//to move in backward direction
{
GLfloat i;
for(i=x1;i>=x2;i--)
{
drawbit(i,i-5,y1,y1-5);
glutPostRedisplay();
}
}
void top(GLfloat x1,GLfloat y1,GLfloat y2)//to move in upward direction
{
GLfloat i;
for(i=y1;i<=y2;i++)
{
drawbit(x1,x1+5,i,i+5);
glutPostRedisplay();
}
}
void bottom(GLfloat x1,GLfloat y1,GLfloat y2)//to move in downward direction
{
GLfloat i;
for(i=y1;i>=y2;i--)
{
drawbit(x1,x1-5,i,i-5);
glutPostRedisplay();
}
}
void drawbit(GLfloat x1,GLfloat x2,GLfloat y1,GLfloat y2)
{
glBegin(GL_POLYGON);
glColor3f(1.0,1.0,1.0);
glVertex2f(x1,y1);
glVertex2f(x2,y1);
glVertex2f(x2,y2);
glVertex2f(x1,y2);
glEnd();
glFlush();
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
firstscreen(); //introduction to the project
sleep(3);
glClear(GL_COLOR_BUFFER_BIT);
casing(); //cpu case
sleep(2);
glClear(GL_COLOR_BUFFER_BIT);
opened(); //when cpu case is opened shows internal components
sleep(1);
operate(); //data transfer between various components
}
回答1:
The problem is similar to this: Pausing in OpenGL successively
glutPostRedisplay
simply sets a flag in glut to call your display callback on the next loop. It doesn't actually draw anything.
The function I suspect you're after is glutSwapBuffers
. Without double buffering, geometry is drawn directly to the screen (although "draw" commands to the GPU are buffered for which you'd want glFlush
). This commonly causes flickering because you see things that later get covered by closer geometry (because of the depth buffer). Double buffering solves this by rendering to an off-screen buffer and then displaying the result all at once. Make sure GLUT_DOUBLE
is passed to glutInit
so that you have a back buffer.
While you're sleep()
ing, your application won't be able to capture and process events. Lets say you want to close the window. Until sleep returns the whole thing will be unresponsive. A sleep can still be important so you don't hog your CPU. I'd separate these concepts.
- Loop/poll with an
idle
function until your delay time has elapsed. Then callglutPostRedisplay
. AddglutSwapBuffers
todisplay
if you're double buffering. - Write a framerate limiter that calls sleep so you don't hog cycles.
A simple method to draw different things after set delays is to write a small state machine...
int state = STATE_INIT;
float timer = 0.0f;
void idle()
{
//insert framerate limiter here
//calculate time since last frame, perhaps using glutGet(GLUT_ELAPSED_TIME)
float deltaTime = ...
timer -= deltaTime;
if (timer < 0.0f)
{
switch (state)
{
case STATE_INIT:
state = STATE_DRAW_FIRST_THING;
timer = 123.0f;
...
}
glutPostRedisplay();
}
}
void display()
{
...
if (state == STATE_DRAW_FIRST_THING)
{
...
}
...
glutSwapBuffers();
}
As your app becomes bigger this I doubt this will be maintainable and you'll want something more robust, but until then this is a good start.
Simply changing a void (*currentView)(void);
callback function in idle
would save some hard coding in display
. You might want to create an object orientated state machine. Beyond boolean states you might want to look into animation and keyframe interpolation. Rather than hard code everything, storing geometry, keyframes and state sequences in a file is a nice way to separate code and data. XML is very nice to work with for this provided you use a library.
来源:https://stackoverflow.com/questions/30451058/why-is-glutpostredisplay-and-sleep-function-is-not-working-in-this-code