• 04/16/02 02:16 PM
    Sign in to follow this  
    Followers 0

    Compiling OpenGL Code with MFC

    Graphics and GPU Programming

    Myopic Rhino
    [size="5"]Using MFC

    [size="3"]MainFrame Class

    Step 1:
    In the Mainframe Class override the initial dimensions of the default Window. Using the CREATESTRUCT we change the dimensions of the window to 400 x 400

    BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
    {
    // TODO: Modify the Window class or styles here by modifying
    // the CREATESTRUCT cs

    cs.cx=400;
    cs.cy=400;

    return CFrameWnd::PreCreateWindow(cs);
    }

    BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
    {
    // TODO: Modify the Window class or styles here by modifying
    // the CREATESTRUCT cs

    cs.cx=400;
    cs.cy=400;

    return CFrameWnd::PreCreateWindow(cs);
    }
    BOOL CMainFrame::OnQueryNewPalette()
    {
    // TODO: Add your message handler code here and/or call default
    CView *pView=GetActiveView();
    pView->Invalidate(FALSE);
    return CFrameWnd::OnQueryNewPalette();
    }
    BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
    {
    // TODO: Modify the Window class or styles here by modifying
    // the CREATESTRUCT cs

    cs.cx=400;
    cs.cy=400;

    return CFrameWnd::PreCreateWindow(cs);
    }
    [size="3"]View Class

    Step 1:
    Step up the pixel format and create a rendering context

    int CMfc_cubeView::OnCreate(LPCREATESTRUCT lpCreateStruct)
    {
    if (CView::OnCreate(lpCreateStruct) == -1)
    return -1;

    // TODO: Add your specialized creation code here
    PIXELFORMATDESCRIPTOR pfd=
    {
    sizeof(PIXELFORMATDESCRIPTOR),
    1,
    PFD_DRAW_TO_WINDOW|
    PFD_SUPPORT_OPENGL|
    PFD_DOUBLEBUFFER,
    PFD_TYPE_RGBA,
    24, //24-bit color
    0,0,0,0,0,0,
    0,0,0,0,0,0,0,
    32, //32 bit depth buffer
    0,0,
    PFD_MAIN_PLANE, //Main layer type
    0,
    0,0,0
    };
    CClientDC clientDC(this);
    /*
    ChoosePixelFormat
    Requests a pixel-format index for a pixel format that most closely
    matches the format requested. This function's two arguments are a
    handle to the DC for which to select the pixel format and the
    address of the PIXELFORMATDESCRIPTOR structure that holds the attributes
    of the requested pixel format
    */
    int pixelFormat =ChoosePixelFormat(clientDC.m_hDC,&pfd);
    BOOL success = SetPixelFormat(clientDC.m_hDC,pixelFormat,&pfd);
    /*
    DescribePixelFormat
    Fills a PIXELFORMATDESCRIPTOR structure with information about the given
    pixel format. This function's four arguments are a handle to the DC, the
    pixel index to examine, and the size and address of PIXELFORMATDESCRIPTOR structure.
    */
    DescribePixelFormat(clientDC.m_hDC,pixelFormat, sizeof(pfd),&pfd);

    if (pfd.dwFlags & PFD_NEED_PALETTE)
    SetupLogicalPalette();

    /*
    wglCreateContext
    Creates a rendering context compatible with the given DC.
    */
    m_hRC=wglCreateContext(clientDC.m_hDC);
    /*
    wglMakeCurrent
    Makes a rendering context current, which binds the rendering
    context to the given DC. This function's two arguments
    are a handle to a DC and the handle to the rendering context.
    */
    wglMakeCurrent(clientDC.m_hDC,m_hRC);

    //Texture Mapping
    //Once you have your DIB loaded and its color tables created, you can
    // actually start thinking about your texture mapping
    //GL_TEXTURE_2D equates to a two-dimensional texture
    //GL_CLAMP for a single image
    //GL_REPEAT for a repeating pattern
    //GL_TEXTURE_MAG_FILTER determines how a texture is magnified when
    // the destination is larger than the texture.
    //GL_TEXTURE_MIN_FILTER determines how a texture is reduced
    //glTexEnvi set the texturing environment

    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);

    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
    glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_DECAL);

    glEnable(GL_DEPTH);
    glEnable(GL_TEXTURE_2D);

    glClearColor(1.0f,1.0f,1.0f,1.0f);

    wglMakeCurrent(clientDC.m_hDC,NULL);

    /* CDib is a class used to read Device Independant Bitmaps */
    m_pDib = new CDib("snake.BMP");
    CreateColorTables(m_pDib);
    SetupColorTables();
    /* The timer determines the rendering refresh rate in milliseconds*/
    SetTimer(1,1,0);
    return 0;
    }
    Step 2: Cleanup resources: Bitmaps, Timers, and device contexts

    void CMfc_cubeView::OnDestroy()
    {
    CView::OnDestroy();

    // TODO: Add your message handler code here
    KillTimer(1);
    delete m_pDib;
    /*Frees the Rendering Context. Cleanup of resources*/
    wglDeleteContext(m_hRC);
    if (m_hPalette)
    DeleteObject(m_hPalette);

    }
    Step 3: Modify the Class style

    BOOL CMfc_cubeView::PreCreateWindow(CREATESTRUCT& cs)
    {
    // TODO: Modify the Window class or styles here by modifying
    // the CREATESTRUCT cs
    cs.style |= WS_CLIPCHILDREN | WS_CLIPSIBLINGS;

    return CView::PreCreateWindow(cs);
    }
    Step 4: When Invalidate(TRUE) is invoked the OnDraw event is fired. The OnDraw method contains the rendering code portion.

    void CMfc_cubeView::OnDraw(CDC* pDC)
    {
    CMfc_cubeDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);

    // TODO: add draw code for native data here
    if (m_hPalette)
    {
    SelectPalette(pDC->m_hDC,m_hPalette, FALSE);
    RealizePalette(pDC->m_hDC);
    }
    wglMakeCurrent(pDC->m_hDC,m_hRC);
    DrawWithOpenGL();
    SwapBuffers(pDC->m_hDC);
    wglMakeCurrent(pDC->m_hDC,NULL);
    }
    Step 5: The OnSize method defines the current viewport, defines the PROJECTION Model and Object Model, and light sources.

    void CMfc_cubeView::OnSize(UINT nType, int cx, int cy)
    {
    CView::OnSize(nType, cx, cy);

    // TODO: Add your message handler code here
    CClientDC clientDC(this);
    wglMakeCurrent(clientDC.m_hDC,m_hRC);
    glViewport(0,0,cx,cy);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glFrustum(-1.0,1.0,-1.0,1.0,2.0,9.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    GLfloat light0Ambient[]={0.0f,0.0f,0.0f,1.0f};
    GLfloat light0Diffuse[]={1.0f,1.0f,1.0f,1.0f};
    GLfloat light0Position[]={0.0f,0.0f,0.0f,1.0f};

    glLightfv(GL_LIGHT0,GL_AMBIENT,light0Ambient);
    glLightfv(GL_LIGHT0,GL_DIFFUSE, light0Diffuse);
    glLightfv(GL_LIGHT0,GL_POSITION,light0Position);

    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);

    glTranslatef(0.0f,0.0f,-6.0f);
    wglMakeCurrent(NULL,NULL);
    }
    Step 6: On Timer event is invoke every X predefine milliseconds

    void CMfc_cubeView::OnTimer(UINT nIDEvent)
    {
    // TODO: Add your message handler code here and/or call default

    if (m_cube_animate==1 )
    {
    m_cube_spin+=2;
    }
    if (m_icosa_animate==1)
    {
    m_icosa_spin+=2;
    }
    Invalidate(FALSE);

    CView::OnTimer(nIDEvent);
    }
    Step 7: Your Rendering Code

    void CMfc_cubeView::DrawWithOpenGL()
    {
    glShadeModel(GL_SMOOTH);
    glEnable(GL_DEPTH_TEST);
    glClearColor(0.0f,0.0f,0.0f,1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    AnimateCube();
    }
    Step 8: The Animated Cube Example

    void CMfc_cubeView::AnimateCube()
    {
    GLfloat glfMaterialColor[]={0.2f,0.8f,0.5f,1.0f};
    GLvoid* pTextureBits = (GLvoid*) m_pDib->GetDibBitsPtr();
    GLint width = m_pDib->GetDibWidth();
    GLint height = m_pDib->GetDibHeight();

    glPushMatrix();
    glTexImage2D(GL_TEXTURE_2D,0,3,width,height,0,GL_COLOR_INDEX,
    GL_UNSIGNED_BYTE,pTextureBits);
    glClear(GL_COLOR_INDEX|GL_DEPTH_BUFFER_BIT);

    glRotatef(m_cube_spin,1.0,1.0,1.0);
    glScalef (0.5,0.5,0.5); /* modeling transformation */

    //glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE,glfMaterialColor);

    glBegin(GL_POLYGON);
    //glNormal3f(0.0f,0.0f,1.0f);
    //vertice 1
    glTexCoord2f(0.0f,1.0f);
    glVertex3f(1.0f,1.0f,1.0f);
    //vertice 2
    glTexCoord2f(0.0f,0.0f);
    glVertex3f(-1.0f,1.0f,1.0f);
    //vertice 3
    glTexCoord2f(1.0f,0.0f);
    glVertex3f(-1.0f,-1.0f,1.0f);
    //vertice 4
    glTexCoord2f(1.0f,1.0f);
    glVertex3f(1.0f,-1.0f,1.0f);
    glEnd();

    glBegin(GL_POLYGON);
    //glNormal3f(0.0f,0.0f,-1.0f);
    //vertice 1
    glTexCoord2f(0.0f,1.0f);
    glVertex3f(1.0f,1.0f,-1.0f);
    //vertice 2
    glTexCoord2f(0.0f,0.0f);
    glVertex3f(1.0f,-1.0f,-1.0f);
    //vertice 3
    glTexCoord2f(1.0f,0.0f);
    glVertex3f(-1.0f,-1.0f,-1.0f);
    //vertice 4
    glTexCoord2f(0.0f,0.0f);
    glVertex3f(-1.0f,1.0f,-1.0f);
    glEnd();

    glBegin(GL_POLYGON);
    //glNormal3f(-1.0f,0.0f,0.0f);
    //vertice 1
    glTexCoord2f(0.0f,1.0f);
    glVertex3f(-1.0f,1.0f,1.0f);
    //vertice 2
    glTexCoord2f(0.0f,0.0f);
    glVertex3f(-1.0f,1.0f,-1.0f);
    //vertice 3
    glTexCoord2f(1.0f,0.0f);
    glVertex3f(-1.0f,-1.0f,-1.0f);
    //vertice 4
    glTexCoord2f(1.0f,1.0f);
    glVertex3f(-1.0f,-1.0f,1.0f);
    glEnd();

    glBegin(GL_POLYGON);
    //glNormal3f(1.0f,0.0f,0.0f);
    //vertice 1
    glTexCoord2f(0.0f,1.0f);
    glVertex3f(1.0f,1.0f,1.0f);
    //vertice 2
    glTexCoord2f(0.0f,0.0f);
    glVertex3f(1.0f,-1.0f,1.0f);
    //vertice 3
    glTexCoord2f(1.0f,0.0f);
    glVertex3f(1.0f,-1.0f,-1.0f);
    //vertice 4
    glTexCoord2f(1.0f,1.0f);
    glVertex3f(1.0f,1.0f,-1.0f);
    glEnd();

    glBegin(GL_POLYGON);
    //glNormal3f(0.0f,1.0f,0.0f);
    //vertice 1
    glTexCoord2f(0.0f,1.0f);
    glVertex3f(-1.0f,1.0f,-1.0f);
    //vertice 2
    glTexCoord2f(0.0f,0.0f);
    glVertex3f(-1.0f,1.0f,1.0f);
    //vertice 3
    glTexCoord2f(1.0f,0.0f);
    glVertex3f(1.0f,1.0f,1.0f);
    //vertice 4
    glTexCoord2f(1.0f,1.0f);
    glVertex3f(1.0f,1.0f,-1.0f);
    glEnd();

    glBegin(GL_POLYGON);
    //glNormal3f(0.0f,-1.0f,0.0f);
    //vertice 1
    glTexCoord2f(0.0f,1.0f);
    glVertex3f(-1.0f,-1.0f,-1.0f);
    //vertice 2
    glTexCoord2f(0.0f,0.0f);
    glVertex3f(1.0f,-1.0f,-1.0f);
    //vertice 3
    glTexCoord2f(1.0f,0.0f);
    glVertex3f(1.0f,-1.0f,1.0f);
    //vertice 4
    glTexCoord2f(1.0f,1.0f);
    glVertex3f(-1.0f,-1.0f,1.0f);
    glEnd();

    glPopMatrix();
    }

    void CMfc_cubeView::CreateColorTables(CDib *pDib)
    {
    LPRGBQUAD pColorTable = pDib->GetDibRGBTablePtr();
    for(UINT i=0; i<256; ++i)
    {
    m_red=(GLfloat) pColorTable.rgbRed/255;
    m_green=(GLfloat) pColorTable.rgbGreen/255;
    m_blue=(GLfloat) pColorTable.rgbBlue/255;
    }
    }

    void CMfc_cubeView::SetupColorTables()
    {
    CClientDC clientDC(this);
    wglMakeCurrent(clientDC.m_hDC,m_hRC);
    glPixelMapfv(GL_PIXEL_MAP_I_TO_R,256,m_red);
    glPixelMapfv(GL_PIXEL_MAP_I_TO_G,256,m_green);
    glPixelMapfv(GL_PIXEL_MAP_I_TO_B,256,m_blue);
    glPixelTransferi(GL_MAP_COLOR,TRUE);
    wglMakeCurrent(clientDC.m_hDC,m_hRC);
    }

    void CMfc_cubeView::SetupLogicalPalette()
    {
    struct
    {
    WORD Version;
    WORD NumberOfEntries;
    PALETTEENTRY aEntries[256];
    }logicalPalette={0x300,256};

    BYTE reds[]={0,36,72,109,145,182,218,255};
    BYTE greens[]={0,36,72,109,145,182,218,255};
    BYTE blues[]={0,85,170,255};

    for(int colorNum=0; colorNum<256; ++colorNum)
    {
    logicalPalette.aEntries[colorNum].peRed=reds[colorNum&0x07];
    logicalPalette.aEntries[colorNum].peGreen=greens[(colorNum>>0x03)&0x07];
    logicalPalette.aEntries[colorNum].peBlue=blues[(colorNum>>0x06)&0x03];
    logicalPalette.aEntries[colorNum].peFlags=0;
    }
    m_hPalette=CreatePalette ((LOGPALETTE*)&logicalPalette);
    }
    0


    Sign in to follow this  
    Followers 0


    User Feedback

    Create an account or sign in to leave a review

    You need to be a member in order to leave a review

    Create an account

    Sign up for a new account in our community. It's easy!


    Register a new account

    Sign in

    Already have an account? Sign in here.


    Sign In Now

    There are no reviews to display.