You are on page 1of 38

Nhãm ®Ò tµi M« pháng sè c¸c hÖ ®éng lùc 09-01-2001

OpenGL vµ øng dông trong ®å ho¹ ®éng
Phan M¹nh DÇn 1, Ph¹m ThÞ H¬ng 2, §ç §¨ng Khoa 2, Hoµng Sü TuÊn 2, §Æng Anh ViÖt 3 Bé m«n c¬ häc øng dông 2 Líp c¬ tin - K42 3 Líp ®iÒu khiÓn tù ®éng 1 - K42 Trêng ®¹i häc b¸ch khoa Hµ Néi Tãm t¾t: Sö dông th viÖn lËp tr×nh ®å ho¹ 3 chiÒu OpenGL cho phÐp nhanh chãng t¹o ra c¸c øng dông ®å ho¹ tèc ®é cao vµ cã chÊt lîng h×nh ¶nh cao. Th viÖn ®· ®îc sö dông trong ®Ò tµi "M« pháng sè c¸c hÖ ®éng lùc" ®Ó t¹o ra mét sè ch¬ng tr×nh m« pháng c¸c hÖ c¬ häc. B¶n b¸o c¸o nµy giíi thiÖu th viÖn víi nh÷ng néi dung sau: s¬ lîc vÒ th viÖn OpenGL, c¸c bíc ®Ó x©y dùng mét ch¬ng tr×nh øng dông ®å ho¹ sö dông OpenGL, nh÷ng kü thuËt chñ yÕu trong lËp tr×nh ®å ho¹ ®éng sö dông OpenGL. Ngoµi ra nh÷ng c¸c bíc cô thÓ triÓn khai mét øng dông OpenGL sö dông th viÖn hç trî GLUT vµ sö dông Microsoft Foundation Class (MFC) còng ®îc giíi thiÖu.
1

1 Giíi thiÖu 1.1 LÞch sö OpenGL
OpenGL lµ mét th viÖn ®å ho¹ tèc ®é cao, ®éc lËp víi c¸c hÖ thèng giao diÖn cña hÖ ®iÒu hµnh. Ban ®Çu do h·ng Silicon Graphics Inc. ph¸t triÓn cho c¸c workstation ®å ho¹ tèc ®é cao víi tªn IRIS GL tõ n¨m 1982. OpenGL ®· trë thµnh mét chuÈn c«ng nghiÖp vµ c¸c ®Æc tÝnh kü thuËt cña OpenGL do Uû ban kü thuËt (ARB : Architectural Review Board) phª chuÈn. ARB ®îc nh÷ng h·ng phÇn mÒm hµng ®Çu nh Silicon Graphics Inc. (SGI), Intel, Microsoft, IBM, Intergraph... lËp ra n¨m 1990. §· ®îc triÓn khai trªn nhiÒu hÖ thèng kh¸c nhau tõ Microsoft Windows 95/ 98/ NT/ 2000, Macintosh, Unix, Linux... Cã thÓ ph¸t triÓn c¸c øng dông ®å ho¹ víi OpenGL sö dông nh÷ng ng«n ng÷ lËp tr×nh kh¸c nhau. HiÖn ®· cã c¸c triÓn khai cña OpenGL cho c¸c ng«n ng÷ nh C/C++, Fortran, Java, Ada...

1.2 Kh¶ n¨ng th viÖn OpenGL
VÒ c¬ b¶n OpenGL lµ mét th viÖn cña mét tËp hîp gåm kho¶ng 150 hµm hç trî c¸c thao t¸c ([4]): • ThÓ hiÖn c¸c ®èi tîng c¬ b¶n nh ®iÓm, ®êng, ®a gi¸c, vµ tõ ®ã cã thÓ t¹o ra nh÷ng ®èi tîng ®å ho¹ phøc t¹p h¬n

1

Nhãm ®Ò tµi M« pháng sè c¸c hÖ ®éng lùc 09-01-2001

nh mÆt cÇu, mÆt nãn, mÆt h×nh trô...hoÆc c¸c ®èi tîng do lËp tr×nh viªn t¹o ra. • Quan s¸t ®èi tîng : c¸c ®èi tîng sau khi ®îc vÏ ra cã thÓ ®îc quan s¸t tõ nh÷ng gãc nh×n kh¸c nhau th«ng qua c¸c phÐp biÕn h×nh (transformation) • §Þnh mµu s¾c : c¸c ®èi tîng cã thÓ ®îc thÓ hiÖn víi mµu s¾c b»ng nhiÒu c¸ch chØ ®Þnh mµu kh¸c nhau: RGBA hay color-index... • Sö dông ¸nh s¸ng : ¸nh s¸ng cã thÓ ®îc sö dông ®Ó t¹o ra nh÷ng c¶nh "thËt" tõ nh÷ng ®èi tîng ®· cã. OpenGL cho phÐp sö dông nhiÒu lo¹i nguån s¸ng kh¸c nhau nh ph¸t x¹ (emitted), bao quanh(ambient), ph©n t¸n (diffuse) vµ ph¶n chiÕu (specular). • C¸c kü thuËt t¨ng chÊt lîng hiÖn thÞ ¶nh nh chèng r¨ng ca (anti-aliasing), trén mµu (blending), s¬ng khãi trong ¶nh (fog)... • Thao t¸c trªn c¸c ¶nh bitmap : lËp tr×nh viªn cã thÓ "d¸n" c¸c ¶nh cña c¶nh thËt lªn trªn bÒ mÆt c¸c ®èi tîng t¹o ra b»ng OpenGL...

1.3 C¸c th viÖn hç trî lËp tr×nh OpenGL
V× OpenGL ®· ®îc chuÈn ho¸, c¸c ch¬ng tr×nh OpenGL c¬ b¶n cã thÓ chuyÓn sang c¸c hÖ thèng kh¸c nhau biªn dÞch mµ kh«ng cÇn hoÆc cÇn rÊt Ýt söa ®æi. Tuy nhiªn v× OpenGL ®éc lËp víi c¸c hÖ thèng giao diÖn, nªn c¸c ch¬ng tr×nh sö dông OpenGL trªn c¸c hÖ thèng kh¸c nhau cÇn triÓn khai phÇn giao tiÕp víi c¸c hÖ thèng giao diÖn riªng. VÝ dô c¸c ch¬ng tr×nh ®å ho¹ sö dông OpenGL trªn Microsoft Windows 95/NT cÇn sö dông th viÖn giao tiÕp WGL, trªn Apple Macintosh sö dông AGL, trªn Unix/Linux X Window System sö dông GLX.... PhÇn giao tiÕp nµy kh«ng kh¶ chuyÓn. Th viÖn giao tiÕp GLUT (OpenGL Utility Toolkit cña t¸c gi¶ Mark Kilgard) gióp t¹o c¸c øng dông ®å ho¹ ban ®Çu ®¬n gi¶n. Th viÖn nµy x©y dùng mét ph¬ng thøc giao tiÕp gi÷a OpenGL

2

Nhãm ®Ò tµi M« pháng sè c¸c hÖ ®éng lùc 09-01-2001

vµ hÖ thèng theo mét c¸ch thøc thèng nhÊt, do vËy ch¬ng tr×nh ®å ho¹ sö dông OpenGL vµ GLUT kh¶ chuyÓn gi÷a tÊt c¶ c¸c hÖ thèng hç trî GLUT. HiÖn ®· cã phiªn b¶n trªn tÊt c¶ c¸c hÖ ®iÒu hµnh chñ yÕu nh Microsoft Windows 95/NT, Unix/Linux X Window System, Apple Macintosh... OpenGL lµ mét th viÖn lËp tr×nh ®å ho¹ thñ tôc (procedural) vµ chØ chøa nh÷ng lÖnh ®å ho¹ c¬ b¶n, c¸c th viÖn th¬ng phÈm nh OpenInventer, Performer... ®îc x©y dùng dùa trªn OpenGL cung cÊp nh÷ng thao t¸c phøc t¹p h¬n trªn c¸c c¶nh (scene), ¸nh s¸ng, vËt liÖu, giao tiÕp víi ngêi dïng... Vµ nhê vËy viÖc x©y dùng c¸c øng dông ®å ho¹ 3 chiÒu sÏ nhanh chãng h¬n. §Æc biÖt phiªn b¶n trªn hÖ ®iÒu hµnh Linux th viÖn hµng ®Çu OpenInventor cña h·ng SGI ®· ®îc h·ng c«ng bè réng r·i cho phÐp t¶i xuèng vµ sö dông miÔn phÝ.

2 C¸c bíc x©y dùng ch¬ng tr×nh ®å häa ®éng sö dông OpenGL
OpenGL lµ mét th viÖn ®å ho¹ tèc ®é cao thÝch hîp víi nhiÒu nÒn phÇn cøng1 kh¸c nhau, cã thÓ lµm viÖc víi nhiÒu hÖ thèng window2 kh¸c nhau. Tuy nhiªn, trong ®Þnh nghÜa c¬ b¶n cña phÇn lín c¸c hÖ thèng window kh«ng hç trî mét th viÖn phøc t¹p nh OpenGL. Sù phøc t¹p nµy ®îc thÓ hiÖn trong viÖc ®Þnh d¹ng ®iÓm ¶nh phong phó vµ phøc t¹p gåm c¶ c¸c vïng ®Öm chiÒu s©u (depth buffer), vïng ®Öm stencil (stencil buffer), vïng ®Öm tÝch luü (accumulation buffer) còng nh vïng ®Öm kÐp (double buffer). Bëi vËy trong phÇn lín c¸c hÖ thèng window ®Òu cã c¸c hµm më réng ®Ó hç trî OpenGL.

2.1 Khëi t¹o
§èi víi hÇu hÕt c¸c hÖ thèng window muèn hç trî ®îc th viÖn OpenGL ®Òu ph¶i cã mét kiÓu cÊu tróc d÷ liÖu chÝnh ®Ó qu¶n lý c¸c th«ng tin ®Þnh d¹ng ®iÓm ¶nh (pixel format information) vÒ cöa sæ OpenGL. C¸c th«ng tin nµy bao gåm: kiÓu ®iÓm ¶nh (RGBA hay color index), vïng ®Öm ®¬n hay kÐp (single or double buffer), ®é ph©n gi¶i mÇu s¾c, sù hiÖn diÖn cña c¸c vïng ®Öm chiÒu s©u (depth buffer), vïng ®Öm stencil (stencil buffer), vïng ®Öm tÝch luü (accumulation buffer).
Window Systems Key Data Structure
X Visualinfo AGLPixelFmtID

X Window Apple Macintosh
1 2

hardware platform window systems : cã thÓ hiÓu lµ c¸c hÖ thèng giao ®iÖn ®å ho¹ 3

Nhãm ®Ò tµi M« pháng sè c¸c hÖ ®éng lùc 09-01-2001

IBM OS/2 Warp Window 95/NT

VISUALCONFIG PIXELFORMATDESCRIPTOR

1.2 §iÒu khiÓn rendering (controlling rendering)
HÇu hÕt c¸c hÖ thèng window ®Òu cã c¸c hµm t¹o vµ qu¶n lý mét ng÷ c¶nh t« vÏ (rendering context) cña OpenGL. Trong OpenGL kh¸i niÖm ng÷ c¶nh lµ mét tËp hîp ®Çy ®ñ c¸c biÕn tr¹ng th¸i cña OpenGL. C¸c thñ tôc nµy thùc hiÖn mét sè nhiÖm vô nh ®ång bé ho¸ qu¸ tr×nh thùc hiÖn gi÷a hÖ thèng window vµ OpenGL, ho¸n ®æi c¸c vïng ®Öm tríc vµ sau (front and back buffer), sö dông c¸c ph«ng ch÷ cña hÖ thèng cöa sæ ®ã.
2.1.1 Qu¶n lý ng÷ c¶nh t« vÏ cña OpenGL

