一篇笔记中的OpenGL框架其实很简单,大致有如下几个步骤:

1,取得窗口的实例,然后定义窗口类

2,注册窗口类

3,创建窗口

4,描述像素格式

5,获取设备描述表

6,找到与此前我们选定的象素格式相对应的象素格式

7,设置象素格式

8,取得绘制描述表

9,激活绘制描述表

10,显示窗口

11,将屏幕的宽度和高度设置给透视OpenGL屏幕(设置视口,进行投影,模型透视)

 

   其他就是对窗口事件的处理了,尤其是重画事件(WM_PAINT),但只是画了一个空窗口,现在加一些代码来画简单的基本图元。:

ContractedBlock.gifExpandedBlockStart.gifOpenGL框架完整代码
None.gif#include <windows.h>
None.gif#include 
<GL\gl.h>
None.gif#include 
<GL\glu.h>
None.gif#include 
<GL\glaux.h>
None.gif
None.gifHINSTANCE hInstance;
//当前程序实例
None.gif
HDC hDC = NULL;//设备环境
None.gif
HGLRC hRC = NULL;//绘制环境
None.gif
HWND  hWnd = NULL;//窗口句柄
None.gif

None.gif
bool keys[256];
None.gif
bool active = TRUE;
None.gif
None.gifLRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
None.gif
None.gif
None.gifGLvoid ReSizeGLScene(GLsizei width, GLsizei height)        
// Resize And Initialize The GL Window
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif    
if (height==0)                                        // Prevent A Divide By Zero By
ExpandedSubBlockStart.gifContractedSubBlock.gif
    dot.gif{
InBlock.gif        height
=1;                                        // Making Height Equal One
ExpandedSubBlockEnd.gif
    }

InBlock.gif
InBlock.gif    glViewport(
0,0,width,height);                        // Reset The Current Viewport
InBlock.gif

InBlock.gif    glMatrixMode(GL_PROJECTION);                        
// Select The Projection Matrix
InBlock.gif
    glLoadIdentity();                                    // Reset The Projection Matrix
InBlock.gif
InBlock.gif    
// Calculate The Aspect Ratio Of The Window
InBlock.gif
    gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);
InBlock.gif
InBlock.gif    glMatrixMode(GL_MODELVIEW);                            
// Select The Modelview Matrix
InBlock.gif
    glLoadIdentity();                                    // Reset The Modelview Matrix
ExpandedBlockEnd.gif
}

None.gif
None.gif
None.gif
int InitGL(GLvoid)                                        // All Setup For OpenGL Goes Here
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif    glShadeModel(GL_SMOOTH);                            
// Enable Smooth Shading
InBlock.gif
    glClearColor(0.3f,0.0f0.5f0.5f);                // Black Background
InBlock.gif
    glClearDepth(1.0f);                                    // Depth Buffer Setup
InBlock.gif
    glEnable(GL_DEPTH_TEST);                            // Enables Depth Testing
InBlock.gif
    glDepthFunc(GL_LEQUAL);                                // The Type Of Depth Testing To Do
InBlock.gif
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);    // Really Nice Perspective Calculations
InBlock.gif
    return TRUE;                                        // Initialization Went OK
ExpandedBlockEnd.gif
}

None.gif
None.gif
int DrawGLScene(GLvoid)                                    // Here's Where We Do All The Drawing
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif    glClear(GL_COLOR_BUFFER_BIT 
| GL_DEPTH_BUFFER_BIT);    // Clear Screen And Depth Buffer
InBlock.gif
    glLoadIdentity();
InBlock.gif    
InBlock.gif    glTranslatef(
-1.5f,0.0f,-6.0f);                        // Move Left 1.5 Units And Into The Screen 6.0
InBlock.gif
    glBegin(GL_TRIANGLES);                                // Drawing Using Triangles
InBlock.gif
        glVertex3f( 0.0f1.0f0.0f);                    // Top
InBlock.gif
        glVertex3f(-1.0f,-1.0f0.0f);                    // Bottom Left
InBlock.gif
        glVertex3f( 1.0f,-1.0f0.0f);                    // Bottom Right
InBlock.gif

InBlock.gif    glEnd();                                            
// Finished Drawing The Triangle
InBlock.gif
    glTranslatef(3.0f,0.0f,0.0f);                        // Move Right 3 Units
InBlock.gif
    glBegin(GL_QUADS);                                    // Draw A Quad
InBlock.gif
        glVertex3f(-1.0f1.0f0.0f);                    // Top Left
