我在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();}
在匹配目标类型的范围内没有具有该名称的函数
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();}
第一步:
在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的程序就大功告成了。
这个说的是对的在MFC下使用OPENGL只复制粘贴是不行的,要重新搭建环境,自己百度一下吧。。网上有很多这种帖子、博客的