我在win32下编写了一个OpenGL画图程序,可以顺利编译及运行,我想将这功能融入到我的MFC对话框程序中,所以我将原来OpenGL内的函数都在对话框中进行了声明并实现,但会报错:error C2664: “glutDisplayFunc” : 不能将参数 1 从“void (void)”转换为“void (__cdecl *)(void)”
        在匹配目标类型的范围内没有具有该名称的函数
error C2664: “glutReshapeFunc” : 不能将参数 1 从“void (int,int)”转换为“void (__cdecl *)(int,int)”
        在匹配目标类型的范围内没有具有该名称的函数
error C2664: “glutKeyboardFunc” : 不能将参数 1 从“void (unsigned char,int,int)”转换为“void (__cdecl *)(unsigned char,int,int)”
        在匹配目标类型的范围内没有具有该名称的函数
这是怎么回事?难道不能直接将OpenGL放进MFC中吗?编程方式不同吗?修改后的OpenGL画图代码如下:
void CErrorDetectionofPrinterDlg::OpenGL_init(void)
{
glClearColor (1.0, 1.0, 1.0, 0);
glShadeModel (GL_FLAT);
}void CErrorDetectionofPrinterDlg::OpenGL_display(void)
{
long i,j,k,distance; glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);


glColor3f (0.0, 0.0, 0.0); glScalef (1.0,1.0,1.0);  
glPushMatrix();
glTranslatef(0,1300,1500);
glutWireCube (200.0);
glPopMatrix(); //画三维图 glLineWidth(0.5);
glColor3f(0,0,1);
glScalef(1,1,1); for(i=0;i<xLength;i++)
for(j=0;j<yLength;j++)
{
if(*(pDataMat+i*yLength+j)   >30)
glColor3f(1,0,0); 
else if(*(pDataMat+i*yLength+j)   >20)
glColor3f(1,1,0);
else if(*(pDataMat+i*yLength+j)   >10)
glColor3f(0,1,0);
else
glColor3f(0,0,1); if( *(pDataMat+i*yLength+j)!=0)
{
glBegin(GL_LINES);
glVertex3f(i,j, *(pDataMat+i*yLength+j)  );
glVertex3f(i,j,0);
}
glEnd();
}

//画坐标轴
glColor3f(0,0,0);
glLineWidth(2.0);
//X axis
glBegin(GL_LINES);
glVertex3f(0,0,0);
glVertex3f(SCALE1*xLength,0,0);
glEnd();
//Y axis
glBegin(GL_LINES);
glVertex3f(0,0,0);
glVertex3f(0,SCALE1*yLength,0);
glEnd();
//Z axis
glBegin(GL_LINES);
glVertex3f(0,0,0);
glVertex3f(0,0,SCALE1*zLength);
glEnd(); //画箭头
glPushMatrix();
glTranslatef(SCALE1*xLength,0,0);
glRotatef(90,0,1,0);
glutSolidCone(zLength/100.0,xLength/24.0,50,50);
glPopMatrix();

glPushMatrix();
glTranslatef(0,SCALE1*yLength,0);
glRotatef(-90,1,0,0);
glutSolidCone(zLength/100.0,yLength/24.0,50,50);
glPopMatrix(); glPushMatrix();
glTranslatef(0,0,SCALE1*zLength);
glutSolidCone(12,zLength/24.0,50,50);
glPopMatrix(); //画字母XYZ
glColor3ub(0,0,0);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glRasterPos3f(SCALE1*xLength,-30,0);
glBitmap(8,13,0,0,0,0,rastersX);
glRasterPos3f(-30,SCALE1*yLength,0);
glBitmap(8,13,0,0,0,0,rastersY);
glRasterPos3f(0,20,SCALE1*zLength);
glBitmap(8,13,0,0,0,0,rastersZ); //画底平面
glColor3f(0.95,0.95,0.95);
glTranslatef(0,0,-zLength/400.0);
glRectf(0,0,xLength,yLength); //画侧面虚线
glEnable(GL_LINE_STIPPLE);
glLineStipple(1,0xe0e0);
glLineWidth(0.6);
glColor3f(0.5, 0.5, 0.5); distance=zLength/4;
for(k=1;k<=zLength;k++)
{
if(k%distance==0) //虚线间距
glBegin(GL_LINES);
glVertex3f(0,0,k);
glVertex3f(0,SCALE1*yLength,k);
glVertex3f(0,0,k);
glVertex3f(SCALE1*xLength,0,k);
glEnd();
}
glDisable(GL_LINE_STIPPLE);
/*
glVertex3f(500,600,400);
glVertex3f(500,600,00);
glColor3ub(255,255,0);
glVertex3f(500,605,900);
glVertex3f(500,605,00); glVertex3f(500,1000,700);
glVertex3f(500,1000,00);
*/ /* 投影变换 */
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
glOrtho (-1*xLength, 1.2*yLength, -1*zLength,1.2*zLength, 100, 200000.0);
    /* 视点变换 */   
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
gluLookAt (20e3, 17e3, 10*zLength,  0, 0, 0,  0, 0, 1); glFlush ();
}void CErrorDetectionofPrinterDlg::OpenGL_reshape(int w, int h)
{
/* 视口变换 */
glViewport (0, 0, (GLsizei) w, (GLsizei) h); 
}void CErrorDetectionofPrinterDlg::OpenGL_keyboard(unsigned char key, int x, int y)
{
switch (key) {
      case 27:
         exit(0);
         break;
   }
}void CErrorDetectionofPrinterDlg::draw3d(float* array, int x, int y)
{
xLength=x;
yLength=y;
pDataMat=array; glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize (WindowWidth, WindowHeight); 
glutInitWindowPosition (100, 50);
glutCreateWindow ("3D GRAPH");
OpenGL_init();
glutDisplayFunc(OpenGL_display); 
glutReshapeFunc(OpenGL_reshape);
glutKeyboardFunc(OpenGL_keyboard); glutMainLoop();}