InBlock.gif
        glVertex3f( 1.0f1.0f0.0f);                    // Top Right
InBlock.gif
        glVertex3f( 1.0f,-1.0f0.0f);                    // Bottom Right
InBlock.gif
        glVertex3f(-1.0f,-1.0f0.0f);                    // Bottom Left
InBlock.gif
    glEnd();                                            // Done Drawing The Quad// Reset The Current Modelview Matrix
InBlock.gif
    return TRUE;                                        // Everything Went OK
ExpandedBlockEnd.gif
}

None.gif
None.gif
None.gifGLvoid KillGLWindow(GLvoid)                                
// Properly Kill The Window
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif    
if (hRC)                                            // Do We Have A Rendering Context?
ExpandedSubBlockStart.gifContractedSubBlock.gif
    dot.gif{
InBlock.gif        
if (!wglMakeCurrent(NULL,NULL))                    // Are We Able To Release The DC And RC Contexts?
ExpandedSubBlockStart.gifContractedSubBlock.gif
        dot.gif{
InBlock.gif            MessageBox(NULL,
"Release Of DC And RC Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
if (!wglDeleteContext(hRC))                        // Are We Able To Delete The RC?
ExpandedSubBlockStart.gifContractedSubBlock.gif
        dot.gif{
InBlock.gif            MessageBox(NULL,
"Release Rendering Context Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
ExpandedSubBlockEnd.gif        }

InBlock.gif        hRC
=NULL;                                        // Set RC To NULL
ExpandedSubBlockEnd.gif
    }

InBlock.gif
InBlock.gif    
if (hDC && !ReleaseDC(hWnd,hDC))                    // Are We Able To Release The DC
ExpandedSubBlockStart.gifContractedSubBlock.gif
    dot.gif{
InBlock.gif        MessageBox(NULL,
"Release Device Context Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
InBlock.gif        hDC
=NULL;                                        // Set DC To NULL
ExpandedSubBlockEnd.gif
    }

InBlock.gif
InBlock.gif    
if (hWnd && !DestroyWindow(hWnd))                    // Are We Able To Destroy The Window?
ExpandedSubBlockStart.gifContractedSubBlock.gif
    dot.gif{
InBlock.gif        MessageBox(NULL,
"Could Not Release hWnd.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
InBlock.gif        hWnd
=NULL;                                        // Set hWnd To NULL
ExpandedSubBlockEnd.gif
    }

InBlock.gif
InBlock.gif    
if (!UnregisterClass("OpenGL",hInstance))            // Are We Able To Unregister Class
ExpandedSubBlockStart.gifContractedSubBlock.gif
    dot.gif{
InBlock.gif        MessageBox(NULL,
"Could Not Unregister Class.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
InBlock.gif        hInstance
=NULL;                                    // Set hInstance To NULL
ExpandedSubBlockEnd.gif
    }

ExpandedBlockEnd.gif}

None.gif
None.gifBOOL CreateGLWindow(
char* title,int width,int height,int bits)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{/**//* title:窗口标题; width:窗口宽度; height:窗口高度; bits:每象素所选的色彩深度*/
InBlock.gif    GLuint PixelFormat;
InBlock.gif    WNDCLASS wc;
InBlock.gif    DWORD dwExStyle;
InBlock.gif    DWORD dwStyle;
InBlock.gif    RECT WindowRect;
InBlock.gif    WindowRect.left 
= (long)0;
InBlock.gif    WindowRect.right 
= (long)width;
InBlock.gif    WindowRect.top 
= (long)0;
InBlock.gif    WindowRect.bottom 
= (long)height;
InBlock.gif
InBlock.gif    hInstance 
= GetModuleHandle(NULL);
InBlock.gif    wc.style 
= CS_HREDRAW|CS_VREDRAW|CS_OWNDC;
InBlock.gif    wc.lpfnWndProc 
= (WNDPROC)WndProc;
InBlock.gif    wc.cbClsExtra 
= 0;
InBlock.gif    wc.cbWndExtra 
= 0;
InBlock.gif    wc.hInstance 
= hInstance;
InBlock.gif    wc.hIcon 
= LoadIcon(NULL,IDI_WINLOGO);
InBlock.gif    wc.hCursor 
= LoadCursor(NULL,IDC_ARROW);
InBlock.gif    wc.hbrBackground 
= NULL;
InBlock.gif    wc.lpszMenuName 
= NULL;
InBlock.gif    wc.lpszClassName 
= "OpenGL";
InBlock.gif    
InBlock.gif    
if(!RegisterClass(&wc))
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        MessageBox(NULL,
"无法注册窗口类!!!","ERROR",MB_OK|MB_ICONEXCLAMATION);
InBlock.gif        
return FALSE;
ExpandedSubBlockEnd.gif    }

InBlock.gif    
InBlock.gif    dwExStyle 
= WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
InBlock.gif    dwStyle 
= WS_OVERLAPPEDWINDOW;
InBlock.gif
InBlock.gif    AdjustWindowRectEx(
&WindowRect,dwExStyle,FALSE,dwStyle);
InBlock.gif    
InBlock.gif    
if(!(hWnd = CreateWindowEx(dwExStyle,                            // Extended Style For The Window
InBlock.gif
                                "OpenGL",                            // Class Name
InBlock.gif
                                title,                                // Window Title
InBlock.gif
                                dwStyle |                            // Defined Window Style
InBlock.gif
                                WS_CLIPSIBLINGS |                    // Required Window Style
InBlock.gif
                                WS_CLIPCHILDREN,                    // Required Window Style
InBlock.gif
                                00,                                // Window Position
InBlock.gif
                                WindowRect.right-WindowRect.left,    // Calculate Window Width
InBlock.gif
                                WindowRect.bottom-WindowRect.top,    // Calculate Window Height
InBlock.gif
                                NULL,                                // No Parent Window
InBlock.gif
                                NULL,                                // No Menu
InBlock.gif
                                hInstance,                            // Instance
InBlock.gif
                                NULL)))                                // Dont Pass Anything To WM_CREATE
ExpandedSubBlockStart.gifContractedSubBlock.gif
    dot.gif{
InBlock.gif        MessageBox(NULL,
"创建窗口失败","ERROR",MB_OK|MB_ICONEXCLAMATION);
InBlock.gif        
return FALSE;
ExpandedSubBlockEnd.gif    }

InBlock.gif    
InBlock.gif
InBlock.gif        
static    PIXELFORMATDESCRIPTOR pfd=                // pfd Tells Windows How We Want Things To Be
ExpandedSubBlockStart.gifContractedSubBlock.gif
    dot.gif{
InBlock.gif        
sizeof(PIXELFORMATDESCRIPTOR),                // Size Of This Pixel Format Descriptor
InBlock.gif
        1,                                            // Version Number
InBlock.gif
        PFD_DRAW_TO_WINDOW |                        // Format Must Support Window
InBlock.gif
        PFD_SUPPORT_OPENGL |                        // Format Must Support OpenGL
InBlock.gif
        PFD_DOUBLEBUFFER,                            // Must Support Double Buffering
InBlock.gif
        PFD_TYPE_RGBA,                                // Request An RGBA Format
InBlock.gif
        bits,                                        // Select Our Color Depth
InBlock.gif
        000000,                            // Color Bits Ignored
InBlock.gif
        0,                                            // No Alpha Buffer
InBlock.gif
        0,                                            // Shift Bit Ignored
InBlock.gif
        0,                                            // No Accumulation Buffer
InBlock.gif
        0000,                                    // Accumulation Bits Ignored
InBlock.gif
        16,                                            // 16Bit Z-Buffer (Depth Buffer)  
InBlock.gif
        0,                                            // No Stencil Buffer
InBlock.gif
        0,                                            // No Auxiliary Buffer
InBlock.gif
        PFD_MAIN_PLANE,                                // Main Drawing Layer
InBlock.gif
        0,                                            // Reserved
InBlock.gif
        000                                        // Layer Masks Ignored
ExpandedSubBlockEnd.gif
    }
;
InBlock.gif    
InBlock.gif    
if(!(hDC = GetDC(hWnd)))
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        KillGLWindow();        
InBlock.gif        MessageBox(NULL,
"无法创建GL设备环境.","ERROR",MB_OK|MB_ICONEXCLAMATION);
InBlock.gif        
return FALSE;    
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
if (!(PixelFormat=ChoosePixelFormat(hDC,&pfd)))    // Did Windows Find A Matching Pixel Format?
ExpandedSubBlockStart.gifContractedSubBlock.gif
    dot.gif{
InBlock.gif        KillGLWindow();                                
// Reset The Display
InBlock.gif
        MessageBox(NULL,"无法找到合适的像素格式.","ERROR",MB_OK|MB_ICONEXCLAMATION);
InBlock.gif        
return FALSE;                                // Return FALSE
ExpandedSubBlockEnd.gif
    }

InBlock.gif
InBlock.gif
InBlock.gif    
if(!SetPixelFormat(hDC,PixelFormat,&pfd))        // Are We Able To Set The Pixel Format?
ExpandedSubBlockStart.gifContractedSubBlock.gif
    dot.gif{
InBlock.gif        KillGLWindow();                                
// Reset The Display
InBlock.gif
        MessageBox(NULL,"像素格式无法设置.","ERROR",MB_OK|MB_ICONEXCLAMATION);
InBlock.gif        
return FALSE;                                // Return FALSE
ExpandedSubBlockEnd.gif
    }

InBlock.gif
InBlock.gif    
if (!(hRC=wglCreateContext(hDC)))                // Are We Able To Get A Rendering Context?
ExpandedSubBlockStart.gifContractedSubBlock.gif
    dot.gif{
InBlock.gif        KillGLWindow();                                
// Reset The Display
InBlock.gif
        MessageBox(NULL,"无法创建一个绘制环境.","ERROR",MB_OK|MB_ICONEXCLAMATION);
InBlock.gif        
return FALSE;                                // Return FALSE
ExpandedSubBlockEnd.gif
    }

InBlock.gif
InBlock.gif    
if(!wglMakeCurrent(hDC,hRC))                    // Try To Activate The Rendering Context
ExpandedSubBlockStart.gifContractedSubBlock.gif
    dot.gif{
InBlock.gif        KillGLWindow();                                
// Reset The Display
InBlock.gif
        MessageBox(NULL,"无法激活绘制环境.","ERROR",MB_OK|MB_ICONEXCLAMATION);
InBlock.gif        
return FALSE;                                // Return FALSE
ExpandedSubBlockEnd.gif
    }

InBlock.gif
InBlock.gif    ShowWindow(hWnd,SW_SHOW);
InBlock.gif    SetForegroundWindow(hWnd);
InBlock.gif    SetFocus(hWnd);
InBlock.gif
InBlock.gif    
InBlock.gif    ReSizeGLScene(width, height);
InBlock.gif    
if(!InitGL())//初始化新建的GL窗口
ExpandedSubBlockStart.gifContractedSubBlock.gif
    dot.gif{
InBlock.gif        KillGLWindow();
//重置显示区
InBlock.gif
        MessageBox(NULL,"Initialization Failed.","ERROR",MB_OK|MB_ICONEXCLAMATION);
InBlock.gif        
return FALSE;//返回 FALSE
ExpandedSubBlockEnd.gif
    }

InBlock.gif
InBlock.gif    
return TRUE;
InBlock.gif
InBlock.gif
ExpandedBlockEnd.gif}

None.gif
None.gifLRESULT CALLBACK WndProc(    HWND    hWnd,            
// Handle For This Window
None.gif
                            UINT    uMsg,            // Message For This Window
None.gif
                            WPARAM    wParam,            // Additional Message Information
None.gif
                            LPARAM    lParam)            // Additional Message Information
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif    
switch (uMsg)                                    // Check For Windows Messages
ExpandedSubBlockStart.gifContractedSubBlock.gif
    dot.gif{
InBlock.gif        
case WM_ACTIVATE:                            // Watch For Window Activate Message
ExpandedSubBlockStart.gifContractedSubBlock.gif
        dot.gif{
InBlock.gif            
if (!HIWORD(wParam))                    // Check Minimization State
ExpandedSubBlockStart.gifContractedSubBlock.gif
            dot.gif{
InBlock.gif                active
=TRUE;                        // Program Is Active
ExpandedSubBlockEnd.gif
            }

InBlock.gif            
else
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                active
=FALSE;                        // Program Is No Longer Active
ExpandedSubBlockEnd.gif
            }

InBlock.gif
InBlock.gif            
return 0;                                // Return To The Message Loop
ExpandedSubBlockEnd.gif
        }

InBlock.gif
InBlock.gif        
case WM_SYSCOMMAND:                            // Intercept System Commands
ExpandedSubBlockStart.gifContractedSubBlock.gif
        dot.gif{
InBlock.gif            
switch (wParam)                            // Check System Calls
ExpandedSubBlockStart.gifContractedSubBlock.gif
            dot.gif{
InBlock.gif                
case SC_SCREENSAVE:                    // Screensaver Trying To Start?
InBlock.gif
                case SC_MONITORPOWER:                // Monitor Trying To Enter Powersave?
InBlock.gif
                return 0;                            // Prevent From Happening
ExpandedSubBlockEnd.gif
            }

InBlock.gif            
break;                                    // Exit
ExpandedSubBlockEnd.gif
        }

InBlock.gif
InBlock.gif        
case WM_CLOSE:                                // Did We Receive A Close Message?
ExpandedSubBlockStart.gifContractedSubBlock.gif
        dot.gif{
InBlock.gif            PostQuitMessage(
0);                        // Send A Quit Message
InBlock.gif
            return 0;                                // Jump Back
ExpandedSubBlockEnd.gif
        }

InBlock.gif
InBlock.gif        
case WM_KEYDOWN:                            // Is A Key Being Held Down?
ExpandedSubBlockStart.gifContractedSubBlock.gif
        dot.gif{
InBlock.gif            keys[wParam] 
= TRUE;                    // If So, Mark It As TRUE
InBlock.gif
            return 0;                                // Jump Back
ExpandedSubBlockEnd.gif
        }

InBlock.gif
InBlock.gif        
case WM_KEYUP:                                // Has A Key Been Released?
ExpandedSubBlockStart.gifContractedSubBlock.gif
        dot.gif{
InBlock.gif            keys[wParam] 
= FALSE;                    // If So, Mark It As FALSE
InBlock.gif
            return 0;                                // Jump Back
ExpandedSubBlockEnd.gif
        }

InBlock.gif
InBlock.gif        
case WM_SIZE:                                // Resize The OpenGL Window
ExpandedSubBlockStart.gifContractedSubBlock.gif
        dot.gif{
InBlock.gif            ReSizeGLScene(LOWORD(lParam),HIWORD(lParam));  
// LoWord=Width, HiWord=Height
InBlock.gif
            return 0;                                // Jump Back
ExpandedSubBlockEnd.gif
        }

ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
// Pass All Unhandled Messages To DefWindowProc
InBlock.gif
    return DefWindowProc(hWnd,uMsg,wParam,lParam);
ExpandedBlockEnd.gif}

None.gif
None.gif
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif    MSG        msg;                                    
// Windows Message Structure
InBlock.gif
    BOOL    done=FALSE;                                // Bool Variable To Exit Loop
InBlock.gif
InBlock.gif
InBlock.gif    
// Create Our OpenGL Window
InBlock.gif
    if (!CreateGLWindow("NeHe's OpenGL Framework",640,480,16))
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
return 0;                                    // Quit If Window Was Not Created
ExpandedSubBlockEnd.gif
    }

InBlock.gif
InBlock.gif    
while(!done)                                    // Loop That Runs While done=FALSE
ExpandedSubBlockStart.gifContractedSubBlock.gif
    dot.gif{
InBlock.gif        
if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))    // Is There A Message Waiting?
ExpandedSubBlockStart.gifContractedSubBlock.gif
        dot.gif{
InBlock.gif            
if (msg.message==WM_QUIT)                // Have We Received A Quit Message?
ExpandedSubBlockStart.gifContractedSubBlock.gif
            dot.gif{
InBlock.gif                done
=TRUE;                            // If So done=TRUE
ExpandedSubBlockEnd.gif
            }

InBlock.gif            
else                                    // If Not, Deal With Window Messages
ExpandedSubBlockStart.gifContractedSubBlock.gif
            dot.gif{
InBlock.gif                TranslateMessage(
&msg);                // Translate The Message
InBlock.gif
                DispatchMessage(&msg);                // Dispatch The Message
ExpandedSubBlockEnd.gif
            }

ExpandedSubBlockEnd.gif        }

InBlock.gif        
else                                        // If There Are No Messages
ExpandedSubBlockStart.gifContractedSubBlock.gif
        dot.gif{
InBlock.gif            
// Draw The Scene.  Watch For ESC Key And Quit Messages From DrawGLScene()
InBlock.gif
            if (active)                                // Program Active?
ExpandedSubBlockStart.gifContractedSubBlock.gif
            dot.gif{
InBlock.gif                
if (keys[VK_ESCAPE])                // Was ESC Pressed?
ExpandedSubBlockStart.gifContractedSubBlock.gif
                dot.gif{
InBlock.gif                    done
=TRUE;                        // ESC Signalled A Quit
ExpandedSubBlockEnd.gif
                }

InBlock.gif                
else                                // Not Time To Quit, Update Screen
ExpandedSubBlockStart.gifContractedSubBlock.gif
                dot.gif{
InBlock.gif                    DrawGLScene();                    
// Draw The Scene
InBlock.gif
                    SwapBuffers(hDC);                // Swap Buffers (Double Buffering)
ExpandedSubBlockEnd.gif
                }

ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
// Shutdown
InBlock.gif
    KillGLWindow();                                    // Kill The Window
InBlock.gif
    return (msg.wParam);                            // Exit The Program
InBlock.gif

InBlock.gif    
ExpandedBlockEnd.gif}

None.gif



其中最核心的代码是:

None.gifint DrawGLScene(GLvoid)                                    // Here's Where We Do All The Drawing
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif    glClear(GL_COLOR_BUFFER_BIT 
| GL_DEPTH_BUFFER_BIT);    // Clear Screen And Depth Buffer
InBlock.gif
    glLoadIdentity();
InBlock.gif    
InBlock.gif    glTranslatef(
-1.5f,0.0f,-6.0f);                        // Move Left 1.5 Units And Into The Screen 6.0
InBlock.gif
    glBegin(GL_TRIANGLES);                                // Drawing Using Triangles
InBlock.gif
        glVertex3f( 0.0f1.0f0.0f);                    // Top
InBlock.gif
        glVertex3f(-1.0f,-1.0f0.0f);                    // Bottom Left
InBlock.gif
        glVertex3f( 1.0f,-1.0f0.0f);                    // Bottom Right
InBlock.gif

InBlock.gif    glEnd();                                            
// Finished Drawing The Triangle
InBlock.gif
    glTranslatef(3.0f,0.0f,0.0f);                        // Move Right 3 Units
InBlock.gif
    glBegin(GL_QUADS);                                    // Draw A Quad
InBlock.gif
        glVertex3f(-1.0f1.0f0.0f);                    // Top Left
InBlock.gif
        glVertex3f( 1.0f1.0f0.0f);                    // Top Right
InBlock.gif
        glVertex3f( 1.0f,-1.0f0.0f);                    // Bottom Right
InBlock.gif
        glVertex3f(-1.0f,-1.0f0.0f);                    // Bottom Left
InBlock.gif
    glEnd();                                            // Done Drawing The Quad// Reset The Current Modelview Matrix
InBlock.gif
    return TRUE;                                        // Everything Went OK
ExpandedBlockEnd.gif
}

None.gif
None.gif


200741601.JPG


按照我的个人理解,,就好比照相机拍照一样,被拍的物体移动和照相机反方向移动可以得到相同的效果(使得成像的大小变化),这里的glTranslatef是用来进行造型变换的(类似移动物体却不移动照相机)。通过改变平移值的大小可以明显看出平移的效果。

 

这里要注意的是存在两种不同的坐标变换方式,glTranslatef(x,y,z)中的xyz是相对与当前所在点的位移,但glVertex(x,y,z)是相对于glTranslatef(x,y,z)移动后的新原点的位移。因而这里可以认为glTranslate移动的是坐标原点,glVertex中的点是相对最新的坐标原点的坐标值。

 

当调用glLoadIdentity()之后,实际上将当前点移到了屏幕中心,X坐标轴从左至右,Y坐标轴从下至上,Z坐标轴从里至外。OpenGL屏幕中心的坐标值是XY轴上的0.0f点。中心左面的坐标值是负值,右面是正值。移向屏幕顶端是正值,移向屏幕底端是负值。移入屏幕深处是负值,移出屏幕则是正值。


   glTranslatef(x, y, z)沿着XYZ轴移动。根据前面的次序,下面的代码沿着X轴左移1.5个单位,Y轴不动(0.0f),最后移入屏幕6.0f个单位。注意在glTranslatef(x, y, z)中当移动的时候,并不是相对屏幕中心移动,而是相对与当前所在的屏幕位置。


       glTranslatef(-1.5f,0.0f,-6.0f); // 左移1.5单位,并移入屏幕6.0


   现在我们已经移到了屏幕的左半部分,并且将视图推入屏幕背后足够的距离以便我们可以看见全部的场景-创建三角形。

 

在屏幕的左半部分画完三角形后,我们要移到右半部分来画正方形。为此要再次使用glTranslate。这次右移,所以X坐标值为正值。因为前面左移了1.5个单位,这次要先向右移回屏幕中心(1.5个单位),再向右移动1.5个单位。总共要向右移3.0个单位。

       glTranslatef(3.0f,0.0f,0.0f);           // 右移3单位


   还有一点值得特别注意:
使用顺时针次序来画正方形-左上-右上-右下-左下。采用顺时针绘制的是象的后表面。就是所看的是正方形的背面。逆时针画的正方形才是正面朝着我的。