C¸c hÖ thèng window ®Òu cã mét hµm ®Ó t¹o ng÷ c¶nh t« vÏ, hµm nµy cã d¹ng chung lµ xxxCreateContext(). Hµm nµy sÏ sö dông ®Þnh d¹ng ®iÓm ¶nh mµ ta ®· lùa chän nh mét th«ng sè ®Ó t¹o ra ng÷ c¶nh. §Ó ®Æt mét ng÷ c¶nh t« vÏ trë thµnh hiÖn hµnh c¸c hÖ thèng window sö dông hµm xxxMakeCurrent(). T¹i mét thêi ®iÓm chØ cã mét ng÷ c¶nh t« vÏ ®îc ®iÒu khiÓn. Hµm nµy sÏ cho biÕt phÇn cã kh¶ n¨ng vÏ nµo sÏ ®îc thùc hiÖn vµ ng÷ c¶nh t« vÏ nµo sÏ sö dông nã. Sö dông hµm cã d¹ng xxxGetCurrentContext() ®Ó x¸c ®Þnh ng÷ c¶nh t« vÏ sö dông cho c¸c hÖ thèng window. Mçi hÖ thèng window sö dông c¸c hµm kh¸c nhau ®Ó quyÕt ®Þnh kh¶ n¨ng vÏ nµo sÏ ®îc thùc hiÖn, tuú theo ®Æc trng cña tõng hÖ thèng.
Window Systems Routine
glxGetCurrentDrawable() aglGetCurrentDrawable() pglGetCurrentWindow() wglGetCurrentDevice ()

X Window Apple Macintosh IBM OS/2 Warp Window95/NT

§Ó sao chÐp c¸c biÕn tr¹ng th¸i tõ ng÷ c¶nh nµy sang ng÷ c¶nh kh¸c c¸c hÖ thèng window sö dông hµm cã d¹ng xxxCopyContext().Khi mét ng÷ c¶nh kÕt thóc hµm xxxDestroyContext() sÏ ®îc gäi.
2.1.2 §ång bé ho¸ qu¸ tr×nh thùc hiÖn (synchronizing execution)

§ång bé ho¸ qu¸ tr×nh thùc hiÖn lµ buéc c¸c yªu cÇu cña hÖ thèng ph¶i chê cho ®Õn khi viÖc t« vÏ cña OpenGL ®îc thùc hiÖn xong hoµn toµn. §iÒu ®ã cã nghÜa lµ bÊt cø lÖnh nµo cña

4

Nhãm ®Ò tµi M« pháng sè c¸c hÖ ®éng lùc 09-01-2001

OpenGL ®· ®îc ph¸t ra tríc ®ã sÏ ®îc ®¶m b¶o thùc hiÖn tríc bÊt cø lÖnh vÏ nµo cña hÖ thèng gäi sau lÖnh tr× ho·n. Còng cã thÓ lµm t¬ng tù víi c¸c lÖnh cña OpenGL.
Window Systems Window Systems Wait
glXWaitGL()

OpenGL Wait
glXWaitX()

X Window Apple Macintosh IBM OS/2 Warp Window95/NT

pglWaitGL() glFinish()

pglWaitPM() GdiFlush()

2.1.3 Ho¸n chuyÓn c¸c bé ®Öm (swapping buffer)

Sö dông bé ®Öm kÐp nh»m gióp cho viÖc thÓ hiÖn ®å ho¹ ®îc hoµn thiÖn. §Ó cã thÓ thu ®îc mét h×nh ¶nh chuyÓn ®éng thùc th× cÇn 24 khung h×nh trªn mét gi©y.§iÒu ®ã cã nghÜa lµ ®Ó vÏ mét khung h×nh cÇn 1/24 gi©y. C¸c phÇn vÏ ®Çu cã thÓ thÊy trong suèt 1/24 gi©y,c¸c phÇn vÏ vÒ sau bÞ xo¸ ngay khi ch¬ng tr×nh b¾t ®Çu khung h×nh tiÕp theo.§Ó gi¶i quyÕt vÊn ®Ò nµy phÇn lín c¸c øng dông OpenGL ®Òu sö dông bé ®Öm kÐp. Khi c¸i nµy ®îc thÓ hiÖn th× c¸i kia ®îc vÏ.Khi qu¸ tr×nh vÏ thùc hiÖn xong sÏ cã sù ho¸n ®æi gi÷a hai bé ®Öm, kÕt qña lµ c¸i dïng ®Ó xem tríc kia th× nay ®îc dïng ®Ó vÏ vµ ngîc l¹i.
Window Systems Routine
glXSwapBuffer() aglSwapBuffer() pglSwapBuffer() SwapBuffer()

X Window Apple Macintosh IBM OS/2 Warp Window95/NT

2.1.4 VÝ dô khëi t¹o øng dông trªn Microsoft Window

§Ó khëi t¹o mét ch¬ng tr×nh sö dông OpenGL trªn Microsoft Window thùc hiÖn theo s¸u bíc díi ®©y: Bíc 1: T¹o øng dông ban ®Çu b»ng AppWizard Bíc 2: Gép c¸c tËp tin tiªu ®Ò sau vµo nh÷ng tËp tin ch¬ng tr×nh cÇn sö dông c¸c lÖnh OpenGL: "gl.h”,”glu.h”,”glaux.h”. §Æt l¹i setting ®Ó ch¬ng tr×nh liªn kÕt víi c¸c th viÖn opengl32.lib glu32.lib
glaux.lib.

Bíc 3: Khëi t¹o cÊu tróc format.

PIXELFORMATDESCRIPTOR

vµ ®Æt pixel

Bíc 4: T¹o OpenGL rendering context

5

Nhãm ®Ò tµi M« pháng sè c¸c hÖ ®éng lùc 09-01-2001

Bíc 5: §Æt c¸c chÕ ®é cÇn thiÕt cho OpenGL : ¸nh s¸ng, mÇu s¾c, ®iÓm nh×n, chÕ ®é chiÕu, ®Æt cöa sæ giíi h¹n vïng vÏ. Bíc 6: ViÕt hµm vÏ c¶nh sö dông c¸c hµm cña OpenGL. Chi tiÕt vÒ c¸c thiÕt lËp nµy cã thÓ xem trong phÇn phô lôc LËp tr×nh OpenGl trªn Microsoft Windows sö dông Microsoft Visual C++ vµ MFC.

3 C¸c kü thuËt c¬ b¶n cña OPENGL 3.1 Quan s¸t ®èi tîng
Trong thùc tÕ khi quan s¸t mét vËt thÓ (xem [2] trang 384, [6] trang 91) ta ph¶i ®Æt vËt ë c¸ch xa hay gÇn m¾t tïy thuéc vµo vËt lín hay nhá, muèn quan s¸t hÕt c¸c phÇn cña vËt thÓ (vÝ dô mÆt tríc mÆt sau...) ta cã thÓ xoay vËt thÓ hoÆc thay ®æi m¾t nh×n.T¬ng tù nh vËy viÖc quan s¸t c¸c ®èi tîng h×nh häc trong ®å häa m¸y tÝnh còng sö dông c¸c thao t¸c t¬ng tù. C¸c thao t¸c nµy ®îc thùc hiÖn trong m¸y tÝnh nhê kü thuËt : • Camera tæng hîp (synthetic camera) • C¸c phÐp biÕn h×nh : viewing, modeling vµ projection
3.1.1 Camera tæng hîp (synthetic camera)

Mét camera tæng hîp lµ mét c¸ch ®Ó x¸c ®Þnh vÞ trÝ vµ híng chiÕu cña camera trong kh«ng gian 3 chiÒu,gåm cã 3 thµnh phÇn chÝnh : • Mét mÆt ph¼ng chiÕu (view plane) trong ®ã ®Þnh nghÜa mét cöa sæ • Mét hÖ to¹ ®é chiÕu (viewing coordinate system) • Mét m¾t nh×n ®îc ®Þnh nghÜa trong hÖ to¹ ®é chiÕu (eye) C¸c bíc ®iÒu khiÓn mét camera b×nh thuêng trong mét studio vµ mét camera tæng hîp trong m¸y tÝnh
Camera Camera tæng hîp

X¸c ®Þnh vÞ trÝ vµ híng Viewing chiÕu X¸c ®Þnh ®èi tîng cÇn Modeling chôp X¸c ®Þnh ®é lín cña ¶nh Projection cÇn chôp
6

Nhãm ®Ò tµi M« pháng sè c¸c hÖ ®éng lùc 09-01-2001

Chôp lªn h×nh Viewing transformation

Viewport

3.1.2 C¸c phÐp biÕn h×nh : viewing, modeling vµ projection

Mét viewing transformation lµm thay ®æi vÞ trÝ vµ híng cña ®iÓm chiÕu (viewpoint). NÕu gäi mét camera tæng hîp viewing transformation sÏ x¸c ®Þnh vÞ trÝ vµ híng cña camera Khi di chuyÓn camera ®Õn mét vÞ trÝ nµo ®ã vµ quay nã theo ph¬ng mong muèn, vËy phÐp viewing transformation bao gåm phÐp tÞnh tiÕn vµ phÐp quay. • C¸c hµm thùc hiÖn viewing transformation
glTranslate*() glRotate*() gluLookAt()

PhÐptÞnhtiÕn PhÐpquay §Þnh ®iÓm nh×n

Modeling transformation

§îc dïng ®Ó x¸c ®Þnh vÞ trÝ vµ ®Þnh híng cho m« h×nh. Víi mét modeling transformation cã thÓ thùc hiÖn phÐp quay, phÐp tÞnh tiÕn, phÐp co d·n mét m« h×nh bÊt kú • C¸c hµm thùc hiÖn modeling transformation
glTranslate*() glRotate*() glScale*()

PhÐp tÞnh tiÕn PhÐp quay PhÐp co d·n

Projection transformation

Mét projection transformation ®Þnh nghÜa mét khung nh×n (view volume) x¸c ®Þnh theo hai c¸ch. Mét khung nh×n x¸c ®Þnh c¸ch mµ mét ®èi tîng ®îc chiÕu lªn mµn h×nh vµ nã x¸c ®Þnh ®èi tîng hay mét phÇn ®èi tîng bÞ c¾t. Cã hai phÐp chiÕu ®îc dïng trong th viÖn OpenGL lµ phÐp chiÕu phèi c¶nh (perspective) vµ phÐp chiÕu trùc giao (orthogonal) PhÐp chiÕu phèi c¶nh : x¸c ®Þnh mét view volume h×nh chãp côt. C¸c ®èi tîng ë trong view volume ®îc chiÕu th¼ng tíi ®Ønh cña h×nh chãp, ë ®©y lµ camera hoÆc ®iÓm nh×n. §èi tîng cµng ë gÇn ®iÓm nh×n xuÊt hiÖn cµng lín h¬n

7

Nhãm ®Ò tµi M« pháng sè c¸c hÖ ®éng lùc 09-01-2001

• C¸c hµm ®Ó ®Þnh nghÜa view volume vµ perspective projection
glFrustum() gluPerspectivePorjection()

§Þnh nghÜa mét h×nh côt x¸c ®Þnh phÐp chiÕu phèi c¶nh

PhÐp chiÕu trùc giao: x¸c ®Þnh mét view volume lµ mét h×nh hép ch÷ nhËt. Do kÝch cì cña mét view volume kh«ng thay ®æi tõ tríc ra sau... cho nªn kho¶ng c¸ch cña camera kh«ng ¶nh hëng g× tíi ®é lín cña ®èi tîng xuÊt hiÖn sau khi chiÕu. • C¸c hµm ®Þnh nghÜa mét view volume
glOrtho()

T¹o ra mét view volume cña phÐp chiÕu trùc giao

3.2 Mµu s¾c vËt liÖu vµ ¸nh s¸ng (material color and lighting)
Víi kü thuËt xö lý ¸nh s¸ng vµ mµu s¾c cña OpenGL (xem [6] trang 151, 169) chóng ta hoµn toµn cã thÓ m« pháng c¸c ®èi tîng trªn m¸y tÝnh gièng víi ®èi tîng thùc trong thùc tÕ. OpenGL cho phÐp thùc hiÖn c¸c c«ng viÖc sau: • BiÓu diÔn mét ®èi tîng ®îc chiÕu s¸ng b»ng c¸ch ®Þnh nghÜa nguån s¸ng vµ vËt thÓ chiÕu s¸ng. • §Þnh nghÜa c¸c thuéc tÝnh vËt liÖu cña ®èi tîng ®îc chiÕu s¸ng.
3.2.1 Kh¸i niÖm vÒ c¸c lo¹i ¸nh s¸ng

