如何在VC6或者VC7下用 ATL做一个OpenGL的(COM)控件?

    技术2022-05-11  175

    如何在VC6或者VC7下用 ATL做一个OpenGL的(COM)控件?

    目的:由于在写OpenGL程序的时候这些东西每次都要写一遍,而且特别繁琐!为了刚步入OpenGL人提供一个界面控件,让他们较早的看到自己写的OpenGL程序的效果!让他们觉得OpenGL的神奇!

    作者:王卫星(wangweixing2000

    1,  新建一个ATL空项目(项目名OpenGL_ATL

    2,  添加一个ATL对象(MyControl)VC6下为Full Control,VC7下为ATL控件)必须选中Support Connection Points为了添加事件。

    3,  在对象的.H头文件中添加:

      #include <gl/gl.h> #include <gl/glu.h> #pragma comment(lib, "opengl32.lib") #pragma comment(lib, "glu32.lib")

    4,  在接口实现类添加一个OpenGL RC(rendering context)成员变量:

    HGLRC m_hRC;

    5,  添加一个设置OpenGL像素格式(接口实现类的)成员函数:

    // Set OpenGL pixel format for given DC

    BOOL MyControl::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)

        {

            ATLASSERT(FALSE);

            return FALSE;

        }

     

        if (SetPixelFormat(hdc, pixelformat, &pfd) == FALSE)

        {

            ATLASSERT(FALSE);

            return FALSE;

        }

     

        return TRUE;

    }

    6, 添加一个Windows消息WM_CREATE

    LRESULT CMyControl::OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/,

        LPARAM /*lParam*/, BOOL& /*bHandled*/)

    {

        HDC hdc = GetDC();

        RECT rc;

        GetClientRect(&rc);

        CreateContext(hdc, rc);   //初始化

     

        return 0;

    }

    7,添加一个Windows消息WM_DESTROY

    LRESULT CMyControl::OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) {   wglMakeCurrent(NULL, NULL);   if (m_hRC)   {     wglDeleteContext(m_hRC);     m_hRC = NULL;   }   return 0; }

    7, 添加一个事件OnRender,点击ClassView中的IMyControlEvents添加方法OnRender参数int right,int left,int bottom,int top确定,然后编译你的idl文件,点击CMyControl实现连接点选中IMyControlEvents点击确定。

    8,  OnDraw添加代码:

    HRESULT OnDraw(ATL_DRAWINFO& di) {     HDC hdc = di.hdcDraw;     RECT& rc = *(RECT*)di.prcBounds;       wglMakeCurrent(hdc, m_hRC);       glClearColor(1.0f, 0.0f, 0.0f, 10.0f);     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //激发OnRender事件 FireOnRender(rc.right , rc.left, rc.bottom , rc.top) //vc7下不用加前缀Fire //OnRender(rc.right , rc.left, rc.bottom , rc.top)     glFinish();     SwapBuffers(wglGetCurrentDC());     return S_OK; } 9,  编译。

    要使用本控件很简单注册拖到你的窗体上,然后在OnRender事件中写你要画的物体就可以了!


    最新回复(0)