在VC.net下调用OpenGL的方法

在VC.net下调用OpenGL的方法

一.相关的Windows Api
    OpenGL向渲染上下文(RC)绘制图形,而非设备上下文(DC),所以必须用WinApi把它们关联起来。
要在.net的窗体中调用OpenGL的函数绘图,所使用的Api有六个:
    以下三个函数位于"opengl32.dll"中,负责把OpenGL所使用的渲染上下文(RC)和设备上下文关联起来。
    HGLRC wglCreateContext(HDC hdc);
    BOOL wglDeleteContext(HGLRC hglrc);
    BOOL wglMakeCurrent(HDC hdc, HGLRC hglrc);
    以下三个函数位于"gdi32.dll"中,负责设置像素格式和交换内存缓冲区。
    int ChoosePixelFormat(HDC hdc,PIXELFORMATDESCRIPTOR* pfd);
    int SetPixelFormat(HDC hdc,int pf,PIXELFORMATDESCRIPTOR* pfd);
    int SwapBuffers(HDC hdc);
    在以上这些Api中,使用了句柄HDC和HGLRC,而.net的类库中没有这些类,所以必须对它们重新封装,使其可以在.net编程环境中被调用。

二.用PInvoke封装函数
    为了调用上面提到的六个Windows Api,要使用PInvoke技术。所谓PInvoke技术,就是在托管代码中使用非托管的Api。
首先在程序中添加下面的名字空间:
    using namespace System::Runtime::InteropServices;

    下面对上面提到的六个Windows Api进行封装:
    [DllImportAttribute("opengl32.dll")]
    extern int wglCreateContext(Int32 hdc);
    [DllImportAttribute("opengl32.dll")]
    extern bool wglDeleteContext(Int32 hglrc);
    [DllImportAttribute("opengl32.dll")]
    extern bool wglMakeCurrent(Int32 hdc,Int32 hglrc);
 
    [DllImportAttribute("gdi32.dll")]
    extern int ChoosePixelFormat(Int32 hdc,PIXELFORMATDESCRIPTOR* pfd);
    [DllImportAttribute("gdi32.dll")]
    extern int SetPixelFormat(Int32 hdc,Int32 pf,PIXELFORMATDESCRIPTOR* pfd);
    [DllImportAttribute("gdi32.dll")]
    extern int SwapBuffers(Int32 hdc);

    注意在上面的代码中,我们把句柄封装成int类型,这是因为句柄就是一个指针。
    这样,我们就可以在.net的程序中调用这几个Api和OpenGL函数进行绘图。

三.代码示例
    下面给出一个简单的代码实例:
    新建一个windows窗体应用程序,在窗体的构造函数中加入如下代码:

    PIXELFORMATDESCRIPTOR pfd ;                 //像素格式描述         
    pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);  
    pfd.nVersion = 1 ;                           // Version number
    pfd.dwFlags =  PFD_DOUBLEBUFFER |            // Use double buffer
                   PFD_SUPPORT_OPENGL |          // Use OpenGL
                   PFD_DRAW_TO_WINDOW ;          // Pixel format is for a window.
    pfd.iPixelType = PFD_TYPE_RGBA ;
    pfd.cColorBits = 24;                         // 8-bit color
    pfd.cDepthBits = 32 ;                      // 32-bit depth buffer
    pfd.iLayerType = PFD_MAIN_PLANE ;            // Layer type
 
    hdc=this->CreateGraphics()->GetHdc().ToInt32(); //得到设备上下文
    int pf = ChoosePixelFormat(hdc, &pfd);
    SetPixelFormat(hdc, pf, &pfd);
    hglrc = wglCreateContext(hdc);                  //得到渲染上下文
    wglMakeCurrent(hdc,hglrc);

    在窗体的Paint事件中加入如下代码:
    glClearColor(0.3,0.3,0.3,0.0);                          //黑色背景
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_TEXTURE_2D);

    int w=this->Width;
    int h=this->Height;
    glShadeModel(GL_SMOOTH);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(60.0,(GLfloat)w/(GLfloat)h,1.0,25.0);        //设置视野
    gluLookAt(0.0,5.0,5.0,0.0,-5.0,-5.0,0.0,1.0,0.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    float light_position[]={5.0,5.0,5.0,1.0};                   //设置光源
    float light_diffuse[]={1.0,1.0,1.0,1.0};
    float light_ambient[]={1.0,1.0,1.0,1.0};
    float light_specular[]={1.0,1.0,1.0,1.0};
    glLightfv(GL_LIGHT0,GL_AMBIENT,light_ambient);
    glLightfv(GL_LIGHT0,GL_DIFFUSE,light_diffuse);
    glLightfv(GL_LIGHT0,GL_SPECULAR,light_specular);
    glLightfv(GL_LIGHT0,GL_POSITION,light_position);
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);

    float mat_ambient[]={0.2,0.2,0.2,0.0};                  //设置材质属性
    float mat_diffuse[]={0.2,0.4,0.9,0.0};
    float mat_specular[]={0.2,0.5,0.8,0.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,80.0);
    glutSolidTeapot(2.0);
    glFlush();
    SwapBuffers(hdc);
    上面这个代码实例绘制了一个带光照效果的茶壶。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值