Trong OpenGL sö dông 3 lo¹i ¸nh s¸ng, bao gåm ¸nh s¸ng bao quanh (ambient light), ¸nh s¸ng khuÕch t¸n (diffuse light), ¸nh s¸ng g¬ng (specular light) Bao quanh: lµ ¸nh s¸ng ®îc ph¸t ra tõ mäi phÝa trong m«i trêng. H·y tëng tîng thay v× tù chiÕu s¸ng, ta cã sù khuÕch t¸n ¸nh s¸ng theo mäi phÝa tõ mét nguån s¸ng bÊt kú, khi ®ã kÕt qu¶ thu ®îc do sù ph¶n x¹ ¸nh s¸ng tõ c¸c bÒ mÆt trong m«i trêng chÝnh lµ ¸nh s¸ng ambient. KhuÕch t¸n: lµ ¸nh s¸ng ®îc chiÕu ®Õn ®èi tîng theo mét ph¬ng nµo ®ã, bëi vËy ë nh÷ng vÞ trÝ nµo trªn bÒ mÆt ®îc chiÕu s¸ng mµ vu«ng gãc víi tia s¸ng khuÕch t¸n (diffuse light) sÏ s¸ng h¬n so víi c¸c vÞ trÝ kh¸c. G¬ng: lµ ¸nh s¸ng ®îc chiÕu ®Õn vËt thÓ theo mét ph¬ng ®Æc biÖt. Sù ph¶n chiÕu cña ¸nh s¸ng nµy cã thÓ quan s¸t ®îc trªn bÊt cø bÒ mÆt nh½n bãng nµo.
8

Nhãm ®Ò tµi M« pháng sè c¸c hÖ ®éng lùc 09-01-2001

Gi¶ sö khi chiÕu s¸ng mét qu¶ cÇu ta thÊy cã mét phÇn s¸ng bãng, nã ®îc t¹o ra bëi sù ph¶n x¹ ¸nh s¸ng g¬ng (specular light) trªn bÒ mÆt cÇu.
3.2.2 Mµu s¾c vËt liÖu.

Gièng nh ®èi víi ¸nh s¸ng, vËt liÖu còng cã c¸c mµu bao quanh (ambient color),mµu khuÕch t¸n( diffuse color),mµu g¬ng (specular color),dïng ®Ó x¸c ®Þnh hÖ sè ph¶n x¹ xung quanh(ambient reflectance), ph¶n x¹ khuÕch t¸n(diffuse reflectance), ph¶n x¹ g¬ng(specular reflectance) cña vËt liÖu. Mµu cña vËt liÖu dîc x¸c ®Þnh bëi hÖ sè ph¶n x¹ xung quanh (ambient reflectance) vµ khuÕch t¸n(diffuse reflectance ). HÖ sè ph¶n x¹ g¬ng thêng lÊy gi¸ trÞ cña mµu tr¾ng hoÆc x¸m sao cho ®é ph¶n chiÕu cña ¸nh s¸ng g¬ng lµ lín nhÊt. Ngoµi c¸c mµu s¾c nãi trªn vËt liÖu cßn cã mét thuéc tÝnh mµu kh¸c gäi lµ mµu ph¸t x¹ (emmisive color). NÕu sö dông thuéc tÝnh mµu nµy cña vËt liÖu chóng ta cã thÓ lµm cho vËt thÓ trë nªn, bãng, ®Ñp vµ thËt h¬n.
3.2.3 HÖ mµu trong m¸y tÝnh

Trªn mµn h×nh m¸y tÝnh mµu mçi ®iÓm ¶nh ph¸t ra c¸c mµu: ®á (red), xanh l¸ c©y (green), xanh níc biÓn (blue) víi gi¸ trÞ kh¸c nhau, gäi lµ c¸c gi¸ trÞ R, G, B. Th«ng thêng 3 gi¸ trÞ nµy tæ hîp l¹i t¹o thµnh t¹o gi¸ trÞ mµu RGB, ®«i khi cßn thªm gi¸ trÞ mµu A (alpha) t¹o ra gi¸ trÞ mµu RGBA. C¸c th«ng tin vÒ mµu s¾c cã thÓ ®îc lu tr÷ trong RGBA mode hoÆc color-index mode trong ®ã mçi sè riªng lÎ (chØ sè mµu) ®îc lu tr÷ cho mét ®iÓm ¶nh.Mçi chØ sè mµu nµy chØ ra mét môc trong mét b¶ng ®Þnh nghÜa mét c¸ch chi tiÕt tËp c¸c gi¸ trÞ cña R,G,B. B¶ng nµy ®îc gäi lµ b¶n ®å mµu s¾c. C¸c gi¸ trÞ R, G, B n»m trong kho¶ng tõ 0 ®Õn 1, ¸nh s¸ng, vËt liÖu sÏ cã mµu tr¾ng khi tÊt c¶ R,G,B ®Òu cã gi¸ trÞ lµ 1.0 vµ cã mµu ®en khi tÊt c¶ cã gi¸ trÞ 0.0. Mµu cña ¸nh s¸ng vµ vËt liÖu ®îc t¹o ra mµ m¾t ta nh×n thÊy sÏ lµ sù pha trén cña 3 mÇu c¬ b¶n trªn.
3.2.4 Khëi t¹o, x¸c ®Þnh vÞ trÝ, sö dông nguån s¸ng

Enable mét nguån s¸ng

§Ó hµm cã ®îc hiÖu øng ¸nh s¸ng trong ch¬ng tr×nh mét hay nhiÒu nguån s¸ng ph¶i kÝch ho¹t b»ng c¸ch gäi hµm
glEnable(light);

light

GL_LIGHTi

Tªn nguån s¸ng i = 0,1,...7

T¹o nguån s¸ng
9

Nhãm ®Ò tµi M« pháng sè c¸c hÖ ®éng lùc 09-01-2001

§Ó khëi t¹o nguån s¸ng gäi hµm:
glLightf(GLenum light,GLenum pname,Type param); glLighti(GLenum light,GLenum pname,Type param); glLightfv(GLenum light,GLenum pname,Type* param); glLightiv(GLenum light,GLenum pname,Type *param);

trong ®ã
light pname GL_LIGHTi GL_XXX GL_AMBIENT GL_DIFFUSE GL_SPECULAR GL_POSITION GL_CONSTANT_ATTENUATIO N GL_LINEAR_ATTENUATION GL_QUADRATIC_ATTENUATI ON

Tªn nguån s¸ng i = 0,1,...7 Lo¹i th«ng sè cÇn thiÕt lËp cêng ®é ¸nh s¸ng ambient cêng ®é ¸nh s¸ng diffuse cêng ®é ¸nh s¸ng specular vÞ trÝ nguån s¸ng{x,y,z,w} hÖ sè ¸nh s¸ng hÖ sè ¸nh s¸ng hÖ sè ¸nh s¸ng

HÖ sè ¸nh s¸ng göi ®Õn (attenuation factor) ®îc sö dông khi vËt thÓ cÇn chiÕu s¸ng ®Æt qu¸ xa nguån s¸ng hoÆc vËt thÓ lín mµ mét sè phÇn cña vËt thÓ khi ¸nh s¸ng chiÕu ®îc ®Õn th× cêng ®é s¸ng cña nã bÞ suy gi¶m vµ do ®ã viÖc chiÕu s¸ng sÏ kh«ng ®¹t hiÖu qu¶ nh mong muèn bëi vËy hÖ sè ¸nh s¸ng göi ®Õn ®îc ®a ra ®Ó gi¶i quyÕt ®îc vÊn ®Ò nµy.

VÝ dô sö dông hµm glLightf()

GLfloat light_ambient = {0.0,0.0,0.5,1.0}; GLfloat light_diffuse = {1.0,0.0,0.5,1.0}; GLfloat light_specular = {1.0,1.0,1.0,1.0}; GLfloat light_position = {1.0,1.0,1.0,0.0}; GLfloat constant GLfloat linear GLfloat quadratic = 1; = 0.001; =0.0001;

glLightfv(GL_LIGHT0,GL_AMBIENT,light_ambient); glLightfv(GL_LIGHT0,GL_ DIFFUSE,light_diffuse); glLightfv(GL_LIGHT0,GL_ SPECULAR,light_specular); glLightfv(GL_LIGHT0,GL_ POSITION,light_position); glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION,costant); glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION,linear); glLightf(GL_LIGHT0,GL_QUADRATIC_ATTENUATION,quadratic);

10

Nhãm ®Ò tµi M« pháng sè c¸c hÖ ®éng lùc 09-01-2001

glEnable(GL_LIGHT0);

Chó ý: NÕu sö dông nhiÒu nguån s¸ng cïng mét lóc sÏ lµm cho tèc ®é tÝnh to¸n gi¶m ®i rÊt nhiÒu lÇn.
3.2.5 §Þnh nghÜa c¸c thuéc tÝnh cña vËt liÖu

§Þnh c¸c thuéc tÝnh mµu cña vËt liÖu sö dông mét trong c¸c hµm

glMateriali(GLenum face,GLenum pname,TYPE param); glMaterialf(GLenum face,GLenum pname,TYPE param); glMaterialiv(GLenum face,GLenum pname,TYPE *param); glMaterialfv(GLenum face,GLenum pname,TYPE *param);

face

GL_FRONT GL_BACK GL_FRONT_AND_BACK

BÒ mÆt nµo ®îc chiÕu s¸ng Lo¹i thuéc tÝnh vËt liÖu

pname GL_AMBIENT GL_DIFFUSE GL_AMBIENT_AND_DIFFUSE GL_SPECULAR GL_SHININESS GL_EMMISSION

mÇu ambient cña vËt liÖu mÇu diffuse cña vËt liÖu mÇu ambient & diffuse cña vËt liÖu mÇu specular cña vËt liÖu thµnh phÇn cña specular mµu emissive cña vËt liÖu

VÝ dô sö dông thuéc tÝnh vËt liÖu

//..... GLfloat mat_ambient[]={0.7,0.7,0.7,1.0}; GLfloat mat_diffuse[]={0.7,0.1,0.2,1.0}; GLfloat mat_specular[]={1.0,1.0,1.0,1.0}; GLfloat mat_emission[]={0.0,0.0,0.0,1.0}; GLfloat mat_shininess[]=50; //..... glMaterialfv(GL_FRONT,GL_AMBIENT,mat_ambient); glMaterialfv(GL_FRONT,GL_DIFFUSE,mat_diffuse); glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular); glMaterialfv(GL_FRONT,GL_EMMISSION,mat_emmission); glMaterialfv(GL_FRONT,GL_SHININESS,mat_shininiess);

11

Nhãm ®Ò tµi M« pháng sè c¸c hÖ ®éng lùc 09-01-2001

//.....

3.2.6 VÝ dô vÒ kÕt hîp sö dông thuéc tÝnh vËt liÖu vµ ¸nh s¸ng

Sau ®©y lµ mét ch¬ng tr×nh vÏ mét qu¶ cÇu ®îc g¸n c¸c thuéc tÝnh vËt liÖu (mÇu tÝm) vµ ®îc chiÕu s¸ng bëi bét nguån s¸ng ®iÓm:
#include <windows.h> #include <GL\glaux.h> #include "stdio.h" #include <GL\gl.h> #include <GL\glu.h> void init(void) { GLfloat mat_ambient[]={255/255,181/255, 255/255,1.0}; GLfloat mat_diffuse[]={1.0,0.0,0.0,1.0}; GLfloat mat_specular[]={1.0,1.0,1.0,1.0}; GLfloat light_pos[]={1.0,1.0,1.0,0.0}; glClearColor(0.0,0.0,0.0,0.0); glShadeModel(GL_SMOOTH); glEnable(GL_DEPTH_TEST); glMaterialfv(GL_FRONT,GL_AMBIENT,mat_ambient); glMaterialfv(GL_FRONT,GL_DIFFUSE,mat_diffuse); glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular); glMaterialf(GL_FRONT,GL_SHININESS,50.0f); glLightfv(GL_LIGHT0,GL_POSITION,light_pos); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glColorMaterial(GL_FRONT,GL_DIFFUSE); glEnable(GL_COLOR_MATERIAL); } void CALLBACK dis(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); auxSolidSphere(1.0); glFlush(); } void CALLBACK reshape(GLsizei w, GLsizei h)

