Professional Documents
Culture Documents
Chuong Trinh Do Hoa 3D Voi OpenGL
Chuong Trinh Do Hoa 3D Voi OpenGL
Clayton Walnum
Ng−êi dÞch : Vò Lª Huy
Hµ Néi - 2/2000
_1_
§å ho¹ 3D víi OpenGL
Ch−¬ng 3
C¬ së vÒ ®å ho¹ 3D
1. §Þnh nghÜa kiÓu d÷ liÖu
KiÓu d÷ liÖu cho mét ®Ønh :
typedef struct vertex
{
int x,y;
}VERTEX;
CÊu tróc nµy chøa mét sè nguyªn n¾m gi÷ sè ®Ønh cña h×nh vµ mét con trá trá tíi
m¶ng cÊu tróc VERTEX.
B»ng c¸ch sö dông c¸c kiÓu d÷ liÖu míi nµy, b¹n cã thÓ viÕt nhiÒu øng dông
ph¸t triÓn m· nguån vÏ h×nh, ®Æt vßng lÆp vµ c¸c biÕn trong nã phô thuéc c¸c chøc
n¨ng cña chÝnh nã. M· tr×nh cã thÓ gièng nh− sau :
_2_
§å ho¹ 3D víi OpenGL
newX=shape1.vertices[x].x;
newY=maxY-shape1.vertices[x].y;
if (x==0)
{
dc.MoveTo(newX,newY);
startX=newX;
startY=newY;
}
else dc.LineTo(newX,newY);
}
dc.LineTo(newX,newY);
}
//-----------------------------------------------------------------
void Translate(SHAPE & shape, int xTrans, int yTrans)
{
for (int x=0; x<shape.numVerts; x++)
{
shapse.vertices[x].x = xTrans;
shapse.vertices[x].y = yTrans;
}
}
//-----------------------------------------------------------------
void Scale(SHAPE & shape, float scaleFactor)
{
for (int x=0; x<shape.numVerts; x++)
{
shapse.vertices[x].x = (int)(shape.vertices[x].x*scalseFactor);
shapse.vertices[x].y = (int)(shape.vertices[x].y*scalseFactor);
}
}
//-----------------------------------------------------------------
void Scale(SHAPE & shape, float xscale, float yscale)
{
for (int x=0; x<shape.numVerts; x++)
{
shapse.vertices[x].x = (int)(shape.vertices[x].x*xscalse);
shapse.vertices[x].y = (int)(shape.vertices[x].y*yscalse);
}
}
//-----------------------------------------------------------------
_3_
§å ho¹ 3D víi OpenGL
_4_
§å ho¹ 3D víi OpenGL
MATRIX3X3 m;
m[0][0] = cos(radians); m[0][1] = sin(radians); m[0][2] = 0.0;
m[1][0] = -sin(radians); m[1][1] = cos(radians); m[1][2] = 0.0;
m[2][0] = 0.0; m[2][1] = 0.0; m[2][2] = 1.0;
void MultMatrix(MATRIX3X3 & product,
MATRIX3X3 & matrix1, MATRIX3X3 & matrix2)
{
for (int x=0 ; x<3 ; x++)
for (int y=0 ; y<3 ; y++)
{
double sum = 0;
for (int z=0 ; z<3 ; z++)
sum += matrix1[x][z]*matrix2[z][y];
product[x][y]=sum;
}
}
//-----------------------------------------------------------------
void Transform(SHAPE & shape, MATRIX3X3 &m)
{
int transformedX, transformedX;
for (int x=0;x<shape.numVerts; x++)
{
transformedX = (int) (shape.vertices[x].x*m[0][0]+
shape.vertices[x].y*m[1][0]+m[2][0]);
transformedY = (int) (shape.vertices[x].x*m[0][1]+
shape.vertices[x].y*m[1][1]+m[2][1]);
shape.vertices[x].x= transformedX;
shape.vertices[x].y= transformedY;
}
}
//-----------------------------------------------------------------
void InitMatrix(MATRIX3X3 & m)
{
m[0][0] = 1.0; m[0][1] = 0.0; m[0][2] = 0.0;
m[1][0] = 0.0; m[1][1] = 1.0; m[1][2] = 0.0;
m[2][0] = 0.0; m[2][1] = 0.0; m[2][2] = 1.0;
}
//-----------------------------------------------------------------
void CopyMatrix(MATRIX3X3 & dst, MATRIX3X3 & src)
_5_
§å ho¹ 3D víi OpenGL
{
for (int i=0 ; i<3 ; i++)
for (int j=0 ; j<3 ; j++)
dst[i][j]=src[i][j];
}
//-----------------------------------------------------------------
void Transtate(MATRIX3X3 & m, int xTrans, int yTrans)
{
MATRIX3X3 m1,m2;
m1[0][0] = 1.0; m1[0][1] = 0.0; m1[0][2] = 0.0;
m1[1][0] = 0.0; m1[1][1] = 1.0; m1[1][2] = 0.0;
m1[2][0] = xTrans; m1[2][1] = yTrans;
m1[2][2] = 1.0;
MulMatrix(m2,m1,m);
CopyMatrix(m,m2);
}
//-----------------------------------------------------------------
void Scale(MATRIX3X3 & m, double xScale, double yScale)
{
MATRIX3X3 m1,m2;
m1[0][0] = xScale; m1[0][1] = 0.0; m1[0][2] = 0.0;
m1[1][0] = 0.0; m1[1][1] = yScale; m1[1][2] = 0.0;
m1[2][0] = 0.0; m1[2][1] = 0.0; m1[2][2] = 1.0;
MulMatrix(m2,m1,m);
CopyMatrix(m,m2);
}
//-----------------------------------------------------------------
void Rotate(MATRIX3X3 & m, int degrees)
{
MATRIX3X3 m1,m2;
if (degrees==0) return;
double radians = 6.283485308/360.0/degrees;
double c = cos(radians);
double s = sin(radians);
m1[0][0] = c; m1[0][1] = s; m1[0][2] = 0.0;
m1[1][0] = -s; m1[1][1] = c; m1[1][2] = 0.0;
m1[2][0] = 0.0; m1[2][1] = 0.0; m1[2][2] = 1.0;
MulMatrix(m2,m1,m);
CopyMatrix(m,m2);
}
_6_
§å ho¹ 3D víi OpenGL
CÊu tróc MODEL chøa 2 sè nguyªn kh«ng dÊu n¾m gi÷ sè ®Ønh vµ c¹nh trong
mét ®èi t−îng. Trong ®ã mét con trá kiÓu VERTEX n¾m ®Þa chØ cña danh s¸ch c¸c
®Ønh cña ®èi t−îng.
y
VÝ dô : 1 (0,4,0) 2
VERTEX cubeVets[8] = { 0,4,0, (4,4,0)
4 (0,4,-4)
4,4,0, 3
4,4,-4, (4,4,-4)
0,4,-4,
0,0,0, z
4,0,0, 5 6
(0,0,0) (4,0,0) x
0,0,-4, 8 (0,0,-4)
0,0,-4};
EDGE cubeEdges[12] = {1,2, 2,3, 3,4, 4,1, 5,6, 6,7,
7,8, 8,5, 5,1, 6,2, 7,3, 8,4};
MODEL cube = {8,cubleVerts,12,cubeEdges};
_7_
§å ho¹ 3D víi OpenGL
vertNum = model.edges[i].vertex2;
newX=model.vertices[vertNum-1].x;
newY=-model.vertices[vertNum-1].y+maxY-1;
pDC->LineTo(newX,newY);
}
}
_8_
§å ho¹ 3D víi OpenGL
_9_
§å ho¹ 3D víi OpenGL
CopyMatrix(m,m2);
}
//-----------------------------------------------------------------
void Scale(MATRIX4X4 & m, double xScale, double yScale, double zScale)
{
MATRIX4X4 m1,m2;
m1[0][0] = xScale; m1[0][1] = 0.0; m1[0][2] = 0.0; m1[0][3] = 0.0;
m1[1][0] = 0.0; m1[1][1] = yScale; m1[1][2] = 0.0; m1[1][3] = 0.0;
m1[2][0] = 0.0; m1[2][1] = 0.0; m1[2][2] = zScale; m1[2][3] = 0.0;
m1[3][0] = 0.0; m1[3][1] = 0.0; m1[3][2] = 0.0; m1[3][3] = 1.0;
MulMatrix(m2,m1,m);
CopyMatrix(m,m2);
}
//-----------------------------------------------------------------
void RotateZ(MATRIX4x4 & m,int zAngle)
{
MATRIX4x4 m1,m2;
if (zAngle==0) return;
double radians=6.283185308/(360.0/zAngle);
double c=cos(radians);
double s=sin(radians);
m1[0][0]=c; m1[0][1]=s; m1[0][2]=0; m1[0][3]=0;
m1[1][0]=-s; m1[1][1]=c; m1[1][2]=0; m1[1][3]=0;
m1[2][0]=0; m1[2][1]=0; m1[2][2]=1; m1[2][3]=0;
m1[3][0]=0; m1[3][1]=0; m1[3][2]=0; m1[3][3]=1;
MulMatrix(m2,m1,m);
CopyMatrix(m,m2);
}
//-----------------------------------------------------------------
void RotateY(MATRIX4x4 & m,int yAngle)
{
MATRIX4x4 m1,m2;
if (yAngle==0) return;
double radians=6.283185308/(360.0/yAngle);
double c=cos(radians);
double s=sin(radians);
m1[0][0]=c;m1[0][1]=0;m1[0][2]=s;m1[0][3]=0;
m1[1][0]=0;m1[1][1]=1;m1[1][2]=0;m1[1][3]=0;
_ 10 _
§å ho¹ 3D víi OpenGL
m1[2][0]=-s;m1[2][1]=0;m1[2][2]=c;m1[2][3]=0;
m1[3][0]=0;m1[3][1]=0;m1[3][2]=0;m1[3][3]=1;
MulMatrix(m2,m1,m);
CopyMatrix(m,m2);
}
//-----------------------------------------------------------------
void RotateX(MATRIX4x4 & m,int xAngle)
{
MATRIX4x4 m1,m2;
if (xAngle==0) return;
double radians=6.283185308/(360.0/xAngle);
double c=cos(radians);
double s=sin(radians);
m1[0][0]=1;m1[0][1]=0;m1[0][2]=0;m1[0][3]=0;
m1[1][0]=0;m1[1][1]=c;m1[1][2]=s;m1[1][3]=0;
m1[2][0]=0;m1[2][1]=-s;m1[2][2]=c;m1[2][3]=0;
m1[3][0]=0;m1[3][1]=0;m1[3][2]=0;m1[3][3]=1;
MulMatrix(m2,m1,m);
CopyMatrix(m,m2);
}
_ 11 _
§å ho¹ 3D víi OpenGL
Ch−¬ng 4
Ch−¬ng tr×nh OpenGL tèi thiÓu
1. C¸c kiÓu d÷ liÖu
OpenGL ®Þnh nghÜa nhiÒu kiÓu d÷ liÖu cã thÓ sö dông trong ch−¬ng tr×nh
OpenGL :
KiÓu d÷ liÖu KiÓu t−¬ng ®−¬ng
GLbyte signed char
GLshort short
GLint int
GLsizei long
GLfloat float
GLclampf float
GLdouble double
GLclampd double
GLubyte unsigned char
GLboolean unsigned char
GLushort unsigned short
GLuint unsigned long
GLenum unsigned long
GLbitfield unsigned long
GLvoid void
HGLRC HGDIOBJ
_ 12 _
§å ho¹ 3D víi OpenGL
_ 13 _
§å ho¹ 3D víi OpenGL
BYTE cAlphaShift;
BYTE cAccumBits;
BYTE cAccumRedBits;
BYTE cAccumGreenBits;
BYTE cAccumBlueBits;
BYTE cAccumAlphaBits;
BYTE cDepthBits;
BYTE cStencilBits;
BYTE cAuxBuffers;
BYTE iLayerType;
BYTE bReserved;
DWORD dwLayerMask;
DWORD dwVisibleMask;
DWORD dwDamageMask;
} PIXELFORMATDESCRIPTOR,
* PIXELFORMATDESCRIPTOR,
FAR * LPPIXELFORMATDESCRIPTOR;
Khi b¹n thùc sù ®Æt mét ®Þnh d¹ng ®iÓm ¶nh cña ng÷ c¶nh thiÕt bÞ, b¹n cÇn
ph¶i ®iÒn ®Çy cÊu tróc PIXELFORMATDESCRIPTOR vµ truyÒn ®Þa chØ cña nã nh−
mét ®èi môc cña hµm SetPixelFormat(). B¶ng sau m« t¶ c¸c thµnh phÇn cña cÊu tróc:
Thµnh phÇn M« t¶
_ 14 _
§å ho¹ 3D víi OpenGL
cColorBits Sè c¸c bit sö dông ®Ó ®¹i diÖn cho mét mÇu, nã còng x¸c ®Þnh
sè mÇu cã thÓ cã. VÝ dô, gi¸ trÞ cña 8 ë ®©y cung cÊp nhiÒu nhÊt
lµ 256 mÇu.
cRedBits Sè c¸c bit ®á trong vïng ®Öm mÇu RGBA
cRedShift §Õm vÞ trÝ dÞch chuyÓn cho sè bit ®á trong vïng ®Öm mÇu
RGBA
cGreenBits Sè c¸c bit xanh l¸ c©y trong vïng ®Öm mÇu RGBA
cGreenShift §Õm vÞ trÝ dÞch chuyÓn cho sè bit xanh l¸ c©y trong vïng ®Öm
mÇu RGBA
cBlueBits Sè c¸c bit xanh da trêi trong vïng ®Öm mÇu RGBA
cBlueShift §Õm vÞ trÝ dÞch chuyÓn cho sè bit xanh da trêi trong vïng ®Öm
mÇu RGBA
cAlphaBits Sè bit alpha trong vïng ®Öm mÇu RGBA
cAlphaShift §Õm vÞ trÝ dÞch chuyÓn cho sè bit alpha trong vïng ®Öm mÇu
RGBA
cAccumBits Sè c¸c bÝt trªn mét ®iÓm ¶nh trong vïng ®Öm tÝch luü
cAccumRedBits Sè c¸c bit ®á trªn mét ®iÓm ¶nh trong vïng ®Öm tÝch luü
cAccumGreenBits Sè c¸c bit green trªn mét ®iÓm ¶nh trong vïng ®Öm tÝch luü
cAccumBlueBits Sè c¸c bit blue trªn mét ®iÓm ¶nh trong vïng ®Öm tÝch luü
cAccumAlphaBits Sè c¸c bit alpha trªn mét ®iÓm ¶nh trong vïng ®Öm tÝch luü
cDepthBits Sè c¸c bit trªn mét ®iÓm ¶nh trong vïng ®Öm s©u
cStencilBits Sè c¸c bit trªn mét ®iÓm ¶nh trong vïng ®Öm khu«n t«
cAuxBuffers Sè vïng ®Öm phô. Kh«ng cung cÊp trong WindowNT
iLayerType X¸c ®Þnh kiÓu líp, ph¶i lµ PFD_MAIN_PLANE trong WinNT.
C¸c kiÓu kh¸c cã thÓ ®−îc cung cÊp cña OpenGL lµ
PFD_OVERLAY_PLANE vµ PFD_UNDERLAY_PLANE.
bReserved Ph¶i lµ 0
dwLayerMask X¸c ®Þnh mÆt l¹ líp. Kh«ng cung cÊp trong WindowNT
dwDamageMask X¸c ®Þnh mÆt l¹ bÊt lîi. Kh«ng cung cÊp trong WindowNT
_ 15 _
§å ho¹ 3D víi OpenGL
Cê ®Æc tÝnh M« t¶
_ 16 _
§å ho¹ 3D víi OpenGL
vïng ®Öm khung stecil lµm cho øng dông cã thÓ vÏ h¹n chÕ tíi miÒn x¸c ®Þnh cña cöa
sæ.
_ 17 _
§å ho¹ 3D víi OpenGL
kú ®Þnh d¹ng cã s½n nµo. Mét c¸ch ®Ó ch¾c ch¾n r»ng b¹n cã chÝnh x¸c ®Þnh d¹ng
b¹n muèn lµ kiÓm tra tÊt c¶ c¸c ®Þnh d¹ng cã s½n vµ chän mét c¸i mµ b¹n nghÜ lµ tèt
nhÊt cho cho øng dông cña b¹n, cã thÓ tèt h¬n khi chuyÓn nhiÖm vô nµy cho
Windows. §©y lµ ®o¹n m· thÓ hiÖn lµm viÖc nµy nh− thÕ nµo :
PIXELFORMATDESCRIPTOR pfd;
CClientDC clientDC(this);
int numFormat=DescriblePixelFormat(clientDC.m_hDC,1,sizeof(pfd),&pfd);
for (int i=1; i<=numFormat; i++)
{
DescriblePixelFormat(clientDC.m_hDC,i,sizeof(pfd),&pfd);
//kiÓm tra cÊu tróc PIXELFORMATDESCRIPTOR ë ®©y.
}
Dßng thø 3 gäi DescriblePixelFormat() ®Ó lÊy sè ®Þnh d¹ng ®iÓm ¶nh ®−îc
cung cÊp trong d¹ng nÒn hiÖn t¹i. Hµm nµy tr¶ l¹i sè ®Þnh d¹ng ®iÓm ¶nh cã s½n hoÆc
0 nÕu hµm gäi sai. Khi gäi hµm nµy ®Ó lÊy sè ®Þnh d¹ng cã s½n, sö dông gi¸ trÞ 1 cho
®èi môc thø hai.
Sau khi lÊy sè ®Õm ®Þnh d¹ng, ®o¹n m· trªn sö dông vßng lÆp for tõ 1 tíi sè
®Þnh d¹ng cã s½n. Trong vßng lÆp, ®o¹n m· gäi hµm DescriblePixelFormat() ®Ó ®iÒn
®Çy cÊu tróc PIXELFORMATDESCRIPTOR cho mçi ®Þnh d¹ng, ®−îc ®Æc tr−ng bëi
biÕn lÆp i. Sau mçi lÇn gäi DescriblePixelFormat(), ch−¬ng tr×nh cña b¹n sÏ kiÓm tra
cÊu tróc PIXELFORMATDESCRIPTOR cho c¸c thuéc tÝnh yªu cÇu bëi øng dông.
ChØ cã mét hµm ®Þnh d¹ng ®iÓm ¶nh mµ b¹n ®· kh«ng sö dông tíi trong ®o¹n
m· vÝ dô trªn lµ GetPixelFormat(). Hµm nay ®¬n gi¶n chØ tr¶ l¹i chØ sè cña ®Þnh d¹ng
®iÓm ¶nh hiÖn hµnh cña ng÷ c¶nh thiÕt bÞ. Nã ®−îc gäi nh− sau :
int pixelFormat = GetPixelFormat(hDC);
§èi môc ®¬n cña GetPixelFormat() lµ ®iÒu khiÓn cña DC cho nh÷ng g× b¹n muèn
®Þnh d¹ng ®iÓm ¶nh. NÕu hµm gäi sai, nã tr¶ l¹i gi¸ trÞ 0.
_ 18 _
§å ho¹ 3D víi OpenGL
Chó ý :
NÕu b¹n ®ang sö dông c¸c dÉn xuÊt trong øng dông WindowNT cña b¹n, b¹n ph¶i biÕt
r»ng ng÷ c¶nh diÏn t¶ ®−îc lµm cho hiÖn hµnh chØ víi lêi gäi dÉn xuÊt. ChØ dÉn xuÊt víi ng÷
c¶nh diÔn t¶ hiÖn hµnh míi cã thÓ gäi c¸c hµm OpenGL. H¬n n÷a, dÉn xuÊt cã thÓ cã chØ mét
ng÷ c¶nh diÔn t¶ hiÖn hµnh ë mét thêi ®iÓm x¸c ®Þnh. Dï nÕu øng dông cña b¹n kh«ng sö dông
dÉn xuÊt kÐp, c¸c quy t¾c t−¬ng tù ®−îc ¸p dông. Cuèi cïng, øng dông lu«n cã Ýt nhÊt mét dÉn
xuÊt.
_ 19 _
§å ho¹ 3D víi OpenGL
0,0,
PFD_MAIN_PLANE,
0,
0,0,0
};
CClientDC clientDC(this);
int pixelFormat=ChoosePixelFormat(clientDC.m_hDC,&pfd);
BOOL success =SetPixelFormat(clientDC.m_hDC,pixelFormat,&pfd);
m_hRC=wglCreateContext(clientDC.m_hDC);
return 0;
}
//-----------------------------------------------------------------
void CChapter4View::OnDraw(CDC* pDC)
{
CChapter4Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
wglMakeCurrent(pDC->m_hDC,m_hRC);
DrawWithOpenGL();
wglMakeCurrent(pDC->m_hDC,NULL);
}
//-----------------------------------------------------------------
void CChapter4View::OnDestroy()
{
CView::OnDestroy();
// TODO: Add your message handler code here
wglDeleteContext(m_hRC);
}
Hµm OnCreate() ®¸p l¹i th«ng ®iÖp WM_CREATE víi viÖc ®Çu tiªn lÊy DC
cña vïng lµm viÖc cña cöa sæ, råi gäi ChoosePixelFormat() ®Ó t×m l¹i chØ sè tíi ®Þnh
d¹ng ®iÓm ¶nh cho DC vµ gäi SetPixelFormat() ®Ó ®Æt ®Þnh d¹ng ®iÓm ¶nh.
TiÕp theo, OnCreate() gäi wglCreatContext() ®Ó t¹o lËp ng÷ c¶nh diÔn t¶. §èi
môc ®¬n cña hµm nµy lµ ®iÒu khiÓn cña DC. NÕu thµnh c«ng, nã tr¶ vÒ ®iÒu khiÓn tíi
ng÷ c¶nh diÔn t¶, ng−îc l¹i nã tr¶ l¹i 0.
Trong ®o¹n ch−¬ng tr×nh nµy, OnCreate() t¹o lËp chØ mét DC t¹m thêi, bëi
ph¹m vi ®Þa ph−¬ng cña nã, nã tù ®éng ®−îc xo¸ bá khi hµm kÕt thóc. V× DC bÞ xo¸
bá, nã kh«ng thÓ lµm ng÷ c¶nh diÔn t¶ thµnh hiÖn hµnh ë ®iÓm nµy trong ch−¬ng
tr×nh.
_ 20 _
§å ho¹ 3D víi OpenGL
Khi nã lµ lÇn ®Ó cËp nhËt néi dung cña cöa sæ øng dông, MFC gäi hµm
OnDraw() cña líp quan s¸t. B©y giê, nã gäi hµm OnDraw() ®Ó lµm ng÷ c¶nh diÔn t¶
thµnh hiÖn hµnh, nã thùc hiÖn b»ng lêi gäi hµm wglMakeCurrent() sö dông ®iÒu
khiÓn cña ®èi t−îng DC chuyÓn tíi hµm. Hµm nµy cã 2 ®èi môc lµ ®iÒu khiÓn tíi DC
vµ ®iÒu khiÓn cña ng÷ c¶nh diÔn t¶. NÕu thµnh c«ng, wglMakeCurrent() tr¶ l¹i TRUE,
ng−îc l¹i nã tr¶ vÒ FALSE.
Sau khi lµm ng÷ c¶nh diÔn t¶ thµnh hiÖn hµnh, OmPaint() gäi hµm
DrawWithOpenGL() ®Ó vÏ, sau ®ã gäi tíi wglMakeCurrent() lÇn thø hai víi ®èi môc
NULL lµ tham sè thø 2, lµm ng÷ c¶nh diÔn t¶ kh«ng cßn lµ hiÖn hµnh. (B¹n ph¶i tù
viÕt lÊy hµm DrawWithOpenGL() ®Ó biÓu diÔn nh÷ng g× b¹n muèn thÓ hiÖn).
Cuèi cïng, khi øng dông ®ãng l¹i, MFC gäi hµm OnDestroy() cña líp quan
s¸t. Trong OnDestroy(), ch−¬ng tr×nh chØ gäi wglDeleteContext() ®Ó xo¸ bá ng÷ c¶nh
diÔn t¶. Hµm nµy cã ®èi môc ®¬n lµ ®iÒu khiÓn cña ng÷ c¶nh diÔn t¶. NÕu thµnh c«ng,
hµm nµy tr¶ vÒ TRUE, ng−îc l¹i tr¶ vª FALSE. Bëi v× DC ®· ®−îc t¹o lËp vµ bÞ ph¸
ph¸ huû trong th«ng ®iÖp WM_PAINT, kh«ng cã DC ®Ó xo¸ ë cuèi ch−¬ng tr×nh.
Chó ý :
Khi gäi wglMakeCurrent() ®Ó lµm mét ng÷ c¶nh diÔn t¶ kh«ng cßn lµ hiÖn hµnh, ®iÒu
khiÓn DC trong tham sè ®Çu bÞ bá qua, tham sè thø 2 lµ NULL. V× lý do nµy, khi lµm ng÷ c¶nh
diÔn t¶ thµnh kh«ng hiÖn hµnh, c¶ 2 ®èi môc cña wglMakeCurrent() cã thÓ ®−îc cho lµ NULL.
_ 21 _
§å ho¹ 3D víi OpenGL
Ch−¬ng 5
VÏ h×nh vµ sö dông mÇu
Trong ch−¬ng nµy : - Gäi c¸c hµm OpenGL thÕ nµo
- VÒ c¸c tr¹ng th¸i OpenGL
- Chän mÇu nh− thÕ nµo
- §Þnh nghÜa mét h×nh nh− thÕ nµo
- C¸c h×nh c¬ b¶n ®−îc cung cÊp bëi OpenGL
HËu tè ý nghÜa
b Cho ®èi môc GLbyte
d GLdouble hoÆc GLclampd
f GLfloat hoÆc GLclampf
i GLint hoÆc GLsizei
s GLshort
ub GLubyte hoÆc GLboolean
ui GLuint , GLenum , GLbitfield
us GLushort
_ 22 _
§å ho¹ 3D víi OpenGL
_ 23 _
§å ho¹ 3D víi OpenGL
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0f,1.0f,1.0f);
glBegin(GL_LINES);
glVertex2f(0.25f,0.25f);
glVertex2f(0.75f,0.25f);
glEnd();
glFlush();
}
B©y giê b¹n ®· biÕt vÒ c¸c hËu tè cña c¸c hµm OpenGL, b¹n cã thÓ ®ãng gãi
trong DrawWithOpenGL(). Trong c¸c môc sau, b¹n sÏ thÊy mçi dßng lµm g× vµ t¹i
sao nã quan träng víi ch−¬ng tr×nh OpenGL.
_ 24 _
§å ho¹ 3D víi OpenGL
_ 25 _
§å ho¹ 3D víi OpenGL
glVertex2f(0.0f,1.0f);
glVertex2f(0.0f,1.0f);
glVertex2f(1.0f,1.0f);
glVertex2f(1.0f,1.0f);
glVertex2f(1.0f,0.0f);
glEnd();
C¸c gi¸ trÞ cña c¸c ®Ønh trªn lµ c¬ së trong hÖ to¹ ®é Cartesian mÆc ®Þnh ®Æt
trong OpenGL. C¸c to¹ ®é cë së mÆc ®Þnh ®Þnh nghÜa mét khèi 2x2x2, víi gèc 0,0 ë
träng t©m cña khèi lËp ph−¬ng. Bëi vËy, c¸c to¹ ®é trªn t¹o mét h×nh ch÷ nhËt ë gãc
trªn bªn ph¶i cña cöa sæ.
§Ó kÓt thóc ®Þnh nghÜa h×nh, DrawWithOpenGL() gäi glEnd(). Hµm nµy ph¶i
lu«n gäi theo sau danh s¸ch c¸c hµm glVertex(), vµ hµm nµy kh«ng cã tham sè.
_ 26 _
§å ho¹ 3D víi OpenGL
®Þnh nghÜa c¸c ®iÓm trªn mÆt ph¼ng Cartesian 2D, víi c¸c ®Ønh ®−îc ®Þnh nghÜa b»ng
c¸c to¹ ®é X vµ Y. C¸c ®iÓm nµy thùc tÕ cã c¸c gi¸ trÞ Z vµ W, nÕu chØ cung cÊp c¸c
to¹ ®é X vµ Y, OpenGL tù ®éng ®Æt Z vµ W vÒ gi¸ trÞ mÆc ®Þnh t−¬ng øng lµ 0 vµ 1.
NÕu b¹n ®Þnh nghÜa c¸c ®iÓm trong to¹ ®é Cartesian 3D, ®o¹n m· trªn cã thÓ gièng
nh− sau :
glBegin(GL_POINTS);
glVertex3f(0.0f,0.0f,0.0f);
glVertex3f(0.75f,0.75f,1.0f);
glVertex3f(-0.75f,-0.75f,1.0f);
glVertex3f(-0.75f,0.75f,-1.0f);
glVertex3f(0.75f,-0.75f,-1.0f);
glEnd();
ë ®©y, ®o¹n m· sö dông phiªn b¶n 3f cña glVertex() víi trËt tù ®Þnh nghÜa c¸c to¹ ®é
3D : X, Y vµ Z.
Víi mµn h×nh cã ®é ph©n gi¶i cao, mét ®iÓm ®¬n khã nh×n thÊy trªn mµn h×nh.
May m¾n lµ OpenGL cã hµm glPointSize() cho phÐp b¹n vÏ c¸c ®iÓm cã kÝch th−íc
bÊt kú. Hµm sau ®Æt kÝch th−íc cña mét ®iÓm lµ 4 ®iÓm ¶nh :
glPointSize(4.0f);
§èi môc ®¬n cña hµm nµy lµ mét gi¸ trÞ GLfloat x¸c ®Þnh ®−êng kÝnh cña ®iÓm
®−îc yªu cÇu. §Ó x¸c ®Þnh d¶i c¸c kÝch th−íc c¸c ®iÓm ®−îc cung cÊp, b¹n cã thÓ gäi
glGetFloatv() nh− sau :
GLfloat ps[2];
glGetFloatv(GL_POINT_SIZE_RANGE,ps);
ë ®©y, ps lµ m¶ng 2 phÇn tö gi¸ trÞ GLfloat sÏ n¾m gi÷ c¸c kÝch th−íc ®iÓm nhá nhÊt
vµ lín nhÊt. ViÖc gäi glFloatv() yªu cÇu ®èi môc ®Çu lµ mét h»ng sè x¸c ®Þnh c¸c gi¸
trÞ b¹n muèn lÊy l¹i vµ ®èi môc thø 2 lµ ®Þa chØ cña m¶ng GLfloat trong ®ã l−u gi¸ trÞ
tr¶ vÒ cña hµm. Cã nhiÒu nhÊt 150 h»ng sè b¹n cã thÓ sö dông víi c¸c biÕn d¹ng cña
glGet().
B¹n cã thÓ cã kÝch th−íc ®iÓm hiÖn hµnh trong nhiÒu c¸ch nh− nhau :
GLfloat ps;
GlGetFloatv(GL_POINT_SIZE,&ps);
Trong tr−êng hîp nµy, ps lµ biÕn glFloat, nã sÏ n¾m gi÷ kÝch th−íc ®iÓm hiÖn hµnh.
§Þa chØ cña biÕn nµy ®−îc cho lµ ®èi môc thø 2 cña hµm glGetFloatv().
§o¹n m· sau t¹o ra c¸c ®iÓm cã kÝch th−íc lín nhÊt cã thÓ :
glClearColor(1.0f,1.0f,1.0f,1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0f,0.0f,0.0f);
GLfloat ps[2];
_ 27 _
§å ho¹ 3D víi OpenGL
glGetFloatv(GL_POINT_SIZE_RANGE,&ps);
glPointSize(ps[1]);
glBegin(GL_POINTS);
glVertex2f(0.0f,0.0f);
glVertex2f(0.75f,0.75f);
glVertex2f(-0.75f,-0.75f);
glVertex2f(-0.75f,0.75f);
glVertex2f(0.75f,-0.75f);
glEnd();
glFlush();
_ 28 _
§å ho¹ 3D víi OpenGL
glGetFloatv(GL_LINE_WIDTH,&lw);
Trong tr−êng hîp nµy, lw lµ biÕn GLfloat sÏ n¾m gi÷ ®é réng cña ®−êng hiÖn hµnh.
§Þa chØ cña biÕn nµy ®−îc cho lµ ®èi môc thø 2 cña hµm glGetFLoatv().
§o¹n m· sau vÏ c¸c ®−êng ®−êng th¼ng víi ®é réng lín nhÊt cã thÓ :
glClearColor(1.0f,1.0f,1.0f,1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0f,0.0f,0.0f);
GLfloat lw[2];
glGetFloatv(GL_LINE_WIDTH_RANGE,lw);
glLineWidth(lw[1]);
glBegin(GL_LINES);
glVertex2f(0.75f,0.75f);
glVertex2f(0.25f,0.75f);
glVertex2f(-0.75f,0.25f);
glVertex2f(0.75f,0.25f);
glVertex2f(-0.75f,-0.75f);
glVertex2f(0.75f,-0.75f);
glEnd();
glFlush();
_ 29 _
§å ho¹ 3D víi OpenGL
Sau khi ®Æt mÉu vÏ b»ng chÊm, b¹n ph¶i lµm cho ®−êng th¼ng chÊm cã thÓ lµm
viÖc ®−îc, bëi viÖc gäi :
glEnable(GL_LIXE_STIPPLE);
Hµm glEnable() cã mét ®èi môc ®¬n lµ kh¶ n¨ng cña OpenGL mµ b¹n muèn cho
phÐp thao t¸c. VÝ dô, h»ng GL_LINE_STIPPLE cho c¸c ®−êng th¼ng vÏ b»ng chÊm
cña OpenGL, còng vËy GL_LIGHTING cho c¸c kh¶ n¨ng cña openGL ®Ó ¸p dông
chiÕu s¸ng ¶nh. Cã kho¶ng 50 h»ng mµ b¹n cã thÓ sö dông víi glEnable() vµ
glDisable(). Chóng ®−îc liÖt kª trong tµi liÖu trùc tuyÕn trong visualC++
§o¹n m· sau t¹o ra c¸c ®−êng vÏ b»ng chÊm :
glClearColor(1.0f,1.0f,1.0f,1.0f);
glClear(GL_COLOR_BUFFER_BIT);
gl Color3f(0.0f,0.0f,0.0f);
GLfloat lw[2];
glGetFloat(GL_LINE_WIDTH_RANGE,lw);
glLineWidth(lw[1]);
glLineStipple(1,0x4444);
glEnable(GL_LINE_STIPPLE);
glBegin(GL_LINE);
glVertex2f(-0.75f,0.75f);
glVertex2f(0.75f,0.75f);
glVertex2f(-0.75f,0.25f);
glVertex2f(0.75f,0.25f
glVertex2f(-0.75f,-0.25f);
glVertex2f(0.75f,-0.25f);
glEnd();
glFlush();
_ 30 _
§å ho¹ 3D víi OpenGL
GLfloat lw[2];
glGetFloatv(GL_LINE_WIDTH_RANGE,lw);
glLineWidth (l−[1]/2);
glBigin (GL_LINE_STRIP);
glVertex2f (-1.0f, 0.25f );
glVertex2f (1.0f, 0.75f );
glVertex2f (-1.0f, 0.25f );
glVertex2f (1.0f, 0.25f );
glVertex2f (-1.0f, -0.25f );
glVertex2f (1.0f,- 0.25f );
glVertex2f (-1.0f, -0.75f );
gl Vertex2f (1.0f, -0,75f);
glEnd ();
glFlush ();
_ 31 _
§å ho¹ 3D víi OpenGL
§Þnh nghÜa ®a gi¸c còng dÔ nh− ®Þnh nghÜa ®−êng th¼ng. B¹n chØ cÇn Ýt nhÊt ba
®Ønh. Tuy nhiªn, b¹n ph¶i ch¾c ch¾n r»ng b¹n ®Þnh nghÜa c¸c ®Ønh theo chiÒu ®óng,
phô thuéc vµo gi¸ trÞ hiÖn hµnh cña biÕn tr¹ng th¸i GL_FRONT_FACE. Nh− ®· kÓ
trªn, ®Ønh mÆc ®Þnh ®Þnh nghÜa chiÒu lµ chiÒu quay kim ®ång hå, do ®ã ®o¹n m· sau
®Þnh nghÜa mÆt tr−íc h×nh vu«ng :
glBegin(GL_POLYGON );
glVertex2f(-0.5f,0.5f);
glVertex2f(-0.5f,-0.5f);
glVertex2f(0.5f,-0.5f);
glVertex2f(0.5f,0.5f);
glEnd( );
§Ó ®Þnh nghÜa mét ®a gi¸c, b¹n sö dông glBegin víi h»ng GL_POLYGON, råi
b¹n ®Þnh nghÜa c¸c ®Ønh cña ®a gi¸c theo thø tù theo chiÒu kim ®ång hå, viÖc ®Þnh
nghÜa h×nh kÕt thóc víi viÖc gäi tíi glEnd( ).
VÝ dô : glClearColor (1.0f,1.0f,1.0f,1.0f);
glClear (GL_COLOR_BUFFER_BIT);
glColor3f (0.0f,0.0f.0.0f);
glPolygonMode(GL_FPONT,GL_LINE);
glPolygonMode (GL_BLACK,GL_FILL);
glFrontFace (GL_CCW);
glVertex2f(-0.5f,0.5f);
glVertex2f(-0.5f,-0.5f);
glVertex2f(0.5f,-0.5f);
glVertex2f(0.5f,0.5f);
glEnd();
Chó ý r»ng, trong ®o¹n m· trªn, 2 lÇn gäi glPolygonMode() yªu cÇu phÝa tr−íc
®a gi¸c ®−îc vÏ nh− mét h×nh ®Æc. Bëi v× ®a gi¸c lµ mÆt tr−íc, chØ phÝa tr−íc cña ®a
gi¸c míi ®−îc thÓ hiÖn, biÓu diÔn ra mµ th«i.
Thay ®æi lêi gäi glFrontFace (GL_CCW) thµnh glFrontFace(GL_CW) b¶o
OpenGL r»ng ®a gi¸c sÏ ®−îc xem theo chiÒu míi.
4.5. VÏ c¸c ®a gi¸c b»ng ®iÓm
Nh− b¹n cã thÓ vÏ c¸c ®−êng th¼ng víi mçi ®iÓm ®−îc ®Þnh nghÜa bëi ng−êi sö
dông, còng vËy cã thÓ b¹n vÏ c¸c ®a gi¸c ®−îc t« kÝn víi mÉu bÊt kú b¹n muèn. B−íc
®Çu tiªn ®Ó vÏ ®a gi¸c ®¬n lµ ®Þnh nghÜa mÉu mµ OpenGL sÏ t« ®a gi¸c. MÉu nµy lµ
¶nh bitmap 32x32, ë ®ã mçi mét bit trong mÉu t¹o mét chÊm trªn mµn h×nh.
_ 32 _
§å ho¹ 3D víi OpenGL
Mét khi b¹n cã mÉu ®· thiÕt kÕ, b¹n ph¶i chuyÓn thµnh gi¸ trÞ trong hÖ thËp lôc
ph©n (chÝnh lµ mét m¶ng c¸c gi¸ trÞ GLubyte) ®Ó b¹n cã thÓ sö dông trong ch−¬ng
tr×nh. ViÖc chuyÓn ®æi nµy b¾t ®Çu víi byte ë gãc thÊp bªn tr¸i cña l−íi, lÇn l−ît sang
bªn ph¶i vµ lªn trªn.
§Ó ®−a mÉu ®iÓm tíi OpenGL, b¹n gäi hµm glPolygonStipple() :
glPolygonStipple (pattern);
tham sè ®¬n cña hµm nµy lµ ®Þa chØ cña m¶ng d÷ liÖu ®Þnh nghÜa mÉu vÏ b»ng chÊm.
B©y giê b¹n cã mÉu ®· ®Þnh nghÜa vµ ®Ó b¶o víi OpenGL lµ b¹n ®· sö dông
mÉu g×, b¹n ph¶i chän ®a gi¸c ®iÓm bëi gäi glEnable() víi cê hiÖn
GL_POLYGON_STIPPLE :
glEnable (GL_POLYGON_STIPPLE);
Tõ thêi ®iÓm nµy, bÊt kú ®a gi¸c ®Æc nµo b¹n vÏ sÏ ®−îc t« víi mÉu chÊm ®· chän.
Khi b¹n muèn trë l¹i vÏ ®a gi¸c theo mÆc ®Þnh, b¹n gäi glDisable() ®Ó t¾t ®a gi¸c
®iÓm:
glDisable (GL_POLYGON_STIPPLE);
_ 33 _
§å ho¹ 3D víi OpenGL
§Ó vÏ ®−îc ®a gi¸c lâm, b¹n vÏ 2 hoÆc nhiÒu ®a gi¸c låi phèi hîp víi nhau
thµnh h×nh cÇn thiÕt, b¹n kÕt thóc vÏ víi c¸c ®−êng bªn trong ®a gi¸c vÉn hiÓn thÞ mµ
b¹n kh«ng muèn. B¹n cã thÓ kh¾c phôc vÊn ®Ò nµy nhê sö dông hµm glEdgeFlag()
cña OpenGL, nã t¾t c¸c c¹nh vÏ gi÷a c¸c ®Ønh ®−îc chØ ®Þnh. NÕu b¹n gäi hµm
glEdgeFlag (FALSE) tr−íc ®Þnh nghÜa mét ®Ønh, OpenGL sÏ kh«ng vÏ c¹nh gi÷a c¸c
®Ønh ®ã vµ ®Ønh tiÕp theo mµ b¹n ®Þnh nghÜa. B¹n gäi glEdgeFlag(TRUE) ®Ó quay l¹i
vÏ víi c¸c c¹nh ®−îc hiÓn thÞ.
VÝ dô : glClearColor (1.0f,1.0f,1.0f,1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f (0.0f,0.0f,0.0f);
glPolygonMode (GL_FRONT_AND_BACK,GL_LINE);
glBegin (GL_POLYGON);
glEdgeFlag (TRUE);
glVertex2f (-0.2f,0.3f);
glEdgeFlag (FALSE);
glVertex2f (-0.2f,-0.1f);
glVertex2f (0.0f,-0.1f);
glVertex2f (0.0f,0.3f);
glEnd();
glBegin (GL_POLYGON);
glEdgeFlag (TRUE);
glVertex2f (-0.2f,-0.1f);
glVertex2f (-0.2f,-0.4f);
glEdgeFlag (FALSE);
glVertex2f (-0.0f,-0.4f);
glVertex2f (0.0f,-0.1f);
glEnd( );
glBegin (GL_POLYGON);
glEdgeFlag (FALSE);
glVertex2f (-0.0f,-0.1f);
glEdgeFlag (TRUE);
glVertex2f (0.0f,-0.4f);
glVertex2f (0.3f,-0.4f);
glVertex2f (0.3f,-0.1f);
glEnd( );
glFlush( );
_ 34 _
§å ho¹ 3D víi OpenGL
_ 35 _
§å ho¹ 3D víi OpenGL
glVertex2f (0.75f,0.3f);
glEnd( );
glFlush( );
_ 36 _
§å ho¹ 3D víi OpenGL
glVertex2f (-0.75f,-0.45f);
glVertex2f (0.25f,-0.75f);
glVertex2f (0.5f,-0.25f);
glEnd( );
glFlush( );
_ 37 _
§å ho¹ 3D víi OpenGL
Ch−¬ng 6
C¸c phÐp biÕn h×nh openGL
1. Lùa chän ma trËn chiÕu
B−íc ®Çu tiªn sö dông phÐp chiÕu phèi c¶nh lµ b¹n ph¶i b¶o víi OpenGL r»ng
b¹n muèn thao t¸c víi ma trËn chiÕu:
glMatrixMode(GL_PROJECTION);
OpenGL sö dông 3 ma trËn kh¸c nhau ®Ó chuyÓn ®æi c¸c ®Ønh cña c¸c ®èi t−îng mµ
nã cÇn ph¶i biÓu diÔn. B¹n cã thÓ nghÜ ng¨n xÕp ma trËn ®¬n gi¶n lµ mét ma trËn ®¬n
4x4. Hµm glMatrixMode() gióp b¹n cã thÓ lùa chän ma trËn mµ b¹n muèn lµm viÖc
víi nã. §èi môc ®¬n cña hµm, cã thÓ lµ GL_MODELVIEW, GL_PROJECTION
hoÆc GL_TEXTURE, lµ mét h»ng ®¹i diÖn cho ma trËn mµ b¹n muèn thao t¸c .
C¸ch gäi trªn tíi glMatrixMode() sö dông h»ng GL_PROJECTION ®Ó lùa
chän ma trËn chiÕu cña OpenGL, nh− thÕ nã lµ ma trËn b¹n cÇn trong ®Ó ¸p dông
phÐp chiÕu phèi c¶nh tíi c¸c ®èi t−îng b¹n muèn biÓu diÔn.
3. §Þnh nghÜa mét khèi quan s¸t mÆt ph¼ng gÇn trªn
mÆt ph¼ng xa
ViÖc tiÕp theo trong viÖc ¸p dông phÐp
chiÕu phèi c¶nh lµ gäi hµm glFrustum() ®Ó tr¸i
b¶o OpenGL giíi h¹n mét khèi quan s¸t mµ ph¶i
nã lµ mét vïng 3D mµ c¸c ®èi t−îng cña b¹n
tån t¹i trong ®ã. ViÖc gäi hµm cã thÓ gièng m¾t d−íi
nh− sau :
glFrustum (-1.0,1.0,-1.0,1.0,2.0,7.0);
Hµm nµy t¹o lËp ma trËn phèi c¶nh vµ nh©n nã víi ma trËn ®ang ®−îc chän hiÖn
hµnh. Hµm nµy gåm 6 ®èi môc GLdouble , nã ®Þnh nghÜa c¸c to¹ ®é tr¸i, ph¶i, trªn,
d−íi, gÇn vµ xa cña khèi quan s¸t. C¸c gèi môc gÇn vµ xa ®Æc tr−ng cho kho¶ng c¸ch
tõ m¾t tíi khèi quan s¸t vµ ph¶i lµ c¸c gi¸ trÞ d−¬ng. M¾t lµ ®iÓm mµ tõ ®ã b¹n quan
s¸t c¶m nhËn, trõ khi b¹n thay ®æi nã, mÆt ph¼ng ë gÇn lµ b¾t ®Çu cña khèi quan s¸t,
bÊt kú ®èi t−îng hoÆc mét phÇn cña ®èi t−îng n»m gi÷a m¾t vµ mÆt ph¼ng gÇn sÏ
_ 38 _
§å ho¹ 3D víi OpenGL
kh«ng xuÊt hiÖn trong quan s¸t cña b¹n. BÊt kú mét ®èi t−îng hoÆc mét phÇn cña ®èi
t−îng ë xa h¬n mÆt ph¼ng xa còng kh«ng xuÊt hiÖn, v× mÆt ph¼ng xa ®¹i diÖn cho kÕt
thóc cña khèi nh×n.
_ 39 _
§å ho¹ 3D víi OpenGL
glClearColor(1.0f,1.0f,1.0f,1.0f);
glClear(GL_COLOR_BUFFER_BIT)
glColor3f(0.0f,0.0f,0.0f);
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
glBegin (GL_POLYGON);
glVertex3f(-0.5f,0.5f,0.5f);
glVertex3f(-0.5f,-0.5f,0.5f);
glVertex3f(0.5f,-0.5f,0.5f);
glVertex3f(0.5f,0.5f,0.5f);
glEnd();
glBegin(GL_POLYGON);
glVertex3f(0.5f,0.5f,0.5f);
glVertex3f(0.5f,-0.5f,0.5f);
glVertex3f(0.5f,-0.5f,-0.5f);
glVertex3f(0.5f,0.5f,-0.5f);
glEnd();
glBegin (GL_POLYGON);
glVertex3f(0.5f,0.5f,-0.5f);
glVertex3f(0.5f,-0.5f,-0.5f);
glVertex3f(0.5f,-0.5f,-0.5f);
glVertex3f(0.5f,0.5f,-0.5f);
glEnd();
glBegin (GL_POLYGON);
glVertex3f(
…
glEnd();
glBegin (GL_POLYGON);
glVertex3f(
…
glEnd();
glBegin (GL_POLYGON);
glVertex3f (-0.5f,0.5f,-0.5f);
glVertex3f (-0.5f,0.5f,0.5f);
glVertex3f (0.5f,0.5f,0.5f);
glVertex3f (0.5f,0.5f,-0.5f);
glEnd();
glFlush();
_ 40 _
§å ho¹ 3D víi OpenGL
_ 41 _
§å ho¹ 3D víi OpenGL
glClear(GL_COLOR_BUFFER_BIT)
glColor3f(0.0f,0.0f,0.0f);
glPolygonMode (GL_FRONT_AND_BACK,GL_LINE);
DrawCube();
glFlush();
_ 42 _
§å ho¹ 3D víi OpenGL
wglMakeCurrent (NULL,NULL);
}
ViÖc x¸c ®Þnh c¸c ®èi môc ®óng cho hµm glFrustum() cã thÓ lµ c«ng viÖc m¬
hå. §ã lµ lý do t¹i sao th− viÖn c«ng cô cña OpenGL gép hµm glPerspective(), nã cho
phÐp b¹n cã thÓ ®Þnh nghÜa khèi quan s¸t mét c¸ch trùc quan h¬n.
gluPerspective (viewAngle, aspectRatio, nearPlane, farPlane);
ë ®©y ®èi môc ®Çu tiªn lµ gi¸ trÞ GLdouble ®−îc chuyÓn cho tr−êng khèi quan
s¸t, nã lµ gãc n»m gi÷a c¸c ®−êng th¼ng ®−îc vÏ tõ ®Ønh cña mÆt ph¼ng c¾t gÇn vµ
®¸y cña mÆt ph¼ng c¾t gÇn tíi m¾t.
§èi môc thø hai lµ gi¸ trÞ GLdouble nã cho tû lÖ bªn ngoµi cña khèi quan s¸t.
NÕu cho tû lÖ bªn ngoµi lµ 1.0 th× khèi quan s¸t cã ®é réng b»ng ®é cao cña nã. VÝ
dô, gi¸ trÞ 0.5 cña tû lÖ ngoµi cho khèi quan s¸t cã ®é cao gÊp 2 lÇn chiÒu réng.
Hai ®èi môc cuèi lµ c¸c gi¸ trÞ GLdouble cho kho¶ng c¸ch tõ ®iÓm quan s¸t tíi
mÆt c¾t gÇn vµ xa. Chóng ph¶i lu«n lµ gi¸ trÞ d−¬ng.
NÕu b¹n muèn gi÷ khung nh×n vµ c¸c khèi quan s¸t víi c¸c tû lÖ ngoµi còng
kh«ng cã vÊn ®Ò g× phøc t¹p, khi ng−êi sö dông thay®æi kÝch th−íc cöa sæ, b¹n cã thÓ
sö dông ®o¹n m· nh− sau ®Ó ®¸p l¹i th«ng ®iÖp WM_SIZE:
CClientDC clientDC(this);
wglMakeCurrent (clientDC.m_hCD,m_hRC);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
GLdouble aspectRatio= (GLdouble)cx/(GLdouble)cy;
gluPerspective(40.0, aspectRatio, 3.5, 10.0);
glViewport(0,0,cx,cy);
glMakeCurrent(NULL,NULL);
_ 43 _
§å ho¹ 3D víi OpenGL
Ch−¬ng 7
_ 44 _
§å ho¹ 3D víi OpenGL
Hµm glLightfv() cã 3 ®èi môc lµ kiÓu nguån s¸ng ®−îc ®Þnh nghÜa, mét h»ng
x¸c ®Þnh ®Æc tÝnh cña ¸nh s¸ng b¹n muèn thay ®æi, vµ ®Þa chØ cña m¶ng chøa c¸c gi¸
trÞ mµ ®Æc tÝnh ¸nh s¸ng ®−îc ®Æt.
Bëi v× OpenGL cung cÊp 8 nguån s¸ng nªn ®èi môc ®Çu tiªn cã thÓ lµ h»ng tõ
GL_LIGHT0 ®Õn GL_LIGHT7. §èi môc thø 2 ph¶i lµ mét trong c¸c h»ng :
GL _AMBIENT
GL_CONSTANT_ATTENUATION
GL_DIFFUSE
GL_POSITION
GL_QUADRATIC_ATTENUATION
GL_SPECULAR
GL_SPOT_CUTOFF
GL_SPOT_DIRECTION
GL_SPOT_EXPONENT
C¸c phiªn b¶n kh¸c cña hµm glLight( ) lµ glLightf( ), glLightiv( ) vµ glLight…( ).
_ 45 _
§å ho¹ 3D víi OpenGL
_ 46 _
§å ho¹ 3D víi OpenGL
_ 47 _
§å ho¹ 3D víi OpenGL
glShadeModel(GL_SMOOTH);
glEnable(GL_DEPTH_TEST);
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
_ 48 _
§å ho¹ 3D víi OpenGL
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
GLfloat materialAmbient[] = {0.0f, 1.0f, 0.0f, 1.0f);
GLfloat materialSpecular[] = {0.7f, 0.70f, 0.7f, 1.0f);
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, material(
Ambient));
glMaterialfv (GL_FRONT, GL_SPECULAR, material Specular);
glMaterialfv (GL_FRONT, GL_SHININESS, 100.0f);
GLfloat ambientLinght0[] = {0.7f, 0.7f, 0.7f, 1.0f};
GLfloat diffuseLinght0[] = {0.0f, 0.0f, 0.0f, 1.0f};
GLfloat specularLinght0[] = {0.0f, 0.0f, 0.0f, 1.0f};
GLfloat possitionLinght0[] = {0.0f, 0.0f, 1.0f, 0.0f};
glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight0);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight0);
glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight0);
glLightfv(GL_LIGHT0, GL_POSITION, positionLight0);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glTranslatef (m-x Translate, m-y Translate, m-z TRanslate);
glScale (m-x Scale, m-y Scale, m-z Scale);
glRotate (m-x Rotate, 1.0f, 0.0f, 0.0f);
glRotate (m-y Rotate, 0.0f, 1.0f, 0.0f);
glRotate (m-z Rotate, 0.0f, 0.0f, 1.0f);
auxSolidSphere (1.0);
glFlush ();
§èi t−îng ®−îc vÏ lµ h×nh cÇu ®Æc ®−îc ®Æt ë gèc, OpenGL bæ trî hµm
auxSolidSphere(). §èi môc ®¬n cña hµm nµy lµ b¸n cña h×nh cÇu.
8.2. HiÖu øng cña ¸nh s¸ng khuyÕch t¸n (Diffuse Light)
Thay ®æi c¸c m¶ng ®Þnh nghÜa nguån s¸ng trong phÇn trªn bëi:
GLfloat ambientLinght0[] = {0.0f, 0.0f, 0.0f, 1.0f};
GLfloat diffuseLinght0[] = {0.7f, 0.7f, 0.7f, 1.0f};
GLfloat specularLinght0[] = {0.0f, 0.0f, 0.0f, 1.0f};
GLfloat possitionLinght0[] = {0.0f, 0.0f, 1.0f, 0.0f};
_ 49 _
§å ho¹ 3D víi OpenGL
8.3. HiÖu øng cña ¸nh s¸ng ph¶n chiÕu (Specular Light)
8.4. Phèi hîp c¸c kiÓu ¸nh s¸ng (Ambient, Diffuse, Specular Linht)
_ 50 _
§å ho¹ 3D víi OpenGL
Ch−¬ng 8
T¹o lËp h×nh thÓ 3D
1. Sö dông c¸c ng¨n xÕp ma trËn
Ng¨n xÕp ma trËn (matrix stack) rÊt gièng víi ng¨n xÕp m¸y tÝnh mµ b¹n sö
dông, ngo¹i trõ ng¨n xÕp ma trËn l−u gi÷ c¸c gi¸ trÞ cña c¸c ma trËn, h¬n thÕ n÷a kiÓu
cña c¸c gi¸ trÞ ®ã b¹n cã thÓ l−u tr÷ trong ng¨n xÕp m¸y tÝnh. Mçi ma trËn chuyÓn ®æi
cã mét ng¨n xÕp ma trËn cña chÝnh b¶n th©n nã. §Ó ghi l¹i ng÷ c¶nh cña ma trËn hiÖn
hµnh, ®¬n gi¶n b¹n chØ cÇn gäi hµm sau:
glPushMatrix();
Sau khi ®Æt ma trËn hiÖn hµnh vµo trong ng¨n xÕp, b¹n cã thÓ thùc hiÖn tÊt c¶
c¸c phÐp chuyÓn ®æi b¹n muèn mµ kh«ng ph¶i lo l¾ng vÒ sù thay ®æi ma trËn gèc.
Khi b¹n muèn tr¶ l¹i ma trËn gèc b¹n gäi hµm glPopMatrix() nh− sau:
glPopMatrix();
Nh− b¹n cã thÓ thÊy, c¸c hµm nµy kh«ng cã ®èi môc. Chóng lu«n lµm viÖc víi
ma trËn ®−îc chän hiÖn hµnh.
_ 51 _
§å ho¹ 3D víi OpenGL
PIXELFORMATDESCRIPTOR
{
sizeo (PIXELFORMATDESCRIPTOR),
1,
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,
PFD_MAIN_PLANE,
0,
0, 0, 0
};
Nh− b¹n thÊy, ®¬n gi¶n chØ cÇn OR cê PFD_DOUBLEBUFFER víi c¸c cê
kh¸c trong thµnh phÇn cÊu tróc dwFlag.
Thay ®æi thø hai b¹n cÇn lµm víi ch−¬ng tr×nh cña b¹n lµ gäi hµm
SwapBuffers() sau khi ch−¬ng tr×nh cña b¹n vÏ ¶nh míi.
_ 52 _
§å ho¹ 3D víi OpenGL
Ch−¬ng 9
H»ng M« t¶
GL_ALPHA Mçi ®¬n ¶nh lµ mét thµnh phÇn mÇu adphe
GL_BLUE Mçi ®¬n ¶nh lµ mét thµnh phÇn mÇu blue
GL_COLOR_INDEX Mçi ®¬n ¶nh lµ mét thµnh chØ sè mµu
GL_DEPTH_COMPONET Mçi ®¬n ¶nh lµ mét thµnh phÇn mÇu ®é s©u
GL_GREEN Mçi ®¬n ¶nh lµ mét thµnh phÇn mÇu green
GL_LUMINANCE Mçi ®¬n ¶nh lµ mét thµnh phÇn mÇu Luminance
GL_RED Mçi ®¬n ¶nh lµ mét thµnh phÇn mÇu red
GLRBG Mçi ®¬n ¶nh ®−îc ®Æc tr−ng bëi thµnh phÇn R, G vµ B
GL_RGBA
GL_STENCIL_INDEX
Víi ®iÒu kiÖn, kÝch th−íc cña d÷ liÖu ®ã ®Æc tr−ng cho biÕn thµnh phÇn ¶nh
®¬n tõ image tíi image vµ tõ m¸y tíi m¸y. V× lý do ®ã, OpenGL ®Þnh nghÜa mét sè
h»ng kiÓu d÷ liÖu ®ã ®−îc liÖt kª sau ®©y :
_ 53 _
§å ho¹ 3D víi OpenGL
H»ng M« t¶
GL_BITMAP H»ng nguyªn 8 bit kh«ng dÊu
GL_BYTE H»ng nguyªn 8 bit kh«ng dÊu
GL_FLOAT
GL_INT H»ng nguyªn cã dÊu 32 bit
GL_SHORT H»ng nguyªn cã dÊu 16 bit
GL_UNSIGNED_BYTE H»ng nguyªn kh«ng dÊu 8bit
GL_UNSIGNED_INT H»ng nguyªn kh«ng dÊu 32 bit
GL_UNSIGNED_SHORT H»ng nguyªn kh«ng dÊu 16 bit
_ 54 _
§å ho¹ 3D víi OpenGL
B¹n cã thÓ ®iÒu khiÓn vÞ trÝ l−íi mµ glDrawPixel() thÓ hiÖn d÷ liÖu ¶nh nh− thÕ
nµo? Víi hµm glRasterPos3f() nh− sau :
glRasterPos3f (1.0f,1.0f,0.0f);
Hµm nµy ®Æt vÞ trÝ l−íi hiÖn hµnh, mµ ®−îc cho trong 3 ®èi môc X, Y, X cña
hµm. C¸c gi¸ trÞ nµy kh«ng ph¶i lµ to¹ ®é mµn h×nh gièng nh− ®· sö dông víi hµm
glReadPixels(), nh−ng cã thÓ lµ to¹ ®é Cartesian nã ®−îc chuyÓn ®æi tíi to¹ ®é mµn
h×nh bëi m« h×nh quan s¸t vµ phÐp biÕn ®æi phèi c¶nh. Hµm glRasterPos cã 3 phiªn
b¶n phô thuéc vµo sè vµ kiÓu cña ®èi môc.
_ 55 _
§å ho¹ 3D víi OpenGL
+ ThiÕt bÞ phô thuéc bitmap : lµ c¸c ¶nh ®å ho¹ mµ chØ cã thÓ biÓu diÔn theo
mét kiÓu cña thiÕt bÞ vËt lý. VÝ dô, khi b¹n sö dông c¸c hµm cña Windows còng nh−
CreateBitmap() vµ LoadBitmap(), b¹n ®ang t¹o lËp trong bé nhí mét ¶nh bitmap, ®ã
lµ sù t−¬ng t¸c víi thiÕt bÞ nµo ®ã, th−êng lµ mµn h×nh. C¸c kiÓu nµy cña bitmap còng
thØnh tho¶ng ®−îc gäi lµ GDIbitmap bëi v× WindowGDI cã thÓ ®iÒu khiÓn chóng mét
c¸ch trùc tiÕp. ThiÕt bÞ phô thuéc bitmap ®−îc l−u tr÷ ®éc lËp víi b¶ng mÇu, bëi v×
chóng sö dông mµu cña thiÕt bÞ phèi hîp cña chóng. NhiÒu tr−êng hîp kh¸c, thiÕt bÞ
phô thuéc bitmap chØ th−êng tró ngô trong bé nhí, hoÆc nh− mét file trªn ®Üa.
+ ThiÕt bÞ kh«ng phô thuéc bitmap : lµ c¸c ¶nh ®å ho¹ cã thÓ ®−îc biÓu diÔn
trªn nhiÒu thiÕt bÞ kh¸c nhau. C¸c kiÓu cña bitmap nµy mang cïng víi chóng mét
b¶ng mÇu, thiÕt bÞ hiÖn hµnh ph¶i sö dông ®Ó biÓu diÔn bitmap do ®ã kh«ng cã t−¬ng
thÝch gi÷a thiÕt bÞ nµy víi thiÕt bÞ kh¸c.
_ 56 _
§å ho¹ 3D víi OpenGL
_ 57 _
§å ho¹ 3D víi OpenGL
Thµnh phÇn biCompression chØ ra kiÓu nÐn ®−îc sö dông víi ¶nh bitmap, ë
®©y nÕu lµ 0 x¸c ®Þnh lµ kh«ng nÐn, 1 x¸c ®Þnh chÕ ®é nÐn RLE-8, 2 x¸c ®Þnh chÕ ®é
nÐn RLE-4. NÕu b¹n kh«ng thao t¸c ®−îc víi kü thuËt nÐn d÷ liÖu, ®õng lo l¾ng vÒ
®iÒu ®ã: DIB hiÕm khi ®−îc nÐn. B¹n sÏ th−êng thÊy gÝ trÞ 0 trong thµnh phÇn cÊu
tróc biConpression.
Thµnh phÇn biSizeImage lµ kÝch th−íc cña bitmap tÝnh theo byte vµ th−êng
chØ ®−îc sö dông víi bitmap ®−îc nÐn. Gi¸ trÞ nµy n¾m gi÷ sè byte trªn mçi hµng
cña bitmap vµ lu«n lu«n lµ béi cña 1. Dï thÕ, trõ khi b¹n ®ang viÕt mét ch−¬ng tr×nh
t¹o lËp DIBs, b¹n kh«ng cÇn chia víi lµng chÌn vµ dÞch m· n¶y sinh tõ nã.
Thµnh phÇn biXPelsPerMeter vµ biYPelsPerMeter chøa sè ®iÓm ¶nh trªn mÐt
theo ph−¬ng ngang vµ ®øng, nh−ng th−êng ®−îc ®Æt lµ 0.
Thµnh phÇn biClrUsed vµ biClrImportant chøa tæng sè mµu ®−îc sö dông
trong bitmap vµ sè mµu quan träng trong bitmap vµ còng th−êng ®−îc ®Æt b»ng 0.
6.4. CÊu tróc RGBQUAD
typedef stuct tagRGBQUAD
{
BYTE rgbBlue;
BYTE rgbGreen;
BYTE rgbRed;
BYTE rgbReserved;
} RGBQUAD;
CÊu tróc nµy chøa c−êng ®é cña c¸c phÇn tö mÇu Red, Green, Blue. Mçi mÇu
trong DIB ®−îc ®Æc tr−ng bëi mét cÊu tróc RGBQUAD. Nã lµ 16 mÇu (4 bit), bitmap
cã b¶ng mÇu 16 RGBQUAD, cã 256 mÇu (8 bit) th× bitmap chøa b¶ng mÇu chøa 256
cÊu tróc RGBQUAD. Víi ¶nh 24 bit mÇu nã kh«ng cã b¶ng mÇu.
CÊu tróc BITMAPINFOHEADER cña DIB lµ d÷ liÖu ¶nh ho¹t ®éng cña
bitmap. KÝch th−íc cña d÷ liÖu nµy phô thuéc vµo kÝch th−íc cña ¶nh.
BITMAPFILEHEADER
BITMAPINFOHEADER BITMAPINFO
RGBQUAD (256)
d÷ liÖu ¶nh
_ 58 _
§å ho¹ 3D víi OpenGL
//----------------------------------------------------------
// CDIB.CPP: implentation file for the DIB class
//----------------------------------------------------------
# include "stdafx.h"
# include "cdib.h"
# include "windowsx.h"
//---------------------------
CDib::CDib(const char * filename)
{
//Load the bitmap and inittialize the class's data members
LoadBitmapLife(filename);
}
_ 59 _
§å ho¹ 3D víi OpenGL
//---------------------------
CDib::CDib()
{
// Free the memory assigned to the bitmap
GlobalFreePtr(m_pBmInfo);
}
//---------------------------
void CDib::LoadBitmapFile(Const char * filename)
{
//construct and open a file oject
CFile file(filename, CFile::modeRead);
_ 60 _
§å ho¹ 3D víi OpenGL
m_pBmInfoHeader->biSizeImage = GetDibSizeImage();
if (m_pBmInfoHeader->biClrUsed == 0)
m_pBmInfoHeader->biClrUsed = m_numColor;
DWORD clrTableSize = m_numColor * sizeof(GRBQUAD);
m_pDirBits = pDib+m_pBmInfoHeader->biSize+clrTableSize;
}
}
//end of LoadBitmapFile();
//---------------------------
DWORD CDib:: GetDibSizeImage( )
{
if (m_pBmInfoHeader->biSizeimage == 0)
{
DWORD byteWidth = (DWORD) GetDibWidth( );
DWORD byteHeight = (DWORD) GetDibHeight( );
DWORD imageSize = byteWidth*byteHeight;
return imageSize;
}
return m_pBmInfoHeader->biSizeImage;
}
//----------------------------------------------
UINT CDib:: GetDibWidth()
{
return (UINT)m_pBmInfoHeader->biWidth;
}
//---------------------------------------------
UINT CDib:: GetDibHeight()
{
return (UINT)m_pBmInfoHeader->biHeight;
}
//-------------------------------------------
UINT CDib:: GetDibNumColor()
{
if((m_pBmInfoHeader->biClrUsed==0)&&(m_pBmInfoHeader->biBitCount
<9)
return (1<< m_pBmInfoHeader->biBitCount);
return (int) m_pBmInfoHeader->biBitUsed;
}
//-----------------------------------------------------
LPBITMAPINFOHEADER CDib::GetDibInfoHeaderPtr( )
_ 61 _
§å ho¹ 3D víi OpenGL
{
return m_pBmInfoHeader;
}
//---------------------------------------------------
LPBITMAPINFO CDib:: GetDibInfoPtr( )
{
return m_pBmInfo;
}
//----------------------------------------------------
LPRGBQUAD CDib:: GetDibRGBTablePtr()
{
return m_pBmInfo;
}
//---------------------------
BYTE * CDib::GetDibBitsPtr()
{
return m_pDibBits;
}
//--------------------------------------
//End of file CDIB.CPP.
//----------------------------------------
_ 62 _
§å ho¹ 3D víi OpenGL
mµ mçi ®iÓm ¶nh trong ¶nh sÏ ®−îc vÏ. Trong tr−êng hîp kh¸c, DIB 24 bit chøa c¸c
gi¸ trÞ thùc sù RGB nã x¸c ®Þnh c−êng ®é cña tæ hîp mÇu red, green vµ blue cho mçi
®iÓm ¶nh trong ¶nh. §©y th«ng tin OpenGL ph¶i biÕt vÒ kiÓu DIB tr−íc khi nã cã thÓ
x¸c ®Þnh ra c¸ch ®Ó biÓu diÔn nã nh− thÕ nµo. B¹n cã thÓ ¸p dông nh÷ng g× häc ë ®©y
víi c¸c kiÓu kh¸c cña DIB .
Bëi v× DIB 256 mÇu chøa chØ sè mµu, nã ph¶i ®−îc chuyÓn ®æi thµnh ®Þnh
d¹ng RGB theo trËt tù cho OpenGL ®Ó biÓu diÔn nã trong chÕ ®é mµu RGBA. §iÒu
nµy ®−îc thùc hiÖn theo c¸c b−íc :
1. N¹p DIB v¸o bé nhí
2. T¹o b¶ng mÇu red, green vµ blue tõ b¶ng mÇu cña RGB
3. Gäi hµm glPixelMapv( ) ®Ó ®−a b¶ng mµu tíi OpenGL
4. Gäi hµm glPixelTransferi() ®Ó ®Æt OpenGL tíi chÕ ®é ¸nh x¹ mÇu.
8.2. T¹o lËp b¶ng mÇu
Víi líp CDib ®· ph¸t triÓn trong ch−¬ng nµy, n¹p mét DIB vµo bé nhí, ®¬n
gi¶n gäi cÊu tö CDib víi tªn file. LÊy con trá tíi b¶ng mÇu cña DIB dÔ dµng, yªu cÇu
chØ gäi hµm thµnh viªn cña líp Cdib lµ GetDibRGBTablePtr(). Trong tr×nh tù sö
dông DIB víi OpenGL, b¹n ph¶i t¹o 3 b¶ng mÇu _ mét cho mçi mÇu red, green, blue
®Ó OpenGL cã thÓ gäi c¸c gi¸ trÞ cÇn ®Ó biÓu diÔn mçi ®iÓm ¶nh trong ¶nh.
D÷ liÖu ¶nh cña DIB chøa c¸c chØ sè mÇu trong b¶ng mÇu cña DIB, b¶ng mÇu
chøa c¸c gi¸ trÞ RGB cho mçi mÇu trong 256 mÇu mµ ¶nh sö dông. Nã sÏ lín nÕu b¹n
cã thÓ sö dông c¸c gi¸ trÞ RGB trùc tiÕp khi x©y dùng b¶ng mÇu OpenGL. Kh«ng
may, b¶ng mÇu cña DIB sö dông c¸c sè nguyªn tõ 0 ®Õn 255 ®Ó biÓu diÔn mµu,
nh−ng tr¸i l¹i OpenGL chê ®îi b¶ng mÇu víi c¸c gi¸ trÞ chÊm ®éng cã d¶i tõ 0.0 tíi
1.0. May m¾n viÖc chuyÓn c¸c gi¸ trÞ RGB cña DIB tíi c¸c gi¸ trÞ mÇu OpenGL dÔ
dµng h¬n c¶ b¹n mong chê. Hµm sau lµm c«ng viÖc nµy:
void CreateColorTable(CDib * pDib)
{
LPRGBQUAD pColorTable = pDib GetDibRGBTablePtr( );
for (UINT i=0; i<256; i++)
{
red[i] = (GLfloat) pColorTable[i].rgbRed/255;
green[i] = (GLfloat) pColorTable[i].rgbGreen/255;
blue[i] = (GLfloat) pColorTable[i].rgbBlue/255;
}
}
KÕt qu¶ tÝnh to¸n ®−îc l−u trong b¶ng mÇu red[], green[] vµ blue[] lµ c¸c m¶ng 256
phÇn tö cã gi¸ trÞ GLfloat.
_ 63 _
§å ho¹ 3D víi OpenGL
VÝ dô :
BITMAPHEADER
0 0 0 0 0.0000 0.0000 0.0000 0
PALETTE
32 0 0 1 0.12549 0.0000 0.0000 1
54 25 0 2 0.21176 0.09804 0.0000 2
54 64 12 3 0.21176 0.25098 0.04706 3
2
255
254
Tªn h»ng M« t¶
GL_PIXEL_MAP_A_TO_A B¶n ®å thµnh phÇn Alpha tíi thµnh phÇn Alpha
GL_PIXEL_MAP_B_TO_B B¶n ®å thµnh phÇn Blue tíi thµnh phÇn Blue
GL_PIXEL_MAP_G_TO_G B¶n ®å thµnh phÇn Green tíi thµnh phÇn Green
GL_PIXEL_MAP_I_TO_A ChØ sè mµu tíi thµnh phÇn Alpha
_ 64 _
§å ho¹ 3D víi OpenGL
_ 65 _
§å ho¹ 3D víi OpenGL
_ 66 _
§å ho¹ 3D víi OpenGL
Hµm glTexImage2D() b¶o víi OpenGL t×m texture mµ b¹n muèn sö dông ë
®©u. §èi môc ®Çu tiªn ph¶i lµ GL_TEXTURE_2D. §èi môc thø hai lµ møc ®é chi
tiÕt, chØ ®−îc sö dông víi ¶nh texture kÐp (¸nh x¹ kÐp). Trõ khi b¹n ®ang sö dông ¶nh
kÐp víi c¸c kÝch th−íc thay ®æi cho mçi texture th× ®Æt 0 cho ®èi môc nµy. §èi môc
thø ba ®−a ra sè thµnh phÇn mÇu trong texture, v× trong tr−êng hîp nµy b¹n ®ang lµm
viÖc víi ¶nh RGB nªn gi¸ trÞ nµy lµ 3.
§èi môc thø t− vµ thø n¨m lµ chiÒu réng vµ chiÒu cao cña texture. §èi môc thø
s¸u x¸c ®é réng cña biªn texture vµ ph¶i lµ 1 vµ 0. Víi gi¸ trÞ chuÈn, b¹n sÏ sö dông
gi¸ trÞ 0. §èi môc thø b¶y cho ®Þnh d¹ng d÷ liÖu ¶nh Texture. Bëi v× d÷ liÖu ¶nh DIB
®Æc tr−ng bëi chØ sè mµu nªn ®èi môc nµy lµ GL_COLOR_INDEX trong vÝ dô trªn.
C¸c gi¸ trÞ cã thÓ cã lµ: GL_ALPHA, GL_BLUE, GL_GREEN, GL_LUMINANCE,
GL_RED, GL_RGB vµ GL_RGBA. Hai ®èi môc cuèi cïng lµ kiÓu d÷ liÖu vµ ®Þa chØ
cña texture.
Sau khi ®−a texture tíi OpenGL, b¹n ph¶i ®Þnh nghÜa c¸c ®Ønh cña ®a gi¸c,
trong khi ë cïng thêi ®iÓm, ph¶i gióp OpenGL x¸c ®Þnh quan hÖ gi÷a c¸c ®Ønh cña ®a
gi¸c vµ c¸c to¹ ®é cña texture nh− thÕ nµo. B¹n lµm viÖc nµy bëi gäi hµm
glTextCoord2f() cho mçi ®Ønh. Hµm cã hai ®èi môc lµ c¸c to¹ ®é texture : S vµ T,
còng gièng nh− X vµ Y.
_ 67 _
§å ho¹ 3D víi OpenGL
Ch−¬ng 10
Sö dông sù pha trén, khö r¨ng c−a vµ s−¬ng mï
1. Sö dông pha trén
Sù pha trén lµ phÐp sö lý cña viÖc phèi hîp mÇu cña ®iÓm ¶nh nguån vµ ®Ých
theo c¸c c¸ch kh¸c nhau cã trËt tù ®Ó t¹o ra c¸c kÕt qu¶ ®Æc biÖt. C¸ch sö dông phæ
biÕn nhÊt cña sù phèi hîp ®Ó t¹o ra c¸c ®èi t−îng trong mê. Khi c¸c ®èi t−îng cã sö
dông sù pha trén ®Ì lªn c¸c ®èi t−îng kh¸c, ®èi t−îng bÞ che cã thÓ hiÖn xuyªn qua
nã. Bëi v× mÇu cña ®iÓm ¶nh nguån vµ mÇu cña ®iÓm ¶nh bÞ che ®−îc phèi hîp (hoÆc
®−îc pha trén) ®Ó t¹o ra mÇu míi.
B¹n còng cã thÓ sö dông sù pha trén ®Ó ®¹t ®−îc nhiÒu kÕt qu¶ ®Æc biÖt kh¸c
nhau. Mét ch−¬ng tr×nh ®å ho¹ OpenGL cã thÓ sö dông sù phèi hîp ®Ó lµm cho ng−êi
sö dông cã thÓ t¹o c¸c líp cña c¸c mÇu ë trªn mét phÇn cña bøc tranh. OpenGL còng
sö dông sù pha trén ®Ó gi¶i quyÕt c¸c r¨ng c−a trong c¸c ®−êng th¼ng, viÖc xö lý ®ã
®−îc gäi lµ antialiasing.
1.1. C¸c kh¶ n¨ng pha trén
Nh− víi hÇu hÕt c¸c hµm OpenGL ®Æc biÖt, còng nh− chiÕu s¸ng, kiÓm tra ®é
s©u, hoÆc vÏ c¸c d¶i ®−êng th¼ng, ®Çu tiªn b¹n ph¶i lµm cho cã thÓ t¸c ®éng víi sù
pha trén nh− sau:
glEnable(GL_BLEND);
H»ng GL_BLEND b¶o víi OpenGL chÊp nhËn sù pha trén. B¹n cã thÓ sö dông
còng h»ng nµy trong lêi gäi hµm glDisable() ®Ó t¾t sù pha trén nh− sau:
glDisdable(GL_BLEND);
_ 68 _
§å ho¹ 3D víi OpenGL
GL_ONE (1,1,1,1)
GL_ONE_MINUS_DST_ALPHA (1,1,1,1)-(AD,AD,AD,AD)
GL_ONE_MINUS_DST_COLOR (1,1,1,1)-(RD,GD,BD,AD)
GL_ONE_MINUS_SRC_ALPHA (1,1,1,1)-(RS,Gs,BS,AS)
GL_SRC_ALPHA (AS,AS,AS,AS)
GL_SRC_ALPHA_SATURATE (F,F,F,1)
GL_ZERO (0,0,0,0)
KÕt qu¶ c¸c phÐp tÝnh chØ râ c¸c mÇu nguån vµ ®Ých t¸c ®éng s©u s¾c nh− thÕ
nµo, ngo¹i trõ mÇu kÕt thóc. Xem hµm lùa chän sau:
glBlendFunc (GL_ONE, GL_ZERO);
Sù lùa chän nµy cã kÕt qu¶ kh«ng cã sù pha trén bëi v× mÇu nguån hoµn toµn
xo¸ s¹ch mÇu nguån. (C¸c thµnh phÇn mÇu nguån RGBA ®−îc nh©n víi 1, rêi chóng
tù nhiªn, víi c¸c thµnh phÇn ®Ých RGBA d−îc nh©n víi 0 mµ rêi chóng ë 0).
B©y giê, xem sù lùa chän c¸c hµm pha trén chung nhÊt :
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
NÕu b¹n xem b¶ng, b¹n thÊy r»ng GL_SRC_ALPHA cã ý nãi r»ng OpenGL nh©n c¸c
thµnh phÇn mÇu nguån víi c¸c gi¸ trÞ Alpha cña mÇu nguån. NÕu b¹n xem
GL_ONE_MINUS_SRC_ALPHA trong b¶ng ®Ých, b¹n thÊy r»ng víi hµm ®ã gi¸ trÞ
alpha nguån bÞ trõ bëi 1. Råi OpenGL nh©n kÕt qu¶ cña phÐp trõ víi gi¸ trÞ ®Ých
RGBA.
Gi¶ sö ®iÓm ¶nh nguån cã c¸c gi¸ trÞ RGBA (0.7, 0.5, 0.8, 0.6) vµ ®iÓm ¶nh
®Ých ®ã (®iÓm mµ OpenGL sÏ vÏ ®iÓm ¶nh nguån) cã c¸c gi¸ trÞ RGBA (0.6, 0.3, 0.6,
1.0). §Çu tiªn, OpenGL ¸p dông hµm GL_SRC_ALPHA tíi c¸c gi¸ trÞ nguån RGBA,
_ 69 _
§å ho¹ 3D víi OpenGL
cã ý nãi r»ng sÏ nh©n 0,6 lÇn l−ît víi 0.7, 0.5, 0.8 vµ 0.6. KÕt qu¶ nµy ®−îc ®Æt vµo
trong c¸c gi¸ trÞ ®iÓm ¶nh nguån (0.42, 0.3, 0.48, 0.36).
Råi OpenGL ¸p dông hµm GL_ONE_MINUS_SRC_ALPHA víi ®iÓm ¶nh
®Ých. Nã thùc hiÖn viÖc nµy nh− sau : ®Çu tiªn lÊy 1 trõ ®i gi¸ trÞ alpha cña mÇu
nguån, cho kÕt qu¶ 0.4. Råi OpenGL nh©n kÕt qu¶ nµy cíi c¸c thµnh phÇn cña ®iÓm
¶nh nguån víi (0.24, 0.12, 0.24, 0.40).
1- AS = 1- 0.6 = 0.4
=> 0.4x(RS,GS,BS,AS) = 0.4x(0.6,0.3,0.6,1.0) = (0.24, 0.12, 0.24, 0.4)
Nh− b¹n thÊy, sù lùa chän GL_SRC_ALPHA lµm hµm pha trén nguån vµ
GL_ONE_MINUS_SRC_ALPHA lµm hµm pha trén ®Ých, gi¸ trÞ alpha nguån x¸c
®Þnh gi¸ trÞ phÇn tr¨m cña mçi mÇu thµnh phÇn OpenGL ®ã tíi d¹ng mÇu cuèi cïng.
Trong tr−êng hîp mét gi¸ trÞ alpha GL_SRC_ALPHA lµm hµm pha trén nguån vµ
GL_ONE_MINUS_SRC_ALPHA nh− hµm pha trén ®Ých, gi¸ trÞ alpha nguån x¸c
®Þnh gi¸ trÞ phÇn tr¨m cña mçi mÇu thµnh phÇn OpenGL ®ã tíi d¹ng mÇu cuèi cïng.
Trong tr−êng hîp gi¸ trÞ alpha lµ 0.6, tøc lµ 60% cña mÇu ®−îc lÊy tõ mÇu nguån vµ
40% ®−îc lÊy tõ mÇu ®Ých.
Chó ý :
Gi¸ trÞ alpha cao h¬n, mê ®ôc h¬n trë thµnh ®iÓm ¶nh cuèi cïng. B¹n cã thÓ nghÜ gi¸ trÞ
alpha nh− tÝnh mê ®ôc cña h×nh b¹n ®ang vÏ. NÕu b¹n muèn h×nh chØ chÊp nhËn mét phÇn nhá
cña ®èi t−îng bÞ che cã thÓ hiÖn qua, sö dông gi¸ trÞ alpha cao víi c¸c hµm pha trén nguån vµ
®Ých lµ GL_SRC_ALPHA vµ GL_ONE_MINUS_SRC_ALPHA. T−¬ng tù, víi gi¸ trÞ alpha nhá
sÏ cho phÐp nhiÒu ®iÓm ¶nh bÞ che ®−îc thÓ hiÖn qua h¬n, khi gi¸ trÞ alpha b»ng 0 ®èi t−îng
nguån kh«ng ®−îc thÓ hiÖn.
OpenGL lµm nhiÒu phÐp tÝnh d−íi tÊm che ®Ó x¸c ®Þnh mÇu cuèi cïng. C¸c
phÐp to¸n qu¸ ®−îc lµm qu¸ phøc t¹p ®Ó gi¶i thÝch ë ®©y vµ sÏ kh«ng ®Æc biÖt h÷u Ých
víi lËp tr×nh viªn. ChØ cÇn nhí r»ng hÇu hÕt c¸c hµm pha trén nguån vµ ®Ých t−¬ng
øng lµ: GL_SRC_ALPHA vµ GL_ONE_MINUS_SRC_ALPHA.
_ 70 _
§å ho¹ 3D víi OpenGL
Trong ®o¹n m· trªn, c¸c gi¸ trÞ alpha ®−îc OpenGL sö dông trong c¸c hµm pha
trén lµ 0.5, lµ gi¸ trÞ alpha trong lÇn gäi hµm glColor4f() lÇn thø hai. NghÜa lµ trong
vïng mµ hai h×nh ch÷ nhËt ®Ì lªn nhau, mçi mÇu nguån vµ ®Ých cã 50% gi¸ trÞ mÇu
®−îc thÓ hiÖn trong kÕt qu¶ pha trén cuèi cïng. Víi gi¸ trÞ alpha cao h¬n, kÕt qu¶ sÏ
cho h×nh ch÷ nhËt thø hai mê ®ôc h¬n.
_ 71 _
§å ho¹ 3D víi OpenGL
t×nh tr¹ng cña vïng ®Öm s©u, nã kh«ng thÓ gì bá c¸c ®èi t−îng bÞ che khuÊt b¹n
muèn thÓ hiÖn qua c¸c ®èi t−îng trong mê.
§Ó lµm vïng ®Öm s©u thµnh chØ ®äc, b¹n gäi hµm glDepthMask(GL_FALSE);
§èi môc ®¬n GLboolean lµm cho OpenGL cã thÓ hoÆc kh«ng thÓ ghi lªn vïng ®Öm
s©u. Gi¸ trÞ GL_FALSE lµm vïng ®Öm s©u thµnh chØ ®äc, ng−îc l¹i gi¸ trÞ GL_TRUE
kh«i phôc vïng ®Öm s©u thµnh tr¹ng th¸i ®äc vµ ghi.
VÝ dô:
glClearColor(0.3f, 0.3f, 0.3f, 0.0f);
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable (GL_BLEND);
glEnable (GL_LIGHTING);
glEnable (GL_LIGHT0);
glEnable (GL_DEPTH_TEST);
glBlendFunc (GL_ONE, GL_ZERO);
GLfloat lightAmbient[] = {0.1f, 0.1f, 0.1f, 0.0f};
GLfloat lightDiffuse[] = {1.0f, 1.0f, 1.0f, 0.0f};
GLfloat lightSpecular[] = {1.0f, 1.0f, 1.0f, 0.0f};
GLfloat lightPositoin[] = {2.0f, 0.5f, 3.0f, 1.0f};
GLfloat materialSpecular[] = {1.0f, 1.0f, 1.0f, 0.0f};
GLfloat materialSphere1[] = {1.0f, 0.0f, 0.0f, 0.0f};
GLfloat materialSphere2[] = {0.0f, 1.0f, 0.0f, 0.0f};
GLfloat materialCube[] = {1.0f, 1.0f, 0.0f, 0.0f};
glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmbient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDiffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, lightSpecular);
glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
glMaterialfv (GL_FRONT, GL_SPECULAR, materialSpecular);
glMaterialfv (GL_FRONT, GL_SHININESS, 50.0f)
glTranslatef(-1.5f, 0.5f, -0.3f);
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE,
materialSphere1);
auxSolidSphere (0.75);
glDepthMask(GL_FALSE);
glBendFunc(GL_SRC_ALPHA, GL_ONE);
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DUFFUSE,
materialCube);
glTranslatef(-1.0f, 0.0f, -1.5f);
_ 72 _
§å ho¹ 3D víi OpenGL
_ 73 _
§å ho¹ 3D víi OpenGL
GL_SMOOTH_HINT
GL_PERSPECTIVE_CORRECTION_HINT
GL_POINT_SMOOTH_HINT
GL_…_SMOOTH_HINT
§èi môc thø hai x¸c ®Þnh dÊu vÕt lµ : GL_DONT_CARE (®Ó OpenGL lµm
nh÷ng g× nã muèn), GL_FASTEST (nã b¶o víi OpenGL sö dông ph−¬ng thøc nhanh
nhÊt), GL_NICEST (b¶o víi OpenGL sö dông ph−¬ng thøc chÝnh x¸c nhÊt).
_ 74 _
§å ho¹ 3D víi OpenGL
glFogf(GL_FOG_START, 0.0f);
glFogf(GL_FOG_END, 10.0f);
H»ng GL_FOG_START b¶o víi OpenGL r»ng b¹n muèn ®Æt ®iÓm b¾t ®Çu lµm
mê. §èi môc thø hai lµ kho¶ng c¸ch tõ ®iÓm nh×n, mµ tõ ®iÓm ®ã viÖc lµm mê sÏ b¾t
®Çu. H»ng GL_FOG_END b¶o víi OpenGL r»ng b¹n muèn ®Æt ®iÓm cuèi cña viÖc
lµm mê, mµ còng ®−îc biÓu diÔn nh− kho¶ng c¸ch tõ ®iÓm nh×n. B¹n cã thÓ ®Æt c¸c
®iÓm b¾t ®Çu vµ kÕt thóc chØ khi b¹n chän hµm lµm mê GL_LINEAR. Víi c¸c hµm
GL_EXP vµ GL_EXP2 viÖc ®Æt c¸c ®iÓm b¾t ®Çu vµ kÕt thóc lµm mê kh«ng cã kÕt
qu¶. Dï vËy khi sö dông GL_EXP vµ GL_EXP2, b¹n cã thÓ ®Æt mËt ®é cña s−¬ng mï
bëi gäi hµm glFog() víi GL_FOG_DENSITY nh− ®èi môc ®Çu tiªn vµ gi¸ trÞ mËt ®é
cho ®èi môc thø hai.
5.3. §Æt mÇu s−¬ng mï
TiÕp theo b¹n sÏ ®Æt mÇu s−¬ng mï, mµ cã thÓ cã ¶nh h−ëng lín tíi mÇu ®Ých
®−îc sö dông trong khung c¶nh cña b¹n. Trong tr−êng hîp nµy, b¹n sÏ muèn mÇu
s−¬ng tr¾ng hoÆc dÞu, vµ b¹n chän nh− sau:
GLfloat fogColor[] = {0.6f, 0.6f, 0.5f, 1.0f};
glFogfv(GL_FOG_COLOR, fog Color);
Hµm glFogfv (d¹ng kh¸c cña glFog()) ®ßi hái hai ®èi môc. §Çu tiªn lµ tham sè lµm
mê b¹n muèn ®Æt vµ thø hai lµ ®Þa chØ cña m¶ng chøa c¸c gi¸ trÞ ®Æt mÇu s−¬ng mï.
B¹n cã thÓ thÊy vµi kÕt qu¶ l¹ vµ thó vÞ khi sö dông c¸c mÇu s−¬ng kh¸c mÇu tr¾ng.
B¹n sÏ ph¶i thö nghiÖm víi c¸c thiÕt ®Æt s−¬ng mï kh¸c nhau ®Ó ®¸nh gi¸ c¸c kÕt qu¶
cña sù lµm mê.
5.3. §Æt dÊu vÕt s−¬ng mï
glHint (GL_FOG_HINT, GL_DON’T_CARE);
Ghi chó :
TËp s¸ch nµy cã ch−¬ng tr×nh nguån kÌm theo (ch−¬ng tr×nh vÝ dô cho tõng ch−¬ng), nÕu
b¹n cã nhu cÇu xin liªn hÖ :
Vò Lª Huy
§iÖn tho¹i: 04.8774441
§Þa chØ : sè 25 - hÎm 99/1/4 - phè §øc Giang - thÞ trÊn §øc Giang - huyÖn Gia L©m - HN.
_ 75 _
§å ho¹ 3D víi OpenGL
Môc lôc
Ch−¬ng 3 : C¬ së vÒ ®å ho¹ 3D 2
1. §Þnh nghÜa kiÓu d÷ liÖu 2
2. Sö dông to¸n häc ma trËn trong c¸c phÐp biÕn h×nh 4
3. ChuyÓn c¸c to¹ ®é ®Þa ph−¬ng ra to¹ ®é mµn h×nh 8
4. C¸c phÐp biÕn h×nh cho c¸c ®èi t−îng 3D 9
_ 76 _
§å ho¹ 3D víi OpenGL
_ 77 _