Compiling OpenGL Code with MFC

Published April 16, 2002 by David Nishimoto, posted by Myopic Rhino
Do you see issues with this article? Let us know.
Advertisement
[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);
}
Cancel Save
0 Likes 0 Comments

Comments

Nobody has left a comment. You can be the first!
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!
Advertisement