Source: Computer World: http://www2.ccw.com.cn/99/9934/9934b16.ASP VC 6.0 Use OpenGL
Qinghua University Li Yong
---- To learn the OpenGL programming, hope that the readers have a basic graphic knowledge. This article uses a Visual C job-driven programming, which has a certain help for readers who have not learned VC. Our first priority will make a minimum need for OpenGL graphics. For this task, I will be in the next 5 steps:
- 1 Set the format of the window pixel; 2 build RC; 3 make the RC to be used as before; 4 create a viewpoint and matrix model; 5 draw a standing and a teapot.
---- Now you can open your Visual C , build a single document. First, we will add all the OpenGL files and libraries that must be needed in this item. In the menu, select Build Settings, then click the Link button (or press the Ctrl Tab button to move to the child). Key to OpenGL32.lib Glu32.lib Glaux.lib in the Object / Library column, and confirm. Open the document stdafx.h Insert as below:
#Include
#Include
#Include
---- OpenGL can only display a window with WS_CLIPCHILDREN and WS_CLIPSIBLINGS type, we need to edit the onPrecreate function, specify the window type.
Bool CopView :: PrecreateWindow (CreateStruct & Cs)
{cs.style | = (ws_clipchildren | ws_clipsiblings);
Return CView :: PrecreateWindow (CS);
}
---- Under the following, we have to define the pixel format of the window, this is very important to build RC. The first first we need to build a guaranteed member function BOOL SETWINDOWPIELFORMAT (HDC HDC). As follows:
Bool CopView :: SetWindowPixelformat (HDC HDC)
{
Pixelformatdescriptor Pixeldesc;
Pixeldesc.nsize = sizeof (Pixelformatdescript)
Tor);
Pixeldesc.nversion = 1;
Pixeldesc.dwflags = PFD_DRAW_TO_WINDOW |
PFD_DRAW_TO_BITMAP | PFD_support_opengl |
Pfd_support_gdi | pfd_stereo_dontcare;
Pixeldesc.ipixeltype = pfd_type_rgba;
Pixeldesc.ccolorbits = 32;
Pixeldesc.credbits = 8;
Pixeldesc.credshift = 16; pixeldesc.cgreenbits = 8;
Pixeldesc.cgreenshift = 8;
Pixeldesc.cbluebits = 8;
Pixeldesc.cblueshift = 0;
Pixeldesc.calphabits = 0;
Pixeldesc.calphashift = 0;
Pixeldesc.caccumbits = 64;
Pixeldesc.caccumredbits = 16;
Pixeldesc.caccumgreenbits = 16;
Pixeldesc.caccumbluebits = 16;
Pixeldesc.caccumalphabits = 0;
Pixeldesc.cdepthbits = 32;
Pixeldesc.cstencilbits = 8;
Pixeldesc.cauxbuffers = 0;
Pixeldesc.ilyertype = pfd_main_plane;
Pixeldesc.breserved = 0;
Pixeldesc.dwlayermask = 0;
Pixeldesc.dwvisiblemask = 0;
Pixeldesc.dwdamagemask = 0;
m_glpixelindex = choosepixelformat (hdc, & pixeldesc);
IF (m_glpixelindex == 0) // let's choose a default index.
{
m_glpixelindex = 1;
IF (Describepixelformat (HDC, M_GLpixelindex, Sizeof
(Pixelformatdescriptor), & Pixeldesc) == 0)
{
Return False;
}
}
IF (setpixelformat (hdc, m_glpixelindex,
& Pixeldesc) == false)
{
Return False;
}
Return True;
}
---- Add a member variable to the view class:
INT m_glpixelindex; // protected
---- Final, add function on ClassWizard to respond to message WM_CREATE, the function is as follows:
INT COPVIEW :: oncreate
(Lpcreatestruct lpcreatestruct)
{
IF (cview :: oncreate (lpcreatestructure) == -1)
Return -1;
HWND HWND = GetSafehWnd ();
HDC HDC = :: getdc (hwnd);
IF (SETWINDOWPIXELFORMAT (HDC) == FALSE
Return 0;
CreateViewGlContext (HDC) == false)
Return 0;
Return 0;
}
---- The step of the next step is to build RC and set it to the front RC.
---- Adding the CreateViewGlContext (HDC HDC) and Variable HGLRC M_HGLCONText:
Bool CopView :: CreateViewGlcontext (HDC HDC)
{
m_hglcontext = WGLCReateContext (HDC); if (m_hglcontext == null)
{
Return False;
}
IF (WGLmakecurrent (HDC, M_HGLCONTEXT) == false)
{
Return False;
}
Return True;
}
Add Functions OnDestroy to respond to WM_DESTROY:
Void CopView :: ONDESTROY ()
{
IF (WGlgetCurrentContext ()! = null)
{
WGLmakecurrent (null, null);
}
IF (m_hglcontext! = null)
{
WGLDeleteContext (m_hglcontext);
m_hglcontext = null;
}
CView :: ONDESTROY ();
}
---- The last, edit the CopView class structure function:
COPVIEW :: CopView ()
{
m_hglcontext = null;
m_glpixelindex = 0;
}
---- Now, we can take the OpenGL drawing, although it looks like a typical MFC program.
---- Now we will build a vertical viewpoint and matrix model in our next step, add the function on the function on the view class with ClassWizard. As follows:
Void CopView :: Onsize (uint ntype, int CX, int CY)
{
CView :: Onsize (NTYPE, CX, CY);
Glsizei width, height; gldouble aspect;
Width = cx; height = cy;
IF (cy == 0)
Aspect = (gldouble) width;
Else
Aspect = (gldouble) width / (gldouble) Height;
GLVIEWPORT (0, 0, Width, Height);
Glmatrixmode (GL_PROJECTION);
GLLoadIndentity ();
Gluperspective (45, Aspect, 1, 10.0);
Glmatrixmode (GL_ModelView);
GLLoadIndentity ();
}
Join the function: void copview :: onpaint ()
{
CPAINTDC DC (this); // Device Context for Painting
COPDOC * PDOC = getDocument ();
PDOC -> Renderscene ();
}
---- Add a public function renderscene (): in the document class.
Void Copdoc :: Renderscene (Void)
{GLCLEAR (GL_COLOR_BUFFER_BIT); GLFLUSH ();
---- Now is only a black-black screen after running, we need to add some east west.
---- Add an enumeration variable in the document class GLDISPLAYLISTNAMES:
ENUM GLDISPLAYLISTNAMES {Armpart1, Armpart2};
---- To build a display table. Editing the function onnewdocument (), the code is as follows:
Bool Copdoc :: OnNewDocument () ife (! Cdocument :: onnewdocument ())
Return False;
Glnewlist (armpart1, gl_compile);
GLFLOAT Redsurface [] = {1.0F, 0.0F, 0.0F, 1.0F};
GLFLOAT GREENSURFACE [] = {0.0F, 1.0F, 0.0F, 1.0F};
GLFLOAT Bluesurface [] = {0.0F, 0.0F, 1.0F, 1.0F};
GLFLOAT LIGHTAMBIENT [] = {0.1F, 0.1F, 0.1F, 0.1F};
GLFLOAT LIGHTDIFFUSE [] = {0.7F, 0.7F, 0.7F, 0.7F};
GLFLOAT LIGHTSPECULAR [] = {0.0F, 0.0F, 0.0F, 0.1F};
GLFLOAT LIGHTPSITION [] = {5.0F, 5.0F, 5.0F, 0.0F};
GLLIGHTFV (GL_LIGHT0, GL_AMBIENT, LIGHTAMBIENT);
GLLIGHTFV (GL_LIGHT0, GL_DIFFUSE, LIGHTDIFFUSE);
GLLightFv (GL_Light0, GL_SPECULAR, LIGHTSPECUL);
GLLightFv (GL_LIGHT0, GL_POSITION, LIGHTPSITION);
Glenable (GL_LIGHT0);
GLMATERIALFV (GL_FRONT_AND_BACK,
GL_AMBIENT, RedSurface;
Glbegin (GL_POLYGON);
GLNORMAL3D (1.0, 0.0, 0.0);
GLVERTEX3D (1.0, 1.0, 1.0); GlvertEX3D (
1.0, -1.0, 1.0);
GlvertEX3D (1.0, -1.0, -1.0); GlvertEX3D
(1.0, 1.0, -1.0); // draw the first surface
glend;
Glbegin (GL_POLYGON);
GLNORMAL3D (-1.0, 0.0, 0.0);
// This is the second surface.
The center of the center is the coordinate point.
glend;
GLMATERIALFV (GL_FRONT_AND_BACK,
GL_AMBIENT, GREENSURFACE;
// This is the third, four faces,
Note flat surface method and coordinate.
GLMATERIALFV (GL_FRONT_AND_BACK,
GL_AMBIENT, BluesURFACE;
// This is the fifth and sixth surfaces.
glendlist ();
Glnewlist (armpart2, gl_compile);
GLMATERIALFV (GL_FRONT_AND_BACK,
GL_AMBIENT, GREENSURFACE;
AuxSolidteapot (1.0); // draw a teapot with a secondary library function.
glendlist ();
Return True;
}
---- How to show it below. Edit Renderscene Function:
Void Copdoc :: Renderscene (Void)
{
Double m_angle1 = 60.0; double m_angle2 = 30.0;
Glclear
(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
GLPUSHMATRIX ();
Gltranslated (3.0, 0.0, -8.0); glrotated (m_angle1, 0, 0, 1); glrotated (m_angle2, 0, 1, 0);
GlcallList (armpart1);
GLPOPMAMATRIX ();
GLPUSHMATRIX ();
Gltranslated (0.0, 0.0, -8.0);
Glcalllist (armpart2);
GLPOPMAMATRIX ();
GLFlush ();
}
---- The result of the execution is as shown below: