Compiling OpenGL Code with MFC
Using MFCSource Code: MFC Cube Zip Format MainFrame ClassStep 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); } View ClassStep 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 miliseconds 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[i]=(GLfloat) pColorTable[i].rgbRed/255; m_green[i]=(GLfloat) pColorTable[i].rgbGreen/255; m_blue[i]=(GLfloat) pColorTable[i].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); } Discuss this article in the forums
See Also: © 1999-2011 Gamedev.net. All rights reserved. Terms of Use Privacy Policy
|