OpenGL入门笔记(二)

本文详细介绍了OpenGL绘图框架,包括创建窗口、设置像素格式、激活渲染环境等关键步骤。核心内容在于绘制基本图元,如三角形和正方形,并解释了如何通过glTranslatef进行坐标变换以实现对象的平移。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一篇笔记中的OpenGL框架其实很简单,大致有如下几个步骤:<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

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

2,注册窗口类

3,创建窗口

4,描述像素格式

5,获取设备描述表

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

7,设置象素格式

8,取得绘制描述表

9,激活绘制描述表

10,显示窗口

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

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

ContractedBlock.gif ExpandedBlockStart.gif OpenGL框架完整代码
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->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.gifHINSTANCEhInstance;
//当前程序实例
None.gif
HDChDC=NULL;//设备环境
None.gif
HGLRChRC=NULL;//绘制环境
None.gif
HWNDhWnd=NULL;//窗口句柄
None.gif

None.gif
boolkeys[256];
None.gif
boolactive=TRUE;
None.gif
None.gifLRESULTCALLBACKWndProc(HWND,UINT,WPARAM,LPARAM);
None.gif
None.gif
None.gifGLvoidReSizeGLScene(GLsizeiwidth,GLsizeiheight)
//ResizeAndInitializeTheGLWindow
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif
if(height==0)//PreventADivideByZeroBy
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifheight
=1;//MakingHeightEqualOne
ExpandedSubBlockEnd.gif
}

InBlock.gif
InBlock.gifglViewport(
0,0,width,height);//ResetTheCurrentViewport
InBlock.gif

InBlock.gifglMatrixMode(GL_PROJECTION);
//SelectTheProjectionMatrix
InBlock.gif
glLoadIdentity();//ResetTheProjectionMatrix
InBlock.gif
InBlock.gif
//CalculateTheAspectRatioOfTheWindow
InBlock.gif
gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);
InBlock.gif
InBlock.gifglMatrixMode(GL_MODELVIEW);
//SelectTheModelviewMatrix
InBlock.gif
glLoadIdentity();//ResetTheModelviewMatrix
ExpandedBlockEnd.gif
}

None.gif
None.gif
None.gif
intInitGL(GLvoid)//AllSetupForOpenGLGoesHere
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gifglShadeModel(GL_SMOOTH);
//EnableSmoothShading
InBlock.gif
glClearColor(0.3f,0.0f,0.5f,0.5f);//BlackBackground
InBlock.gif
glClearDepth(1.0f);//DepthBufferSetup
InBlock.gif
glEnable(GL_DEPTH_TEST);//EnablesDepthTesting
InBlock.gif
glDepthFunc(GL_LEQUAL);//TheTypeOfDepthTestingToDo
InBlock.gif
glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);//ReallyNicePerspectiveCalculations
InBlock.gif
returnTRUE;//InitializationWentOK
ExpandedBlockEnd.gif
}

None.gif
None.gif
intDrawGLScene(GLvoid)//Here'sWhereWeDoAllTheDrawing
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gifglClear(GL_COLOR_BUFFER_BIT
|GL_DEPTH_BUFFER_BIT);//ClearScreenAndDepthBuffer
InBlock.gif
glLoadIdentity();
InBlock.gif
InBlock.gifglTranslatef(
-1.5f,0.0f,-6.0f);//MoveLeft1.5UnitsAndIntoTheScreen6.0
InBlock.gif
glBegin(GL_TRIANGLES);//DrawingUsingTriangles
InBlock.gif
glVertex3f(0.0f,1.0f,0.0f);//Top
InBlock.gif
glVertex3f(-1.0f,-1.0f,0.0f);//BottomLeft
InBlock.gif
glVertex3f(1.0f,-1.0f,0.0f);//BottomRight
InBlock.gif