12

Nhãm ®Ò tµi M« pháng sè c¸c hÖ ®éng lùc 09-01-2001

{ glViewport(0,0,(GLsizei)w,(GLsizei)h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glLoadIdentity(); if (w<=h) glOrtho(-1.5,1.5,-1.5*(GLfloat) h/(GLfloat) w,1.5*(GLfloat) h/(GLfloat) w,-10.0,10.0); else glOrtho(-1.5*(GLfloat) w/(GLfloat) h,1.5*(GLfloat) w/(GLfloat) h,1.5,1.5,-10.0,10.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } int main(int argc, char* argv[]) { auxInitDisplayMode(AUX_SINGLE|AUX_RGB |AUX_DEPTH); auxInitWindow("R - G - B changing"); auxInitPosition(0,0,640,480); init(); auxReshapeFunc(reshape); auxMainLoop(dis); return 0; }

3.3 Trén mµu, lo¹i bá r¨ng ca vµ kü thuËt t¹o s¬ng (blending, antialiasing, fog)
§Ó c¶i thiÖn chÊt lîng h×nh ¶nh vµ t¹o thªm mét sè c¸ch biÓu diÔn c¸c ®èi tîng h×nh häc trªn m¸y tÝnh OpenGL ®· ®a ra mét sè kü thuËt: blending, antialiasing vµ fog. C¸c kü thuËt nµy cho phÐp thùc hiÖn c¸c c«ng viÖc sau: • Pha trén mµu s¾c ®Ó t¹o ra mét vËt thÓ cã thÓ nh×n xuyªn qua (nh g¬ng, kÝnh mê) • Lµm mÞn (lo¹i bá r¨ng ca) c¸c c¹nh cña c¸c ®êng th¼ng vµ ®a gi¸c víi antiliasing

13

Nhãm ®Ò tµi M« pháng sè c¸c hÖ ®éng lùc 09-01-2001

• T¹o ra c¸c c¶nh víi hiÖu øng s¬ng mï (râ khi gÇn, mê dÇn khi xa dÇn)
3.3.1 Trén mµu (blending)

Trong thùc tÕ cã nh÷ng vËt trong suèt hay mê mê mµ ta cã thÓ cã thÓ nh×n xuyªn qua nh kÝnh, pha lª, nhùa hay ®¸ quÝ...ViÖc biÓu diÔn c¸c vËt nµy trªn m¸y tÝnh ®ßi hái mét sè kü thuËt cao cÊp. OpenGL cho phÐp thùc hiÖn c«ng viÖc nµy mét c¸ch dÔ dµng víi kü thuËt trén mµu (blending). Khi thùc hiÖn trén mµu gi¸ trÞ mµu alpha (A) trong hÖ RGBA ®îc dïng ®Ó tæ hîp víi gi¸ trÞ mµu cña c¸c ®iÓm ¶nh ®· ®îc lu tr÷ trong bé ®Öm. Cã thÓ h×nh dung gi¸ trÞ mµu RGB biÓu diÔn mµu cña c¸c ®iÓm ¶nh (hay lµ mµu cña vËt thÓ biÓu diÔn) cßn gi¸ trÞ anpha (A) biÓu diÔn tÝnh trong mê cña vËt thÓ. Gi¶ sö ta nh×n mét qu¶ bãng mµu vµng qua mét chiÕc ly mµu xanh khi ®ã mµu mµ ta nh×n thÊy sÏ lµ mét phÇn mµu xanh cña chiÕc ly vµ mét phÇn mµu vµng cña qu¶ bãng, tØ lÖ nµy cßn phô thuéc vµo kh¶ n¨ng cho ¸nh s¸ng truyÒn qua cña chiÕc ly, nÕu chiÕc ly cho 80% ¸nh s¸ng chiÕu tíi nã ®i qua (tøc lµ sÏ cã 20% ¸nh s¸ng bÞ chÆn l¹i) khi ®ã mµu mµ ta nh×n thÊy sÏ lµ mµu tæ hîp cña 20% mµu chiÕc ly vµ 80% mµu qu¶ bãng. • C¸c bíc ®Ó t¹o ra mét vËt thÓ trong mê:
glEnable(GL_BLEND) glBlendFund(GL_SRC_ALPHA,GL_SRC_COLOR)

Khëi t¹o blending Hµm thùc hiÖn viÖc trén mµu

3.3.2 Lo¹i bá r¨ng ca (antiliasing)

Trªn rÊt nhiÒu bøc ¶nh ®îc vÏ trong m¸y tÝnh ta nhËn thÊy trªn c¸c ®êng th¼ng ®Æc biÖt lµ c¸c ®êng gÇn nh th¼ng ®øng hay gÇn nh n»m ngang xuÊt hiÖn c¸c r¨ng ca. C¸c r¨ng ca nµy xuÊt hiÖn bëi ®êng th¼ng ®îc xÊp xØ bëi mét tËp hîp c¸c ®iÓm n»m trªn líi ®iÓm. Trªn ¶nh t¹o ra trong m¸y tÝnh viÖc xuÊt hiÖn c¸c r¨ng ca lµm gi¶m chÊt lîng h×nh ¶nh mÊt ®i tÝnh trung thùc cña ®èi tîng mµ ta biÓu diÔn bëi vËy viÖc lo¹i bá c¸c r¨ng ca rÊt ®îc quan t©m. Mét kü thuËt kh«ng thÓ thiÕu cña ®å häa h×nh ¶nh chÊt lîng cao ®ã lµ kü thuËt lo¹i bá r¨ng ca (antiliasing). Khi thùc hiÖn viÖc lo¹i bá r¨ng ca OpenGL tÝnh to¸n mét gi¸ trÞ trung b×nh cho mçi ®o¹n dùa trªn mét m¶ng c¸c ®iÓm ¶nh h×nh vu«ng cã thÓ nh×n thÊy trªn mµn h×nh §êng th¼ng sÏ ®îc vÏ víi c¸c gi¸ trÞ trung b×nh nµy. • C¸c bíc thùc hiÖn trong OpenGL ®Ó lo¹i bá r¨ng ca

14

Nhãm ®Ò tµi M« pháng sè c¸c hÖ ®éng lùc 09-01-2001

glEnable(pname) glLineWidth(value) Pname

Hµm khëi t¹o antialiasing Hµm ®Æt chiÒu réng ®êng Lµ mét trong c¸c gi¸ trÞ sau

GL_POINT_SMOOTH GL_LINE_SMOOTH GL_POLYGON_SMOOTH Value

lo¹i bá r¨ng ca c¸c ®iÓm lo¹i bá r¨ng ca c¸c ®êng th¼ng lo¹i bá r¨ng ca cña c¸c ®a gi¸c value ®é réng cña ®êng th¼ng

3.3.3 S¬ng mï (fog)

Trong m¸y tÝnh ®«i khi ta cÇn t¹o ra c¸c c¶nh sao cho nã xuÊt hiÖn mét c¸ch tù nhiªn h¬n, vÝ dô nh khi nh×n mét chiÕc « t« ®ang ch¹y, lóc ®Çu ta thÊy chiÕc « t« rÊt râ nhng khi chiÕc xe ch¹y xa dÇn h×nh ¶nh cña nã còng mê dÇn vµ ®Õn mét kho¶ng c¸ch nµo ®ã th× mÊt h¼n, OpenGL cho phÐp sö dông kü thuËt t¹o s¬ng mï (fog) ®Ó t¹o ra c¸c h×nh ¶nh tù nhiªn sèng ®éng. • §Ó t¹o ra s¬ng mï trong c¸c øng dông ta sö dông c¸c hµm sau ®©y:
glEnable(GL_FOG) glFog*(GL_FOG_MODE,GL_EXP) glFog*(GL_FOG_COLOR,fogcolor) glFog*(GL_FOG_DENSITY,density) fogcolor

mµu cña s¬ng, cã thÓ chän bÊt cø mµu nµo nhng nªn chän mµu gÇn víi mµu nÒn nhÊt ®Ó t¹o ra hiÖu qu¶ cao nhÊt cêng ®é s¬ng (®é mÞn cña líp s¬ng), cã gi¸ trÞ trong kho¶ng [0,1] density cµng nhá líp s¬ng cµng dµy,tÇm nh×n cµng bÞ h¹n chÕ.

density

3.4 VÏ ®iÓm, ¶nh bitmap vµ font
Trong m¸y tÝnh bÊt kú mét ®èi tîng hay vËt thÓ nµo khi vÏ ®Òu liªn quan tíi c¸c d÷ liÖu h×nh häc c¬ së nh ®iÓm, ®êng vµ c¸c ®a gi¸c ([6] trang 317). Mét h×nh ¶nh cã thÓ lµ mét tËp hîp c¸c ®iÓm, mét tËp hîp c¸c ®êng hay mét tËp c¸c ®a gi¸c. Ngoµi c¸c líp d÷ liÖu c¬ së trªn trong Open GL cßn cã hai líp d÷ liÖu quan träng kh¸c ®îc dïng ®Ó biÓu diÔn vËt thÓ ®ã lµ:
15

Nhãm ®Ò tµi M« pháng sè c¸c hÖ ®éng lùc 09-01-2001

• Bitmaps, ®iÓn h×nh cho viÖc t¹o ra c¸c ký tù trong fonts • D÷ liÖu ®iÓm ¶nh (image data), cã thÓ ®îc quÐt vµo trong m¸y hoÆc cã ®îc tõ c¸c kÕt qu¶ tÝnh to¸n.
3.4.1 Bitmaps vµ fonts

Bitmap lµ mét m¹ng líi c¸c h×nh ch÷ nhËt xÕp thµnh nhiÒu hµng vµ cét, mçi h×nh ch÷ nhËt ®îc ®iÒu khiÓn bëi mét m· s¸ng hoÆc t¾t, 1 t¬ng øng víi m· s¸ng, 0 t¬ng øng víi t¾t. C¸c bitmap sÏ ®îc m¸y tÝnh chuyÓn thµnh c¸c ®iÓm (pixel) ®Ó thÓ hiÖn trªn mµn h×nh. §Ó vÏ c¸c ký tù trªn mµn h×nh c¸ch th«ng thêng nhÊt lµ dïng c¸c ¶nh bitmap. Ph«ng ch÷ (font) lµ mét tËp hîp hoµn chØnh c¸c ký tù (ch÷ c¸i, con sè, ký tù ®Æc biÖt dÊu c©u). • C¸c hµm ®îc sö dông ®Ó vÏ ¶nh bimap
glRasterPos*(x, y, z) glBitmap()

X¸c ®Þnh vÞ trÝ cña bitmap §Ó vÏ bitmap

3.4.2 C¸c ®iÓm ¶nh (image)

Mét ®iÓm ¶nh t¬ng ®¬ng víi mét bitmap nhng thay v× chØ cã mét bÝt ®¬n cho mçi ®iÓm trong mét diÖn tÝch h×nh ch÷ nhËt trªn mµn h×nh, mçi ®iÓm ¶nh cßn cã thÓ cã rÊt nhiÒu th«ng tin. VÝ dô mét ®iÓm ¶nh cã thÓ chøa toµn bé d÷ liÖu mµu cho mçi ®iÓm (pixel). C¸c ®iÓm ¶nh cã thÓ ®îc lÊy tõ: • Mét bøc ¶nh ®îc sè ho¸ nhê mét m¸y scanner • Mét ®iÓm ¶nh, ®Çu tiªn ®îc t¹o ra trªn mµn h×nh b»ng mét tr×nh ®å häa, råi sau ®ã ®îc ®äc trë l¹i, tõng ®iÓm mét • Mét ch¬ng tr×nh phÇn mÒm sinh ra c¸c ®iÓm ¶nh trong bé nhí ®iÓm C¸c hµm c¬ b¶n ®Ó thùc hiÖn viÖc xö lý c¸c ®iÓm ¶nh
glReadPixels() glDrawPixel() glCopyPixel()

§äc c¸c ®iÓm ch÷ nhËt tõ bé ®Öm vµ ®a vµo lu tr÷ trong bé xö lý cña m¸y tÝnh Ghi c¸c ®iÓm ch÷ nhËt tõ bé xö lý vµo bé ®Öm Copy c¸c ®iÓm ch÷ nhËt tõ bé ®Öm sang n¬i kh¸c

16

Nhãm ®Ò tµi M« pháng sè c¸c hÖ ®éng lùc 09-01-2001

3.5 KÜ thuËt d¸n ¶nh (texture mapping)
KÜ thuËt d¸n ¶nh (xem [6] trang 317) , lµ c«ng nghÖ d¸n mét ¶nh lªn mét bÒ mÆt bÊt kú nµo ®ã nh mÆt ph¼ng mÆt cong... Víi kü thuËt nµy hoµn toµn cã kh¶ n¨ng t¹o ra mét vËt thÓ cã hoa v¨n bÊt kú. B¹n hoµn toµn cã thÓ vÏ mét bøc têng víi hµng ngµn viªn g¹ch b»ng c¸ch lÆp l¹i mÉu ¶nh mét viªn trªn toµn bé diÖn tÝch têng.
3.5.1 §èi tîng texture

Mét ®èi tîng texture (texture object) sÏ lu gi÷ c¸c d÷ liÖu texture. B¹n cã thÓ ®iÒu khiÓn ®îc nhiÒu texture, dÔ dµng dïng l¹i c¸c texture ®· ®îc t¶i tríc ®ã. §©y thêng lµ c¸ch nhanh nhÊt trong sö dông texture v× t¶i l¹i mét ¶nh texture nhanh h¬n nhiÒu so víi viÖc ph¶i tÝnh to¸n l¹i xem mét ¶nh nguån ph¶i d¸n cho phï hîp víi mét bÒ mÆt nh thÕ nµo. C¸c bíc ®Ó t¹o ra mét ®èi tîng texture: • T¹o ra c¸c tªn cho c¸c texture (1 m¶ng int). • • • Khëi t¹o c¸c texture. KiÓm tra kh¶ n¨ng cña bé nhí cho viÖc sö dông c¸c §a c¸c d÷ liÖu vµo tr¹ng th¸i s½n sµng ®Ó vÏ.

®èi tîng texture.

3.5.2 C¸c bíc thùc hiÖn kü thuËt d¸n ¶nh

§Ó t¹o ra mét c¶nh sö dông kü thuËt d¸n ¶nh, cÇn thùc hiÖn c¸c bíc sau: • T¹o ra mét ®èi tîng texture vµ chØ ra texture cho ®èi tîng ®ã • • • ChØ ra tuú chän mµ texture ®Ó ¸p dông cho mçi Enable d¸n ¶nh VÏ c¶nh ®iÓm ¶nh

Vµ sau ®©y lµ chi tiÕt thùc hiÖn c¸c bíc nµy: T¹o ra mét ®èi tîng texture vµ x¸c ®Þnh texture cho ®èi tîng ®ã

Th«ng thêng lµ ta sö dông texture 2 chiÒu, Ýt khi sö dông texture mét chiÒu. D÷ liÖu thêng bao gåm 3 thµnh phÇn RGB.
17

Nhãm ®Ò tµi M« pháng sè c¸c hÖ ®éng lùc 09-01-2001

Cho phÐp mét ®Õn bèn thµnh phÇn trong RGBA. Tªn cña ®èi tîng texture lµ mét sè nguyªn d¬ng kh¸c 0.

ChØ ra tuú chän mµ texture ®Ó ¸p dông cho mçi ®iÓm ¶nh

OpenGL cho phÐp kÕt hîp c¸c d÷ liÖu cña texture víi bÒ mÆt cÇn d¸n t¬ng tù nh blending... Ta cã thÓ kÕt hîp texture víi ¸nh s¸ng chiÕu lªn bÒ mÆt. Mode GL_DECAL thêng ®îc sö dông nhiÒu nhÊt.

Enable c¬ chÕ d¸n ¶nh Gäi hµm

glEnable(pname) glDisable(pname)

Pname

GL_TEXTURE_2D, GL_TEXTURE_1D

VÏ c¶nh Gäi c¸c hµm vÏ th«ng thêng.

3.5.3 C¸c hµm chñ yÕu ®Ó t¹o ra mét øng dông d¸n ¶nh

C¸c hµm khëi t¹o

glGenTextures(1,&texName) glBindTexture(GL_TEXTURE_2D,texName) glTexParameteri(GL_TEXTURE_2D,GL_TEXTU RE_MAG_FILTER,GL_LINEAR) glTexParameteri(GL_TEXTURE_2D,GL_TEXTU RE_MIN_FILTER,GL_LINEAR) glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA, W,H,0,GL_RGBA,GL_UNSIGNED_BYTE,Img)

glGenTextures(n,texName)

Hµm t¹o tªn cho c¸c texture míi ®¶m b¶o c¸c texName[i] kh«ng trïng víi c¸c texture ®· cã. Hµm t¹o ra texture.

glBindTexture(target, texName)

NÕu sö dông lÇn ®Çu víi texName > 0 th× mét texture míi sÏ ®îc t¹o ra. NÕu sö dông víi mét ®èi tîng texture ®· ®îc t¹o ra tríc ®ã th× ®èi tîng texture nµy sÏ trë thµnh hiÖn hµnh (active). NÕu sö dông víi texName = 0 th× OpenGL sÏ dõng sö dông texture hiÖn t¹i vµ quay vÒ texture kh«ng tªn mÆc ®Þnh.
18

Nhãm ®Ò tµi M« pháng sè c¸c hÖ ®éng lùc 09-01-2001

glTexParameter{if}(GLenum target, GLenum pname, TYPE param) glTexParameter{if}v(GLenum target, GLenum pname, TYPE * param)

Hµm nµy ®Æt m«i trêng cho texture, target chØ ra GL_TEXTURE_2D hoÆc GL_TEXTURE_1D. pname chØ ra biÕn m«i trêng cÇn ®Æt víi gi¸ trÞ chØ ra bëi param. C¸c gi¸ trÞ cã thÓ cña pname vµ param ®îc cho trong b¶ng sau :
pname
GL_TEXTURE_WRAP_S GL_TEXTURE_WRAP_T GL_TEXTURE_MAG_FILTER GL_TEXTURE_MIN_FILTER

param
GL_REPEAT, GL_CLAMP GL_REPEAT, GL_CLAMP GL_NEAREST, GL_LINEAR GL_NEAREST, GL_LINEAR GL_NEAREST_ MIPMAP_NEAREST, GL_NEAREST_ MIPMAP_LINEAR, GL_LINEAR_ MIPMAP_NEAREST, GL_LINEAR_ MIPMAP_LINEAR,

GL_TEXTURE_BORDER_COL OR GL_TEXTURE_PRIORITY

4 gi¸ trÞ [0.0,1.0] (1 vecto) [0.0,1.0]

glTexEnvf{if}(GLenum target, GLenum pname , TYPE param) glTexEnvf{if}v(GLenum target , GLenum pname , TYPE * param)

Hµm nµy chØ ra c¸ch kÕt hîp texture víi c¸c d÷ liÖu ®· ®îc vÏ tríc ®ã. target ph¶i lµ GL_TEXTURE_ENV. pname cã thÓ cã 2 gi¸ trÞ :
GL_TEXTURE_ENV_MODE th× param cã thÓ lµ GL_DECAL,GL_REPLACE,GL_MODULATE , GL_BLEND. GL_TEXTURE_ENV_COLOR th× param lµ mét vecto (R,G,B,A). Tuy nhiªn c¸c gi¸ trÞ nµy chØ cã t¸c dông nÕu GL_BLEND ®îc chän. glTexImage2D(GLenum target , GLint level , GLint internalFormat , GLsizei Widht , GLsizei Height ,GLint border,GLenum format,GLenum type , const GLvoid * pixels)

C¸c hµm vÏ texture

glTexCoord*() t¬ng tù glNormal*() nã chØ ra ®iÓm trªn texture mµ c¸c ®iÓm h×n häc ®îc chØ ra sau lÖnh nµy sÏ nhËn ®iÓm nµy khi texture ®îc d¸n lªn

3.5.4 VÝ dô

VÝ dô sau vÏ mét mÆt bËc 2 vµ d¸n lªn nã mét h×nh ¶nh bµn cê.
#include <windows.h>

19

Nhãm ®Ò tµi M« pháng sè c¸c hÖ ®éng lùc 09-01-2001

#include <stdlib.h> #include <stdio.h> #include <GL/gl.h> #include <GL/glu.h> #include <GL/glut.h> #define W 64 #define H 64 static GLubyte Img[H][W][4]; static GLuint texName; void MakeCheckImg(int x) { int i,j,c,d; if(x==0) for(i=0;i<H;i++) for(j=0;j<W;j++) { c = 225*((i+j)%2); Img[i][j][0] = (GLubyte) 255; Img[i][j][1] = (GLubyte) c; Img[i][j][2] = (GLubyte) c; Img[i][j][3] = (GLubyte) 255; } else for(i=0;i<H;i++) for(j=0;j<W;j++) { c = ((((i&0x8)==0)^((j&0x8))==0))*255; Img[i][j][0] = (GLubyte) 255; Img[i][j][1] = (GLubyte) c; Img[i][j][2] = (GLubyte) c; Img[i][j][3] = (GLubyte) 255; } } void init(void )

20

Nhãm ®Ò tµi M« pháng sè c¸c hÖ ®éng lùc 09-01-2001

{ glClearColor(0.0,0.0,0.0,0.0); glShadeModel(GL_FLAT); glEnable(GL_DEPTH_TEST); MakeCheckImg(1); glGenTextures(1,&texName); glBindTexture(GL_TEXTURE_2D,texName); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,W,H,0,GL_RGBA,GL_UNSIGNED_BYTE,Im g); } void display() { glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D,texName); glBegin(GL_QUADS); glTexCoord2f(0.0,0.0); glVertex3f(-2.0,-1.0,0.0); glTexCoord2f(0.0,1.0); glVertex3f(-2.0,1.0,0.0); glTexCoord2f(1.0,1.0); glVertex3f(0.0,1.0,0.0); glTexCoord2f(1.0,0.0); glVertex3f(0.0,-1.0,0.0); glTexCoord2f(0.0,0.0); glVertex3f(1.0,-1.0,0.0); glTexCoord2f(0.0,0.2); glVertex3f(1.0,1.0,0.0); glTexCoord2f(0.2,0.2); glVertex3f(3.0,1.0,0.0); glTexCoord2f(0.2,0.0); glVertex3f(3.0,-1.0,0.0); glEnd(); glFlush(); glDisable(GL_TEXTURE_2D); } void reshape(int w,int h) { glViewport(0,0,(GLsizei)w,(GLsizei)h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0,(GLfloat)w/(GLfloat)h,1.0,30.0);

21

Nhãm ®Ò tµi M« pháng sè c¸c hÖ ®éng lùc 09-01-2001

glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0.0,0.0,-6.0); } void keyboard(unsigned char key,int x, int y) { switch(key) { case 27: exit(0); break; default: break; } } int main(int arg, char ** argv) { glutInit(&arg,argv); glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB|GLUT_DEPTH); glutInitWindowSize(250,250); glutInitWindowPosition(100,100); glutCreateWindow(argv[0]); init(); glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); glutMainLoop(); return 0; }

