Reputation: 45
I am working on visualizing the output of a CUDA program I wrote by using OpenGL/GLEW/FreeGlut. I currently have a program that calculates some 3D Cartesian coordinates from some data. I also wrote a separate little OpenGL program that can display X,Y,Z points as spheres on a 3D axis.
My problem is I cannot get the OpenGL display to accept input from the two threads performing the computations.
I tried adding my OpenGL display just before I launch threads that perform the X,Y,Z calculations and having the threads write their outputs to global variables used by both sides of the program. I think that the issue with this is that the glutMainLoop() function is not returning control back over to the main program as I am left with just the empty display of the 3D axis and no points. Is there a way to launch the OpenGL display function and have it passively wait for coordinates?
Below is the display function I am working with. I am trying to have it read from global variables float XYZ_Size[] and NumObj that are updated in different parts the program. I am having the issue that when this display function is reached in the program, the program is stuck in this function.
///////////////////////////////main.cpp
#include "simpleGL.h"
#include <stdio.h>
#include <string.h>
void gen_XYZ_coords(int time)
{
//Large program that just munches on data creating XYZ coords
//memset( XYZ_Size,0,sizeof(float)*(NumObj+1)*4);
float x = 0.0;
float y = 0.0;
float z = 0.0;
float sz = 1;
NumObj = 1;
for(int i = 0; i<4; i++)
{
x = float(time)/100.0f;
y = float(time)/100.0f;
z = float(time)/100.0f;
XYZ_Size[NumObj*4] = x;
XYZ_Size[NumObj*4+1] = y;
XYZ_Size[NumObj*4+2] = z;
XYZ_Size[NumObj*4+3] = sz;
}
for(int num =0; num < NumObj; num++)
{
printf("x: %f y: %f z: %f size: %f\n", XYZ_Size[NumObj*4] , XYZ_Size[NumObj*4+1], XYZ_Size[NumObj*4+2], XYZ_Size[NumObj*4+3] );
}
}
void main(int argc, char** argv)
{
float t = 0.0;
simpleGL(argc, argv); //Gets stuck here, but I want it to be up and generating spheres when gen_xyz starts running
for(t = 0; t < 10000; t++)
{
gen_XYZ_coords(t/10);
}
}
////////////////////////simpleGL.h
#ifndef SIMPLEGL_H
#define HEADERFILE_H
extern float XYZ_Size[];
extern int NumObj;
int simpleGL(int argc, char **argv);
#endif
//////////////////////////////////simpleGL.cu
#include <GL/glew.h>
#include <GL/freeglut.h>
#include "simpleGL.h"
GLfloat Color_Material_AMB[] = {0.25, 0.20725, 0.20725,1}; //
GLfloat Color_Material_SPEC[] = {0.296648, 0.296648, 0.296648}; //
GLfloat Color_Material_DIFF[] = {0.829, 0.829,1.0, 1.0}; //
GLfloat SpecularLight[] = {1.0, 1.0, 1.0};//
GLfloat AmbientLight[] = {1.0, 1.0, 1.0};//
GLfloat DiffuseLight[] = {1.0, 1.0, 1.0}; //
GLfloat mShininess[] = {11.264}; //set the shininess of the material 0 =very shiny 128 = duller than a rock
GLfloat Light_Position[] = {10,10,10,1};
// This is for
float XYZ_Size[4*50]; //imit to 50 obj
int NumObj = 0;
// List for fast creationg of axis
static GLuint axes_list;
// mouse controls
int mouse_old_x, mouse_old_y;
int mouse_buttons = 0;
float rotate_x = 0.0;
float rotate_y = 0.0;
float xshift = 0.0;
float yshift = 0.0;
float translate_z = -3.0;
GLfloat angle = 0.0;
void keyboard(unsigned char key, int x, int y);
void mouse(int button, int state, int x, int y);
void motion(int x, int y);
void init (void)
{
glEnable (GL_DEPTH_TEST);
glEnable (GL_LIGHTING);
glEnable (GL_LIGHT0);
glShadeModel(GL_SMOOTH); // Enable smooth shading
}
void light (void)
{
glLightfv(GL_LIGHT0, GL_SPECULAR, SpecularLight);
glLightfv(GL_LIGHT0, GL_AMBIENT, AmbientLight);
glLightfv(GL_LIGHT0, GL_DIFFUSE, DiffuseLight);
glLightfv(GL_LIGHT0, GL_POSITION, Light_Position);
}
///////////////////////////////////////////////////////////////////////////////
// draw a grid on the xz plane
///////////////////////////////////////////////////////////////////////////////
void drawGrid(float size, float step)
{
// disable lighting
glDisable(GL_LIGHTING);
glBegin(GL_LINES);
glColor3f(0.3f, 0.3f, 0.3f);
for(float i=step; i <= size; i+= step)
{
glVertex3f(0, 0, i); // lines parallel to X-axis
glVertex3f( size, 0, i);
glVertex3f( i, 0, 0); // lines parallel to Z-axis
glVertex3f( i, 0, size);
}
// x-axis red
glColor3f(0.5f, 0, 0);
glVertex3f(0, 0, 0);
glVertex3f( size, 0, 0);
// z-axis blue
glColor3f(0,0,0.5f);
glVertex3f(0, 0, 0);
glVertex3f(0, 0, size);
// y-axis green
glColor3f(0,0.5f,0);
glVertex3f(0, 0, 0);
glVertex3f(0, 6.4, 0);
glEnd();
// enable lighting back
glEnable(GL_LIGHTING);
}
///////////////////////////////////////////////////////////////////////////////
// draw the local axis of an object
///////////////////////////////////////////////////////////////////////////////
void drawAxis(float size)
{
glDisable(GL_LIGHTING);
glPushMatrix();
// draw axis
glLineWidth(3);
glBegin(GL_LINES);
glColor3f(1, 0, 0); //red
glVertex3f(0, 0, 0);
glVertex3f(size, 0, 0); //
glColor3f(0, 1, 0); //green
glVertex3f(0, 0, 0);
glVertex3f(0, size, 0);
glColor3f(0, 0, 1); //blue
glVertex3f(0, 0, 0);
glVertex3f(0, 0, size);
glEnd();
glLineWidth(1);
// draw arrows(actually big square dots)
glPointSize(5);
glBegin(GL_POINTS);
glColor3f(1, 0, 0);
glVertex3f(size, 0, 0);
glColor3f(0, 1, 0);
glVertex3f(0, size, 0);
glColor3f(0, 0, 1);
glVertex3f(0, 0, size);
glEnd();
glPointSize(1);
// restore default settings
glPopMatrix();
glEnable(GL_LIGHTING);
glDepthFunc(GL_LEQUAL);
}
////////////////////////////////////////////////////////////////////////////////
//! Mouse event handlers
////////////////////////////////////////////////////////////////////////////////
void mouse(int button, int state, int x, int y)
{
//mouse buttons
if (state == GLUT_DOWN)
{
mouse_buttons |= 1<<button;
}
else if (state == GLUT_UP)
{
mouse_buttons = 0;
}
mouse_old_x = x;
mouse_old_y = y;
}
void motion(int x, int y)
{ //mouse motion
float dx, dy;
dx = (float)(x - mouse_old_x);
dy = (float)(y - mouse_old_y);
if (mouse_buttons & 1)
{
rotate_x += dy * 0.2f;
rotate_y += dx * 0.2f;
}
else if (mouse_buttons & 4)
{
int mod = glutGetModifiers();
if (mod == GLUT_ACTIVE_CTRL)
{
xshift = xshift + dx*0.04;
yshift = yshift - dy*0.04;
}
else
{
translate_z += dy * 0.1f;
}
}
mouse_old_x = x;
mouse_old_y = y;
}
////////////////////////////////////////////////////////////////////////////////
//! Display Tracked Points
////////////////////////////////////////////////////////////////////////////////
void trackedSphere(float x, float y, float z, int size)
{
//Plot sphere, preserving original coords
glPushMatrix();
glTranslatef((GLfloat) x,(GLfloat) y, (GLfloat) z); //Move to object location
glutSolidSphere(0.15,50,50); //maybe switch to size of object, scaled appropriately
glPopMatrix();
}
////////////////////////////////////////////////////////////////////////////////
//! Render Display
////////////////////////////////////////////////////////////////////////////////
void display (void)
{
glClearColor (0.0,0.0,0.0,1.0);
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
// Draw axes
glPushMatrix();
glCallList(axes_list);
glPopMatrix();
light();
// shift model, use right click and drag to move Z, control+right click and drag to pan
glTranslatef(0 + xshift,-3 + yshift,-20 + translate_z);
// rotate based off left click and drag
glRotatef(rotate_x, 1.0, 0.0, 0.0);
glRotatef(rotate_y, 0.0, 1.0, 0.0);
// draw grid
drawGrid(7.1, 0.71);
// Display objects in buffer
// Color objects to be drawn
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, Color_Material_DIFF);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, Color_Material_SPEC);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, Color_Material_AMB);
glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mShininess);
//This needs to be an input to display as well as XYZsize
for(int i = 0; i<NumObj; i++ )
{
float xl = XYZ_Size[4*(i+1)];
float yl = XYZ_Size[4*(i+1)+1];
float zl = XYZ_Size[4*(i+1)+2];
float sz = XYZ_Size[4*(i+1)+3];
trackedSphere(xl,yl,zl,sz);
}
drawAxis(1); // plot axis
glutSwapBuffers();
}
////////////////////////////////////////////////////////////////////////////////
//! Window reshaping
////////////////////////////////////////////////////////////////////////////////
void reshape (int w, int h)
{
glViewport (0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
//glOrtho(-10.0f, 10.0f, -10.0f, 10.0f, 1.0f, 100.0f); //ridged model, no perspective (objects dont get smaller in the background
gluPerspective (60, (GLfloat)w / (GLfloat)h, 1.0, 100.0); //Has persepective when displayed << I like this one
glMatrixMode (GL_MODELVIEW);
}
int simpleGL(int argc, char **argv)
{
glutInit (&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize (500, 500);
glutInitWindowPosition (100, 100);
glutCreateWindow ("OutPutDisplay");
init ();
glutDisplayFunc (display);
glutIdleFunc (display);
glutMouseFunc(mouse);
glutMotionFunc(motion);
glutReshapeFunc (reshape);
glutMainLoop ();
return 0;
}
Upvotes: 1
Views: 1264
Reputation: 45
Here is the solution I came up with for now. It shows how I was able to update the display with a separate function's output using some glut calls. The problem was with the glutMainLoop function, using a separate function that has glutPostRedisplay and glutMainloopEvent I was able to update the rendering when the coordinates were updated. The program will display a 3d Sphere moving across a 3D coord system.
///////////////////////////////main.cpp
#include "simpleGL.h"
#include <stdio.h>
#include <string.h>
void gen_XYZ_coords(int time){
//Large program that just munches on data creating XYZ coords
//memset( XYZ_Size,0,sizeof(float)*(NumObj+1)*4);
float x = 0.0;
float y = 0.0;
float z = 0.0;
float sz = 1;
NumObj = 1;
for(int i = 0; i<4; i++){
x = float(time)/100.0f;
y = float(time)/100.0f;
z = float(time)/100.0f;
XYZ_Size[NumObj*4] = x;
XYZ_Size[NumObj*4+1] = y;
XYZ_Size[NumObj*4+2] = z;
XYZ_Size[NumObj*4+3] = sz;
}
for(int num =0; num < NumObj; num++){
printf("x: %f y: %f z: %f size: %f\n", XYZ_Size[NumObj*4] , XYZ_Size[NumObj*4+1], XYZ_Size[NumObj*4+2], XYZ_Size[NumObj*4+3] );
}
}
void main(int argc, char** argv){
float t = 0.0;
simpleGL(argc, argv); //Gets stuck here, but I want it to be up and generating spheres when gen_xyz starts running
for(t = 0; t < 10000; t++){
gen_XYZ_coords(t/10);
updateGL();
}
}
////////////////////////simpleGL.h
#ifndef SIMPLEGL_H
#define HEADERFILE_H
extern float XYZ_Size[];
extern int NumObj;
int simpleGL(int argc, char **argv);
void updateGL(void);
#endif
//////////////////////////////////simpleGL.cu
#include <GL/glew.h>
#include <GL/freeglut.h>
#include "simpleGL.h"
GLfloat Color_Material_AMB[] = {0.25, 0.20725, 0.20725,1}; //
GLfloat Color_Material_SPEC[] = {0.296648, 0.296648, 0.296648}; //
GLfloat Color_Material_DIFF[] = {0.829, 0.829,1.0, 1.0}; //
GLfloat SpecularLight[] = {1.0, 1.0, 1.0};//
GLfloat AmbientLight[] = {1.0, 1.0, 1.0};//
GLfloat DiffuseLight[] = {1.0, 1.0, 1.0}; //
GLfloat mShininess[] = {11.264}; //set the shininess of the material 0 =very shiny 128 = duller than a rock
GLfloat Light_Position[] = {10,10,10,1};
// This is for
float XYZ_Size[4*50]; //imit to 50 obj
int NumObj = 0;
// List for fast creationg of axis
static GLuint axes_list;
// mouse controls
int mouse_old_x, mouse_old_y;
int mouse_buttons = 0;
float rotate_x = 0.0;
float rotate_y = 0.0;
float xshift = 0.0;
float yshift = 0.0;
float translate_z = -3.0;
GLfloat angle = 0.0;
void keyboard(unsigned char key, int x, int y);
void mouse(int button, int state, int x, int y);
void motion(int x, int y);
void init (void) {
glEnable (GL_DEPTH_TEST);
glEnable (GL_LIGHTING);
glEnable (GL_LIGHT0);
glShadeModel(GL_SMOOTH); // Enable smooth shading
}
void light (void) {
glLightfv(GL_LIGHT0, GL_SPECULAR, SpecularLight);
glLightfv(GL_LIGHT0, GL_AMBIENT, AmbientLight);
glLightfv(GL_LIGHT0, GL_DIFFUSE, DiffuseLight);
glLightfv(GL_LIGHT0, GL_POSITION, Light_Position);
}
///////////////////////////////////////////////////////////////////////////////
// draw a grid on the xz plane
///////////////////////////////////////////////////////////////////////////////
void drawGrid(float size, float step)
{
// disable lighting
glDisable(GL_LIGHTING);
glBegin(GL_LINES);
glColor3f(0.3f, 0.3f, 0.3f);
for(float i=step; i <= size; i+= step)
{
glVertex3f(0, 0, i); // lines parallel to X-axis
glVertex3f( size, 0, i);
glVertex3f( i, 0, 0); // lines parallel to Z-axis
glVertex3f( i, 0, size);
}
// x-axis red
glColor3f(0.5f, 0, 0);
glVertex3f(0, 0, 0);
glVertex3f( size, 0, 0);
// z-axis blue
glColor3f(0,0,0.5f);
glVertex3f(0, 0, 0);
glVertex3f(0, 0, size);
// y-axis green
glColor3f(0,0.5f,0);
glVertex3f(0, 0, 0);
glVertex3f(0, 6.4, 0);
glEnd();
// enable lighting back
glEnable(GL_LIGHTING);
}
///////////////////////////////////////////////////////////////////////////////
// draw the local axis of an object
///////////////////////////////////////////////////////////////////////////////
void drawAxis(float size)
{
glDisable(GL_LIGHTING);
glPushMatrix();
// draw axis
glLineWidth(3);
glBegin(GL_LINES);
glColor3f(1, 0, 0); //red
glVertex3f(0, 0, 0);
glVertex3f(size, 0, 0); //
glColor3f(0, 1, 0); //green
glVertex3f(0, 0, 0);
glVertex3f(0, size, 0);
glColor3f(0, 0, 1); //blue
glVertex3f(0, 0, 0);
glVertex3f(0, 0, size);
glEnd();
glLineWidth(1);
// draw arrows(actually big square dots)
glPointSize(5);
glBegin(GL_POINTS);
glColor3f(1, 0, 0);
glVertex3f(size, 0, 0);
glColor3f(0, 1, 0);
glVertex3f(0, size, 0);
glColor3f(0, 0, 1);
glVertex3f(0, 0, size);
glEnd();
glPointSize(1);
// restore default settings
glPopMatrix();
glEnable(GL_LIGHTING);
glDepthFunc(GL_LEQUAL);
}
////////////////////////////////////////////////////////////////////////////////
//! Mouse event handlers
////////////////////////////////////////////////////////////////////////////////
void mouse(int button, int state, int x, int y){
//mouse buttons
if (state == GLUT_DOWN)
{
mouse_buttons |= 1<<button;
}
else if (state == GLUT_UP)
{
mouse_buttons = 0;
}
mouse_old_x = x;
mouse_old_y = y;
}
void motion(int x, int y)
{ //mouse motion
float dx, dy;
dx = (float)(x - mouse_old_x);
dy = (float)(y - mouse_old_y);
if (mouse_buttons & 1)
{
rotate_x += dy * 0.2f;
rotate_y += dx * 0.2f;
}
else if (mouse_buttons & 4)
{
int mod = glutGetModifiers();
if (mod == GLUT_ACTIVE_CTRL){
xshift = xshift + dx*0.04;
yshift = yshift - dy*0.04;
}
else{
translate_z += dy * 0.1f;
}
}
mouse_old_x = x;
mouse_old_y = y;
}
////////////////////////////////////////////////////////////////////////////////
//! Display Tracked Points
////////////////////////////////////////////////////////////////////////////////
void trackedSphere(float x, float y, float z, int size){
//Plot sphere, preserving original coords
glPushMatrix();
glTranslatef((GLfloat) x,(GLfloat) y, (GLfloat) z); //Move to object location
glutSolidSphere(0.15,50,50); //maybe switch to size of object, scaled appropriately
glPopMatrix();
}
////////////////////////////////////////////////////////////////////////////////
//! Render Display
////////////////////////////////////////////////////////////////////////////////
void display (void) {
glClearColor (0.0,0.0,0.0,1.0);
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
// Draw axes
glPushMatrix();
glCallList(axes_list);
glPopMatrix();
light();
// shift model, use right click and drag to move Z, control+right click and drag to pan
glTranslatef(0 + xshift,-3 + yshift,-20 + translate_z);
// rotate based off left click and drag
glRotatef(rotate_x, 1.0, 0.0, 0.0);
glRotatef(rotate_y, 0.0, 1.0, 0.0);
// draw grid
drawGrid(7.1, 0.71);
// Display objects in buffer
// Color objects to be drawn
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, Color_Material_DIFF);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, Color_Material_SPEC);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, Color_Material_AMB);
glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mShininess);
//This needs to be an input to display as well as XYZsize
for(int i = 0; i<NumObj; i++ ){
float xl = XYZ_Size[4*(i+1)];
float yl = XYZ_Size[4*(i+1)+1];
float zl = XYZ_Size[4*(i+1)+2];
float sz = XYZ_Size[4*(i+1)+3];
trackedSphere(xl,yl,zl,sz);
}
drawAxis(1); // plot axis
glutSwapBuffers();
}
////////////////////////////////////////////////////////////////////////////////
//! Window reshaping
////////////////////////////////////////////////////////////////////////////////
void reshape (int w, int h) {
glViewport (0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
//glOrtho(-10.0f, 10.0f, -10.0f, 10.0f, 1.0f, 100.0f); //ridged model, no perspective (objects dont get smaller in the background
gluPerspective (60, (GLfloat)w / (GLfloat)h, 1.0, 100.0); //Has persepective when displayed << I like this one
glMatrixMode (GL_MODELVIEW);
}
int simpleGL(int argc, char **argv) {
glutInit (&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize (500, 500);
glutInitWindowPosition (100, 100);
glutCreateWindow ("OutPutDisplay");
init ();
glutDisplayFunc (display);
glutIdleFunc (display);
glutMouseFunc(mouse);
glutMotionFunc(motion);
glutReshapeFunc (reshape);
return 0;
}
void updateGL(void){
glutPostRedisplay();
glutMainLoopEvent();
}
Upvotes: 2