Jump to content

  • Log In with Google      Sign In   
  • Create Account

Interested in a FREE copy of HTML5 game maker Construct 2?

We'll be giving away three Personal Edition licences in next Tuesday's GDNet Direct email newsletter!

Sign up from the right-hand sidebar on our homepage and read Tuesday's newsletter for details!


We're also offering banner ads on our site from just $5! 1. Details HERE. 2. GDNet+ Subscriptions HERE. 3. Ad upload HERE.


Like
0Likes
Dislike

Compiling OpenGL Code with MFC

By David Nishimoto | Published Apr 16 2002 08:16 AM in OpenGL

//vertice gltexcoord2f(0 glvertex3f(-1 glvertex3f(1 gltexcoord2f(1 todo rendering class
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

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 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[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.




PARTNERS