3.6 Danh s¸ch hiÓn thÞ (display list)
Mét danh s¸ch hiÓn thÞ lµ mét nhãm lÖnh cña OpenGL ®îc lu tr÷ l¹i cho nh÷ng lÇn thùc hiÖn lÖnh sau ®ã Danh s¸ch hiÓn thÞ chøa trong bé nhí nhãm lÖnh mµ ta ®Æt vµo danh s¸ch hiÓn thÞ khi khëi t¹o nã. Khi muèn sö dông l¹i nhãm lÖnh nµy, ta chØ ph¶i gäi l¹i danh s¸ch hiÓn thÞ chøa

22

Nhãm ®Ò tµi M« pháng sè c¸c hÖ ®éng lùc 09-01-2001

nhãm lÖnh. Ngoµi ra, danh s¸ch hiÓn thÞ lu c¸c lÖnh theo mét c¸ch ®· ®îc tèi u ho¸ cho nªn nã ®îc thùc hiÖn nhanh h¬n. Môc ®Ých chñ yÕu cña danh s¸ch hiÓn thÞ chÝnh lµ dµnh cho viÖc vÏ l¹i nhiÒu lÇn mét vËt thÓ , hoÆc vÏ c¸c vËt thÓ cã h×nh d¹ng gièng hÖt nhau hoÆc dÞch chuyÓn , quay theo mét c¸ch nµo ®ã. ViÖc lµm nµy thùc sù mang l¹i hiÖu qu¶ khi muèn vÏ l¹i mét vËt thÓ phøc t¹p. ViÖc sö dông danh s¸ch hiÓn thÞ cho phÐp t¨ng tèc ®é ch¹y ch¬ng tr×nh gÊp 1,5-2 lÇn tèc ®é vÏ l¹i vËt thÓ ®ã b»ng c¸ch sö dông c¸c lÖnh vÏ ë chÕ ®é immediate mode. ViÖc sö dông danh s¸ch hiÓn thÞ cßn cã mét u ®iÓm n÷a lµ to¹ ®é c¸c ®iÓm cña vËt thÓ cÇn vÏ ®îc lu tr÷ ë mét file ngoµi. C«ng nghÖ sö dông danh s¸ch hiÓn thÞ rÊt quan träng trong m«i trêng m¹ng v× thay cho viÖc truyÒn trùc tiÕp c¸c lÖnh vÏ th× ta chØ cÇn truyÒn danh s¸ch hiÓn thÞ mét lÇn råi truyÒn lÖnh gäi l¹i nã. ViÖc lµm nµy gi¶m ®îc lîng th«ng tin truyÒn trªn m¹ng , do ®ã nã rÊt quan träng.
3.6.1 C¸c bíc thùc hiÖn t¹o ra mét øng dông sö dông kü thuËt danh s¸ch hiÓn thÞ

