Compiling OpenGL Code with MFC
By David Nishimoto | Published Apr 16 2002 08:16 AM in OpenGL
| If you find this article contains errors or problems rendering it unreadable (missing images or files, mangled code, improper text formatting, etc) please contact the editor so corrections can be made. Thank you for helping us improve this resource |
Using MFC
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
Step 1: Step up the pixel format and create a rendering context
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);
} 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 contextsvoid 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 styleBOOL 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 millisecondsvoid 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 Codevoid 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 Examplevoid 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);
}
Comments
Note: Please offer only positive, constructive comments - we are looking to promote a positive atmosphere where collaboration is valued above all else.