InBlock.gifglEnd();
//FinishedDrawingTheTriangle
InBlock.gif
glTranslatef(3.0f,0.0f,0.0f);//MoveRight3Units
InBlock.gif
glBegin(GL_QUADS);//DrawAQuad
InBlock.gif
glVertex3f(-1.0f,1.0f,0.0f);//TopLeft
InBlock.gif
glVertex3f(1.0f,1.0f,0.0f);//TopRight
InBlock.gif
glVertex3f(1.0f,-1.0f,0.0f);//BottomRight
InBlock.gif
glVertex3f(-1.0f,-1.0f,0.0f);//BottomLeft
InBlock.gif
glEnd();//DoneDrawingTheQuad//ResetTheCurrentModelviewMatrix
InBlock.gif
returnTRUE;//EverythingWentOK
ExpandedBlockEnd.gif
}

None.gif
None.gif
None.gifGLvoidKillGLWindow(GLvoid)
//ProperlyKillTheWindow
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif
if(hRC)//DoWeHaveARenderingContext?
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
if(!wglMakeCurrent(NULL,NULL))//AreWeAbleToReleaseTheDCAndRCContexts?
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifMessageBox(NULL,
"ReleaseOfDCAndRCFailed.","SHUTDOWNERROR",MB_OK|MB_ICONINFORMATION);
ExpandedSubBlockEnd.gif}

InBlock.gif
InBlock.gif
if(!wglDeleteContext(hRC))//AreWeAbleToDeleteTheRC?
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifMessageBox(NULL,
"ReleaseRenderingContextFailed.","SHUTDOWNERROR",MB_OK|MB_ICONINFORMATION);
ExpandedSubBlockEnd.gif}

InBlock.gifhRC
=NULL;//SetRCToNULL
ExpandedSubBlockEnd.gif
}

InBlock.gif
InBlock.gif
if(hDC&&!ReleaseDC(hWnd,hDC))//AreWeAbleToReleaseTheDC
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifMessageBox(NULL,
"ReleaseDeviceContextFailed.","SHUTDOWNERROR",MB_OK|MB_ICONINFORMATION);
InBlock.gifhDC
=NULL;//SetDCToNULL
ExpandedSubBlockEnd.gif
}

InBlock.gif
InBlock.gif
if(hWnd&&!DestroyWindow(hWnd))//AreWeAbleToDestroyTheWindow?
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifMessageBox(NULL,
"CouldNotReleasehWnd.","SHUTDOWNERROR",MB_OK|MB_ICONINFORMATION);
InBlock.gifhWnd
=NULL;//SethWndToNULL
ExpandedSubBlockEnd.gif
}

InBlock.gif
InBlock.gif
if(!UnregisterClass("OpenGL",hInstance))//AreWeAbleToUnregisterClass
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifMessageBox(NULL,
"CouldNotUnregisterClass.","SHUTDOWNERROR",MB_OK|MB_ICONINFORMATION);
InBlock.gifhInstance
=NULL;//SethInstanceToNULL
ExpandedSubBlockEnd.gif
}

ExpandedBlockEnd.gif}

None.gif
None.gifBOOLCreateGLWindow(
char*title,intwidth,intheight,intbits)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{/**//*title:窗口标题;width:窗口宽度;height:窗口高度;bits:每象素所选的色彩深度*/
InBlock.gifGLuintPixelFormat;
InBlock.gifWNDCLASSwc;
InBlock.gifDWORDdwExStyle;
InBlock.gifDWORDdwStyle;
InBlock.gifRECTWindowRect;
InBlock.gifWindowRect.left
=(long)0;
InBlock.gifWindowRect.right
=(long)width;
InBlock.gifWindowRect.top
=(long)0;
InBlock.gifWindowRect.bottom
=(long)height;
InBlock.gif
InBlock.gifhInstance
=GetModuleHandle(NULL);
InBlock.gifwc.style
=CS_HREDRAW|CS_VREDRAW|CS_OWNDC;
InBlock.gifwc.lpfnWndProc
=(WNDPROC)WndProc;
InBlock.gifwc.cbClsExtra
=0;
InBlock.gifwc.cbWndExtra
=0;
InBlock.gifwc.hInstance
=hInstance;
InBlock.gifwc.hIcon
=LoadIcon(NULL,IDI_WINLOGO);
InBlock.gifwc.hCursor
=LoadCursor(NULL,IDC_ARROW);
InBlock.gifwc.hbrBackground
=NULL;
InBlock.gifwc.lpszMenuName
=NULL;
InBlock.gifwc.lpszClassName
="OpenGL";
InBlock.gif
InBlock.gif
if(!RegisterClass(&wc))
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifMessageBox(NULL,
"无法注册窗口类!!!","ERROR",MB_OK|MB_ICONEXCLAMATION);
InBlock.gif
returnFALSE;
ExpandedSubBlockEnd.gif}