• T¹o danh s¸ch hiÓn thÞ Duíi ®©y lµ mét ®o¹n m· ch¬ng tr×nh
int listIndex ; listIndex = glGenLists(1); if (listIndex != 0) { glNewList(listIndex , GL_COMPILE); //gäi mét sè lÖnh GL nµo ®ã glEndList(); }

Trong ®o¹n m· trªn, glGenLists(1) sÏ tr¶ l¹i mét sè nguyªn t¬ng øng víi mét danh s¸ch hiÓn thÞ míi. Hµm nµy ®¶m b¶o listIndex kh«ng trïng víi nh÷ng danh s¸ch hiÓn thÞ ®· cã. listIndex lµ mét sè nguyªn mµ glNewList dïng nh mét tªn ®Ó t¹o vµ qu¶n lÝ mét danh s¸ch hiÓn thÞ. VÒ sau, ta dïng sè nguyªn nµy ®Ó gäi l¹i danh s¸ch hiÓn thÞ ®· t¹o ra :
glCallLits(listIndex);

Sè nguyªn truyÒn vµo cho glGenLists lµ sè danh s¸ch hiÓn thÞ mµ ta cÇn t¹o míi. Khi ®ã c¸c gi¸ trÞ tiÕp sau cña listIndex sÏ chØ c¸c danh s¸ch hiÓn thÞ t¬ng øng. VÝ dô :
int listIndex ; listIndex = glGenLists(5);

23

Nhãm ®Ò tµi M« pháng sè c¸c hÖ ®éng lùc 09-01-2001

if (listIndex != 0) { glNewList(listIndex , GL_COMPILE); //gäi mét sè lÖnh GL nµo ®ã glEndList(); glNewList(listIndex + 1, GL_COMPILE); //gäi mét sè lÖnh GL nµo ®ã glEndList(); glNewList(listIndex + 2, GL_COMPILE); //gäi mét sè lÖnh GL nµo ®ã glEndList(); glNewList(listIndex + 3, GL_COMPILE); //gäi mét sè lÖnh GL nµo ®ã glEndList(); glNewList(listIndex + 4, GL_COMPILE); //gäi mét sè lÖnh GL nµo ®ã glEndList(); }

• Gäi l¹i danh s¸ch hiÓn thÞ Ta thùc hiÖn c¸c danh s¸ch hiÓn thÞ trong hµm vÏ cÇn thiÕt. Gäi l¹i c¸c danh s¸ch nµy b»ng lÖnh glCallList(int ) víi ®èi sè lµ tªn cña danh s¸ch :
glCallLits(listIndex); glCallLits(listIndex+1); //.... glCallLits(listIndex+n-1);

3.6.2 C¸c hµm chñ yÕu
glGenLists(range)

Tr¶ l¹i tªn cã thÓ dïng ®Ó qu¶n lÝ c¸c danh s¸ch hiÓn thÞ, range lµ sè danh s¸ch hiÓn thÞ mµ ta cÇn t¹o míi. TrÞ tr¶ vÒ ®¶m b¶o range sè tiÕp theo sau ®Òu lµ tªn míi cho c¸c danh s¸ch hiÓn thÞ CÆp lÖnh chØ ra néi dung cña danh s¸ch hiÓn thÞ cã tªn lµ list (mét sè d¬ng ) mode: GL_COMPILE_AND_EXECUTE vµ GL_COMPILE. GL_COMPILE chØ ra néi dung kh«ng ®îc thùc hiÖn khi ®Þnh nghÜa , vµ GL_COMPILE_AND_EXECUTE chØ ra néi dung cña danh s¸ch hiÓn thÞ ®îc thùc

glNewList(list,mode) glEndList()

24

Nhãm ®Ò tµi M« pháng sè c¸c hÖ ®éng lùc 09-01-2001

hiÖn ngay khi ®Þnh nghÜa. Gi÷a 2 lÖnh nµy chÝnh lµ c¸c lÖnh OpenGL mµ ta cÇn ®Æt vµo danh s¸ch hiÓn thÞ. glCallList(GLuint list) thùc hiÖn danh s¸ch hiÓn thÞ cã tªn list
3.6.3 VÝ dô
#include<GL/gl.h> #include<GL/glu.h> #include<GL/glut.h> #include<stdlib.h> GLuint listName; static void init (void) { listName=glGenLists(1); glNewList(listName,GL_COMPILE); glColor3f(1.0,0.0,0.0); glBegin(GL_TRIANGLES); glVertex(0.0,0.0); glVertex(1.0,0.0); glVertex(0.0,1.0); glEnd(); glTranslatef(1.5,0.0,0.0); glEndList(); glShadeModel(GL_FLAT); } static void display(void) { GLuint i; glClear(GL_COLOR_BUFFER_BIT); glColor3f(0.0,1.0,0.0); for( i=0;i<10;i++) glCallList(listName); glutWireCube(5); glFlush(); } void reshape(int w,int h)

25

Nhãm ®Ò tµi M« pháng sè c¸c hÖ ®éng lùc 09-01-2001

{ glViewport(0,0,(GLsizei)w,(GLsizei)h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0,(GLfloat)w/(GLfloat)h,1.0,30.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0.0,0.0,-6.0); } int main(int arg, char ** argv) { glutInit(&arg,argv); glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB|GLUT_DEPTH); glutInitWindowSize(250,250); glutInitWindowPosition(100,100); glutCreateWindow(argv[0]); init(); glutDisplayFunc(display); glutReshapeFunc(reshape); glutMainLoop(); return 0; }

Phô lôc A : lËp tr×nh øng dông OpenGL ®éc lËp m«i trêng sö dông th viÖn GLUT :
GLUT (OpenGL Utility Toolkit ) cho phÐp t¹o c¸c øng dông ®å ho¹ ®¬n gi¶n kh«ng phô thuéc vµo hÖ thèng. Chóng ta cã thÓ lËp tr×nh ®å häa mµ kh«ng cÇn hiÓu c¸c hµm API cña hÖ thèng. §iÒu ®ã cã nghÜa lµ mét øng dông GLUT ®îc viÕt ra cã thÓ dÞch l¹i vµ ch¹y trªn bÊt k× hÖ thèng windows nµo cã hç trî OpenGL. Chó ý : Ngoµi viÖc include (tÖp) <glut.h> vµ chØ ra c¸c tÖp th viÖn cña OpenGL ®Ó liªn kÕt ta cßn ph¶i liªn kÕt víi c¸c tÖp th viÖn chøa c¸c hµm API cña hÖ thèng window mµ øng dông cÇn ®îc dÞch.

CÊu tróc mét ch¬ng tr×nh sö dông GLUT 1. 2. Hµm main() Hµm khëi t¹o
26

Nhãm ®Ò tµi M« pháng sè c¸c hÖ ®éng lùc 09-01-2001

3. 4. 5.

§¨ng ký hµm hiÓn thÞ c¶nh (display callback) §¨ng ký c¸c hµm sö lý sù kiÖn : reshape , keyboard , Ch¹y vßng lÆp chÝnh cña ch¬ng tr×nh (main loop)

mouse... C¶ 4 c«ng viÖc cuèi ®Òu ®îc thùc hiÖn trong ch¬ng tr×nh chÝnh : main(). Tuy nhiªn c¸c hµm hiÓn thÞ c¶nh vµ c¸c hµm xö lÝ sù kiÖn ph¶i ®îc ®Þnh nghÜa vµ khai b¸o ngoµi hµm main.

VÝ dô :

Sau ®©y lµ mét ch¬ng tr×nh sö dông OpenGL vÏ mét qu¶ cÇu nhá sö dông th viÖn GLUT.
#include <GL/glut.h> //da lien ket voi glut32.lib opengl32.lib glu32.lib GLUquadricObj * qobj; void init(void ) { qobj = gluNewQuadric(); glClearColor(0.0,0.0,0.0,0.0); glMatrixMode(GL_PROJECTION); gluPerspective(0.0f, 1.0, 0, 100); glMatrixMode(GL_MODELVIEW); } void display() { glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glColor3f(1.0,0.0,0.0); gluSphere(qobj , 1.0,20,20); glutSwapBuffers(); }

27

Nhãm ®Ò tµi M« pháng sè c¸c hÖ ®éng lùc 09-01-2001

void main(int arg, char ** argv) { glutInit(&arg,argv); glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB|GLUT_DEPTH); glutInitWindowSize(250,250); glutInitWindowPosition(100,100); glutCreateWindow(argv[0]); glutCreateWindow("Test GLUT"); init(); glutDisplayFunc(display); glutMainLoop(); }

C¸c hµm chñ yÕu :

• Khëi t¹o vµ ®Æt m«i trêng
glutInit(&arg,argv)

Hµm khëi t¹o GLUT , thßng ®îc gäi ®Çu tiÖn trong ch¬ng tr×nh chÝnh. Hµm nµy sÏ dÞch c¸c lÖnh tiÕp theo vµ ®¶m b¶o r»ng hÖ thèng cã hç trî OpenGL. Hµm chØ ra mét tËp hîp c¸c chØ thÞ x¸c ®Þnh c¸c kh¶ n¨ng cña frame buffer. Trong lêi gäi trªn , GLUT_DOUBLE chØ ra cã 2 buffer. GLUT_RGB chØ ra chÕ ®é mµu lµ RGBA , GLUT_DEPTH chØ ra cã dïng mét buffer (z buffer ) ®Ó lu ®é s©u , sö dông ®Ó kiÓm tra vµ vÏ nh÷ng vËt ë gÇn h¬n. §©y lµ hµm do ngêi dïng tù ®Þnh nghÜa , kh«ng b¾t buéc. Tuy nhiªn, ®Ó ch¬ng tr×nh chÝnh ®îc râ rµng, ta ®Ó riªng c¸c khëi t¹o tr¹ng th¸i, tuú chän m«i trêng... ra hµm nµy. VÝ dô nh t¹o danh s¸ch hiÓn thÞ, t¹o ®èi tîng texture, chän ¸nh s¸ng...

