Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
This runs well in Linux but on Windows the window stops responding and mouse goes in waiting cursor. What am I missing?
// initialization
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutInitWindowSize(1024, 768);
glutCreateWindow("GL Window");
glutTimerFunc(2, update, 0);
glutDisplayFunc(display);
glutMainLoop();
// ...
fflush(stdout);
// update rate
void update(int value)
{
glutPostRedisplay();
glutTimerFunc(250, update, 0);
}
// loop
while(true)
{
display()
{
drawing(5);
glutSwapBuffers();
}
}
// drawing
void drawing(unsigned int sides)
{
if (sides < 3) return;
const float step = (2 * PI) / static_cast<float>(sides);
glBegin(GL_LINE_LOOP);
for (unsigned int i = 0; i < sides; ++i)
{
glVertex2f(cos(i * step), sin(i * step));
}
glEnd();
}
Thanks for comment from Alex and Qix.
I found out I'm running the opengl draw function in a loop. Removing the loop solved the issue.
Still wondering why in Linux it was working though ?
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I am trying to run a very simple example on OpenGlut for my class assignment and for some reason the code is not working on my xcode. I am currently using Xcode 10 on macOS Mojave.
Following is the code:
#include <GLUT/glut.h>
void render()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBegin(GL_TRIANGLES);
glVertex2f( -0.5, -0.5 );
glVertex2f( 0.5, -0.5 );
glVertex2f( 0.0, 0.5 );
glEnd();
glutSwapBuffers();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowSize(800, 600);
glutCreateWindow("Hello, GL");
glutDisplayFunc(render);
glutMainLoop();
return 0;
}
This is the error message:
2018-09-29 14:38:03.737378-0700 gluttest[18974:837022] MessageTracer: load_domain_whitelist_search_tree:73: Search tree file's format version number (0) is not supported
2018-09-29 14:38:03.738891-0700 gluttest[18974:837022] MessageTracer: Falling back to default whitelist
2018-09-29 14:38:03.857540-0700 gluttest[18974:837022] flock failed to lock maps file: errno = 35
2018-09-29 14:38:03.858276-0700 gluttest[18974:837022] flock failed to lock maps file: errno = 35
To make things more clear, I am adding more information about what I have already tried:
The same code is running absolutely fine on Xcode 10 in High Sierra.
I have changed destination target to macOS 10.8 in Xcode
I have made sure OpenGL and Glut framework binaries are linked to the project.
For some reason, the window isn't drawn initially whenever glutMainLoop() is called on Mojave. You can kind of work around this by calling it in the keyboard function:
void keyboard(unsigned char key, int x, int y) {
glutPostRedisplay();
}
int main(int argc, char** argv) {
// ...
glutKeyboardFunc(keyboard);
glutMainLoop();
return 0;
}
EDIT: A better idea:
bool hasDrawn = false;
void display() {
// ...
if (!hasDrawn) {
glutPostRedisplay();
hasDrawn = true;
}
}
void main() {
glutDisplayFunc(display);
}
I read this tutorial and I execute it correctly.
However, I wanted to apply some changes. The first change was to see a different view of that circle, for example showing just the 1/4 of the circle. I know this is done by glViewPort(parameters). However, after changing the parameters, nothing happens. I have checked many forums to figure out why this problem occurs, but I couldn't figure out anything.
Can someone explain me more on this and how to use it? (To understand where the problem happens)
This is the code (Which is originally written on that tutorial)
Code:
#include <GL/glut.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
void init(void)
{
glClearColor(1.0,1.0,1.0,0.0);
glMatrixMode(GL_PROJECTION);
//glLoadIdentity();
gluOrtho2D(0.0,200.0,0.0,200.0);
//glViewport(0, 0, 250, 250);
}
void setPixel(GLint x,GLint y)
{
glBegin(GL_POINTS);
glVertex2i(x,y);
glEnd();
}
void Circle(){
int xCenter=100,yCenter=100,r=50;
int x=0,y=r;
int p = 3/2 - r;
glClear(GL_COLOR_BUFFER_BIT);
glColor3f( 1 ,0, 0);
while(x<=y){
setPixel(xCenter+x,yCenter+y);
setPixel(xCenter+y,yCenter+x);
setPixel(xCenter-x,yCenter+y);
setPixel(xCenter+y,yCenter-x);
setPixel(xCenter-x,yCenter-y);
setPixel(xCenter-y,yCenter-x);
setPixel(xCenter+x,yCenter-y);
setPixel(xCenter-y,yCenter+x);
if (p<0)
p += (2*x)+3;
else {
p += (2*(x-y))+5;
y -= 1;
}
x++;
}
glFlush();
}
int main(int argc,char **argv){
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowPosition(0,0);
glutInitWindowSize(500,500);
glutCreateWindow("My Circl2e");
init();
glViewport(0,0,250,250);
//glLoadIdentity();
glutDisplayFunc(Circle);
glutMainLoop();
return 0;
}
p.s: In some examples I see they use setWindow(parameters) before using glViewPort(parameters). but setWindow() needs library which is not available for ubuntu.
The default GLUT reshape function calls glViewport() with the window size. From the documentation:
If a reshape callback is not registered for a window or NULL is passed to glutReshapeFunc (to deregister a previously registered callback), the default reshape callback is used. This default callback will simply call glViewport(0,0,width,height) on the normal plane (and on the overlay if one exists).
Since you call glViewport() so early, the window will be shaped after you make your call, overriding the viewport you specified.
You either need to register your own reshape function, and call glViewport() with your desired viewport parameters there, or call glViewport() at the start of your Circle() function.
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 am in a class in which we will be learning OpenGL. The professor is using Visual Studio, but that isn't working too well with my install of Parallels, so I just decided to use XCode (which I prefer anyway). I have got basic example code working, but I am having issues running the example that the professor gave us. Here it is:
#include <glut.h> //must be included for OpenGL
#include <gl\gl.h> //must be included for OpenGL
#include <time.h> //must be included for time functions
#include <iostream> //must be included for console input/output
using namespace std;
#define WINDOW_WID 800
#define WINDOW_HEI 600
int randomPx, randomPy;
/////////////////////////////////////////
void myInit(void)
{
randomPx = 400;
randomPy = 300;
glClearColor (1.0, 1.0, 1.0, 0.0); // set background color to black
glShadeModel (GL_FLAT);
}
void myDisplay(void)
{
glClear(GL_COLOR_BUFFER_BIT); // clear the screen
glColor3f(1,0,0); //set the drawing color
glPointSize(10); //set the point size
glBegin(GL_POINTS);
glVertex2d(randomPx,randomPy); //Set the position of the vertex
glEnd();
glutSwapBuffers (); //put everything on your screen
}
void myReshape ( int w, int h)
{
glViewport (0, 0, w, h);
glMatrixMode (GL_PROJECTION); // set "camera type"
glLoadIdentity (); // clear the matrix
glOrtho(0.0, w, 0.0, h, -1.0, 1.0); // viewing transformation
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
}
void Animation()
{
srand(time(NULL)+rand()); //set the seed for your rand function
randomPx = rand()%WINDOW_WID;
randomPy = rand()%WINDOW_HEI;
Sleep(200); //put the program to sleep for 200 ms
myDisplay();
}
void myMouse(int button, int state, int x, int y)
{
y = WINDOW_HEI - y;
switch (button)
{
case GLUT_LEFT_BUTTON: //when left mouse button is clicked
if (state == GLUT_DOWN)
{
cout << "When mouse is up, animation starts\n";
}
else if(state == GLUT_UP)
{
glutIdleFunc(Animation); //do Animation when idle
}
break;
case GLUT_RIGHT_BUTTON: //when right mouse button is clicked
if (state == GLUT_DOWN)
{
glutIdleFunc(NULL); //do nothing when idle
}
break;
case GLUT_MIDDLE_BUTTON:
if (state == GLUT_DOWN)
{
exit (-1); //exit your program
}
break;
}
myDisplay();
}
void myMotion(int x, int y)
{
y = WINDOW_HEI - y;
myDisplay();
}
void myKeyboard(unsigned char key, int x, int y)
{
//TODO
myDisplay();
}
/*
* Request double buffer display mode.
* Register mouse input callback functions
*/
int main(int argc, char** argv)
{
glutInit(&argc, argv); // initialize the toolkit
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB); // set display mode
// glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB); // set display mode
glutInitWindowSize (WINDOW_WID, WINDOW_HEI); // set screen window size
glutInitWindowPosition (100, 100); // set window position on screen
glutCreateWindow (argv[0]); // open the screen window
myInit ();
glutDisplayFunc(myDisplay); // register redraw function
glutReshapeFunc(myReshape); // register reshape function
glutMouseFunc(myMouse); //GLUT provides a way for you to register the function that will be responsable for processing events generated by mouse clicks.
glutMotionFunc(myMotion); //There are two types of motion that GLUT handles: active and passive motion. Active motion occurs when the mouse is moved and a button is pressed.
glutKeyboardFunc(myKeyboard);
//glutPassiveMotionFunc(myPassiveMotion); //Passive motion is when the mouse is moving but no buttons are pressed. If an application is tracking motion, an event will be generated per frame during the period that the mouse is moving.
//glutEntryFunc(processMouseEntry); //GLUT is also able to detect when the mouse leaves or enters the window region. A callback function can be registered to handle these two events.
glutMainLoop(); // go into a perpetual loop
return 0;
}
I took out the imports statements, and replaced them with the imports for example XCode OpenGL code:
#include <iostream>
#include <GLUT/glut.h>
#include <time.h>
And I don't get any error messages, but when I run the application, and click on the window, it does not start the animation it is supposed to. (I know it works, because in Visual Studio on every other computer in the class it worked fine.)
It does register the click on the screen by printing out: "When mouse is up, animation starts"
But after that, it just gives me the Spinning Beachball of Death until I stop it from running via XCode. So is there something else I have to adjust to get this working?
First of all, why are you using a backslash for your import gl.h? Secondly, you should link your code to the GLUT and OpenGL library, so you should include/import them as OpenGL/gl.h and GLUT/glut.h. But your main problem here is the sleep function. It doesn't exist on macs and thus, your code crashes when it tries to animate. Use [NSThread sleepForTimeInterval:0.2] instead if you want to wait for 200 ms. But you will have to change your file extension to .mm in order to use objective-c code and also import the Foundation library to use the NSThread class.
About the sleep.. use
#include <unistd.h> //FROM C
and use
sleep(0.2)
wich is at seconds.. so 2000 miliseconds = 0.2 seconds.. so
just switch from sleep(2000) to sleep(0.2)
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;
}