OpenGL和多线程
OpenGL and Multithreading
我在OpenGL和多线程方面遇到了一些麻烦。问题是我不明白为什么我有这个问题。我正在使用MACOS(因此,如果您尝试我的代码,包含内容将有所不同)。下面是我成功运行的简单程序,没有出现任何问题。
char title[] = "3D Shapes with animation";
GLfloat anglePyramid = 0.0f; // Rotational angle for pyramid [NEW]
GLfloat angleCube = 0.0f; // Rotational angle for cube [NEW]
int refreshMills = 15; // refresh interval in milliseconds [NEW]
bool serverHasInput = false ;
float matrix[16] = {0.7599139,0.0,-0.65002376,0.0,-0.45789394,0.709777,-0.5353035,0.0,0.4613719,0.70442647,0.5393694,0.0,0.0,0.0,0.0,1.0};
float moveX = 0;
float moveY = 0;
pthread_mutex_t mymutex ;
pthread_cond_t mycondition ;
/* Initialize OpenGL Graphics */
void initGL() {
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Set background color to black and opaque
glClearDepth(1.0f); // Set background depth to farthest
glEnable(GL_DEPTH_TEST); // Enable depth testing for z-culling
glDepthFunc(GL_LEQUAL); // Set the type of depth-test
glShadeModel(GL_SMOOTH); // Enable smooth shading
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Nice perspective corrections
}
/* Handler for window-repaint event. Called back when the window first appears and
whenever the window needs to be re-painted. */
void display() {
//while(matrixSet == true){
// sleep(0.01);
//}
pthread_mutex_lock(&mymutex);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear color and depth buffers
glMatrixMode(GL_MODELVIEW); // To operate on model-view matrix
// Render a color-cube consisting of 6 quads with different colors
glLoadIdentity(); // Reset the model-view matrix
glTranslatef(1.5f, 0.0f, -7.0f); // Move right and into the screen
glRotatef(angleCube, 1.0f, 1.0f, 1.0f); // Rotate about (1,1,1)-axis [NEW]
glMultMatrixf(matrix);
pthread_mutex_unlock(&mymutex);
glBegin(GL_QUADS); // Begin drawing the color cube with 6 quads
// Top face (y = 1.0f)
// Define vertices in counter-clockwise (CCW) order with normal pointing out
glColor3f(0.0f, 1.0f, 0.0f); // Green
glVertex3f( 1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f( 1.0f, 1.0f, 1.0f);
// Bottom face (y = -1.0f)
glColor3f(1.0f, 0.5f, 0.0f); // Orange
glVertex3f( 1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f( 1.0f, -1.0f, -1.0f);
// Front face (z = 1.0f)
glColor3f(1.0f, 0.0f, 0.0f); // Red
glVertex3f( 1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f( 1.0f, -1.0f, 1.0f);
// Back face (z = -1.0f)
glColor3f(1.0f, 1.0f, 0.0f); // Yellow
glVertex3f( 1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f( 1.0f, 1.0f, -1.0f);
// Left face (x = -1.0f)
glColor3f(0.0f, 0.0f, 1.0f); // Blue
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
// Right face (x = 1.0f)
glColor3f(1.0f, 0.0f, 1.0f); // Magenta
glVertex3f(1.0f, 1.0f, -1.0f);
glVertex3f(1.0f, 1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, -1.0f);
glEnd(); // End of drawing color-cube
glutSwapBuffers(); // Swap the front and back frame buffers (double buffering)
// Update the rotational angle after each refresh [NEW]
//anglePyramid += 1.2f;
//angleCube -= 0.15f;
pthread_cond_signal(&mycondition);
pthread_mutex_unlock(&mymutex);
}
/* Called back when timer expired [NEW] */
void timer(int value) {
glutPostRedisplay(); // Post re-paint request to activate display()
glutTimerFunc(refreshMills, timer, 0); // next timer call milliseconds later
}
/* Handler for window re-size event. Called back when the window first appears and
whenever the window is re-sized with its new width and height */
void reshape(GLsizei width, GLsizei height) { // GLsizei for non-negative integer
// Compute aspect ratio of the new window
if (height == 0) height = 1; // To prevent divide by 0
GLfloat aspect = (GLfloat)width / (GLfloat)height;
// Set the viewport to cover the new window
glViewport(0, 0, width, height);
// Set the aspect ratio of the clipping volume to match the viewport
glMatrixMode(GL_PROJECTION); // To operate on the Projection matrix
glLoadIdentity(); // Reset
// Enable perspective projection with fovy, aspect, zNear and zFar
gluPerspective(45.0f, aspect, 0.1f, 100.0f);
}
void keyPressed (unsigned char key, int x, int y) {
if (key == 'y'){
moveY += 0.5;
cout << "y" << endl ;
}
}
/* Main function: GLUT runs as a console application starting at main() */
int main(int argc, char* argv[]) {
glutInit(&argc, argv); // Initialize GLUT
glutInitDisplayMode(GLUT_DOUBLE); // Enable double buffered mode
glutInitWindowSize(640, 480); // Set the window's initial width & height
glutInitWindowPosition(50, 50); // Position the window's initial top-left corner
glutCreateWindow(title); // Create window with the given title
glutDisplayFunc(display); // Register callback handler for window re-paint event
glutReshapeFunc(reshape); // Register callback handler for window re-size event
initGL(); // Our own OpenGL initialization
glutTimerFunc(0, timer, 0); // First timer call immediately [NEW]
glutKeyboardFunc(keyPressed); // Tell GLUT to use the method "keyPressed" for key presses
glutMainLoop(); // Enter the infinite event-processing loop
}
这就是我的基本代码。然而,当我试图创建一个线程使其运行时,我不能再得到keyboardinput以及其他一些错误的方面(例如,不能在X上点击退出窗口)。
下面是我的代码:我的OpenGL函数都是一样的,除了这部分:/* Main function: GLUT runs as a console application starting at main() */
void* launch(void* args) {
mainArg* arg = (mainArg*) args ;
glutInit(arg->argc, &arg->argv); // Initialize GLUT
下面是我创建线程的方法:
//the thread function
void *connection_handler(void *);
void * connection_thread(void *);
void * input_thread(void *);
void test();
int main(int argc , char *argv[])
{
//Draw* d = new Draw() ;
pthread_t server_thread ;
pthread_t drawing_thread ;
pthread_t input_thread ;
mainArg args ;
args.argc = &argc ;
args.argv = *argv ;
pthread_mutex_init (&mymutex, NULL);
pthread_cond_init (&mycondition, NULL);
cout << "Begin" << endl ;
if( pthread_create( &server_thread , NULL , &connection_thread , NULL) != 0)
{
cout << "could not create Connection thread" << endl ;
return 1;
}
/*if( pthread_create( &input_thread , NULL , &connection_thread , NULL) != 0)
{
cout << "could not create input thread" << endl ;
return 1;
}*/
if( pthread_create( &drawing_thread , NULL , &launch , &args) != 0)
{
perror("could not create Drawing thread");
return 1;
}
//while(1);
pthread_join(server_thread, NULL);
pthread_join(drawing_thread,NULL);
你知道这里出了什么问题吗?因为我已经看了好几天了,我似乎找不到答案。
编辑:我不分享OpenGL上下文或任何必须是OGL渲染在另一个线程的一部分。我的另一个线程只是一个服务器通信与其他设备。
EDIT2:我看到这里之前没有在主线程上的OGL渲染不应该是一个问题OpenGL渲染在次要线程
所以@user1118321是正确的。
尝试在后台线程上进行渲染绝对没有问题。然而,GLUT将无法访问操作系统窗口的信息(即键盘按下,退出窗口…)如果是这样的话。但是,如果渲染线程的目的只是渲染,那么把它放在后台线程上完全没有问题。
希望它也能帮助到其他人。
相关文章:
- 在C++中使用cURL和多线程
- 多线程双缓冲区
- 为什么我的多线程作业队列崩溃
- 在main()之外初始化std::vector会导致性能下降(多线程)
- 试图创建一个多线程程序来查找0-100000000之间的总素数
- 为什么一个向量上的多线程操作很慢
- 学习多线程C++:添加线程不会使执行速度更快,即使它看起来应该
- 全局变量 多读取器 一个写入器多线程安全?
- boost::文件系统::recursive_directory_iterator多线程安全
- 在多线程程序中创建OpenGL结构
- Ubuntu VirtualBox中的OpenGL多线程示例
- OpenGL多线程,可变处理
- OpenGL 上的多线程渲染
- 利用 openGL 的多线程
- 土壤中的多线程支撑用于OpenGL
- Opengl游戏循环多线程
- OpenGL CL多线程互操作
- OpenGL多线程/共享上下文和glGenBuffers
- c++OpenGL多线程缓冲资源
- OpenGL和多线程