🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

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