I've tried some OpenGL C++ training.
But I have a logic problem, how can I update my OpenGL Windows window.
It should draw text one, then delay 1-2sec, then draw text 2, but now it draws same time. Can anyone help or give a hint.
void text () {
wait(1);
Sleep(1000);
std::string text_one;
text_one = "Text 1";
glColor3f(1,01, 0);
drawText(text_one.data(), text_one.size(), 050, 150);
glutPostRedisplay();
wait (1)
std::string text_two;
text_two = "Text 2";
glColor3f(1,0, 0);
drawText(text_two.data(), text_two.size(), 250, 150);
}
and here the main
int main(int argc, char **argv) {
// init GLUT and create Window
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(100,100);
glutInitWindowSize(640,640);
glutCreateWindow("Test 001");
// register callbacks
glutDisplayFunc(renderScene);
glutIdleFunc(text);
// enter GLUT event processing cycle
glutMainLoop();
return 1;
}
You should render in renderScene callback. It will be called automatically in you screen refresh rate. If you want some delay you need to implement it inside this callback (functions called from this callback).
So basically you need to re-render everything every 1/60 second.
If you want to implement easy delay you can do something like this:
void renderScene() {
time += deltaTime;
RenderText1();
if (time > delayTime)
RenderText2();
glutSwapBuffers();
}
Related
I want to create in OpenGL two differents windows but they should appears not together.
I mean: when I execute my code I visualize both of windows contemporarily.
My aim instead is to visualize at the beginning the first window, then the first window should be closed and the second will appear. My pseudocode is the following (this realeses only the two windows together ntemporarily):
int main(int argc, char** argv)
{
glutInit(&argc, argv);
initRendering();
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(500, 500);
//window1=
glutCreateWindow("First window");
glutDisplayFunc(drawScene1);
glutKeyboardFunc(handleKeypress);
glutReshapeFunc(handleResize);
cout << "Before inserting 'choice' I want to visualize the first window\n
After the insert of 'choice' I want to visualize the second window
and close the first one !";
cin >> choice;
//create the second window
//window2 =
glutCreateWindow("Second Window");
//define a window position for second window
glutPositionWindow(540, 40);
// register callbacks for second window, which is now current
glutReshapeFunc(handleResize);
glutDisplayFunc(drawScene2);
glutKeyboardFunc(handleKeypress);
glutMainLoop();
return 0;
}
The code is designed to load a .obj file, draw, rotate camera around mesh (this is ongoing) and display rotation value when the mouse button is clicked. I am using eclipse C++ IDE with FLTK. When the mouse button is clicked the window crashes. The error message when debugging is "no source available for gl_draw".
The code is as follows:
void onMouseButton(int button, int state, int x, int y)
{
switch(button){
case GLUT_LEFT_BUTTON:
if (state == GLUT_DOWN){
// Print value on object
char s[40];
sprintf(s, "ROT=%.2f", g_rotation);
glRasterPos2f(60,40);
gl_draw(s, strlen(s));
}
}
}
The main code:
int main(int argc, char **argv)
{
Fl_Window win(WIDTH,HEIGHT, "Wavefront");
win.resizable(win);
win.show(argc, argv);
// Docs say to add glut subwindow /after/ calling win.show()
win.begin();
// initialize and run program
//glutInit(&argc, argv); // GLUT initialization
glutInitWindowSize(WIDTH-20, HEIGHT-20);
glutInitWindowPosition(10,10); // place inside parent window
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_MULTISAMPLE);
glutCreateWindow("Ear");
glutDisplayFunc(display); // register Display Function
glutIdleFunc( display ); // register Idle Function
glutMouseFunc( onMouseButton );
glutKeyboardFunc( keyboard ); // register Keyboard Handler
initialize();
obj.Load("Ear_obj.obj");
//gl_draw(s, strlen(s));
glutMainLoop();
win.end();// run GLUT mainloop
return 0;
}
If gl_draw(s, strlen(s)); is removed code run as expected , therefore loads the mesh, draws it, displays the mesh as the camera is rotated but would do nothing if the mouse is clicked.
Is the a way to display any text when the mouse is clicked or is there a step I am missing that is causing the error?
I have a real robot that is ordering my virtual robot in open gl. I want show every movement of my master robot(real robot) in slave (virtual one in open gl) online, so i need to update my glut window continuously, actually as long as real robot moves my virtual one moves too, and all these movement should be online.
I get data from master always with get data function, but I dont know how I should update the window.
Here is my code:
********************************************/
void OnIdle(void){
initSocket();
printf("\n Defining Step Time Parameters and Initial Conditions for solving Dynamic equations\n");
xi=0;
xf=0.1;
printf("\n end value x : %f ",xf);
i=0; yi[i]=0;
i++;yi[i]=-1.570796;
i++;yi[i]=-1.570796;
i++;yi[i]=0;
i++;yi[i]=0;
i++;yi[i]=0;
ndata=2; fi=1;
double counter=0.1;
Eqdifp(v1,v2,v3,v4,v5,v6,xi,xf,yi,ndata,p,fi);
for(int i=0;i<50;i++)
//while(1)
{
getData();
printf("\n");
for(int i=0;i<6; i++)
{
printf("%d = %.3f\n", i,drecvbuf[i]);
}
printf("\n");
yi[0]=v1[ndata];
yi[1]=v2[ndata];
yi[2]=v3[ndata];
yi[3]=v4[ndata];
yi[4]=v5[ndata];
yi[5]=v6[ndata];
printf("my nadata %f\n",v1[ndata]);
counter=counter+0.1;
Eqdifp(v1,v2,v3,v4,v5,v6,xi,xf,yi,ndata,p,fi);
glutPostRedisplay();
}
}
/////////////////////////////////////////////////////
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowSize(900,500);
int u=glutCreateWindow("3DOF robot");
myinit();
createMenu();
glutIdleFunc (OnIdle);
glutDisplayFunc(Display);
glutReshapeFunc(reshape);
glutKeyboardFunc(KeyDown);
glutMainLoop();
System::Timers::Timer^ aTimer = gcnew System::Timers::Timer( 100 );
// Hook up the Elapsed event for the timer.
aTimer->Elapsed += gcnew System::Timers::ElapsedEventHandler( OnTimedEvent );
// Set the Interval to 2 seconds (2000 milliseconds).
aTimer->Enabled = true;
return 0;
}
You can call glutPostRedisplay after the update, which schedules the window to be redrawn (using GLUT's display func, of course) as soon as it returns to the message queue, I think.
But this won't work if you are continously polling the robot data in an infinite loop as this continously blocks the program. What you should do is use a timer to schedule the robot update in short intervals, so that between these updates the program can return to the main event loop and redraw the window. Or you can call some function, which tells the framework to visit the event loop. Your code sample doesn't really explain how you do it at the moment (or I'm just not familiar with the functions you call).
GLUT offers you a idle callback (void (*)(void) signature), set through glutIdleFunc. Retrieve the robot input data in the idle handler. Or use a separate thread polling the data, filling data structures; use a semaphore to unlock idle after new data arrived, use a locking with timeout so that your program remains interactive. Pseudocode:
Semaphore robot_data_semaphore;
void wait_for_data(void)
{
SemaphoreLockStatus lock_status =
semaphore_raise_timeout(robot_data_semaphore, RobotDataTimeout);
if( lock_status == SEMAPHORE_RAISED ) {
update_scene_with_robot_data();
semaphore_lower(robot_data_semaphore);
glutPostRedisplay();
}
}
void main(int argc, char *argv[])
{
/* ... */
semaphore_init(robot_data_semaphore);
Thread thread_robot_data_poller = thread_create(robot_data_poller);
glutIdleFunc(wait_for_data);
/* ... */
thread_start(thread_robot_data_poller);
glutMainLoop();
}
I would do the following. Treat glutMainLoop() as your loop and every time you process one getData() you draw it, it will be faster than you think.
What needs to happen for you to get a 'continuous' update is to:
Process data (getData() then your calculations)
Redraw (Display() glut calls this every time it loops)
Other functions defined using glut_____Func()
Back to 1
Glut keeps going until the program is exited.
//called every time glutMainLoop
//do data processing
void OnIdle(void)
{
getData();
printf("\n");
for(int i=0;i<6; i++)
{
printf("%d = %.3f\n", i,drecvbuf[i]);
}
printf("\n");
yi[0]=v1[ndata];
yi[1]=v2[ndata];
yi[2]=v3[ndata];
yi[3]=v4[ndata];
yi[4]=v5[ndata];
yi[5]=v6[ndata];
printf("my nadata %f\n",v1[ndata]);
Eqdifp(v1,v2,v3,v4,v5,v6,xi,xf,yi,ndata,p,fi);
}
//also called every loop of glutMainLoop
void Display()
{
...
//Your previous Display() function just add this:
glutPostRedisplay(); //everytime you are done
// drawing you put it on the screen
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowSize(900,500);
int u=glutCreateWindow("3DOF robot");
myinit();
createMenu();
glutIdleFunc (OnIdle);
glutDisplayFunc(Display);
glutReshapeFunc(reshape);
glutKeyboardFunc(KeyDown);
///////////////
// SETUP YOUR INITIAL DATA
System::Timers::Timer^ aTimer = gcnew System::Timers::Timer( 100 );
// Hook up the Elapsed event for the timer.
aTimer->Elapsed += gcnew System::Timers::ElapsedEventHandler( OnTimedEvent );
// Set the Interval to 2 seconds (2000 milliseconds).
aTimer->Enabled = true;
initSocket();
printf("\n Defining Step Time Parameters and Initial Conditions for solving Dynamic equations\n");
xi=0;
xf=0.1;
printf("\n end value x : %f ",xf);
i=0; yi[i]=0;
i++;yi[i]=-1.570796;
i++;yi[i]=-1.570796;
i++;yi[i]=0;
i++;yi[i]=0;
i++;yi[i]=0;
ndata=2; fi=1;
Eqdifp(v1,v2,v3,v4,v5,v6,xi,xf,yi,ndata,p,fi);
//////////////
//Start the Main Loop
glutMainLoop(); //This statement blocks, meaning that until you exit the
// glut main loop no statments past this point will be executed.
return 0;
}
I'm making a OpenGL game, and I have problem with optimization. When I start it, it does not respond. If in Update() I just put a for loop and _time += 0.1f, I get a blank screen.
void Update(){
for(; ;){
_time += 0.1f;
Render();
}
}
void Render() {
glClearDepth(1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
_colorProgram.use();
GLuint timeLocation = _colorProgram.getUniformLocation("time");
glUniform1f(timeLocation, _time);
_sprite.Render();
_colorProgram.unuse();
glutSwapBuffers();
}
int main(int argc, char** argv) {
std::printf("OpenGL version is %s",glGetString(GL_VERSION));
// Window
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(520, 200);
glutInitWindowSize(800, 600);
glutInitDisplayMode(GLUT_DOUBLE);
glutCreateWindow("OpenGL [ Shader #1 error pt 3 ]");
// Setup GLEW
if( GLEW_OK != glewInit()){
return 1;
} while( GL_NO_ERROR != glGetError() );
// After creating window
Init();
glutDisplayFunc(Render);
Update();
glutMainLoop();
}
The infinite loop in Update() never lets GLUT pump the event queue.
Use glutTimerFunc() or glutIdleFunc() to call Update() instead. That way execution flow periodically returns to GLUT and GLUT can do what it needs to keep the OS happy.
The proper way to run an animation with GLUT is to use a timer function. This way, GLUT can get back to its main loop, and call your display function. You're not supposed to call the display function directly from your own code.
For example, register a timer function during initialization (the first argument is a time in milliseconds):
glutTimerFunc(10, timerFunc, 0);
Then in the timer function:
void timerFunc(int value) {
_time += 0.1f;
glutPostRedisplay();
glutTimerFunc(10, timerFunc, 0);
}
There are two critical pieces in the code fragment above:
You do not call your Render() function directly. Instead, you call glutPostRedisplay() to tell GLUT that a redisplay is needed. It will then call your Render() function because you registered it as the display function with glutDisplayFunc().
You have to register the timer again. glutTimerFunc() fires the timer only once, not periodically. So you have to re-register it every time it fired.
There is one other problem in your code. You have these calls in your main():
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
...
glutInitDisplayMode(GLUT_DOUBLE);
The flags passed in the second call will override the ones from the first call. While GL_RGBA is the default anyway, you will not get a depth buffer because GL_DEPTH is missing in the second call. You can simply remove the second call, since the first one is most likely what you want.
I have created a simple Visual Studio Express 2010 C++ project using GLUT and OpenGL,
it compiles and runs ok, except that the window it creates receives no events..
the close/minimize buttons don't do anything (not even mouseover) no context menu on the task bar on right click, and the window doesn't come to the foreground when clicked if partially covered.
The project is set up as a console application, I can close the program by closing the console.
I have this in main:
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitWindowSize(window_width, window_height);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
glutCreateWindow("MyApp");
glutIdleFunc(main_loop_function);
GLenum err = glewInit();
if (GLEW_OK != err)
{
/* Problem: glewInit failed, something is seriously wrong. */
fprintf(stderr, "Error: %s\n", glewGetErrorString(err));
}
if (GLEW_VERSION_1_3)
{
fprintf(stdout, "OpenGL 1.3 is supported \n");
}
fprintf(stdout, "Status: Using GLEW %s\n", glewGetString(GLEW_VERSION));
GL_Setup(window_width, window_height);
glutMainLoop();
}
You miss a display callback. Could you try:
void display();
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitWindowSize(window_width, window_height);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
glutCreateWindow("MyApp");
/// glutIdleFunc(main_loop_function);
glutDisplayFunc(display);
// ...
glutMainLoop();
}
void display(){
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glutSwapBuffers();
}
Also, your idle function seems bad, if you effectively loop inside that function. Glut is callback oriented. You don't need to create a loop, but rather rely on idle, mouse, keyboard, display and resize callbacks. If you don't do so, you are going to miss window manager events.
EDIT:
If you want to create an animation, you could use:
glutIdleFunc(idleFunc);
void idleFunc(){
glutPostRedisplay();
}