InBlock.gif
InBlock.gifdwExStyle
=WS_EX_APPWINDOW|WS_EX_WINDOWEDGE;
InBlock.gifdwStyle
=WS_OVERLAPPEDWINDOW;
InBlock.gif
InBlock.gifAdjustWindowRectEx(
&WindowRect,dwExStyle,FALSE,dwStyle);
InBlock.gif
InBlock.gif
if(!(hWnd=CreateWindowEx(dwExStyle,//ExtendedStyleForTheWindow
InBlock.gif
"OpenGL",//ClassName
InBlock.gif
title,//WindowTitle
InBlock.gif
dwStyle|//DefinedWindowStyle
InBlock.gif
WS_CLIPSIBLINGS|//RequiredWindowStyle
InBlock.gif
WS_CLIPCHILDREN,//RequiredWindowStyle
InBlock.gif
0,0,//WindowPosition
InBlock.gif
WindowRect.right-WindowRect.left,//CalculateWindowWidth
InBlock.gif
WindowRect.bottom-WindowRect.top,//CalculateWindowHeight
InBlock.gif
NULL,//NoParentWindow
InBlock.gif
NULL,//NoMenu
InBlock.gif
hInstance,//Instance
InBlock.gif
NULL)))//DontPassAnythingToWM_CREATE
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifMessageBox(NULL,
"创建窗口失败","ERROR",MB_OK|MB_ICONEXCLAMATION);
InBlock.gif
returnFALSE;
ExpandedSubBlockEnd.gif}

InBlock.gif
InBlock.gif
InBlock.gif
staticPIXELFORMATDESCRIPTORpfd=//pfdTellsWindowsHowWeWantThingsToBe
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
sizeof(PIXELFORMATDESCRIPTOR),//SizeOfThisPixelFormatDescriptor
InBlock.gif
1,//VersionNumber
InBlock.gif
PFD_DRAW_TO_WINDOW|//FormatMustSupportWindow
InBlock.gif
PFD_SUPPORT_OPENGL|//FormatMustSupportOpenGL
InBlock.gif
PFD_DOUBLEBUFFER,//MustSupportDoubleBuffering
InBlock.gif
PFD_TYPE_RGBA,//RequestAnRGBAFormat
InBlock.gif
bits,//SelectOurColorDepth
InBlock.gif
0,0,0,0,0,0,//ColorBitsIgnored
InBlock.gif
0,//NoAlphaBuffer
InBlock.gif
0,//ShiftBitIgnored
InBlock.gif
0,//NoAccumulationBuffer
InBlock.gif
0,0,0,0,//AccumulationBitsIgnored
InBlock.gif
16,//16BitZ-Buffer(DepthBuffer)
InBlock.gif
0,//NoStencilBuffer
InBlock.gif
0,//NoAuxiliaryBuffer
InBlock.gif
PFD_MAIN_PLANE,//MainDrawingLayer
InBlock.gif
0,//Reserved
InBlock.gif
0,0,0//LayerMasksIgnored
ExpandedSubBlockEnd.gif
}
;
InBlock.gif
InBlock.gif
if(!(hDC=GetDC(hWnd)))
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifKillGLWindow();
InBlock.gifMessageBox(NULL,
"无法创建GL设备环境.","ERROR",MB_OK|MB_ICONEXCLAMATION);
InBlock.gif
returnFALSE;
ExpandedSubBlockEnd.gif}