解决方案 »

  1.   

    当然是错误的,你还没有创建OpenGL的显示环境,首先获取对话框DC,创建OpenGL DC,然后再将两个DC连接在一起。这方面你可以baidu一下 《VC创建OpenGL环境》,上面有很多实例介绍。另外你不能这样显示OpenGL数据,你需要在对话框的控件或者对话框背景上显示。所以就不需要使用GLUT库另外创建窗口了,不然就会报你上面所说的错误。
      

  2.   

    需要在对话框的控件或者背景上显示是什么意思?我百度了下如何在MFC中使用OpenGL,是需要按下面的做吗?如何在MFC中调用OpenGL
    第一步:
    在CView类cpp中添加头文件支持:
    #include <gl/GL.h>
    #include <gl/glut.h>第二步:
    更改窗口样式使其支持OpenGL.
    在CView类成员函数PreCreateWindow中添加代码
    cs.style|=WS_CLIPSIBLINGS|WS_CLIPCHILDREN;第三步:
    重写CView中的Create函数,在函数中添加代码
    CString ClassName=AfxRegisterWndClass(CS_OWNDC);第四步:
    重新设置像素格式,并将其设置为当前像素格式
    在CView类中添加public型成员函数
    BOOL SetupPixelFormat(HDC hDC);
    函数体如下:
    //step 3 重新设置像素格式
    BOOL CXXXMFCGLView::SetupPixelFormat(HDC hDC)
    {
    //重新设置画图窗口的像素格式
    static PIXELFORMATDESCRIPTOR pfd =
    {
    sizeof(PIXELFORMATDESCRIPTOR),  // size of this pfd
    1,                              // version number
    PFD_DRAW_TO_WINDOW |            // support window
    PFD_SUPPORT_OPENGL |          // support OpenGL
    PFD_DOUBLEBUFFER,             // double buffered
    PFD_TYPE_RGBA,                  // RGBA type
    24,                             // 24-bit color depth
    0, 0, 0, 0, 0, 0,               // color bits ignored
    0,                              // no alpha buffer
    0,                              // shift bit ignored
    0,                              // no accumulation buffer
    0, 0, 0, 0,                     // accum bits ignored
    32,                             // 32-bit z-buffer
    0,                              // no stencil buffer
    0,                              // no auxiliary buffer
    PFD_MAIN_PLANE,                 // main layer
    0,                              // reserved
    0, 0, 0                         // layer masks ignored
    };
    int pixelformat; //分配一个像素格式号
    if ( (pixelformat = ChoosePixelFormat(hdc, &pfd)) == 0 )
    {
    MessageBox(L"ChoosePixelFormat failed");
    return FALSE;
    } //设置为当前的像素格式
    if (SetPixelFormat(hdc, pixelformat, &pfd) == FALSE)
    {
    MessageBox(L"SetPixelFormat failed");
    return FALSE;
    }
    return TRUE;
    }第五步:
    在CView类中添加消息WM_CREATE,在OnCreate函数中添加代码
    HDC hDC;
    HGLRC hRC;
    hDC=::GetDC(GetSafeHwnd());
    SetupPixelFormat(hDC);
    hRC=wglCreateContext(hDC);
    wglMakeCurrent(hDC, hRC);第六步:
    初始化OpenGL
    重写CView类中的OnInitialUpdate,根据需要在OnInitialUpdate中添加代码
    这里OnInitialUpdate的作用与常用的OpenGL控制台程序中init()相同
    例如:
    //初始化OpenGL
    //////////////////////////////////////////////////////
    glClearColor(1.0, 1.0, 1.0, 1.0);
    glEnable(GL_SMOOTH);
    glEnable(GL_DEPTH_TEST);
    //set material property1
    glNewList(0, GL_COMPILE);
    glEnable(GL_COLOR_MATERIAL);
    GLfloat mat_ambient[]={0.15, 0.07, 0.04, 1.0}; //原材料的环境颜色
    GLfloat mat_diffuse[]={0.15, 0.07, 0.04, 1.0}; //原材料的散射颜色
    GLfloat mat_specular[]={0.15, 0.07, 0.04, 1.0}; //原材料的反射颜色
    GLfloat mat_emission[]={0.15, 0.07, 0.04, 1.0}; //原材料的发散颜色
    glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
    glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
    glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
    glMaterialf(GL_FRONT, GL_SHININESS, 50.0);
    glMaterialfv(GL_FRONT, GL_EMISSION, mat_emission);
    glEndList(); //set light0
    glNewList(1, GL_COMPILE);
    glEnable(GL_LIGHTING);
    GLfloat light0_position[]={1.0, 1.0, 1.0, 1.0};
    GLfloat light0_spot_direction[]={-1.0, -1.0, -1.0, 1.0};
    GLfloat light0_ambient[]={0.015, 0.007, 0.004, 1.0};
    GLfloat ligh0_diffuse[]={1.0, 1.0, 1.0, 1.0};
    GLfloat light0_specular[]={1.0, 1.0, 1.0, 1.0};
    glLightfv(GL_LIGHT0, GL_POSITION, light0_position);
    glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 45);
    glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, light0_spot_direction);
    glLightfv(GL_LIGHT0, GL_AMBIENT, light0_ambient);
    glLightfv(GL_LIGHT0, GL_DIFFUSE, ligh0_diffuse);
    glLightfv(GL_LIGHT0, GL_SPECULAR, light0_specular);
    glEnable(GL_LIGHT0);
    glEndList();
    //////////////////////////////////////////////////////第七步:
    在CView类中添加WM_SIZE的消息响应函数OnSize
    这里OnSize的作用与OpenGL控制台编程中reshape的作用相同
    根据需要在其中添加代码
    例如:
    //////////////////////////////////////////////////////
    glCallList(1); glViewport(0, 0, cx, cy);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    if (cx <= cy) 
    gluOrtho2D (-1.0, 1.0, 
    -1.0*(GLfloat)cy/(GLfloat)cx, 1.0*(GLfloat)cy/(GLfloat)cx);
    else 
    gluOrtho2D (-1.0*(GLfloat)cx/(GLfloat)cy, 
    1.0*(GLfloat)cx/(GLfloat)cy, -1.0, 1.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    //////////////////////////////////////////////////////第八步:
    根据需要在CView类OnDraw函数中添加代码绘图
    在这里OnDraw的功能与OpenGL按制台编程中的display函数相同
    例如:
    //////////////////////////////////////////////////////
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glRotatef(0, 1.0f, 0.0f, 0.0f);
    glRotatef(0, 0.0f, 1.0f, 0.0f); glCallList(0);
    glutSolidTeapot(0.5);
    glPushMatrix();
    glTranslatef(-0.8, -0.3, -0.2);
    glutSolidTorus(0.1, 0.2, 50, 60);
    glPopMatrix(); glPushMatrix();
    glTranslatef(0.9, 0, 0);
    glutSolidSphere(0.2, 80, 80);
    glPopMatrix();
    glFlush();
    SwapBuffers(wglGetCurrentDC());
    //////////////////////////////////////////////////////
    第九步:
    在CView类中添加WM_DESTROYR的消息响应函数OnDestroy
    在其中添加如下代码:
    HGLRC hRC;
    hRC=wglGetCurrentContext();
    wglMakeCurrent(NULL, NULL);
    if (hRC)
    {
    wglDeleteContext(hRC);
    }到这里,一个完整的MFC调用OpenGL的程序就大功告成了。
      

  3.   

    包含的头文件有问题,居然没指定调用规范,默认的是__cdecl,和你的lib文件不匹配
      

  4.   

    修改头文件就可以了吗?环境设置和原来win32的一样吗?该如何修改呢?我不懂呢。我先前设置了环境及copy了相应的库文件,在win32是可以运行的。
      

  5.   


    这个说的是对的在MFC下使用OPENGL只复制粘贴是不行的,要重新搭建环境,自己百度一下吧。。网上有很多这种帖子、博客的