glutInitDisplayMode(mod e)

init()

• T¹o cöa sæ
glutCreateWindow(name

)

t¹o mét cöa sæ cã tªn name vµ còng t¹o mét rendering context g¾n víi cöa sæ ®ã. Cöa sæ míi t¹o thµnh nµy sÏ tù ®éng ®îc chuyÓn thµnh hiÖn hµnh vµ c¸c tuú chän m«i trêng sÏ t¸c ®éng lªn nã. Trong ch¬ng
28

Nhãm ®Ò tµi M« pháng sè c¸c hÖ ®éng lùc 09-01-2001

tr×nh chÝnh ta cã thÓ t¹o nhiÒu cöa sæ con. Mçi cöa sæ con nµy sÏ cã mét bé th«ng sè tr¹ng th¸i riªng. • §¨ng ký c¸c hµm xö lÝ sù kiÖn
glutDisplayFunc(display)

§¨ng kÝ hµm ®îc gäi l¹i khi nµo ch¬ng tr×nh cã yªu cÇu vÏ l¹i. display lµ con trá hµm thùc hiÖn thao t¸c vÏ

glutKeyboardFunc(keyboard)

§¨ng kÝ hµm xö lý sù kiÖn bµn phÝm keyboard(unsigned char key, int x, int y); x,y chØ ra to¹ ®é con trá

glutMouseFunc(mouse)

§¨ng kÝ hµm xö lý sù kiÖn chuét mouse(int btn, int state, int x, int y); state chØ ra tr¹ng th¸i cña btn

glutMotionFunc(motion)

§¨ng kÝ hµm xö lý sù kiÖn motion(int x, int y); §¨ng kÝ hµm xö lý sù kiÖn passive(int x, int y);

glutPassiveFunc(passive)

glutTimerFunc(1000,timer,valu §¨ng kÝ hµm xö lý sù kiÖn e)

1000 ms, value lµ gi¸ trÞ cÇn truyÒn timer(int value);

Vßng lÆp chÝnh vßng lÆp chÝnh, gäi c¸c hµm xö lÝ sù kiÖn ®· ®îc ®¨ng kÝ khi sù kiÖn x¶y ra, hiÓn thÞ c¸c cöa sæ con trong ch¬ng tr×nh. Vßng lÆp nµy lµ v« tËn, ta ph¶i chØ ra ®iÒu kiÖn tho¸t cho nã.

glutMainLoop()

Hµm hiÓn thÞ (ngêi dïng ®Þnh nghÜa )

Trong vÝ dô lµ hµm display(), lµ hµm ta ®Þnh nghÜa. Sau ®ã ®îc ®¨ng kÝ ®Ó ®îc gäi mçi khi ch¬ng tr×nh cÇn vÏ l¹i. Trong hµm nµy ta sÏ gäi nh÷ng lÖnh vÏ ta cÇn nh hiÓn thÞ danh s¸ch hiÓn thÞ, d¸n ¶nh... Sau nh÷ng lÖnh vÏ ®ã, ta ph¶i gäi mét trong 2 lÖnh sau ®Ó ®a c¸c kÕt qu¶ ra bé ®Öm cña mµn h×nh : • glFlush() : c¸c lÖnh vÏ cña ta ®îc thùc hiÖn vµ ®a ra mµn h×nh.

29

Nhãm ®Ò tµi M« pháng sè c¸c hÖ ®éng lùc 09-01-2001

glutSwapBuffers()

tr¸o ®æi buffer. C¸c lÖnh vÏ cña ta ®îc thùc

hiÖn trong bé ®Öm khung (frame buffer), lÖnh nµy sÏ tr¸o ®æi bé ®Öm khung víi bé ®Öm cña mµn h×nh. Trong bé ®Öm khung lóc nµy cã c¸c h×nh ¶nh ®· ®îc vÏ tríc ®ã vµ s½n sµng cho c¸c lÖnh vÏ míi. Tuy nhiªn lÖnh nµy chØ cã t¸c dông khi ta ®· chØ ra ch¬ng tr×nh cã 2 bé ®Öm (double buffer). • glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glClearColor(0.0,0.0,0.0,0.0); Xo¸ c¸c h×nh

Phô lôc B : LËp tr×nh OpenGl trªn Microsoft Windows sö dông Microsoft Visual C++ vµ MFC.

Ng÷ c¶nh t« vÏ (device context)

Mçi mét ch¬ng tr×nh window ®Òu ph¶i xö lý ng÷ c¶nh thiÕt bÞ (device context).Ng÷ c¶nh thiÕt bÞ lu gi÷ c¸c th«ng tin nh th«ng tin ®å ho¹ ®ùoc biÓu diÔn lªn cöa sæ nh thÕ nµo. Mét ng÷ c¶nh thiÕt bÞ x¸c ®Þnh mµu vÏ, chÕ ®é vÏ, b¶ng mµu..vµ nhiÒu thuéc tÝnh kh¸c mµ window cÇn biÕt ®Ó thÓ hiÖn c¸c th«ng tin ®å ho¹. C¸c ch¬ng tr×nh Windows NT OpenGL còng sö dông c¸c ng÷ c¶nh thiÕt bÞ gièng nh c¸c ch¬ng tr×nh Window kh¸c ®ång thêi chóng còng ph¶i xö lý ng÷ c¶nh t« vÏ (rendering context), nã t¬ng tù nh mét kiÓu ng÷ c¶nh thiÕt bÞ cña OpenGL. Ng÷ c¶nh t« vÏ cña c¸c øng dông OpenGL gi÷ nh÷ng th«ng tin mµ OpenGL cÇn ®Ó liªn kÕt víi hÖ thèng cöa sæ cña Windows NT. Trong Visual C++ c¸c hµm “wgl” sau sÏ ®îc dïng ®Ó xö lý ng÷ c¶nh t« vÏ
wglCreateContext() wglDeleteContext() wglGetCurrentContext() wglGetCurrentDC() wglMakeCurrent()

t¹o mét ng÷ c¶nh t« vÏ míi xo¸ mét ng÷ c¶nh t« vÏ tr¶ vÒ mét xö lý tíi ng÷ c¶nh t« vÏ hiÖn hµnh lÊy mét xö lý tíi ng÷ c¶nh thiÕt bÞ liªn kÕt víi ng÷ c¶nh t« vÏ hiÖn hµnh. cho hiÖn hµnh mét ng÷ c¶nh t« vÏ.

§Þnh d¹ng ®iÓm ¶nh (pixel format)

30

Nhãm ®Ò tµi M« pháng sè c¸c hÖ ®éng lùc 09-01-2001

Tríc khi t¹o mét ng÷ c¶nh t« vÏ cÇn ph¶i thiÕt lËp ®Þnh d¹ng ®iÓm ¶nh cña thiÕt bÞ.Nã lu gi÷ c¸c thuéc tÝnh vÒ bÒ mÆt vÏ cña thiÕt bÞ.Nh÷ng thuéc tÝnh ®ã bao gåm:bÒ mÆt vÏ sö dông chÕ ®é mµu RGBA hay index color,vïng ®Öm ®iÓm ¶nh ®îc sö dông lµ ®¬n hay kÐp,sè lîng bÝt mµu, sè lîng bÝt ®îc sö dông cho vïng ®Öm s©u vµ vïng ®Öm stencil vµ c¸c th«ng tin ®« ho¹ kh¸c cña OpenGL. C¸c hµm qu¶n lý ®Þnh d¹ng ®iÓm ¶nh:
ChoosePixelFormat() DescribePixelFormat() GetPixelFormat() SetPixelFormat()

tr¶ vÒ ®Þnh d¹ng ®iÓm ¶nh phï hîp nhÊt so víi yªu cÇu lu gi÷ c¸c th«ng tin vÒ ®Þnh d¹ng ®iÓm ¶nh ®îc ®a ®Õn. lÊy ®Þnh d¹ng ®iÓm ¶nh cña ng÷ c¶nh thiÕt bÞ ®a ®Õn. ®Æt ®Þnh d¹ng ®iÓm ¶nh cña ng÷ c¶nh thiÕt bÞ ®a ®Õn.

CÊu tróc PIXELFORMATDESCRIPTER

Mçi mét thiÕt bÞ thÓ hiÖn cña OpenGL hç trî mét sè h÷u h¹n c¸c ®Þnh d¹ng ®iÓm ¶nh TÊt nhiªn tÝnh s½n cã cña ®Þnh d¹ng ®iÓm ¶nh phô thuéc vµ kh¶ n¨ng cña thiÕt bÞ thÓ hiÖn.C¸c thuéc tÝnh cña mét ®Þnh d¹ng ®iÓm ¶nh cô thÓ ®îc biÓu diÔn th«ng qua cÊu tróc PIXELFORMATDESCRIPTER.CÊu tróc nµy lu tr÷ 26 trêng th«ng tin.
typedef struct tagPIXELFORMATDESCRIPTOR { WORD nSize; WORD nVersion; DWORD dwFlags; BYTE iPixelType; BYTE cColorBits; BYTE cRedBits; BYTE cRedShift; BYTE cGreenBits; BYTE cGreenShift; BYTE cBlueBits; BYTE cBlueShift; BYTE cAlphaBits; BYTE cAlphaShift; BYTE cAccumBits; BYTE cAccumRedBits; BYTE cAccumGreenBits; BYTE cAccumBlueBits; BYTE cAccumAlphaBits; BYTE cDepthBits; BYTE cStencilBits; BYTE cAuxBuffers; BYTE iLayerType;

31

Nhãm ®Ò tµi M« pháng sè c¸c hÖ ®éng lùc 09-01-2001

BYTE bReserved; DWORD dwLayerMask; DWORD dwVisibleMask; DWORD dwDamageMask; } PIXELFORMATDESCRIPTOR;

Khëi t¹o CÊu tróc PIXELFORMATDESCRIPTER

PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), // Structure size. 1, // Structure version number. // Property flags. PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, PFD_TYPE_RGBA, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0 };

// 24-bit color. // Not concerned with these. // No alpha or accum buffer. // 32-bit depth buffer. // No stencil or aux buffer. // Main layer type. // Unsupported. // Reserved. PFD_MAIN_PLANE,

ThiÕt lËp ®Þnh d¹ng ®iÓm ¶nh

Ngay khi khëi t¹o cÊu tróc PIXELFORMATDESCRIPTOR cã thÓ ®Æt ®Þnh d¹ng ®iÓm ¶nh
CClientDC clientDC(this); int pixelFormat=ChoosePixelFormat(clientDC.m_hDC,&pfd); BOOl result=SetPixelFormat(clientDC.m_hDC, pixelFormat,&pfd);

§Çu tiªn lÊy mét DC cho vïng client cña cöa sæ øng dông. Dßng thø hai yªu cÇu chØ sè ®Þnh d¹ng ®iÓm ¶nh thÝch hîp nhÊt víi ®Þnh d¹ng ®iÓm ¶nh yªu cÇu PIXELFORMATDESCRIPTOR gi÷ c¸c thuéc tÝnh cña ®Þnh d¹ng ®iÓm ¶nh yªu cÇu. NÕu gäi hµm thÊt b¹i ChoosePixelFormat() tr¶ vÒ gi¸ trÞ 0 ngîc l¹i tr¶ vÒ chØ sè ®Þnh d¹ng ®iÓm ¶nh. Dßng thø 3 dïng ®Ó ®Æt ®Þnh d¹ng ®iÓm ¶nh víi c¸c th«ng sè xö lý tíi DC, chØ sè ®Þnh d¹ng ®iÓm ¶nh vµ ®Þa chØ cña cÊu tróc PIXELFORMATDESCRIPTOR. Hµm nµy tr¶ vÒ True nÕu thµnh c«ng ngîc l¹i nã sÏ tr¶ vÒ false.