InBlock.gif
InBlock.gif
if(!(PixelFormat=ChoosePixelFormat(hDC,&pfd)))//DidWindowsFindAMatchingPixelFormat?
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifKillGLWindow();
//ResetTheDisplay
InBlock.gif
MessageBox(NULL,"无法找到合适的像素格式.","ERROR",MB_OK|MB_ICONEXCLAMATION);
InBlock.gif
returnFALSE;//ReturnFALSE
ExpandedSubBlockEnd.gif
}

InBlock.gif
InBlock.gif
InBlock.gif
if(!SetPixelFormat(hDC,PixelFormat,&pfd))//AreWeAbleToSetThePixelFormat?
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifKillGLWindow();
//ResetTheDisplay
InBlock.gif
MessageBox(NULL,"像素格式无法设置.","ERROR",MB_OK|MB_ICONEXCLAMATION);
InBlock.gif
returnFALSE;//ReturnFALSE
ExpandedSubBlockEnd.gif
}

InBlock.gif
InBlock.gif
if(!(hRC=wglCreateContext(hDC)))//AreWeAbleToGetARenderingContext?
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifKillGLWindow();
//ResetTheDisplay
InBlock.gif
MessageBox(NULL,"无法创建一个绘制环境.","ERROR",MB_OK|MB_ICONEXCLAMATION);
InBlock.gif
returnFALSE;//ReturnFALSE
ExpandedSubBlockEnd.gif
}

InBlock.gif
InBlock.gif
if(!wglMakeCurrent(hDC,hRC))//TryToActivateTheRenderingContext
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifKillGLWindow();
//ResetTheDisplay
InBlock.gif
MessageBox(NULL,"无法激活绘制环境.","ERROR",MB_OK|MB_ICONEXCLAMATION);
InBlock.gif
returnFALSE;//ReturnFALSE
ExpandedSubBlockEnd.gif
}

InBlock.gif
InBlock.gifShowWindow(hWnd,SW_SHOW);
InBlock.gifSetForegroundWindow(hWnd);
InBlock.gifSetFocus(hWnd);
InBlock.gif
InBlock.gif
InBlock.gifReSizeGLScene(width,height);
InBlock.gif
if(!InitGL())//初始化新建的GL窗口
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifKillGLWindow();
//重置显示区
InBlock.gif
MessageBox(NULL,"InitializationFailed.","ERROR",MB_OK|MB_ICONEXCLAMATION);
InBlock.gif
returnFALSE;//返回FALSE
ExpandedSubBlockEnd.gif
}

InBlock.gif
InBlock.gif
returnTRUE;
InBlock.gif
InBlock.gif
ExpandedBlockEnd.gif}

None.gif
None.gifLRESULTCALLBACKWndProc(HWNDhWnd,
//HandleForThisWindow
None.gif
UINTuMsg,//MessageForThisWindow
None.gif
WPARAMwParam,//AdditionalMessageInformation
None.gif
LPARAMlParam)//AdditionalMessageInformation
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif
switch(uMsg)//CheckForWindowsMessages
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
caseWM_ACTIVATE://WatchForWindowActivateMessage
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
if(!HIWORD(wParam))//CheckMinimizationState
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifactive
=TRUE;//ProgramIsActive
ExpandedSubBlockEnd.gif
}

InBlock.gif
else
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifactive
=FALSE;//ProgramIsNoLongerActive
ExpandedSubBlockEnd.gif
}

InBlock.gif
InBlock.gif
return0;//ReturnToTheMessageLoop
ExpandedSubBlockEnd.gif
}

