Jump to content
  • Advertisement
  • 04/16/02 02:16 PM
    Sign in to follow this  

    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);
    }


      Report Article
    Sign in to follow this  


    User Feedback


    There are no comments to display.



    Create an account or sign in to comment

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

    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

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!