LiÖt kª ®Þnh d¹ng ®iÓm ¶nh
32

Nhãm ®Ò tµi M« pháng sè c¸c hÖ ®éng lùc 09-01-2001

Lu ý r»ng hµm ChoosePixelFormat() tr¶ vÒ mét chØ sè tíi ®Þnh d¹ng ®iÓm ¶nh phï hîp nhÊt víi ®Þnh d¹ng ®iÓm ¶nh yªu cÇu. Hµm DescribePixelFormat() cho phÐp kiÓm tra bÊt cø ®Þnh d¹ng ®iÓm ¶nh s½n cã nµo. Sau ®©y lµ ®o¹n m· thùc hiÖn kiÓm tra ®Þnh d¹ng :
PIXELFORMATDESCRIPTOR pfd; CClientDC clientDC(this); int numFormat= DescribePixelFormat(clientDC.m_hDC, 1,sizeof(pfd) ,&pfd); for(int i=1;i<= numFormat;i++) { DescribePixelFormat(clientDC.m_hDC, i,sizeof(pfd) ,&pfd); }

Dßng thø 3 gäi hµm DescribePixelFormat() ®Ó lÊy sè ®Þnh d¹ng ®iÓm ¶nh ®îc hç trî trªn nÒn hiÖn hµnh.Hµm nµy cã 4 th«ng sè gåm : xö lý tíi DC,chØ sè ®Þnh d¹ng ®Ó kiÓm tra, kÝch thíc vµ ®Þa chØ cÊu tróc PIXELFORMATDESCRIPTOR.Khi gäi hµm nµy dïng mét lµm th«ng sè thø hai.Sau khi cã ®îc sè ®Þnh d¹ng ®iÓm ¶nh s½n cã, mét vßng lÆp ®îc dïng trong ®ã hµm DescribePixelFormat() ®îc gäi ®Ó ®iÒn vµo cÊu tróc PIXELFORMATDESCRIPTOR víi mçi mét ®Þnh d¹ng vµ ®îc ®Æc trng bëi biÕn vßng lÆp i.Sau mçi lÇn gäi hµm ch¬ng tr×nh sÏ kiÓm tra cÊu tróc PIXELFORMATDESCRIPTOR dùa trªn c¸c thuéc tÝnh mµ ch¬ng tr×nh yªu cÇu.Mét hµm ®Þnh d¹ng ®iÓm ¶nh kh«ng ®îc dïng trong ®o¹n lÖnh trªn ®ã lµ hµm getPixelFormat() Hµm nµy chØ ®¬n gi¶n tr¶ vÒ chØ sè cña ®Þnh d¹ng ®iÓm ¶nh hiÖn hµnh cña ng÷ c¶nh thiÕt bÞ int pixelFormat=GetPixelFormat(hDC);

T¹o ng÷ c¶nh t« vÏ

Tuú theo yªu cÇu ch¬ng tr×nh cã hai kü thuËt ®Ó qu¶n lý ng÷ c¶nh t« vÏ: - T¹o ng÷ c¶nh t« vÏ vµ cho nã hiÖn hµnh b»ng th«ng ®iÖp WM_CREATE, xo¸ ng÷ c¶nh t« vÏ ®ång thêi bá hiÖn hµnh b»ng th«ng ®iÖp WM_DESTROY. - T¹o ng÷ c¶nh t« vÏ b¼ng th«ng ®iÖp WM_CREATE,nhng chØ cho hiÖn hµnh khi cÇn vÏ b»ng OpenGL vµ bá hiÖn hµnh ngay sau khi vÏ xong. xo¸ ng÷ c¶nh t« vÏ b»ng th«ng ®iÖp WM_DESTROY. • Ph¬ng ph¸p qu¶n lý ng÷ c¶nh t« vÏ thø nhÊt ¦u ®iÓm cña ph¬ng ph¸p nµy lµ chØ cÇn cho ng÷ c¶nh t« vÏ hiÖn hµnh mét lÇn bëi v× cho hiÖn hµnh ng÷ c¶nh t« vÏ ph¶i

33

Nhãm ®Ò tµi M« pháng sè c¸c hÖ ®éng lùc 09-01-2001

mÊt kh¸ nhiÒu thêi gian ®Ó xö lý nã cho phÐp ch¬ng tr×nh ®¸p øng th«ng ®iÖp WM_PAINT nhanh h¬n mét chót. Nhîc ®iÓm cña ph¬ng ph¸p nµy lµ ph¶i lu«n gi÷ mét DC trong toµn bé thêi gian ch¹y ch¬ng tr×nh. Nãi chung c¸c ch¬ng tr×nh Visual C++ t¹o bëi AppWizart kh«ng thÝch hîp víi ph¬ng ph¸p nµy. • Ph¬ng ph¸p qu¶n lý ng÷ c¶nh t« vÏ thø hai Víi phong ph¸p nµy ch¬ng tr×nh t¹o ra vµ gi¶i phãng DC cña window mçi lÇn muèn vÏ lªn cöa sæ.V× thÕ ch¬ng tr×nh kh«ng cÇn ph¶i gi÷ DC trong suèt qu¸ tr×nh ch¹y.Tuy nhiªn mçi lÇn t¹o mét DC, ch¬ng tr×nh ph¶i cho hiÖn hµnh ng÷ c¶nh t« vÏ.

C¸c bíc thùc hiÖn

• Bíc1: Sö dông AppWizard t¹o mét øng dông ban ®Çu • Bíc 2 : Sö dông ClassWizard t¹o c¸c hµm nCreate(),OnDestroy(),PreCreateWindow(),OnSize(),OnEraseBa ckGround() t¬ng øng víi c¸c th«ng ®iÖp WM_CREATE,WM_DESTROY,WM_SISE, WM_ERASEBKGND,PreCreateWindow. • Bíc 3 : Thay ®æi lÇn lît c¸c hµm nh sau: Hµm OnCreate()
int CAnimateView::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CView::OnCreate(lpCreateStruct) == -1) return -1; PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), // Structure size. 1, // Structure version number. // Property flags. PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, PFD_TYPE_RGBA, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, // 24-bit color. // Not concerned with these. // No alpha or accum buffer. // 32-bit depth buffer. PFD_DRAW_TO_WINDOW |

34

Nhãm ®Ò tµi M« pháng sè c¸c hÖ ®éng lùc 09-01-2001

0, 0, PFD_MAIN_PLANE, 0, 0, 0, 0 };

// No stencil or aux buffer. // Main layer type. // Reserved. // Unsupported.

CClientDC clientDC(this); int pixelFormat = ChoosePixelFormat(clientDC.m_hDC, &pfd); BOOL success = SetPixelFormat(clientDC.m_hDC, pixelFormat, &pfd); DescribePixelFormat(clientDC.m_hDC, pixelFormat, sizeof(pfd), &pfd); if (pfd.dwFlags & PFD_NEED_PALETTE) SetupLogicalPalette(); m_hRC = wglCreateContext(clientDC.m_hDC); SetTimer(1, 50, 0); return 0; }

Hµm OnDestroy()
void CAnimateView::OnDestroy() { CView::OnDestroy(); KillTimer(1); wglDeleteContext(m_hRC); if (m_hPalette) DeleteObject(m_hPalette); }

Hµm OnSize()
void CAnimateView::OnSize(UINT nType, int cx, int cy) { CView::OnSize(nType, cx, cy); CClientDC clientDC(this); wglMakeCurrent(clientDC.m_hDC, m_hRC); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum(-1.0, 1.0, -1.0, 1.0, 2.0, 9.0); glViewport(0, 0, cx, cy); glMatrixMode(GL_MODELVIEW);

35

Nhãm ®Ò tµi M« pháng sè c¸c hÖ ®éng lùc 09-01-2001

glLoadIdentity(); wglMakeCurrent(NULL, NULL); }

Hµm PreCreateWindow()
BOOL CAnimateView::PreCreateWindow(CREATESTRUCT& cs) { cs.style |= WS_CLIPCHILDREN | WS_CLIPSIBLINGS; return CView::PreCreateWindow(cs); }

Hµm OnEraseBackGround()
BOOL CAnimateView::OnEraseBkgnd(CDC* pDC) { return FALSE; }

• Bíc 4 : §Æt hµm vÏ DrawWithOpenGl() vµo trong hµm OnDraw() gi÷a hai lÖnh gäi wglMakeCurrent()
void CAnimateView::OnDraw(CDC* pDC) { CAnimateDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (m_hPalette) { SelectPalette(pDC->m_hDC, m_hPalette, FALSE); RealizePalette(pDC->m_hDC); } wglMakeCurrent(pDC->m_hDC, m_hRC); 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); DrawWithOpenGL(); SwapBuffers(pDC->m_hDC); wglMakeCurrent(pDC->m_hDC, NULL); }

• Bíc 5: NÕu muèn t¹o sù chuyÓn ®éng ®Æt c¸c th«ng sè biÕn ®æi trong hµm OnTimer(),dïng hµm SetTimer().T¹i nh÷ng chç

36

Nhãm ®Ò tµi M« pháng sè c¸c hÖ ®éng lùc 09-01-2001

cÇn sù thay ®æi cña c¸c th«ng sè biÕn ®æi ë trªn ta gäi hµm Invalidate().
void CAnimateView::OnTimer(UINT nIDEvent) { if (m_object == Atom) { m_angle += m_speed; if (m_angle > 355) m_angle = 0.0f; } else { m_angle2 += m_speed / 2; if (m_angle2 > 355) m_angle2 = 0.0f; if (m_armsGoingUp) { m_angle += m_speed; if (m_angle > 90.0f) m_armsGoingUp = FALSE; } else { m_angle -= m_speed; if (m_angle < 0.0f) m_armsGoingUp = TRUE; } } ( Invalidate); CView::OnTimer(nIDEvent); }

37

Nhãm ®Ò tµi M« pháng sè c¸c hÖ ®éng lùc 09-01-2001

KÕt luËn
Sö dông th viÖn OpenGL cho phÐp t¹o ra c¸c øng dông ®å ho¹ ®éng t¬ng t¸c cã chÊt lîng vµ tèc ®é cao. C¸c bíc c¬ b¶n cÇn thiÕt ®Ó t¹o ra mét øng dông OpenGL nãi chung vµ c¸c bíc chi tiÕt khi sö dông Microsoft Foundation Class (MFC) vµ GLUT ®îc giíi thiÖu trong b¸o c¸o gióp c¸c lËp tr×nh viªn cã thÓ nhanh chãng ¸p dông trong m« pháng c¸c hÖ kü thuËt. Tuú theo yªu cÇu vÒ chÊt lîng h×nh ¶nh vµ tèc ®é hiÓn thÞ, c¸c kü thuËt chñ yÕu cña th viÖn OpenGL còng cã thÓ ®îc ¸p dông. Híng nghiªn cøu s¾p tíi cña nhãm sÏ lµ hoµn thiÖn c¸c kü thuËn hiÓn thÞ nh d¸n ¶nh vµ ¸p dông c«ng nghÖ tÝnh to¸n song song ®Ó t¨ng tèc ®é cña c¸c ch¬ng tr×nh m« pháng sö dông OpenGL.

Tµi liÖu tham kh¶o
1. Foley J, D. et al.: Computer Graphics: Principles and Practice, Addison Wesley, 1990. 2. Francis S. Hill: Computer Graphics, Macmillan Publishing, 1990. 3. Renate Kempf, Chris Frazier Ed.: OpenGL Reference Manual, Addison Wesley Developers Press, 1997. 4. Mark J. Kilgard: OpenGL Programming for the X Window System, Addison Wesley Developers Press, 1996. 5. Clayton Walnum: 3-D Graphics Programming with OpenGL, Que, 1995. 6. Mason Woo, Jackie Neider, Tom Davis: OpenGL Programming Guide 2nd Ed., Addison Wesley Developers Press, 1997.

38