InBlock.gif
InBlock.gif
caseWM_SYSCOMMAND://InterceptSystemCommands
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
switch(wParam)//CheckSystemCalls
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
caseSC_SCREENSAVE://ScreensaverTryingToStart?
InBlock.gif
caseSC_MONITORPOWER://MonitorTryingToEnterPowersave?
InBlock.gif
return0;//PreventFromHappening
ExpandedSubBlockEnd.gif
}

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

InBlock.gif
InBlock.gif
caseWM_CLOSE://DidWeReceiveACloseMessage?
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifPostQuitMessage(
0);//SendAQuitMessage
InBlock.gif
return0;//JumpBack
ExpandedSubBlockEnd.gif
}

InBlock.gif
InBlock.gif
caseWM_KEYDOWN://IsAKeyBeingHeldDown?
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifkeys[wParam]
=TRUE;//IfSo,MarkItAsTRUE
InBlock.gif
return0;//JumpBack
ExpandedSubBlockEnd.gif
}

InBlock.gif
InBlock.gif
caseWM_KEYUP://HasAKeyBeenReleased?
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifkeys[wParam]
=FALSE;//IfSo,MarkItAsFALSE
InBlock.gif
return0;//JumpBack
ExpandedSubBlockEnd.gif
}

InBlock.gif
InBlock.gif
caseWM_SIZE://ResizeTheOpenGLWindow
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifReSizeGLScene(LOWORD(lParam),HIWORD(lParam));
//LoWord=Width,HiWord=Height
InBlock.gif
return0;//JumpBack
ExpandedSubBlockEnd.gif
}

ExpandedSubBlockEnd.gif}

InBlock.gif
InBlock.gif
//PassAllUnhandledMessagesToDefWindowProc
InBlock.gif
returnDefWindowProc(hWnd,uMsg,wParam,lParam);
ExpandedBlockEnd.gif}

None.gif
None.gif
intWINAPIWinMain(HINSTANCEhInstance,HINSTANCEhPrevInstance,LPSTRlpCmdLine,intnShowCmd)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gifMSGmsg;
//WindowsMessageStructure
InBlock.gif
BOOLdone=FALSE;//BoolVariableToExitLoop
InBlock.gif
InBlock.gif
InBlock.gif
//CreateOurOpenGLWindow
InBlock.gif
if(!CreateGLWindow("NeHe'sOpenGLFramework",640,480,16))
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
return0;//QuitIfWindowWasNotCreated
ExpandedSubBlockEnd.gif
}

InBlock.gif
InBlock.gif
while(!done)//LoopThatRunsWhiledone=FALSE
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))//IsThereAMessageWaiting?
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
if(msg.message==WM_QUIT)//HaveWeReceivedAQuitMessage?
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifdone
=TRUE;//IfSodone=TRUE
ExpandedSubBlockEnd.gif
}

InBlock.gif
else//IfNot,DealWithWindowMessages
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifTranslateMessage(
&msg);//TranslateTheMessage
InBlock.gif
DispatchMessage(&msg);//DispatchTheMessage
ExpandedSubBlockEnd.gif
}

ExpandedSubBlockEnd.gif}

InBlock.gif
else//IfThereAreNoMessages
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
//DrawTheScene.WatchForESCKeyAndQuitMessagesFromDrawGLScene()
InBlock.gif
if(active)//ProgramActive?
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
if(keys[VK_ESCAPE])//WasESCPressed?
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifdone
=TRUE;//ESCSignalledAQuit
ExpandedSubBlockEnd.gif
}

InBlock.gif
else//NotTimeToQuit,UpdateScreen
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifDrawGLScene();
//DrawTheScene
InBlock.gif
SwapBuffers(hDC);//SwapBuffers(DoubleBuffering)
ExpandedSubBlockEnd.gif
}

ExpandedSubBlockEnd.gif}

ExpandedSubBlockEnd.gif}

ExpandedSubBlockEnd.gif}

InBlock.gif
InBlock.gif
//Shutdown
InBlock.gif
KillGLWindow();//KillTheWindow
InBlock.gif
return(msg.wParam);//ExitTheProgram
InBlock.gif

InBlock.gif
ExpandedBlockEnd.gif}

None.gif



其中最核心的代码是:

None.gif int DrawGLScene(GLvoid) // Here'sWhereWeDoAllTheDrawing
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gifglClear(GL_COLOR_BUFFER_BIT
|GL_DEPTH_BUFFER_BIT);//ClearScreenAndDepthBuffer
InBlock.gif
glLoadIdentity();
InBlock.gif
InBlock.gifglTranslatef(
-1.5f,0.0f,-6.0f);//MoveLeft1.5UnitsAndIntoTheScreen6.0
InBlock.gif
glBegin(GL_TRIANGLES);//DrawingUsingTriangles
InBlock.gif
glVertex3f(0.0f,1.0f,0.0f);//Top
InBlock.gif
glVertex3f(-1.0f,-1.0f,0.0f);//BottomLeft
InBlock.gif
glVertex3f(1.0f,-1.0f,0.0f);//BottomRight
InBlock.gif

InBlock.gifglEnd();
//FinishedDrawingTheTriangle
InBlock.gif
glTranslatef(3.0f,0.0f,0.0f);//MoveRight3Units
InBlock.gif
glBegin(GL_QUADS);//DrawAQuad
InBlock.gif
glVertex3f(-1.0f,1.0f,0.0f);//TopLeft
InBlock.gif
glVertex3f(1.0f,1.0f,0.0f);//TopRight
InBlock.gif
glVertex3f(1.0f,-1.0f,0.0f);//BottomRight
InBlock.gif
glVertex3f(-1.0f,-1.0f,0.0f);//BottomLeft
InBlock.gif
glEnd();//DoneDrawingTheQuad//ResetTheCurrentModelviewMatrix
InBlock.gif
returnTRUE;//EverythingWentOK
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轴上的<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" /><chmetcnv unitname="F" sourcevalue="0" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on"><span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">0.0f</span></chmetcnv>点。中心左面的坐标值是负值,右面是正值。移向屏幕顶端是正值,移向屏幕底端是负值。移入屏幕深处是负值,移出屏幕则是正值。


   glTranslatef(x, y, z)沿着XYZ轴移动。根据前面的次序,下面的代码沿着X轴左移1.5个单位,Y轴不动(<chmetcnv unitname="F" sourcevalue="0" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">0.0f</chmetcnv>),最后移入屏幕<chmetcnv unitname="F" sourcevalue="6" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on"><span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">6.0f</span></chmetcnv>个单位。注意在glTranslatef(x, y, z)中当移动的时候,并不是相对屏幕中心移动,而是相对与当前所在的屏幕位置。


       glTranslatef(<chmetcnv unitname="F" sourcevalue="1.5" hasspace="False" negative="True" numbertype="1" tcsc="0" w:st="on">-<chmetcnv unitname="F" sourcevalue="1.5" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">1.5f</chmetcnv></chmetcnv>,<chmetcnv unitname="F" sourcevalue="0" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">0.0f</chmetcnv>,<chmetcnv unitname="F" sourcevalue="6" hasspace="False" negative="True" numbertype="1" tcsc="0" w:st="on">-<chmetcnv unitname="F" sourcevalue="6" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">6.0f</chmetcnv></chmetcnv>); // 左移1.5单位,并移入屏幕6.0


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

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

       glTranslatef(<chmetcnv unitname="F" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">3.0f</chmetcnv>,<chmetcnv unitname="F" sourcevalue="0" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">0.0f</chmetcnv>,<chmetcnv unitname="F" sourcevalue="0" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">0.0f</chmetcnv>);           // 右移3单位


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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值