Download as pdf or txt
Download as pdf or txt
You are on page 1of 77

§å ho¹ 3D víi OpenGL

Tr−êng §¹i häc B¸ch Khoa Hµ Néi


Khoa C¬ khÝ

(3D Graphics Programming with 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;

§Þnh nghÜa kiÓu d÷ liÖu cho mét h×nh hoµn chØnh :


typedef struct shape
{
int numverts;
VERTEX *vertices;
}SHAPE;

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 :

VERTEX triangleVerts[3] = {2,5,5,2,2,2};


SHAPE shape1 = {3,triangleVerts};
DrawShape(shape1);

void DrawShape(SHAPE & shape1)


{
CClientDC dc(this);
int newX, newY,startX,startY;
RECT clientRect;
GetClientRect(&clientRect);
int maxY=clientRect.bottom;

for (int x=0;x<shape1.numVerts;x++)


{

_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

void Rotate(SHAPE & shape, int degrees)


{
int rotatedX, rotatedY;
double radians = 6.283485308/360.0/degrees;
double c = cos(radians);
double s = sin(radians);
for (int x=0; x<shape.numVerts; x++)
{
rotatedX = (int)(shape.vertices[x].x*c - shape.vertices[x].y*s);
rotatedY = (int)(shape.vertices[x].y*c + shape.vertices[x].x*s);
shapse.vertices[x].x = rotatedX;
shapse.vertices[x].y = rotatedY;
}
}

2. Sö dông to¸n häc Ma trËn trong c¸c phÐp biÕn h×nh


2.1. Sö dông d÷ liÖu Ma trËn cho ®å ho¹ 2D
KiÓu d÷ liÖu cho mét vector :
typedef struct vector
{
int x,y,w;
}VECTOR;
Ma trËn 3x3 sÏ n¾m gi÷ c¸c gi¸ trÞ cÇn thiÕt ®Ó chuyÓn ®æi c¸c ®Ønh, dïng kiÓu d÷
liÖu VECTOR còng lµ mét ma trËn. KiÓu d÷ liÖu cho Ma trËn 3x3 nh− sau :
typedef double MATRIX3X3[3][3];

- Ma trËn dïng cho phÐp tÞnh tiÕn :


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] = xTrans; m[2][1] = yTrans; m[2][2] = 1.0;

- Ma trËn dïng cho phÐp tû lÖ :


MATRIX3X3 m;
m[0][0] = xScaleFactor; m[0][1] = 0.0; m[0][2] = 0.0;
m[1][0] = 0.0; m[1][1] = yScaleFactor; m[1][2] = 0.0;
m[2][0] = 0.0; m[2][1] = 0.0; m[2][2] = 1.0;

- Ma trËn dïng cho phÐp quay :

_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

2.2. Sö dông d÷ liÖu Ma trËn cho ®å ho¹ 2D


§Þnh nghÜa mét ®èi t−îng 3D :
typedef struct vertex
{
int x,y,z,w;
}VERTEX;
//-----------------------
typedef struct edge
{
UINT vertex1,vertex2;
}EDGE;
//-----------------------
// §Þnh nghÜa kiÓu d÷ liÖu cho mét m« h×nh khung d©y
typedef struct model
{
UINT numVerts;
VERTEX * vertices;
UINT numEdges;
EDGE * edges;
}MODEL;

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

3. ChuyÓn c¸c to¹ ®é ®Þa ph−¬ng ra to¹ ®é mµn h×nh


3.1. PhÐp chiÕu song song (Parallel Projection)
Hµm ®Ó vÏ khèi hép sö dông phÐp chiÕu song song nh− sau :
void DrawModel(CDC * pDC, MODEL & model)
{
int newX,newY;
RECT clientRect;
GetClientRect(&clientRect);
int maxY = clientRect.bottom;
for (UINT i=0; i<model.numEdges; i++)
{
UNIT vertNum = model.edges[i].vertex1;
newX=model.vertices[vertNum-1].x;
newY=-model.vertices[vertNum-1].y+maxY-1;
pDC->MoveTo(newX,newY);

vertNum = model.edges[i].vertex2;
newX=model.vertices[vertNum-1].x;
newY=-model.vertices[vertNum-1].y+maxY-1;
pDC->LineTo(newX,newY);
}
}

3.2. PhÐp chiÕu phèi c¶nh (Perspective Projection)


void PersProject(MODEL & model, double eye)
{
for (UINT i=0; i<model.numVerts; i++)
{
int xCoord = model.vertices[i].x;
int yCoord = model.vertices[i].y;
int zCoord = model.vertices[i].z;
double t = 1.0/(1.0-zCoord/eye);
model.vertices[i].x=(int)(xCoord*t);
model.vertices[i].y=(int)(yCoord*t);
}
}

_8_
§å ho¹ 3D víi OpenGL

4. C¸c phÐp biÕn h×nh cho c¸c ®èi t−îng 3D


typedef double MATRIX4X4[4][4];
//-----------------------------------------------------------------
void InitMatrix(MATRIX4X4 & m)
{
m[0][0] = 1.0; m[0][1] = 0.0; m[0][2] = 0.0; m[0][3] = 0.0;
m[1][0] = 0.0; m[1][1] = 1.0; m[1][2] = 0.0; m[1][3] = 0.0;
m[2][0] = 0.0; m[2][1] = 0.0; m[2][2] = 1.0; m[2][3] = 0.0;
m[3][0] = 0.0; m[3][1] = 0.0; m[3][2] = 0.0; m[3][3] = 1.0;
}
//-----------------------------------------------------------------
void CopyMatrix(MATRIX4X4 & dst, MATRIX4X4 & src)
{
for (int i=0 ; i<4 ; i++)
for (int j=0 ; j<4 ; j++)
dst[i][j]=src[i][j];
}
//-----------------------------------------------------------------
void MultMatrix(MATRIX4X4 & product,
MATRIX4X4 & matrix1, MATRIX4X4 & matrix2)
{
for (int x=0 ; x<4 ; x++)
for (int y=0 ; y<4 ; y++)
{
double sum = 0;
for (int z=0 ; z<4 ; z++)
sum += matrix1[x][z]*matrix2[z][y];
product[x][y]=sum;
}
}
//-----------------------------------------------------------------
void Transtate(MATRIX4X4 & m, int xTrans, int yTrans, int zTrans)
{
MATRIX4X4 m1,m2;
m1[0][0] = 1.0; m1[0][1] = 0.0; m1[0][2] = 0.0; m1[0][3] = 0.0;
m1[1][0] = 0.0; m1[1][1] = 1.0; m1[1][2] = 0.0; m1[1][3] = 0.0;
m1[2][0] = 0.0; m1[2][1] = 0.0; m1[2][2] = 1.0; m1[2][3] = 0.0;
m1[3][0] = xTrans; m1[3][1] = yTrans; m1[3][2] = zTrans; m1[3][3] = 1.0;
MulMatrix(m2,m1,m);

_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

2. Ng÷ c¶nh diÔn t¶ (rendering context)


Cã 5 hµm "WGL" ®−îc cung cÊp trong triÓn khai OpenGL trong WindowNT
chÞu tr¸ch nhiÖm qu¶n lý c¸c ng÷ c¶nh diÔn t¶ :
Tªn hµm Sö dông
wglCreateContext() t¹o lËp mét ng÷ c¶nh diÔn t¶ míi.
wglDeleteContext() xo¸ bá mét ng÷ c¶nh diÔn t¶.
wglGetCurrentContext() tr¶ vÒ mét ®iÒu khiÓn tíi ng÷ c¶nh diÔn t¶ hiÖn thêi.
wglGetCurrnetDC() lÊy ®iÒu khiÓn tíi DC céng t¸c víi ng÷ c¶nh diÔn t¶
hiÖn thêi.
wglMakeCurrent() ®−a mét ng÷ c¶nh diÔn t¶ thµnh hiÖn hµnh.

_ 12 _
§å ho¹ 3D víi OpenGL

3. C¸c ®Þnh d¹ng ®iÓm ¶nh


Tr−íc khi ch−¬ng tr×nh cña b¹n cã thÓ t¹o lËp mét ng÷ c¶nh diÔn t¶, nã ph¶i
®Æt ®Þnh d¹ng ®iÓm ¶nh cña thiÕt bÞ mµ nã chøa c¸c thuéc tÝnh cho bÒ mÆt vÏ cña
thiÕt bÞ. C¸c thuéc tÝnh nµy ®−îc gép vµo trong bÒ mÆt vÏ sö dông chÕ ®é mÇu RGBA
hoÆc chØ sè, hoÆc vïng ®Öm ®iÓm ¶nh sö dông vïng ®Öm ®¬n hay kÐp, sè bit mÇu, sè
bit ®−îc sö dông trong c¸c vïng ®Öm s©u vµ khung t«, vµ c¸c th«ng tin ®å ho¹ kh¸c
cña OpenGL.
C¸c hµm Win32 qu¶n lý c¸c ®Þnh d¹ng ®iÓm ¶nh :

Tªn hµm Sö dông


ChoosePixelFormat() tr¶ l¹i ®Þnh d¹ng ®iÓm ¶nh bÞ ®ãng cuèi cïng khi ®Æt
mét ®Þnh d¹ng míi.
DescriblePixelFormat() thu ®−îc th«ng tin vÒ ®Þnh d¹ng ®iÓm ¶nh.
GetPixelFormat() LÊy ®Þnh d¹ng ®iÓm ¶nh cña ng÷ c¶nh thiÕt bÞ.
SetPixelFormat() §Æt mét ®Þnh d¹ng ®iÓm ¶nh cña ng÷ c¶nh thiÕt bÞ.

4. CÊu tróc PIXELFORMATDESCRIPTOR


Mçi thiÕt bÞ thÓ hiÖn OpenGL cung cÊp mét sè chØ ®Þnh cña c¸c ®Þnh d¹ng
®iÓm ¶nh. C¸c ®Þnh d¹ng ®iÓm ¶nh s½n cã cña chóng lµ c¸c kh¶ n¨ng thÓ hiÖn c¬ së.
Thuéc tÝnh cña mét ®Þnh d¹ng ®iÓm ¶nh ®−îc m« t¶ chi tiÕt bëi cÊu tróc
PIXELFORMATDESCRIPTOR, nã cã 26 th−ê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;

_ 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¶

nSize KÝch th−íc theo byte cña cÊu tróc


nVersion Sè phiªn b¶n cña cÊu tróc, mÆc ®Þnh lµ 1
dwFlag C¸c cê ®Æc tÝnh cho ®Þnh d¹ng ®iÓm ¶nh. C¸c cê bit cã thÓ ®−îc
sö dông lµ : PFD_DRAW_TO_BITMAP
PFD_DRAW_TO_WINDOW
PFD_DOUBLEBUFFER
PFD_GENERIC_FORMAT
PFD_NEED_PALETTE
PFD_NEED_SYSTEM_PALETTE
PFD_STEREO
PFD_SUPPORT_GDI
PFD_SUPPORT_OPENGL
iPixelType M« t¶ d÷ liÖu mÇu cña mét ®iÓm ¶nh. Ph¶i lµ
PFD_TYPE_RGBA (cho chÕ ®é mÇu RGBA) hoÆc
PFD_TYPE_INDEX (cho chÕ ®é chØ sè mÇu).

_ 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 cê ®Æc tÝnh ®Þnh d¹ng ®iÓm ¶nh :

Cê ®Æc tÝnh M« t¶

PFD_DRAW_TO_BITMAP øng dông cã thÓ vÏ tíi mét bitmap trong


ng÷ c¶nh thiÕt bÞ bé nhí
PFD_DRAW_TO_WINDOW øng dông cã thÓ vÏ trªn cöa sæ mµn h×nh
hoÆc mét vµi thiÕt bÞ kh¸c
PFD_DOUBLEBUFFER NÕu ®Æt, lùa chän vïng ®Öm kÐp
PFD_GENERIC_FORMAT NÕu ®Æt, lùa chän ®Þnh d¹ng ®iÓm ¶nh
chung, ®−îc cung cÊp bëi GDI
PFD_NEED_PALETTE NÕu ®Æt, b¶ng mÇu logic ®−îc yªu cÇu
PFD_NEED_SYSTEM_PALETTE NÕu ®Æt, hÖ thèng sö dông phÇn cøng
OpenGL ®−îc cung cÊp chØ bëi mét b¶ng
mÇu phÇn cøng.
PFD_STEREO NÕu ®Æt, lùa chän vïng ®Öm lËp thÓ.
Kh«ng cung cÊp trong WindowNT.
PFD_SUPPORT_GDI NÕu ®Æt, vïng ®Öm cung cÊp c¸c chøac
n¨ng vÏ GDI. Kh«ng ®−îc sö dông víi cê
PFD_DOUBLEBUFFER
PFD_SUPPORT_OPENGL NÕu ®Æt, vïng ®Öm cung cÊp c¸c chøc
n¨ng vÏ OpenGL.

5. Khëi t¹o cÊu tróc PIXELFORMATDESCRIPTOR


CÊu tróc phøc t¹p vµ ®ßi hái sù hiÓu biÕt thÊu ®¸o vÒ OpenGL vµ khiÓn khai
cña nã trong WindowNT. C¸c gi¸ trÞ mÆc ®Þnh ®Ó lµm viÖc tèt trªn tÊt c¶ c¸c hÖ thèng
nh− sau :
PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR), //kÝch th−íc cÊu tróc
1, //sè phiªn b¶n
PFD_DRAW_TO_WINDOW | //c¸c cê ®Æc tÝnh
PFD_SUPPORT_OPENGL|PFD_TYPE_RGBA,
24, //dïng 24 bit mÇu
0,0,0,0,0,0, //kh«ng sö dông chóng

_ 16 _
§å ho¹ 3D víi OpenGL

0,0,0,0,0,0,0, //kh«ng vïng ®Öm alpha


//hoÆc accum
32, //32 nit vïng ®Öm s©u
0,0, //kh«ng vïng ®Öm khung
//hoÆc vïng ®Öm phô
PFD_MAIN_PLANE, //kiÓu líp chÝnh
0, //dù tr÷
0,0,0 //kh«ng ®−îc cung cÊp
};

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æ.

5.1. ThiÕt ®Æt mét ®Þnh d¹ng ®iÓm ¶nh


Mét khi b¹n cã cÊu tróc PIXELFORMATDESCRIPTOR ®· khëi t¹o, b¹n cã
thÓ thiÕt ®Æt mét ®Þnh d¹ng ®iÓm ¶nh. §o¹n m· sau trÝch tõ mét ch−¬ng tr×nh MFC
thÓ hiÖn c¸ch lµm viÖc nh− thÕ nµo :
CClientDC clientDC(this);
int pixelFormat = ChoosePixelFormat(clientDC.m_hDC,&pfd);
BOOL success = SetPixelFormat(clientDC.m_hDC,pixelFormat,&pfd);
Trong dßng ®Çu tiªn, ch−¬ng tr×nh lÊy mét DC cho vïng lµm viÖc cña cöa sæ
øng dông.
Dßng thø 2 gäi tíi ChoosePixelFormat() råi yªu cÇu mét chØ sè ®Þnh d¹ng
®iÓm ¶nh cho mét ®Þnh d¹ng ®iÓm ¶nh gÇn nhÊt lµm thµnh ®Þnh d¹ng yªu cÇu. Hai
®èi môc cña hµm nµy lµ mét ®iÒu khiÓn tíi DC cho lùa chän ®Þnh d¹ng ®iÓm ¶nh vµ
®Þa chØ cña cÊu tróc PIXELFORMATDESCRIPTOR n¾m gi÷ c¸c thuéc tÝnh cña ®Þnh
d¹ng ®iÓm ¶nh yªu cÇu. NÕu hµm gäi sai, ChoosePixelFormat() tr¶ l¹i 0, ng−îc l¹i nã
tr¶ l¹i chØ sè ®Þnh d¹ng ®iÓm ¶nh.
Dßng thø 3 trong ®o¹n m· ®¬n gi¶n gäi SetPixelFormat() ®Ó ®Æt ®Þnh d¹ng
®iÓm ¶nh. Ba ®èi môc cña hµm nµy lµ ®iÒu khiÓn tíi DC, chØ sè ®Þnh d¹ng ®iÓm ¶nh
vµ ®Þa chØ cña cÊu tróc PIXELFORMATDESCRIPTOR. Hµm tr¶ l¹i gi¸ trÞ TRUE
nÕu thµnh c«ng, ng−îc l¹i nã tr¶ l¹i FALSE.

5.2. §Õm c¸c ®Þnh d¹ng ®iÓm ¶nh


Chó ý r»ng, hµm ChoosePixelFormat() tr¶ l¹i chØ sè tíi ®Þnh d¹ng ®iÓm ¶nh ®ã
lµm cho phï hîp nhÊt víi ®Þnh d¹ng yªu cÇu. Trong nhiÒu ch−¬ng tr×nh, sù b¸o tr−íc
nµy kh«ng nÈy sinh vÊn ®Ò g×, tuy nhiªn b¹n kh«ng ch¾c ch¾n vÒ ®Þnh d¹ng cña ®iÓm
¶nh mµ b¹n ®· ®Æt khi b¹n kiÓm tra ®Þnh d¹ng ®ã cã phï hîp víi ch−¬ng tr×nh cña
b¹n hay kh«ng. May m¾n lµ hµm DescriblePixelFormat() cã thÓ gióp b¹n kiÓm tra bÊt

_ 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.

6. T¹o lËp mét ng÷ c¶nh m« t¶ (Rendering context)


Nh− ®· nãi trªn, b¹n ph¶i t¹o lËp vµ lµm hiÖn hµnh mét ng÷ c¶nh m« t¶ tr−íc
khi b¹n cã thÓ vÏ trªn cöa sæ víi c¸c hµm OpenGL. Phô thuéc vµo c¸c yªu cÇu cña
ch−¬ng tr×nh cña b¹n, cã hai kü thuËt b¹n cã thÓ sö dông ®Ó qu¶n lý ng÷ c¶nh diÔn t¶:
- T¹o lËp vµ lµm hiÖn hµnh nã trong lêi ®¸p th«ng ®iÖp WM_CREATE. Xo¸ bá
ng÷ c¶nh diÔn t¶ vµ lµm cho nã kh«ng cßn lµ hiÖn hµnh ®−îc gäi trong lêi ®¸p th«ng
®iÖp WM_DESTROY.
- T¹o lËp ng÷ c¶nh diÔn t¶ trong lêi ®¸p th«ng ®iÖp WM_CREATE, nh−ng chØ
lµm nã thµnh hiÖn hµnh khi b¹n thùc sù vÏ víi OpenGL, vµ lµm nã thµnh kh«ng hiÖn
hµnh ngay lËp tøc sau khi hoµn thµnh viÖc vÏ víi OpenGL. Xo¸ bá ng÷ c¶nh diÔn t¶
trong lêi ®¸p th«ng ®iÖp WM_DESTROY.

_ 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.

6.1. Ph−¬ng thøc t¹o lËp ng÷ c¶nh diÔn t¶ 1


Mçi kü thuËt qu¶n lý ng÷ c¶nh diÔn t¶ cã nh÷ng thuËn lîi vµ khã kh¨n riªng
cña nã. ThuËn lîi cña ph−¬ng ph¸p ®Çu lµ ch−¬ng tr×nh cña b¹n chØ cÇn lµm ng÷ c¶nh
diÔn t¶ thµnh hiÖn hµnh chØ mét lÇn. Bëi v× viÖc lµm ng÷ c¶nh diÔn t¶ thµnh hiÖn hµnh
mÊt nhiÒu thêi gian xö lý, nªn ph−¬ng ph¸p ®Çu cã thÓ lµm ch−¬ng tr×nh cña b¹n ®¸p
øng nhanh lÑ h¬n th«ng ®iÖp WM_PAINT. Kh«ng thuËn lîi cña ph−¬ng ph¸p lµ b¹n
ph¶i gi÷ l¹i DC cho toµn bé ch−¬ng tr×nh khi ch¹y. Còng vËy, ch−¬ng tr×nh Visual
C++ t¹o lËp víi AppWizard kh«ng xem ®Æc tÝnh hµm sö dông ph−¬ng ph¸p nµy.

6.2. Ph−¬ng thøc t¹o lËp ng÷ c¶nh diÔn t¶ 2


Trong ph−¬ng ph¸p thø hai cña viÖc qu¶n lý ng÷ c¶nh diÔn t¶, ch−¬ng tr×nh t¹o
lËp vµ gì bá DC cña Window mçi lÇn ch−¬ng tr×nh ph¶i vÏ lªn cö sæ, do ®ã ch−¬ng
tr×nh kh«ng cÇn ph¶i gi÷ DC cho toµn ch−¬ng tr×nh trong lóc ch¹y. Mçi lÇn ch−¬ng
tr×nh t¹o lËp DC, dï sao, nã còng ph¶i n¾m ng÷ c¶nh diÔn t¶ thµnh hiÖn hµnh.
Mét c¸c triÓn khai cña ph−¬ng ph¸p thø hai cña viÖc qu¶n lý ng÷ c¶nh diÔn t¶
trong ch−¬ng tr×nh MFC cã thÓ gièng nh− sau :

int CChapter4View::OnCreate(LPCREATESTRUCT lpCreateStruct)


{
if (CView::OnCreate(lpCreateStruct) == -1) return -1;

// TODO: Add your specialized creation code here


PIXELFORMATDESCRIPTOR pfd=
{
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW |
PFD_SUPPORT_OPENGL|PFD_TYPE_RGBA,
24,
0,0,0,0,0,0,
0,0,0,0,0,0,0,
32,

_ 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.

7. C¸c hµm ng÷ c¶nh diÔn t¶ kh¸c


Trong ®o¹n m· vÝ dô trªn, b¹n ®· thÊy ®−îc c¸ch sö dông c¸c hµm
wglCreateContext(), wglDeleteContext() vµ wglMakeCurrent(). B¹n kh«ng thu ®−îc
bÊt kú kinh nghiÖm g× víi wglGetCurrentContext() vµ wglGetCurrentDC(), cã thÓ
gióp b¹n t×m l¹i th«ng tin vÒ ng÷ c¶nh diÔn t¶ vµ thiÕt bÞ. Lêi gäi hµm
wglGetCurrentContext() cã thÓ nh− sau :
HGLRC hRC = wglGetCurrentContext();
NÕu thµnh c«ng, hµm nµy tr¶ l¹i ®iÒu khiÓn tíi ng÷ c¶nh diÔn t¶ hiÖn hµnh, ng−îc l¹i
nã tr¶ l¹i NULL.
B¹n gäi hµm wglGetCurrentDC() nh− sau :
HDC hDC = wglGetCurrentDC();
NÕu thµnh c«ng, nã tr¶ l¹i ®iÒu khiÓn tíi ng÷ c¶nh thiÕt bÞ bao lÊy ng÷ c¶nh diÔn t¶
hiÖn hµnh, c¸c tr−êng hîp kh¸c cho l¹i 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

1. Có ph¸p cña c¸c hµm OpenGL


OpenGL cã h¬n 100 hµm kh¸c nhau, tÊt c¶ chóng b¾t ®Çu b»ng c¸c tiÒn tè lµ
gl. C¸c hµm OpenGL víi c¸c hËu tè kh¸c nhau phô thuéc vµo kiÓu tham sè mµ chóng
cã thÓ chÊp nhËn.
VÝ dô lÖnh glVertex cã 24 d¹ng :
glVertex2d() glVertex2f() glVertex3d() glVertex3f()
glVertex4d() glVertex4f() glVertex2i() glVertex2s()
glVertex3i() glVertex3s() glVertex4i() glVertex4s()
glVertex2dv() glVertex2fv() glVertex3dv() glVertex3fv()
glVertex4dv() glVertex4fv() glVertex2iv() glVertex2sv()
glVertex3iv() glVertex3sv() glVertex4iv() glVertex4sv()
hËu tè v chØ r»ng ®èi môc cho lÖnh hoÆc hµm ®−îc gäi cho trong mét vector.

C¸c hËu tè cña lÖnh 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

bv GLbyte cho trong 1 vector


dv GLdouble hoÆc GLclampd cho trong 1 vector
fv GLfloat hoÆc GLclampf cho trong 1 vector
iv GLint hoÆc GLsizei cho trong 1 vector
sv GLshort cho trong 1 vector
ubv GLubyte hoÆc GLboolean cho trong 1 vector
uiv GLuint , GLenum , GLbitfield cho trong 1 vector
usv GLushort cho trong 1 vector

2. OpenGL vµ c¸c tr¹ng th¸i


M«i tr−êng OpenGL mµ b¹n ®Æt trong ch−¬ng tr×nh cña b¹n duy tr× mét tr¹ng
th¸i x¸c ®Þnh. VÝ dô khi b¹n ®Æt mÇu vÏ víi glColor(), mÇu ®ã ®−¬c duy tr× trong kÕt
qu¶ cho tíi khi b¹n gäi glColor() l¹i lÇn n÷a ®Ó thay ®æi nã. §©y lµ gîi ý cho tÊt c¶
c¸c ch−¬ng tr×nh Windows, bëi v× ng÷ c¶nh thiÕt bÞ lµm viÖc t−¬ng tù. Khi b¹n chän
mét bót trong mét ng÷ c¶nh thiÕt bÞ, tÊt c¶ c¸c ®−êng ®−îc vÏ sÏ cã ®é réng vµ mÇu
cña bót ®· ®−îc chän. DÊu vÕt bót ®−îc gi÷ l¹i trong kÕt qu¶ cho tíi khi nã ®−îc thay
thÕ bëi mét bót míi.
C¸c thuéc tÝnh biÕn thÓ ®Ó t¹o tr¹ng th¸i cña OpenGL ®−îc l−u trong c¸c biÕn
m«i tr−êng. T¹o nã dÔ dµng ®Ó cã kÕt qu¶ nhanh chãng trong mét ch−¬ng tr×nh
OpenGL, tÊt c¶ c¸c biÕn tr¹ng th¸i cã mét tr¹ng th¸i mÆc ®Þnh, nã ®Ó l¹i kÕt qu¶ cho
tíi khi b¹n gäi hµm dµnh riªng ®Ó thay ®æi thuéc tÝnh x¸c ®Þnh. VÝ dô, mÇu xo¸ (mµ
biÕn tr¹ng th¸i cña nã ®−îc tham kh¶o bëi h»ng GL_COLOR_CLEAR_VALUE) cã
gi¸ trÞ mÆc ®Þnh lµ ®en vµ mÇu vÏ (biÕn tr¹ng th¸i cña nã ®−îc tham kh¶o bëi
GL_CURRENT_COLOR) cã gi¸ trÞ mÆc ®Þnh lµ tr¾ng.
OpenGL cã tÊt c¶ 200 biÕn tr¹ng th¸i.

2.1. Th¨m l¹i ch−¬ng tr×nh OpenGL tèi thiÓu


Trong ch−¬ng 4, "ch−¬ng tr×nh OpenGL tèi thiÓu", b¹n ®· viÕt mét ch−¬ng
tr×nh nhá kh«ng lµm viÖc g× nhiÒu h¬n viÖc vÏ mét ®−êng th¼ng trong vïng lµm viÖc
cña cöa sæ. Trong suèt ch−¬ng tr×nh, ®Æt ®Þnh d¹ng ®iÓm ¶nh cña cöa sæ vµ t¹o lËp
mét ng÷ c¶nh diÔn t¶, tÊt c¶ c¸c hµm OpenGL thùc cña ch−¬ng tr×nh ®−îc gäi trong
hµm DrawWithOpenGL(), nã tr«ng nh− sau :
void CChapter4View::DrawWithOpenGL()
{
glClearColor(0.0f,0.0f,1.0f,0.0f);

_ 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.

2.2. §Æt mÇu xo¸


Trong dßng ®Çu tiªn cña DrawWithOpenGL(), ch−¬ng tr×nh gäi glClearColor()
®Ó ®Æt chÕ ®é mÇu RGBA ®−îc sö dông ®Ó xo¸ nÒn cña ¶nh OpenGL. Hµm nµy sö 4
®èi môc, chóng lµ c¸c gi¸ trÞ GLclampf ®Æc tr−ng bëi riªng tõng c¸c mÇu : ®á, xanh
l¸ c©y, xanh da trêi (red, green, blue) vµ c¸c thµnh phÇn alpha.
Khi trong chÕ ®é mÇu RGBA, c¸c mÇu trong OpenGL, chØ gièng c¸c mÇu
trong Windows, ®−îc ®Æc tr−ng bëi c¸c gi¸ trÞ ®á, xanh l¸ c©y, xanh da trêi, chóng
®−îc tæ hîp ®Ó t¹o thµnh mÇu yªu cÇu. Trong OpenGL, sù tæ hîp c¸c gi¸ trÞ ®á, xanh
l¸ c©y, xanh da trêi cña mét mÇu cã thÓ lµ c¸c gi¸ trÞ tõ 0.0 tíi 1.0, víi 1.0 lµ c−êng
®é mÇu cao nhÊt cã thÓ cña thµnh phÇn ®ã. Do ®ã, gäi glClearColor() trong
DrawWithOpenGL() ®Æt mÇu xo¸ lµ mÇu ®en bëi v× c¶ 3 thµnh phÇn mÇu ®Òu ®−îc
®Æt víi c−êng ®é thÊp nhÊt lµ 0.0. Thay ®æi tÊt c¶ c¸c gi¸ trÞ trong hµm tíi 1.0 sÏ ®Æt
mÇu xo¸ thµnh mÇu tr¾ng, còng vËy khi ®Æt thµnh phÇn ®á lµ 0.0, xanh l¸ c©y lµ 0.0,
xanh da trêi lµ 1.0 sÏ ®Æt mÇu xo¸ thµnh xanh da trêi.
Víi thµnh phÇn alpha ®−îc cho lµ ®èi môc thø 4 trong lêi gäi hµm
glClearColor() lµ g× ? OpenGL sö dông thµnh phÇn alpha cho kÕt qu¶ x¸c ®Þnh sù pha
trén mÇu. MÆc ®Þnh, gi¸ trÞ alpha kh«ng cã kÕt qu¶ trong mÇu ®−îc ®Æt.

2.3. Xo¸ vïng ®Öm mÇu


Dßng thø 2 trong DrawWithOpenGL() xo¸ vïng ®Öm mÇu víi mÇu xo¸ hiÖn
hµnh. Hµm glClear() lÊy mét tham sè ®¬n lµ mét dÉy c¸c cê bit chØ ra c¸c vïng ®Öm
®Ó xo¸. Hµm kh«ng tr¶ l¹i g×. Vïng ®Öm mÇu (chØ ra bëi cê hiÖu
GL_COLOR_BUFFER_BIT) lµ vïng nhí n¾m gi÷ ¶nh thËt ®−îc biÓu diÔn lªn mµn
h×nh. OpenGL sö dông c¸c kiÓu kh¸c cña vïng ®Öm, bao gåm vïng ®Öm s©u vµ vïng
®Öm khung trî gióp viÖc sö lý ¶nh.

_ 24 _
§å ho¹ 3D víi OpenGL

2.4. §Æt mÇu vÏ hiÖn hµnh


TiÕp theo gäi hµm glColor3f() trong DrawWithOpenGL() ®Æt mÇu vÏ hiÖn
hµnh. Ba ®èi môc cña hµm (kiÓu cña ®èi môc ®−îc chØ ra bëi hËu tè 3f) lµ c¸c gi¸ trÞ
GLfloat x¸c ®Þnh c¸c thµnh phÇn mÇu : ®á, xanh l¸ c©y, xanh da trêi cña mÇu cÇn ®Æt.
Cã 32 phiªn b¶n cña hµm glColor(), phô thuéc vµo kiÓu ®èi môc ®Ó x¸c ®Þnh hËu tè
cña hµm.
Sau khi ®Æt mÇu vÏ, bÊt kú ®èi t−îng nµo ®−îc t¹o bëi OpenGL sÏ ®−îc vÏ víi
mÇu ®· chän. Nh− b¹n ®· ®äc khi häc vÒ c¸c biÕn tr¹ng th¸i cña OpenGL, mÇu nµy
sÏ tån t¹i cho tíi khi b¹n thay ®æi nã víi lêi gäi hµm glColor() kh¸c.

2.5. §Þnh nghÜa mét h×nh thÓ


Tr−íc khi b¹n cã thÓ ra lÖnh cho OpenGL vÏ h×nh, b¹n ph¶i b¶o víi OpenGL
vÒ h×nh sÏ vÏ nh− thÕ nµo. B¹n thùc hiÖn viÖc nµy bëi viÖc ®Þnh nghÜa c¸c ®Ønh cho
®èi t−îng, viÖc nµy cïng víi c¸ch b¹n ®· häc trong ch−¬ng 2. Sù kh¸c nhau chÝnh lµ
b¹n sÏ kh«ng sö dông kiÓu d÷ liÖu cña chÝnh b¹n t¹o ra còng nh− VERTEX vµ
MODEL ®Ó ddÞnh nghÜa ®èi t−îng. Thay vµo ®ã, b¹n sÏ sö dông c¸c lÖnh glBegin(),
glVertex() vµ glEnd() cña OpenGL.
Trong hµm DrawWithOpenGL(), ch−¬ng tr×nh gäi glBegin(GL_LINES) ®Ó b¾t
®Çu ®Þnh nghÜa mét h×nh. Trong tr−êng hîp nµy, h×nh sÏ vÏ lµ mét ®−êng th¼ng ®−îc
chØ ra bëi cê hiÖu GL_LINES. C¸c cê hiÖu kh¸c b¹n sÏ sö dông víi glBegin() lµ :
GL_POINT GL_LINES_STRIP GL_LINES_LOOP
GL_TRIANGLES GL_TRIANGLE_STRIP GL_TRIANGLE_FAN
GL_QUADS GL_QUAD_STRIP GL_POLYGON
Bëi v× mét ®−êng th¼ng cã 2 ®Ønh (mét cho ®iÓm cuèi), sau khi gäi hµm
glBegin(), DrawWithOpenGL() cã hai lÇn gäi tíi glVertex(). Hµm glVertex2f() ®Þnh
nghÜa mét ®Ønh, sö dông hai ®èi môc kiÓu GLfloat ®¨c tr−ng cho to¹ ®é X vµ Y cña
mét ®Ønh. Cã 24 phiªn b¶n cña hµm glVertex(), víi hËu tè phô thuéc vµo kiÓu cña ®èi
môc ®−îc sö dông.
C¸c h×nh phøc t¹p h¬n còng nh− c¸c ®a gi¸c yªu cÇu nhiÒu lÇn gäi tíi
glVertex() ®Ó ®Þnh nghÜa c¸c ®Ønh t¹o nªn h×nh d¹ng cña chóng. Khi b¹n ®Þnh nghÜa
c¸c ®å häa phøc t¹p, b¹n sÏ thÊy nh÷ng øng dông ®ßi hái danh s¸ch rÊt dµi c¸c ®Ønh,
®−îc ®Æt vµo gi÷a c¸c cÆp glBegin() vµ glEnd(). VÝ dô, ®Ó ®Þnh nghÜa 4 ®−êng th¼ng
x¸c ®Þnh mét h×nh ch÷ nhËt, b¹n cã thÓ viÕt nh− sau :
glBegin();
glVertex2f(0.0f,0.0f);
glVertex2f(1.0f,0.0f);
glVertex2f(0.0f,0.0f);

_ 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è.

2.6. §¶m b¶o thao t¸c vÏ ®−îc hoµn thiÖn


Sao cho, ch−¬ng tr×nh cã ®Æt mÇu xo¸, mÇu nÒn, xo¸ nÒn, ®Æt mÇu vÏ vµ ®Þnh
nghÜa mét ®−êng th¼ng, toµn bé, ¶nh cuèi cïng cã thÓ xuÊt hiÖn trªn mµn h×nh nhê ë
®iÓm nµy trong ch−¬ng tr×nh, b¹n sÏ ph¶i th−êng xuyªn kÕt thóc thao t¸c vÏ víi hµm
glFlush(). ViÖc lµm nµy ®¶m b¶o cho bÊt kú c¸c lÖnh OpenGL trªn vïng ®Öm sÏ ®−îc
thÓ hiÖn. LÖnh glFlush() kh«ng yªu cÇu ®èi môc. Mét hµm t−¬ng tù lµ glFinish(), nã
thùc hiÖn cïng nhiÖm vô nh− glFlush(), tuy nhiªn chØ khi thao t¸c vÏ ®−îc hoµn
thµnh.

3. §Þnh nghÜa vµ vÏ c¸c ®iÓm


Trong môc tr−íc, b¹n ®· xem nhanh ®Þnh nghÜa c¸c h×nh trong OpenGL nh−
thÕ nµo. B¹n ®· häc c¸ch t¹o mét h×nh, ®Þnh nghÜa c¸c ®Ønh cña mét h×nh.
NhiÒu h×nh d¹ng mµ OpenGL cã thÓ vÏ theo c¸ch chóng hiÖn diÖn. Mét h×nh
®−îc lËp bëi glBegin(GL_POINTS), t¹o thµnh mét ®iÓm lµ chÊm ®¬n trªn mµn h×nh.
B¹n ®Þnh nghÜa mét dÉy c¸c ®iÓm nh− sau :
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();
ë ®©y, mçi lÖnh glVertex() ®Þnh nghÜa mét ®iÓm ®¬n. Nh− b¹n cã thÓ thÊy, b¹n cã
thÓ ®Þnh nghÜa nhiÒu ®iÓm ®¹t gi÷a cÆp glBegin() vµ glEnd(). Chó ý lµ ®o¹n m· trªn

_ 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();

4. §Þnh nghÜa vµ vÏ c¸c ®−êng


Sau ®iÓm, h×nh d¹ng ®¬n gi¶n nhÊt b¹n cã thÓ vÏ víi OpenGL lµ ®−êng th¼ng.
B¹n ®· cã ®−îc giíi thiÖu s¬ l−îc vÒ c¸c ®−êng th¼ng ë ®Çu ch−¬ng nµy. B¹n ®· häc :
mét ®−êng th¼ng ®−îc ®Þnh nghÜa bëi hai ®iÓm ®Æc tr−ng cho ®iÓm b¾t ®Çu vµ ®iÓm
kÕt thóc cña ®−êng th¼ng :
glBegin(GL_LINES);
glVertex2f(1.0f,1.0f);
glVertex2f(1.0f,0.0f);
glEnd();
b¹n còng ®· häc, cã thÓ ®Þnh nghÜa mét sè ®−êng th¼ng ®Ó vÏ c¸c h×nh lªn mµn h×nh :
glBegin(GL_LINES);
glVertex2f(0.0f,1.0f);
glVertex2f(1.0f,1.0f);
glVertex2f(0.0f,1.0f);
glVertex2f(1.0f,0.0f);
glEnd();
Còng nh− víi c¸c ®iÓm, b¹n cã thÓ ®Þnh nghÜa kÝch th−íc cña c¸c ®−êng th¼ng.
B¹n lµm viÖc nµy bëi viÖc gäi hµm glLineWidth() nh− sau :
glLineWidth(4.0f);
§èi môc ®¬n cña hµm nµy lµ gi¸ trÞ GLfloat x¸c ®Þnh ®é réng cña ®−êng th¼ng sÏ vÏ.
§Ó x¸c ®Þnh d¶i ®é réng cña ®−êng th¼ng ®−îc cung cÊp, b¹n cã thÓ gäi hµm
glGetFloatv() nh− sau :
GLfloat lw[2];
glGetFloatv(GL_LINE_WIDTH_RANGE,lw);
ë ®©y, lw lµ m¼ng 2 phÇn tö cã kiÓu lµ GLfloat, nã sÏ n¾m gi¸ trÞ ®é réng lín nhÊt vµ
®é réng nhá nhÊt cña ®−êng th¼ng.
B¹n còng cã thÓ gäi glGetFloatv() ®Ó cã ®é réng cña ®−êng hiÖn hµnh :
GLfloat lw;

_ 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();

4.1. VÏ c¸c ®−êng th¼ng chÊm


B−íc ®Çu tiªn ®Ó vÏ c¸c ®−êng chÊm lµ gäi glStipple() x¸c ®Þnh mÉu vÏ b»ng
chÊm. §Ó lµm viÖc nµy, ®Çu tiªn b¹n ph¶i ®Þnh nghÜa mÉu vÏ mµ b¹n muèn sö dông.
MÉu vÏ b»ng chÊm ®−îc ®Þnh nghÜa b»ng viÖc t¹o gi¸ trÞ nhÞ ph©n víi 1 ®Æc tr−ng cho
chÊm vµ 0 lµ kh«ng cã chÊm.
VÝ dô, mÉu vÏ b»ng chÊm sau sÏ cho kÕt qu¶ trong ®−êng th¼ng víi c¸c kho¶ng
kh«ng gian rçng vµ c¸c g¹ch : 0000000011111111
víi c¸ch kh¸c, mÉu sau t¹o mét ®−êng th¼ng víi c¸c g¹ch ng¾n : 0000111100001111
§Ó sö dông mÉu chÊm nh− mét ®èi môc trong viÖc gäi glStipple(), ®Çu tiªn b¹n
ph¶i chuyÓn ®æi mÉu sang gi¸ trÞ thËp lôc ph©n. Trong tr−êng hîp trªn, vÝ dô ®Çu tiªn
sÏ ®−îc ®Æc tr−ng bëi gi¸ trÞ hÖ 16 lµ 0x00FF, vÝ dô thø 2 lµ 0x0F0F.
Mét khi b¹n ®· cã mÉu ®−îc ®Þnh nghÜa, b¹n cã thÓ gäi glLineStipple() ®Ó
chuyÓn mÉu vÏ tíi OpenGL :
glLineStipple(1,0x00FF);
Hai ®èi môc cña hµm nµy lµ gi¸ trÞ GLint chØ râ c¸ch lÆp l¹i mÉu vµ mét gi¸ trÞ
GLushort chøa mÉu vÏ b»ng chÊm. Nh©n tè lÆp l¹i chØ râ c¸c chÊm ®−îc ®Æc tr−ng
bëi c¸c gi¸ trÞ nhÞ ph©n sÏ ®−îc lÆp l¹i bao nhiªu lÇn. VÝ dô, nÕu sè lÆp l¹i lµ 2,
OpenGL sÏ vÏ mét ®−êng th¼ng ®−îc ®Þnh nghÜa lµ 0011001100110011. B¹n cã thÓ
nghÜ, nh©n tè lÆp l¹i nh− lµ tû lÖ ngang cña ®−êng th¼ng.

_ 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();

4.2. VÏ c¸c d¶i ®−êng th¼ng


Khi b¹n ®Þnh nghÜa mét d¶i ®−êng th¼ng, cÆp ®Çu tiªn cña c¸c ®Ønh ®Þnh nghÜa
®−êng th¼ng ®Çu tiªn , víi mçi ®Ønh sau ®ã ®Þnh nghÜa ®Ønh tiÕp theo mµ openGL sÏ
vÏ. NÕu b¹n ®· cã kinh nghiÖm víi viÖc vÏ c¸c ®−êng th¼ng d−íi Window, b¹n sÏ
nhËn thÊy d¶i ®−êng th¼ng gièng nh− lÖnh MoveTo() theo sau d·y lÖnh LineTo(). §Ó
®Þnh nghÜa mét d¶i ®−êng th¼ng, b¹n sö dông GL_LINE_STRIP nh− mét ®èi môc
cña glBegin(), sau ®ã ban sÏ ®Þnh nghÜa c¸c ®Ønh .
VÝ dô : glclearColor(1.0f, 1.0f, 1.0f, 1.0f );
glClear(GL_COLOR_BUFFER_BIT);
glColor3f (0.0f, 0.0f, 0.0f);

_ 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 ();

4.3. VÏ c¸c ®−êng lÆp


Sö dông h»ng GL_LINE_LOOP lµm ®èi môc cña hµm glBegin( );
4.4. §Þnh nghÜa vµ vÏ c¸c ®a gi¸c
§Ó b¸o víi OenGL, vÏ 1 ®a gi¸c nh− thÕ nµo, b¹n gäi hµm glPolyyonMode( ):
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
Hai ®èi môc cña hµm nµy lµ c¸c gi¸ trÞ GLenum. §Çu tiªn, nã cã thÓ lµ GL_FRONT,
GL_BACK hoÆc GL_FRONT_AND_BACK, chØ ra bÒ mÆt ®a gi¸c víi chÕ ®é vÏ b¹n
muèn ®Æt. H»ng GL_FRONT chän mÆt tr−íc trong khi GL_BACK chän mÆt l−ng
(sau), vµ GL_FRONT_AND_BACK lùa chän c¶ hai bÒ mÆt. §èi môc thø hai chØ ra
chÕ ®é vÏ cho bÒ mÆt ®−îc chän. ChÕ ®é nµy cã thÓ lµ GL_POINT (nã b¶o víi
OpenGL lµ chØ vÏ ë c¸c ®iÓm ë c¸c ®Ønh cña ®a gi¸c ), GL_LINE (b¶o víi OpenGL lµ
vÏ ®a gi¸c d¹ng khung d©y ), hoÆc lµ GL_FILL (b¶o víi OpenGL vÏ ®a gi¸c ®Æc ).
B¹n b¶o víi OpenGL nh− thÕ nµo ®Ó biÕt phÝa cña ®a gi¸c lµ tr−íc hay sau ?
B¹n lµm ®iÒu nµy bëi trËt tù s¾p xÕp trong khi b¹n ®Þnh nghÜa c¸c ®Ønh lµm thµnh ®a
gi¸c. §Æc biÖt, mét ®a gi¸c ®−îc xem nh− lµ mÆt tr−íc khi c¸c ®Ønh cña nã ®−îc ®Þnh
nghÜa theo thø tù ng−îc chiÒu quay kim ®ång hå, b¹n cã thÓ b¶o víi OpenGL ®Ó ®æi
chiÒu kh¸i niÖm cña nã vÒ mÆt tr−íc ®a gi¸c, chØ viÖc gäi hµm glFrontFace() :
glFrontFace(GL_CW);
Gäi glFrontFace() ®Ó b¶o víi OpenGL r»ng mÆt tr−íc ®a gi¸c ®−îc ®Þnh nghÜa theo
chiÒu quay kim ®ång hå. Nh− b¹n cã thÓ thÊy, hµm glFrontFace() cã mét ®èi môc
®¬n, mµ h»ng ®ã ®iÒu khiÓn kiÓu x¸c ®Þnh mÆt tr−íc cña ®a gi¸c. H»ng GL_CW lùa
chän thø tù c¸c ®Ønh theo chiÒu quay kim ®ång hå, trong khi GL_CCW (®−îc
OpenGL ®Æt mÆc ®Þnh ) lùa chän c¸c ®Ønh theo ng−îc chiÒu kim ®ång hå.

_ 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);

VÝ dô : GLubyte pattern {}=


{ox ff ,ox oo, ox ff,

};
glClearColor(1.0f,1.0f,1.0f,1.0f);
glClearColor(GL_COLOR_BUFFER_BIT)
glColor3f(0.0f,0.0f,0.0f);
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
glPolygonStipple (pattern);
glEnable(GL_POLYGON_STIPPLE);
glBegin(GL_POLYGON);
glVertex2f (-0.5f,0.5f);
glVertex2f (-0.5f,-0.5f);
glVertex2f (0.5f,-0.5f);
glVertex2f (0.5f,0.5f);
glEnd();
glFlush();
glDisable(GL_POLYGON_STIPPLE);

4.6. VÏ ®−êng bao c¸c ®a gi¸c kh«ng låi


C¸c øng dông OpenGL cã hai h¹n chÕ víi viÖc vÏ ®a gi¸c. §Çu tiªn, ®a gi¸c vÏ
bëi OpenGL kh«ng thÓ cã hai c¹nh c¾t nhau. Thø hai, tÊt c¶ c¸c ®a gi¸c OpenGL ph¶i
lµ ®a gi¸c låi, chóng kh«ng thÓ chøa c¸c vïng lßng ch¶o trªn ®−êng viÒn hoÆc lç
thñng ë phÇn trong cña chóng.

_ 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

4.7. VÏ c¸c tam gi¸c


OpenGl cung cÊp c«ng cô vÏ c¸c ®a gi¸c ®Æc biÖt, mét trong sè ®ã lµ tam gi¸c.
§Þnh nghÜa mét tam gi¸c kh«ng gièng víi ®Þnh nghÜa c¸c ®a gi¸c kh¸c, sö dông h»ng
GL_TRIANGLES trong lêi gäi hµm glBegin(), sau ®ã b¹n ®Þnh nghÜa c¸c ®Ønh cña
mçi tam gi¸c. B¹n cã thÓ ®Þnh nghÜa nhiÒu tam gi¸c nÕu b¹n thÝch nh−ng mçi tam
gi¸c ph¶i cã 3 ®Ønh ®−îc ®Þnh nghÜa.
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_TRIANGLES);
glVertex2f (-0.5f,0.3f);
glVertex2f (-0.5f,-0.5f);
glVertex2f (0.5f,-0.5f);
glVertex2f (-0.5f,0.8f);
glVertex2f (-0.5f,0.5f);
glVertex2f (0.5f,0.5f);
glEnd( );
glFlush( );

4.8. VÏ c¸c d¶i tam gi¸c


§ã lµ mét d·y c¸c tam gi¸c nèi tiÕp nhau. Mçi h×nh tam gi¸c cã chung c¹nh
víi tam gi¸c ®−îc vÏ tr−íc ®ã, cã nghÜa lµ sau khi ®Þnh nghÜa ba ®Ønh cho mét tam
gi¸c ®Çu tiªn trong d¶i, b¹n chØ cÇn ®Þnh nghÜa mét ®Ønh cho mçi tam gi¸c tiÕp theo
trong d¶i.
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_TRIANGLE_STRIP);
glVertex2f (-0.75f,0.25f);
glVertex2f (-0.75f,-0.25f);
glVertex2f (-0.25f,0.25f);
glVertex2f (0.0f,-0.25f);
glVertex2f (0.25f,0.3f);
glVertex2f (0.5f,0.5f);

_ 35 _
§å ho¹ 3D víi OpenGL

glVertex2f (0.75f,0.3f);
glEnd( );
glFlush( );

4.9. VÏ c¸c h×nh tam gi¸c d¹ng qu¹t


Cuèi cïng b¹n cã thÓ vÏ c¸c tam gi¸c víi OpenGL lµ tam gi¸c qu¹t (chØ ®Þnh
bëi h»ng GL_TRIANGLE_FAN), nã lµ d·y c¸c tam gi¸c mµ tÊt c¶ c¸c h×nh chung
®Ønh ®¬n ®−îc ®Þnh nghÜa ®Çu tiªn cña h×nh qu¹t. Gièng nh− d¶i tam gi¸c, mét qu¹t
tam gi¸c ®−îc t¹o ®Çu tiªn ®−îc ®Þnh nghÜa ®ñ ba ®Ønh. Råi ®Þnh nghÜa thªm ®Ønh ®¬n
cho mçi tam gi¸c céng thªm vµo d¶i qu¹t.
VÝ dô : glBegin(GL_TRIANGLE_FAN);
glVertex2f (-0.75f,0.25f);
glVertex2f (-0.25f,0.25f);
glVertex2f (-0.25f,-0.25f);
glVertex2f (0.25f,0.25f);
glVertex2f (0.25f,0.5f);
glVertex2f (-0.05f,0.7f);
glVertex2f (-0.45f,0.5f);
glEnd();

4.10. VÏ c¸c tø gi¸c


§a gi¸c bèn c¹nh ®−îc gäi lµ tø gi¸c. OpenGL cã hai c¸ch ®Ó vÏ kiÓu ®a gi¸c
®Æc biÖt nµy. B¹n ®Þnh nghÜa mét tø gi¸c nh− cïng c¸ch ®Þnh nghÜa c¸c h×nh kh¸c ®·
m« t¶ trong ch−¬ng nµy, sö dông b»ng GL_QUADS lµm ®èi môc cña hµm glBebin().
Gi÷a c¸c lÖnh glBegin() vµ glEnd() b¹n cã thÓ ®Þnh nghÜa nhiÒu tø gi¸c nh− b¹n
muèn, nh−ng b¹n ph¶i ch¾c ch¾n b¹n ®Þnh nghÜa 4 ®Ønh theo thø tù ng−îc chiÒu kim
®ång hå cho mçi tø gi¸c.
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_QUADS);
glVertex2f (-0.75f,0.75f);
glVertex2f (-0.75f,0.25f);
glVertex2f (-0.25f,0.0f);
glVertex2f (0.0f,0.5f);
glVertex2f (-0.55f,-0.25f);

_ 36 _
§å ho¹ 3D víi OpenGL

glVertex2f (-0.75f,-0.45f);
glVertex2f (0.25f,-0.75f);
glVertex2f (0.5f,-0.25f);
glEnd( );
glFlush( );

4.11. VÏ c¸c d¶i tø gi¸c


Lµ mét d·y c¸c d¶i tø gi¸c cã hai ®Ønh chung. §Ó b¶o OpenGL r»ng b¹n
mu«ns vÏ mét d¶i tø gi¸c, b¹n ph¶i sö dông b»ng GL_QUAD_STRIP víi lÖnh
glBegin(). B¹n t¹o d¶i tø gi¸c bëi ®Þnh nghÜa bèn ®Ønh cho tø gi¸c ®Çu tiªn vµ råi ®Þnh
nghÜa hai ®Ønh riªng cña mçi tø gi¸c tiÕp theo vµo trong d¶i. Dï thÕ nµo, thø tù ®Þnh
nghÜa c¸c ®Ønh lµ quan träng.
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_QUAD_STRIP);
glVertex2f(-0.75f,0.25f);
glVertex2f(-0.65f,0.75f);
glVertex2f(-0.55f,0.1f);
glVertex2f(-0.25f,0.6f);
glVertex2f(-0.15f,-0.2f);
glVertex2f(0.0f,0.45f);
glVertex2f(0.25f,-0.7f);
glVertex2f(0.5f,0.65f);
glVertex2f(0.75f,-0.3f);
glVertex2f(0.85f,0.45f);
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.

2. Khëi t¹o ma trËn


ë trªn, b¹n ®· biÕt r»ng, tr−íc khi b¹n cã thÓ sö dông ma trËn ®Ó chuyÓn ®æi
c¸c ®Ønh cña mét ®èi t−îng, b¹n th−êng muèn l¹p ma trËn víi d¹ng ma trËn ®ång
nhÊt. OpenGL cã hµm ®Æc biÖt ®Ó ®iÒu khiÓn nhiÖm vô nµy :
glLoadIdentity( );
Hµm glLoadIdentity() ®−a ma trËn lùa chän hiÖn hµnh vÒ d¹ng ma trËn ®ång nhÊt .

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.

4. PhÐp biÕn ®æi m« h×nh quan s¸t


§Õn ®©y, b¹n ®· b¶o víi OpenGL khèi quan s¸t tr«ng nh− thÕ nµo, vµ b¹n ®·
®Þnh nghÜa ®èi t−îng cña b¹n, nh−ng b¹n vÉn sÏ kh«ng thÊy bÊt kú thø g× trªn mµn
h×nh. T¹i sao ? Bëi v× khèi hép hiÖn ®ang n»m bªn ngoµi vïng khèi nh×n.
ViÖc gäi tíi glFrustum (-1.0,1.0,-1.0,1.0,2.0,7.0) ®Æt mÆt c¾t gÇn lµ 2 ®¬n vÞ tõ
m¾t vµ ®Æt mÆt ph¼ng Khèi quan s¸t
L−íi gèc to¹ ®é
c¾t xa lµ 7 ®¬n vÞ tõ Cartasian 3D
m¾t. Nh−ng khèi lËp
vÉn cã vÞ trÝ ë gèc
n»m ngoµi khèi nh×n. MÆt ph¼ng gÇn MÆt ph¼ng xa
§Ó gi¶i quyÕt vÊn ®Ò
nµy lµ sö dông phÐp
tÞnh tiÕn ®èi t−îng
vµo trong khèi quan 1 0 -1 -2 -3 -4 -5 -6 -7
s¸t.
( Xem thªm hµm glClipPlane() trong trî gióp cña Visual C++ )
4.1. Thùc hiÖn tÞnh tiÕn
B©y giê b¹n cÇn tÞnh tiÕn khèi hép xuèng theo trôc Z, ®Ó ®Æt nã vµo trong khèi
nh×n. Ba dßng m· sau thùc hiÖn c«ng viÖc nµy :
glMatrixMode (GL_MODEVIEW);
glLoadIdentity();
glTranslatef (0.0f,0.0f,-3.5f);
Dßng ®Çu tiªn b¶o víi OpenGl r»ng b©y giê b¹n muèn lµm viÖc víi ma trËn m«
h×nh quan s¸t, dßng thø hai khëi t¹o m« h×nh quan s¸t thµnh ma trËn ®ång nhÊt, vµ
dßng thø ba tÞnh tiÕn khèi hép 3,5 ®¬n vÞ xuèng theo trôc Z. Hµm glTranslatef() t¹o
lËp ma trËn tÞnh tiÕn vµ nh©n nã víi ma trËn lùa chän hiÖn hµnh. Ba ®èi môc cña nã lµ
c¸c gi¸ trÞ glFloat x¸c ®Þnh kho¶ng tÞnh tiÕn trªn c¸c trôc X, Y, Z. Phiªn b¶n kh¸c cña
hµm glTranslated() cã c¸c ®èi môc glDouble.
VÝ dô: glMatrixMode (GL_PROJECTION);
glLoadIdentity( );
glFrustum (-1.0,1.0,-1.0,1.0,2.0,7.0);
glMatrixMode (GL_MODEVIEW);
glLoadIdentity();
glTranslatef(0.0f,0.0f.-3.5f);

_ 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

4.2. Thùc hiÖn phÐp biÕn ®æi tû lÖ


Hµm glScalef() t¹o lËp ma trËn tû lÖ vµ nh©n ma trËn ®ã víi ma trËn lùa chän
hiÖn hµnh. Ba ®èi môc cña nã lµ c¸c gi¸ trÞ glFloat x¸c ®Þnh gi¸ trÞ tû lÖ cho c¸c trôc
X, Y, Z. Phiªn b¶n kh¸c cña hµm nµy lµ glScaled() gåm c¸c ®èi môc GLdouble.
VÝ dô: glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-1.0,1.0,-1.0,1.0,2.0,7.0);
glMatrixMode (GL_MODEVIEW);
glLoadIdentity();
glScalef (2.0f,1.0f.1.0f);
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);
DrawCube();
glFlush();

4.3. Thùc hiÖn xoay


PhÐp chuyÓn ®æi cuèi cïng b¹n cã thÓ ¸p dông lµ phÐp quay. VÝ dô, gäi hµm
sau quay ®èi t−îng 200 quanh trôc Z :
glRotatef(20.0f,0.0f,0.0f,1.0f);
Hµm nµy t¹o lËp ma trËn quay vµ nh©n nã víi ma trËn hiÖn hµnh. Bèn ®èi môc cña nã
lµ cac gi¸ trÞ GLfloat, nã chØ ra gãc theo ng−îc chiÒu kim ®ång hå cña phÐp quay vµ
theo thø tù quanh c¸c trôc X, Y, Z t¹o vect¬ mµ phÐp quay thùc hiÖn lµm ®èi môc cho
trôc ®ã 1.0 vµ c¸c ®èi môc cho trôc kh¸c 0.0. Phiªn b¶n kh¸c cña hµm glRotatef() lµ
glRotated() cã ®èi môc lµ GLdouble
VÝ dô: glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glFrustum(-1.0,1.0,-1.0,1.0,2.0,7.0);
glMatrixMode (GL_MODEVIEW);
glLoadIdentity();
glTranslatef (0.0f,0.0f,-3.5f);
glRotatef(0.0f,1.0f,0.0f,0.0f);
glRotatef(20.0f,1.0f,0.0f,0.0f);
glRotatef(20.0f,0.0f,1.0f,0.0f);
glClearColor(1.0f,1.0f,1.0f,1.0f);

_ 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();

5. PhÐp chuyÓn ®æi khung nh×n


OpenGL thùc hiÖn chuyÓn ®æi khung nh×n b»ng c¸ch x¸c ®Þnh c¸c ®Ønh ®−îc
¸nh x¹ lªn mµn h×nh nh− thÕ nµo. Mét khung nh×n ®¬n gi¶n lµ h×nh ch÷ nhËt mµ trong
®ã c¶nh ®−îc vÏ.
5.1. §Æt khung nh×n
Tõ tr−íc, b¹n ®· ®ang sö dông khung nh×n mÆc ®Þnh ¸nh x¹ tíi biÓu diÔn ®å
häa mµ c¸c c«ng viÖc vÉn thùc hiÖn tèt nÕu nh− b¹n kh«ng cÇn khung nh×n x¸c ®Þnh.
Tuy nhiªn, khi b¹n muèn sö dông chØ mét phÇn cña cöa sæ khung nh×n cña ønh dông
hoÆc b¹n cã thÓ muèn khung nh×n thay ®æi khi cöa sæ thay ®æi kÝch th−íc. OpenGL
cung cÊp hµm glViewport() ®Ó ®Æt kÝch th−íc vµ vÞ trÝ cña khung nh×n. ViÖc gäi hµm
glViewport() nh− sau:
glViewport (left, bottom, width, height);
Hµm nµy cã 4 ®èi môc. Hai gi¸ trÞ ®Çu tiªn lµ c¸c gi¸ trÞ GLint nã x¸c ®Þnh gãc thÊp
bªn tr¸i cña khung nh×n. Hai ®èi môc thø hai lµ c¸c gi¸ trÞ GLsizel nã x¸c ®Þnh ®é
réng vµ chiÒu cao cña khung nh×n .
5.2. Gi¶i quyÕt víi tû lÖ c¹nh ngoµi
Phô thuéc vµo c¸c kÕt qu¶ b¹n muèn ®¹t ®−îc, b©y giê b¹n ®Æt khung nh×n võa
khÝt víi kÝch th−íc cöa sæ cña b¹n bÊt kÓ kÝch th−íc cña khèi quan s¸t nh− thÕ nµo.
Khi ®ã dï ng−êi sö dông thay ®æi kÝch th−íc cña cöa sæ, b¹n vÉn cã thÓ ®Æt l¹i khung
nh×n tíi kÝch th−íc cña cöa sæ míi.
Trong ch−¬ng tr×nh MFC-OpenGL, b¹n cã thÓ ®Æt trong hµm OnSize() nh− sau:
void COpenglView::OnSize(UINT nType, int cx,int cy)
{
CView::OnSize(nType, cx, cy);
CClientCD clientDC(this);
wglMakeCurrent (clientDC.m_hCD,m_hRC);
glMatrixMode (GL_PROJECTION);
glLoadIdentity();
glFrustum (-1.0,1.0,-1.0,1.0,2.0,7.0);
glViewport (0,0,cx,cy);

_ 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

ChiÕu s¸ng c¸c ®èi t−îng 3D


1. C¸c kiÓu cña ¸nh s¸ng
OpenGL cung cÊp 4 kiªu ¸nh s¸ng: bao quanh (ambient), khuÕch t¸n (diffuse),
ph¶n chiÕu (specular) vµ ph¸t ra (emitted). VÝ dô, ¸nh s¸ng bao quanh lµ ¸nh s¸ng
xuÊt hiÖn tíi tõ tÊt c¶ mäi h−íng tíi nã.

2. §Þnh nghÜa mét nguån s¸ng


OpenGl cho phÐp sö dông 8 nguån s¸ng kh¸c nhau. Mçi nguån s¸ng cã nh÷ng
®Æc tÝnh riªng, nã ®iÒu khiÓn ¶nh h−ëng viÖc chiÕu s¸ng nh− thÕ nµo. C¸c ®Æc tÝnh
cña chóng gåm (nh−ng kh«ng ®−îc giíi h¹n) ¸nh s¸ng bao, ¸nh s¸ng khuyÕch t¸n vµ
vÞ trÝ. B¹n ph¶i chØ râ cho mçi nguån s¸ng c¸c tæ hîp phÇn tr¨m red, green vµ blue
chøa ®ùng trong kiÓu ¸nh s¸ng. B¹n còng ph¶i chØ râ c¸c to¹ ®é X, Y, Z cña nguån
¸nh s¸ng. Trong môc tíi b¹n sÏ ®iÒu khiÓn c¸c viÖc nµy bëi viÖc t¹o lËp c¸c m¶ng
n¾m gi÷ c¸c gi¸ trÞ yªu cÇu.
2.1. Cµi ®Æt c¸c m¶ng c¸c gi¸ trÞ cña ¸nh s¸ng
C¸c m¶ng sau chøa ®ùng c¸c gi¸ trÞ vÞ trÝ cho ®Þnh nghÜa nguån s¸ng:
GLfloat ambientlight [] = {0.3f,0.3f,0.3f,0.1f};
GLfloat diffuselight[] = {0.5f,0.5f,0.5f,1.0f};
GLfloat specularlight[] = {0.0f, 0.0f, 0.0f,1.0f};
GLfloat positionlight[] = {0.0f, 0.0f,1.0f 0.0f};
M¶ng positionlight[] n¾m gi÷ vÞ trÝ cña nguån s¸ng x¸c ®Þnh b»ng c¸c to¹ ®é
X, Y, Z vµ W. NÕu to¹ ®é W lµ 0.0, OpenGL coi lµ nguån s¸ng ®Þnh h−íng, ng−îc l¹i
nÕu gi¸ trÞ 1.0 coi ®ã lµ vÞ trÝ nguån s¸ng ( chØ cã gi¸ trÞ 1.0 vµ 0.0 lµ gi¸ trÞ hîp lÖ cho
tr−êng nµy). VÝ dô, ¸nh s¸ng mÆt trêi lµ nguån s¸ng ®Þnh h−íng, ®Ìn trong phßng lµ
nguån s¸ng vÞ trÝ.
2.2. ChuyÓn c¸c m¶ng tíi OpenGl
Mét khi b¹n cã c¸c cµi ®Æt c¸c m¶ng ®Þnh nghÜa nguån s¸ng cña b¹n, b¹n ph¶i
®−a nã tíi OpenGL. B¹n thùc hiÖn c«ng viÖc nµy víi viÖc gäi hµm glLightfv() nh−
sau :
glLightfv(GL_LIGHT0, GL_AMBIENT, ambientlight0);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuselight0);
glLightfv(GL_LIGHT0, GL_SPECULAR, specularlight0);

_ 44 _
§å ho¹ 3D víi OpenGL

glLightfv (GL_LIGHT0, GL_POSITION, position light0);

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…( ).

3. Lµm cho nguån s¸ng lµm viÖc


Dïng hµm glEndable() ch¼ng h¹n nh− :
glEndable(GL_LIGHTING);
glEndable(GL_LIGHT0);
B¹n ®· biÕt vÒ hµm glEndable() trong ch−¬ng 5 ®Ó vÏ h×nh vµ sö dông mµu,
trong tr−êng hîp nµy, gäi hµm ®Çu tiªn ®Ó bËt chÕ ®é chiÕu s¸ng vµ lÇn gäi thø hai
bËt nguån s¸ng 0.
Chó ý:
VÞ trÝ cña nguån s¸ng ®−îc t¸c ®éng bëi c¸c phÐp biÕn ®æi m« h×nh quan s¸t
gièng nh− c¸c ®èi t−îng kh¸c trong 3D. PhÐp biÕn ®æi x¶y ra khi b¹n gäi glLight()
x¸c ®Þnh vÞ trÝ hay ®Þnh h−íng nguån s¸ng. V× lý do nµy, b¹n sÏ th−êng xuyªn muèn
gäi glMatrixMode(GL_MODELVIEW) vµ glLoadIdentity() tr−íc khi gäi glLight(),
gièng nh− b¹n ®· lµm tr−íc khi ®Þnh nghÜa c¸c ®Ønh cña mét ®a gi¸c. TÊt nhiªn, nÕu
b¹n muèn chuyÓn vÞ trÝ cña nguån s¸ng vµ h−íng chiÕu cïng c¸c ®èi t−îng kh¸c, b¹n
còng sÏ muèn thùc hiÖn c¸c phÐp chuyÓn ®æi cña b¹n tr−íc khi gäi glLight().

4. §Þnh nghÜa c¸c ®Æc tÝnh vËt liÖu


ViÖc tiÕp theo b¹n ph¶i lµm lµ ®Þnh nghÜa c¸c ®Æc tÝnh cña ®èi t−îng.

_ 45 _
§å ho¹ 3D víi OpenGL

4.1. Cµi ®Æt m¶ng c¸c gi¸ trÞ vËt liÖu


B−íc ®Çu tiªn ®Þnh nghÜa c¸c ®Æc tÝnh vËt liÖu lµ cµi ®Æt m¶ng chøa c¸c gi¸ trÞ
®Þnh nghÜa ®Æc tÝnh vËt liÖu:
GLfloat materialAmbient[] ={0.0f, 0,7f, 0.0f, 1.0f};
GLfloat materialSpeculaer[]={1.0f, 1.0f, 1.0f, 1.0f};
C¸c m¶ng nµy chøa ®ùng c¸c gi¸ trÞ RGBA cho kiÓu ®Æc biÖt cña ¸nh s¸ng ph¶n
chiÕu.
4.2. ChuyÓn c¸c m¶ng vËt liÖu tíi OpenGL
B¹n sö dông con trá tíi m¶ng lµ c¸c ®èi môc trong glMaterialft(), nh− sau :
glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE,material Ambient);
glMaterialfv (GL_FRONT, GL_SPECULAR, meterilarSpecular);
Hµm nµy cã c¸c ®èi môc lµ : h»ng x¸c ®Þnh phÝa cña c¸c bÒ mÆt ®a gi¸c mµ
b¹n ®ang ®Þnh nghÜa vËt liÖu, h»ng x¸c ®Þnh ®Æc tÝnh cña vËt liÖu b¹n ®ang ®Þnh
nghÜa, vµ m¶ng chøa c¸c gi¸ trÞ b¹n ®Æt cho ®Æc tÝnh vËt liÖu. §èi môc ®Çu cã thÓ lµ
GL_FRONT, GL_BACK hoÆc GL_FRONT_AND_BACK ®Ó lùa chän c¸c bÒ mÆt
tr−íc hay sau cña ®a gi¸c ®Ó g¸n vËt liÖu cho c¸c ®èi t−îng. Cho mét ®èi t−îng ®Æc
nh− h×nh khèi, b¹n th−êng muèn x¸c ®Þnh GL_FRONT bëi v× mÆt sau cña ®a gi¸c
cña hép kh«ng bao giê ®−îc biÓu thÞ.
§èi thø hai cã thÓ lµ : GL_AMBIENT, GL_AMBIENT_AND_DIFFUSE,
GL_DIFFUSE, GL_COLOR_INDEXES, GL_EMISSION, GL_SHININESS,
GL_SPECULAR. H»ng nµy b¶o víi OpenGL ®Æc tÝnh cña vËt liÖu b¹n muèn ®Þnh
nghÜa.
Hµm glMaterial() cã 4 phiªn b¶n, phô thuéc vµo sè vµ kiÓu c¸c ®èi môc .

5. §Þnh nghÜa c¸c chuÈn


B¹n cã thÓ ®Þnh nghÜa chuÈn cho c¸c ®Ønh cña ®a gi¸c bëi viÖc gäi hµm
glNormal3f() tr−íc khi b¹n gäi glVertex() ®Ó ®Þnh nghÜa c¸c ®Ønh nh− sau:
glBegin(GL_POLYGON);
glNormal3f((GLFloat)x, (GLfloat)y, (GLfloat)z);
glVertex3f(-0.5f, 0.0f, -0.5f);
glVertex3f(-0.5f, 0.0f, 0.5f);
glVertex3f(0.5f, 0.0f, 0.5f);
glVertex3f(0.5f, 0.0f, -0.5f);
glEnd();
Hµm glNormal3f() cã 3 ®èi môc kiÓu GLfloat x¸c ®Þnh c¸c to¹ ®é X, Y, X cña chuÈn.

_ 46 _
§å ho¹ 3D víi OpenGL

5.1. TÝnh c¸c chuÈn


Hµm CalcNormal() cã thÓ tÝnh chuÈn tõ c¸c to¹ ®é X, Y, Z cña 3 ®iÓm bÊt kú
trªn ®a gi¸c. B¹n sÏ sö dông to¹ ®é cña 3 ®Ønh cña ®a gi¸c cho c¸c ®èi môc cña hµm
CalcNormal() nh− sau :
double p1[]={-0.5, 0.0, -0.5};
double p2[]={-0.5, 0.5, 0.5};
double p3[]={0.5, 0.0, 0.5};
double n[3];
CalcNormal(p1, p2, p3, n);
Sau khi gäi hµm CalcNormal() b¹n cã thÓ sö dông m¶ng n[] ®Ó ®Þnh nghÜa
chuÈn cho c¸c ®Ønh cña ®a gi¸c hiÖn hµnh:
glBegin (GL_POLYGON);
glNormal3f((GLfloat)n[0], (GLfloat)n[1], (GLfloat)n[2]);
glVertex3f(-0.5f, 0.0f, -0.5f);
glVertex3f(-0.5f, 0.0f, 0.5f);
glVertex3f(0.5f, 0.0f, 0.5f);
glVertex3f(0.5f, 0.0f, -0.5f);
glEnd();

Hµm CalcNormal() ®−îc ®Þnh nghÜa nh− sau :


void CalcNormal (double*p1,double*p2, double*p3, double*n)
{
double a[3], b[3];
a[0] = p2[0] - p1[0]; b[0] = p3[0] - p1[0];
a[1] = p2[1] - p1[1]; b[1] = p3[1] - p1[1];
a[2] = p2[2] - p1[2]; b[2] = p3[2] - p1[2];
n[0] = a[1]*b[2]- a[2]*b[1];
n[1] = a[2]*b[0]- a[0]*b[2];
n[2] = a[0]*b[1]- a[1]*b[0];
double length = sqrt(n[0]*n[0] + n[1]*n[1] + n[2]*n[2]);
if (length != 0)
{
n[0] /= length;
n[1] /= length;
n[2] /= length;
}
}

_ 47 _
§å ho¹ 3D víi OpenGL

6. X¸c ®Þnh m« h×nh t« bãng vµ kiÓm tra ®é s©u cã thÓ


§Ó chän m« h×nh t« bãng, b¹n gäi hµm glShadeModel() gièng nh−:
glShadeModel(GL_FLAT);
Hµm nµy cã ®èi môc ®¬n lµ h»ng t−îng tr−ng cho m« h×nh ®¸nh bãng mµ b¹n muèn.
H»ng nµy cßn cã thÓ lµ GL_SMOOTH.
Tr−íc khi OpenGL cã thÓ ®iÒu khiÓn kiÓm tra ®Æc tÝnh ®é s©u, b¹n ph¶i lµm
cho cã thÓ kiÓm tra ®é s©u víi hµm glEnable() nh− sau :
glEnable(GL_DEPTH_TEST);
Bëi v× OpenGL sö vïng ®Öm x¸c ®Þnh cho kiÓm tra ®é s©u nªn b¹n ph¶i xo¸
vïng nµy tr−íc khi diÔn t¶ c¶nh. B¹n lµm ®iÒu nµy gièng nh− viÖc xo¸ vïng ®Öm mÇu
bëi gäi hµm glClear() :
glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT);
trong viÖc gäi hµm trªn thùc hiÖn xo¸ c¶ vïng ®Öm mµu vµ vïng ®Öm s©u.

7. §Þnh nghÜa mét ®èm s¸ng


B¹n cã thÓ ®Þnh nghÜa mét ®èm s¸ng trong ch−¬ng tr×nh:
GLfloat ambientLinght1[] = {0.2f, 0.2f, 0.2f, 1.0f};
GLfloat diffuseLinght1[] = {1.0f, 1.0f, 1.0f, 1.0f};
GLfloat specularLinght1[] = {0.0f, 0.0f, 0.0f, 1.0f};
GLfloat possitionLinght1[] = {0.0f, 0.0f, -2.0f, 1.0f};
GLfloat directionLinght1[] = {0.0f, 0.0f, 1.0f};
glLightfv(GL_LIGHT1, GL_AMBIENT, ambientLight1);
glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuseLight1);
glLightfv(GL_LIGHT1, GL_SPECULAR, specularLight1);
glLightfv(GL_LIGHT1, GL_POSITION, positionLight1);
glLightf (GL_LIGHT1,GL_SPOT_CUTOFF, 10.0f);
glLightfv(GL_LIGHT1, GL_SPOT_DERECTION, directionLight1);
Trong m¶ng positionLight1[], nÕu to¹ ®é w=1 th× ®ã lµ vÞ trÝ nguån s¸ng, nÕu b»ng
0.0 th× ®ã lµ h−íng chiÕu s¸ng.

8. BiÓu diÔn c¸c ®èi t−îng 3D ®· chiÕu s¸ng


8.1. HiÖu øng cña ¸nh s¸ng bao quanh (Ambient Light)

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)

GLfloat ambientLinght0[] = {0.0f, 0.0f, 0.0f, 1.0f};


GLfloat diffuseLinght0[] = {0.0f, 0.0f, 0.0f, 1.0f};
GLfloat specularLinght0[] = {0.7f, 0.7f, 0.7f, 1.0f};
GLfloat possitionLinght0[] = {0.0f, 0.0f, 1.0f, 0.0f};

8.4. Phèi hîp c¸c kiÓu ¸nh s¸ng (Ambient, Diffuse, Specular Linht)

GLfloat ambientLinght0[] = {0.2f, 0.2f, 0.2f, 1.0f};


GLfloat diffuseLinght0[] = {0.7f, 0.7f, 0.7f, 1.0f};
GLfloat specularLinght0[] = {1.0f, 1.0f, 1.0f, 1.0f};
GLfloat possitionLinght0[] = {1.0f, 0.5f, 1.0f, 0.0f};
GLfloat materialAmbient[] = {1.0f, 0.0f, 0.0f, 1.0f};
GLfloat materialSpecular[] = {1.0f, 1.0f, 1.0f, 1.0f};

_ 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.

2. Vïng ®Öm kÐp trong OpenGL


OpenGL cung cÊp vïng ®Öm kÐp. Trong OpenGL, c¸c vïng ®Öm nµy ®−îc gäi
lµ vïng ®Öm tr−íc (vïng ®Öm hiÓn thÞ) vµ vïng ®Öm sau (vïng ®Öm Èn). Khi b¹n ®Æt
OpenGL cho vïng ®Öm kÐp, c¸c lÖnh vÏ cña b¹n lu«n lu«n ®i tíi vïng ®Öm l−ng hiÖn
hµnh, do ®ã ng−êi sö dông sÏ kh«ng thÊy trªn mµn h×nh nh÷ng g× b¹n ®ang vÏ. Sau
khi ch−¬ng tr×nh vÏ ¶nh xong, nã ho¸n ®æi vïng ®Öm tr−íc vµ sau, khi ®ã ¶nh míi
xuÊt hiÖn trªn mµn h×nh. Ch−¬ng tr×nh l¹i x©y dùng s−ên cho ho¹t ®éng tiÕp theo
trong vïng ®ªm sau míi vµ råi l¹i ®¶o l¹i vïng ®Öm. ViÖc sö lý nµy tiÕp tôc theo ho¹t
®éng ®ang ch¹y cña ch−¬ng tr×nh víi c¸c vïng ®Öm ®−îc ®¶o liªn tôc nhiÒu lÇn trong
mét gi©y.

3. KÕt hîp c¸c vïng ®Öm kÐp


Trong suèt qu¸ tr×nh ®iÒu khiÓn c¸c vïng ®Öm kÐp cã thÓ lµ mét vÊn ®Ò kü
thuËt khã kh¨n cho viÖc quy −íc lËp tr×nh c¸c ch−¬ng tr×nh ®å ho¹, tuy nhiªn ng−êi
lËp tr×nh OpenGL cã thÓ kÕt hîp chÆt chÏ víi vïng ®Öm kÐp víi chØ 2 sù thay ®æi nhá
trong ch−¬ng tr×nh. §Çu tiªn, b¹n ph¶i b¶o víi OpenGL r»ng b¹n muèn cµi ®Æt m«i
tr−êng vïng ®Öm kÐp. B¹n lµm ®iÒu nµy bëi viÖc céng thªm cê
PFD_DOUBLEBUFFER tíi thµnh phÇn dwFlag cña cÊu tróc
PIXELFOMATDESCRIPTOR, gièng nh− sau :

_ 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

¶nh vµ d¸n ¶nh (Texture mapping)


1. C¸c ¶nh Bitmap vµ c¸c ¶nh kh¸c trong ch−¬ng tr×nh OpenGL
OpenGL cung cÊp 2 kiÓu ®èi t−îng ®å ho¹. §Çu tiªn, víi OpenGL ®¬n gi¶n gäi
mét ¶nh bitmap, nã chØ lµ mét m¶ng c¸c mµu, do ®ã cã thÓ ®−îc sö dông ®Ó lËp c¸c
¶nh ®¬n gi¶n còng nh− c¸c ký tù trong mét font. Bëi v× c¸c ¶nh bitmap cña OpenGL
Ýt h÷u dông nhÊt trong sè c¸c kiÓu ¶nh nªn b¹n sÏ kh«ng häc nhiÒu vÒ chóng ë ®©y.
KiÓu kh¸c cña ®èi t−îng ®å häa mµ OpenGL cung cÊp lµ ¶nh (image). Mét
image cã thÓ thÝch h¬n mét bitmap, b¹n cã thÓ sö dông ®Ó dïng : ®iÒn ®Çy mµu vµ vÏ
chi tiÕt. ¶nh ®ã cã thÓ chøa bÊt kú mét biÓu t−îng hoÆc mét bøc ¶nh chi tiÕt.
ThËt ®¸ng tiÕc, c¸c kiÓu ¶nh kh¸c nhau cã c¸c m¶ng l−u tr÷ d÷ liÖu ¶nh theo
c¸c c¸ch kh¸c nhau. MÆt kh¸c, v× OpenGL lµ mét th− viÖn c¬ së pha t¹p, nã ph¶i cã
c¸ch ®Ó cung cÊp cho bÊt kú kiÓu nµo cã thÓ cña c¸c c¸ch l−u tr÷ ¶nh. OpenGL ®Þnh
nghÜa mét sè h»ng sè ®Æc tr−ng cho c¸c kiÓu kh¸c nhau cña d÷ liÖu b¹n cã thÓ muèn
l−u trong Image.
C¸c h»ng så kiÓu ¶nh cña OpenGL :

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 kiÓu d÷ liÖu cña 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

2. §äc c¸c ¶nh OpenGL


OpenGL cung cÊp ba hµm c¬ së ®Ó thao t¸c víi c¸c d÷ liÖu ®iÓm ¶nh:
glReadPixels(), glDrawPixels(), glCopyPixel(). Hµm glReadPixels() sao chÐp mét
h×nh ch÷ nhËt tõ vïng ®Öm mµu vµ l−u d÷ liÖu trong bé nhí. VÝ dô, c¸c dßng sau ®Þnh
nghÜa l−u tr÷ cho mét ¶nh vµ ®äc d÷ liÖu ¶nh tõ vïng ®Öm mµu vµo kho l−u tr÷:
GLubyte image[64][64][3];
glReadPixels (0,0,64,64,GL_RGB, GL_UNSIGNED_BYTE, image);
Trong vÝ dô trªn, vïng l−u tr÷ ®−îc ®Þnh nghÜa nh− mét m¶ng ba chiÒu cã thÓ l−u ¶nh
64x64, chøa ®ùng tæ hîp 3 ®iÓm ¶nh, mµ trong tr−êng hîp nµy lµ gi¸ trÞ RGB. ViÖc
gäi hµm glReadPixels() thùc hiÖn ®äc d÷ liÖu ¶nh tõ vïng ®Öm mµu vµ l−u tr÷ nã vµo
trong m¶ng image[][][]. B¶ng tham sè cña hµm lµ to¹ ®é X vµ Y cña gãc thÊp tr¸i cña
h×nh ch÷ nhËt, ®é réng vµ chiÒu cao cña h×nh ch÷ nhËt, kiÓu cña d÷ liÖu ®iÓm ¶nh ®Ó
®äc, kiÓu d÷ liÖu cña d÷ liÖu ®ã, vµ ®Þa chØ cña vïng ®Öm mµ nã l−u gi÷ d÷ liÖu ¶nh.
ViÖc gäi hµm trªn thùc hiÖn ®äc mét ¶nh 64x64 tõ gãc thÊp tr¸i cña vïng ®Öm mµu.
¶nh ®−îc ®Æc tr−ng bëi c¸c thµnh phÇn red, green vµ blue mµ nã ®−îc l−u tr÷ lµ kiÓu
byte kh«ng dÊu.

3. VÏ c¸c ¶nh OpenGL


Mét khi b¹n cã d÷ liÖu ¶nh trong bé nhí, b¹n cã thÓ sö dông hµm
glDrawPixels() ®Ó biÓu diÔn d÷ liÖu ®ã lªn mµn h×nh. B¹n cã thÓ biÓu diÔn ¶nh ®· l−u
tr÷ tr−íc ®ã víi hµm ®−îc gäi nh− sau:
glDrawPixels(64,64,GL_UNSIGNED_BYTE, image);
Hµm nµy biÓu diÔn ¶nh ë vÞ trÝ l−íi hiÖn hµnh, 5 ®èi môc cña hµm nµy lµ ®é
réng vµ chiÒu cao cña ¶nh, kiÓu ®iÓm ¶nh cña d÷ liÖu ¶nh, kiÓu d÷ liÖu cña d÷ liÖu
¶nh vµ ®Þa chØ cña image.

_ 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.

4. T×m hiÓu thao t¸c ¶nh


§o¹n m· sau t¹o lËp mét ¶nh RGB trong bé nhí, biÓu diÔn ¶nh lªn gãc ph¶i
thÊp cña cöa sæ, nh− sau:
GLubyte image1[64][64][3];
GLubyte image2[64][64][3];
for (int i=0; i<64; i++)
for (int j=0; j<64; j++)
{
image1[i][j][0] = (GLubyte) 0;
image1[i][j][1] = (GLubyte) 0;
image1[i][j][2] = (GLubyte) (255-i*3.5);
}
glRasterPos3f(-1.0f,-1.0f,0.0f);
glDrawPixels (64,64,GL_RGB,GL_UNSIGNED_BYTE, image1);
GLint rasPos[4];
glGetIntergerv(GL_CURRENT_RASTER_POSTION, rasPos);
glReadPixels(rasPos[0],rasPos[1],64,64,
GL_RGB,GL_UNSIGNED_BYTE, image2);
glRasterPos3f(1.0f,1.0f,0.0f);
glDrawPixels(64,64,GL_RGB,GL_UNSIGNED_BYTE, image2);
glFlush();

Gäi hµm glGetIntegerv() víi h»ng GL_CURRENT_RASTER_POSITION vµ


®Þa chØ cña m¶ng bèn phÇn tö GLint mµ hµm sÏ l−u vÞ trÝ l−íi hiÖn hµnh trong to¹ ®é
cña sæ.

5. Mét sè hµm kh¸c


Cã c¸c hµm CreateBitmap(), LoadBitmap(), StretchDIBits() vµ BitBlt() gióp
b¹n cã thÓ t¹o lËp, l¹p hoÆc biÓu diÔn bitmap lªn mµn h×nh nh−ng b¹n sÏ kh«ng t×m
thÊy c¸c hµm t−¬ng tù cho c¸c ®Þnh d¹ng ¶nh kh¸c trong ch−¬ng tr×nh Window.

_ 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.

6. §Þnh d¹ng DIB


Mét DIB ®−îc l−u tr÷ trªn ®Üa hoÆc trong bé nhí, hÇu hÕt cã cïng cÊu tróc.
Trªn thùc tÕ, DIB ®−îc lµm dùa trªn c¸c kiÓu kh¸c nhau cña c¸c cÊu tróc theo sau.
C¸c cÊu tróc nµy gåm :
6.1. CÊu tróc BITMAPFILEHEADER
B¾t ®Çu cña mét file DIB lµ cÊu tróc BITMAPFILEHEADER ®−îc ®Þnh nghÜa
bëi Window nh− sau:
typedef struct tag BITMAPFILEHEADER
{
WORD bfType;
DWORD bfSide;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOff Bits;
}BITMAPFILEHEADER;
CÊu tróc nµy n»m ë ®Çu cña mét file bitmap, nã kh«ng nhÊt thiÕt lµ mét phÇn
cña bitmap khi l−u trong bé nhí. Thµnh phÇn ®Çu tiªn cña cÊu tróc lµ bfType x¸c
®Þnh file lµ mét bitmap vµ sÏ lµ m· ASCII cña ch÷ BM. Trong hÖ 16, tõ trong bfTyte
sÏ lµ 4D42. Víi c¸c gi¸ trÞ kh¸c, file thùc sù kh«ng ph¶i lµ bitmap. Thµnh phÇn thø 2
lµ bfSize cung cÊp kÝch th−íc cña file bitmap tÝnh theo byte. Tuy nhiªn, cã lóc cã sù
kh«ng râ rµng trong tµi liÖu gèc cña Window, bfSide sÏ kh«ng chÝnh x¸c vµ cã thÓ bÞ
bá qua. Theo c¸ch kh¸c, b¹n cã thÓ ®Õm trªn thµnh phÇn bfOffBit chøa sè c¸c byte tõ
®Çu cña file tíi d÷ liÖu bitmap.

_ 56 _
§å ho¹ 3D víi OpenGL

bfType : chøa gi¸ trÞ ASCII lµ BM


bfSide : kÝch th−íc cña file
bfReserved1 : lu«n lu«n b»ng 0
bfReserved2 : lu«n lu«n b»ng 0
bfOffBits : sè c¸c byte tõ ®Çu cña file tíi d÷ liÖu bitmap
6.2. CÊu tróc BITMAPINFO
Sau cÊu tróc BITMAPFILEHEADER lµ cÊu tróc BITMAPINFO, nã ®−îc ®Þnh
nghÜa bëi Window nh− sau:
typedef struct tag GITMAPINFO
{
BITMAPINFOHEADER bmiHeqder;
RGBQUAD bmiColors[1];
}BITMAPINFO;
CÊu tróc nµy ®−îc dùa trªn tiªu ®Ò ®Æc tr−ng bëi cÊu tróc BITMAPINFOHEADER vµ
b¶ng mÇu ®Æc tr−ng bëi mét b¶ng mÇu cña cÊu tróc RGBQUAD,
6.3. CÊu tróc BITMAPINFOHEADER
typedef struct tag BITMAPINFOHEADER
{
DWORD biSize;
DWORD biwidth;
DWORD biHeight;
DWORD biPlanes;
DWORD biBitCount;
DWORD biCompresion;
DWORD biSizeImage;
DWORD biXPelsPerMeter;
DWORD biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
}BITMAPINFOHEADER;
Thµnh phÇn biSize chøa kÝch th−íc cña cÊu tróc BITMAPINFOHEADER, nã
sÏ lÎ 40 byte. Thµnh phÇn biWidth vµ biHeight lµ bÒ réng vµ chiÒu cao cña bitmap
tÝnh theo sè ®iÓm ¶nh. Thµnh phÇn biPlanes lu«n lu«n ®−îc ®Æt lµ 1. Thµnh phÇn
biBitCount chØ râ sè bit trªn ®iÓm ¶nh cã thÓ lµ 1, 4, 8 hoÆc 24 vµ chØ râ chÕ ®é ®¬n
s¾c, 16 mÇu, 256 mÇu hoÆc 167 triÖu mÇu.

_ 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

7. Giíi thiÖu líp CDib


Líp CDib ®äc DIB tõ ®Üa vµo bé nhí vµ cho l¹i c¸c th«ng tin quan träng vÒ
DIB :

_ 58 _
§å ho¹ 3D víi OpenGL

#ifndef __CDIB_H //Header file of DIB class: CDIB.H


#define __CDIB_H
class CDib: public CObject
{
protected:
LPBITMAPFILEHEADER m_pBmFileHeader;
LPBITMAPINFO m_pBmInfo;
LPBITMAPINFOHEADER m_pBmInfoHeader;
RGBQUAD *m_pRGBTable;
BYTE *m_pDibBits;
UINT m_numColors;
public
CDib (const char * filename);
~CDib();
DWORD GetDibSizeImage();//returns size in bytes of the image.
UINT GetDibwidth();//returns the DIB's width in Pixels.
UINT GetDibheight();//returns the DIB's heihgt in Pixels.
LPBITMAPINFOHEADER GetDibInfoHeaderPtr();
UINT GetDibNumColors();//returns the number of colors in DIB
LPBITMAPINFFO GetDibInfoPtr();
LPRGBQUAD GetDibRGBTablePtr();
BYTE * GetDibBitsPtr();
protected:
void LoadBitmapFile(const char * filename);
};
#endif __CDIB_H

//----------------------------------------------------------
// 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);

// Read the bitmap's file header into memory


BITMAPFILEHEADER bmfileHeader;
file.Read((void*)& bmfileHeader, sizeof(bmfileHeader));
if (bmfieHeader.bfType != 0x4d42)
{
AfxMessageBox("Not a bitmap file");
m_pBmFileHeader=0;
m_pBmInfo=0;
m_pBmInfoHeader=0;
m_pRGBTable=0;
m_pDibBits=0;
m_numColors=0;
}
else
{
// Calculate the size of the DIB, which is the file size minus the size
// of file header
DWORD fileLength=file.GetLength();
DWORD dibSize = fileLength - sizeof(bmFileHeader);
//Allowcate enough memory to fit the bitmap
BYTE * pDib = (BYTE*)GlobalAllocPtr(GMEM_MOVEABLE,
dibSize);
file.Read((void*) pDib, dibSize);
file.Close();
m_pBmInfo = (LPBITMAPINFO) pDib;
m_pBmInfoHeader = (LPBITMAPINFOHEADER) pDib;
m_pRGBTable=(RGBQUAD*)(pDib+m_pBmInfoHeader->biSize);
int m_numColor = GetDibNumColors();

_ 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.
//----------------------------------------

8. ¸p dông ¸nh x¹ ¶nh (texture mapping) lªn mét ®a gi¸c


Víi texture mapping nã thùc hiÖn d¸n mét ¶nh lªn mét bÒ mÆt cña mét ®a gi¸c.
Nã lµ mét qu¸ tr×nh xö lý phøc t¹p nh−ng OpenGL ®iÒu khiÓn tÊt c¶ c¸c phÐp to¸n
cho b¹n. §Ó lµm texture mapping lªn mét ®a gi¸c b¹n chØ cÇn ®Æt vµi tham sè vµ b¶o
víi OpenGL t×m ¶nh ë ®©u mµ b¹n muèn ¸nh x¹ lªn ®a gi¸c. Dï vËy sÏ cã vµi ®iÓm
phøc t¹p n÷a sÏ thÊy trong môc sau.
8.1. C¸c ¶nh chèng l¹i c¸c DIB
VÊn ®Ò ®ã lµ bé mÆt ch−¬ng tr×nh WindowNI ®ang b¶o víi OpenGL ®iÒu khiÓn
¶nh nh− thÕ nµo ®ã ®Ó nã ®−îc t¹o lËp vµ sö dông trong c¸c ch−¬ng tr×nh ®å ho¹
Windows. §Æc ®iÓm chung nhÊt cña ¶nh sö dông víi Windows lµ ¶nh kh«ng phô
thuéc vµo bitmap, mµ b¹n ®· häc c¸ch ®Ó n¹p vµo bé nhí ë môc tr−íc. OpenGL
kh«ng cung cÊp trùc tiÕp c¸c øng dông cña DIB theo trËt tù cho OpenGL ®Ó sö dông
DIB trong viÖc xö lý texture mapping cña nã, b¹n ph¶i b¶o víi OpenGL lµm thÕ nµo
®Ó hiÓu d÷ liÖu ¶nh cña DIB.
B¹n còng ph¶i ®iÒu khiÓn ¶nh ®å ho¹ nh− thÕ nµo trong OpenGL phô thuéc vµo
kiÓu ¶nh. VÝ dô DIB 265 mÇu chøa c¸c chØ sè mÇu x¸c ®Þnh mét mÇu trong b¶ng mÇu

_ 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

204 186 240 252 0.80000 0.72941 0.94118 252


236 202 250 253 0.92549 0.79216 0.98039 253
255 230 255 254 1.00000 0.90196 1.00000 254
255 255 255 255 1.00000 1.00000 1.00000 255
3
IMAGE DATA
252
0

2
255
254

8.3. ChuyÓn c¸c b¶ng mÇu tíi OpenGL


Sau khi t¹o lËp c¸c b¶ng mÇu cña DIB b¹n ph¶i b¸o víi OpenGL cµi ®Æt b¶ng
¸nh x¹, vµ b¶o víi nã b¶ng ®ã ë ®©u. B¹n lµm viÖc nµy bëi gäi hµm PixelMapfv nh−
sau:
glPixelMapfv (GL_PIXEL_MAP_I_TO_R, 256, m_red);
glPixelMapfv (GL_PIXEL_MAP_I_TO_G, 256, m_green);
glPixelMapfv (GL_PIXEL_MAP_I_TO_B, 256, m_blue);
Ba ®èi môc cña hµm lµ : kiÓu ¸nh x¹, kÝch th−íc b¶ng mÇu, vµ ®Þa chØ cña b¶n
®å mÇu. Hµm nµy cã hai d¹ng kh¸c lµ glPixelMapuiv() vµ glPixelMapusv(). B¹n ph¶i
gäi glPixelMapfv() ba lÇn øng víi mçi b¶ng mÇu red, green vµ blue.
C¸c kiÓu ¸nh x¹ cho hµm glPixelMap() :

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

GL_PIXEL_MAP_I_TO_B ChØ sè mµu tíi thµnh phÇn Blue


GL_PIXEL_MAP_I_TO_G ChØ sè mµu tíi thµnh phÇn Green
GL_PIXEL_MAP_I_TO_I ChØ sè mµu tíi chØ sè mµu
GL_PIXEL_MAP_I_TO_R ChØ sè mµu tíi thµnh phÇn Red
GL_PIXEL_MAP_R_TO_R ¸nh x¹ tõ thµnh phÇn Red tíi thµnh phÇn Red
GL_PIXEL_MAP_S_TO_S ¸nh x¹ tõ chØ sè stencil tíi chØ sè stencil

8.4. BËt b¶n ®å mµu


B¹n ®· t¹o lËp b¶ng mÇu cña b¹n vµ chuyÓn chóng ®Õn OpenGL. Sau ®ã chØ
viÖc gäi hµm glTransferi() ®Ó bËt b¶n ®å mÇu nh− sau:
glPixel Transferi(GL_MAP_COLOR, TRUE);
Hµm ®Æt chÕ ®é ®æi ®iÓm ¶nh, cã hai ®èi môc : mét h»ng x¸c ®Þnh chÕ ®é chuyÓn ®æi
®iÓm ¶nh vµ gi¸ trÞ mµ nã chØ râ gi¸ trÞ chuyÓn ®æi. Hµm nµy cã nhiÒu øng dông.
8.5. Cµi ®Æt b¶n ®å l−íi d¸n ¶nh
Mét khi b¹n cã file DIB ®· n¹p vµ c¸c b¶ng mµu ®· ®−îc t¹o lËp. B−íc ®Çu
tiªn lµ b¶o víi OpenGL b¹n muèn viÖc texture mapping cÇn ®−îc thùc hiÖn nh− thÕ
nµo. B¹n lµm viÖc nµy bëi viÖc gäi hµm glTexParameteri() ®Ó ®Æt c¸c biÕn tham sè
texture mapping nh− sau:
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,
GL_NEAREST); //MAG: magnified
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,
GL_NEAREST); //MIN: minfied
C¸c ®èi môc cña hµm glTexParameteri() lµ c¸c h»ng x¸c ®Þnh kiÓu cña texture,
kiÓu cña tham sè vµ gi¸ trÞ tham sè ®−îc ®Æt. Hµm nµy cã bèn d¹ng phô thuéc vµo
kiÓu cña c¸c ®èi môc ®−îc sö dông.
§èi môc ®Çu tiªn ph¶i lµ GL_TEXTURE_1D cho Texture mét chiÒu, hoÆc
GL_TEXTURE_2D cho texture hai chiÒu. B¹n sÏ th−êng xuyªn sö texture hai chiÒu,
nã lµ mét ¶nh h×nh ch÷ nhËt. §èi môc thø hai x¸c ®Þnh tham sè ®Ó b¶o víi OpenGL
viÖc ®iÓu khiÓn texture mapping nh− thÕ nµo d−íi mét sè ®iÒu kiÖn nµo ®ã. VÝ dô,
GL_TEXTURE_WRAP_S vµ GL_TEXTURE_SWAP_I b¶o víi OpenGL sö dông
texture ®¬n hay kÐp khi ¸p dông texture ngang hay däc, ®Ó ®Æc tr−ng cho c¸c tham sè
nµy ph¶i ®−îc ®Æt GL_CLAMP (cho ¶nh ®¬n) hoÆc GL_REPEAT (cho mÉu lÆp l¹i).
¸p dông cho mét ¶nh ®¬n ¸nh x¹ lªn ®a gi¸c sö dông GL_CLAMP, tr−êng hîp kh¸c
cã thÓ sÏ cã kÕt qu¶ rÊt l¹.

_ 65 _
§å ho¹ 3D víi OpenGL

Hai tham sè mapping texture kh¸c b¹n sÏ sö dông lµ :


GL_TEXTURE_MAPPING_FILTER x¸c ®Þnh mét texture ®−îc më réng nh− thÕ
nµo khi vïng ®Ých lín h¬n texture, vµ GL_TEXTURE_MIN_FILTER x¸c ®Þnh
texture ®−îc lµm nhá ®i nh− thÕ nµo khi vïng ®Ých nhá h¬n texture. Sö dông
GL_NEAREST cho tham sè nµy, cho phÐp ¸nh x¹ texture nhanh h¬n vµ còng t¹o ra
¶nh s¾c c¹nh nhÊt. GL_LINEAR cho kÕt qu¶ chËm h¬n v× ph¶i tÝnh to¸n mÇu cho
®iÓm ¶nh dùa trªn gi¸ trung h×nh cña 4 ®iÓm ¶nh c¬ së tèt h¬n lµ mét ®iÓm ¶nh.
Sau khi ®Æt c¸c tham sè texture b¹n ph¶i cµi ®Æt m«i tr−êng texture, vµ b¶o víi
OpenGL hµm texture ph¶i lµm g× ®Ó tÝnh c¸c gi¸ trÞ mÇu cho nét bÒ mÆt texture. Nã
thùc sù chØ yªu cÇu mét hµm ®−îc gäi:
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
Hµm nµy ®Æt m«i tr−êng texture. §èi môc ®Çu tiªn cña nã ph¶i lµ h»ng
GL_TEXTURE_ENV. T−¬ng tù ®èi môc thø hai ph¶i lµ
GL_TEXTURE_ENV_MODE. Cuèi cïng, ®èi môc thø ba lµ h»ng x¸c ®Þnh texture
mµ OpenGL sÏ sö dông vµ ph¶i lµ GL_BLIND, GL_DECAL, hoÆc
GL_MODULATE. HÇu hÕt tr−êng hîp, b¹n sÏ th−êng sö dông GL_DECAL, nã lµ
hµm ®Ó thay thÕ ®iÓm ¶nh ®Ých bëi texture.
B−íc cuèi cïng lµ bËt ¸nh x¹ texture mµ b¹n ®· t¹o víi viÖc gäi hµm
glEnable() nh− sau :
glEnable(GL_TEXTURE_2D);
NÕu b¹n ®ang sö dông texture mét chiÒu, b¹n sÏ ph¶i sö dông
GL_TEXTURE_1D lµm ®èi môc ®¬n cña glEnable().

9. §Þnh nghÜa c¸c ®Ønh vµ c¸c texture cña chóng


§Ó chuyÓn cho OpenGL texture cña b¹n, ®Þnh nghÜa c¸c ®Ønh cña ®a gi¸c, vµ
b¶o víi OpenGL c¸c ®Ønh cña ®a gi¸c cã liªn hÖ víi c¸c to¹ ®é texture nh− thÕ nµo.
B¹n lµm viÖc ®ã nh− sau:
glTexImage2D(GL_TEXTURE_2D, 0, 3, width, height, 0, GL_COLOR_INDEX,
GL_UNSIGNED_BYTE, pTextureBits);
glBegin (GL_POLYGON);
glTexCoord2f (0.0f, 1.0f);
glVertex3f (-1.0f, 1.0f, 0.0f);
glTexCoord2f (0.0f, 0.0f);
glVertex3f (-1.0f, -1.0f, 0.0f);
glTexCoord2f (1.0f, 0.0f);
glVertex3f (1.0f, -1.0f, 0.0f);
glTexCoord2f (1.0f, 1.0f);
glVertex3f (1.0f, 1.0f, 0.0f);
glEnd();
glFlush( );

_ 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);

1.2. Chän c¸c chøc n¨ng pha trén


Mét khi b¹n cã thÓ lµm viÖc víi sù pha trén, b¹n ph¶i b¶o víi OpenGL nã sÏ
phèi hîp c¸c mÇu nh− thÕ nµo. B¹n lµm viÖc nµy bëi viÖc gäi hµm glBlendFund() ®Ó
lùa c¸c chøc n¨ng pha trén nguån vµ ®Ých nh− sau:
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Hµm nµy cã c¸c ®èi môc x¸c ®Þnh c¸c chøc n¨ng pha trén nguån vµ ®Ých.
C¸c h»ng pha trén ®iÓm nguån :

H»ng HÖ sè kÕt qu¶


GL_DST_ALPHA (AD,AD,AD,AD)
GL_DST_COLOR (RD,GD,BD,AD)

_ 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)

C¸c h»ng pha trén ®iÓm ®Ých :

H»ng HÖ sè kÕt qu¶


GL_DST_ALPHA (AD,AD,AD,AD)
GL_ONE (1,1,1,1)
GL_ONE_MINUS_DST_ALPHA (1,1,1,1)-(AD,AD,AD,AD)
GL_ONE_MINUS_SRC_ALPHA (1,1,1,1)-(AS,AS,AS,AS)
GL_ONE_MINUS_SRC_COLOR (1,1,1,1)-(RS,GS,BS,AS)
GL_SRC_ALPHA (AS,AS,AS,AS)
GL_SRC_COLOR (RS,GS,BS,AS)
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.

2. Pha trén c¸c ®a gi¸c


NÕu b¹n ®ang thö pha trén c¸c ®a gi¸c (®ã lµ c¸c ®èi t−îng hai chiÒu), tÊt c¶
viÖc b¹n cÇn lµm b©y giê lµ chän mÇu vÏ cña b¹n vµ vÏ h×nh víi OpenGL råi ¸p dông
c¸c hµm pha trén vµ vÏ c¸c kÕt qu¶ ®ã lªn mµn h×nh. VÝ dô:
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glColor4f(0.0f, 1.0f, 1.0f, 1.0f);
glBegin(GL_POLYGON);
glVertex3f(-1.0f, 0.25f, 0.0f);

_ 70 _
§å ho¹ 3D víi OpenGL

glVertex3f(-1.0f, -1.0f, 0.0f);


glVertex3f(0.25f, -1.0f, 0.0f);
glVertex3f(0.25f, 0.25f, 0.0f);
glEnd();
glColor4f(1.0f, 0.0f, 0.0f, 0.5f);
glBegin(GL_POLYGON)
glVertex3f(-0.25f, 1.0f, 0.0f);
glVertex3f(-0.25f, -0.25f, 0.0f);
glVertex3f(1.0f, -0.25f, 0.0f);
glVertex3f(1.0f, 1.0f, 0.0f);
glEnd();
glFlush();
glDisable(GL_BLEND);

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.

3. Pha trén c¸c ®èi t−îng 3D


Sö dông pha trén cho c¸c h×nh 3D phøc t¹p h¬n trong 2D bëi v× viÖc kiÓm tra
®é s©u cña OpenGL cã thÓ cã theo c¸ch nh÷ng g× b¹n ®ang thö lµm. VÝ dô, nÕu b¹n
vÏ mét h×nh lËp ph−¬ng ®Æc vµ råi vÏ h×nh hép trong míi, viÖc kiÓm tra ®é s©u cña
OpenGL sÏ cho kÕt qu¶ ®èi t−îng bÞ che kh«ng ®−îc thÓ hiÖn. Sau ®ã, trong khi
kiÓm tra ®é s©u, ®èi t−îng bÞ di chuyÓn, nã bÞ che khuÊt bëi c¸c ®èi t−îng kh¸c. Sù
phèi hîp pha trén vËt thÓ trong 3D, b¹n ph¶i lµm theo c¸c b−íc sau:
1- Lµm cho cã thÓ kiÓm tra ®é s©u.
2- VÏ tÊt c¶ c¸c ®èi t−îng mê ®ôc.
3- §Æt vïng ®Öm s©u ë chÕ ®é chØ ®äc.
4- VÏ tÊt c¶ c¸c ®èi t−îng trong mê.
5- Tr¶ l¹i vïng ®Öm s©u vÒ chÕ ®é ®äc vµ ghi.
TÊt nhiªn, c¸c b−íc nµy kh«ng thÓ hiÖn c¸c kÕ thõa phøc t¹p kh¸c trong viÖc
thÓ hiÖn m« h×nh 3D, bao gåm viÖc khëi t¹o m« h×nh ¸nh s¸ng vµ thùc hiÖn c¸c phÐp
biÕn ®æi m« h×nh quan s¸t. Nh−ng c«ng viÖc quan träng trong danh s¸ch c«ng viÖc
nµy lµ ®Æt vïng ®Öm s©u thµnh chØ ®äc tr−íc khi vÏ c¸c ®èi t−îng trong mê. OpenGL
sö dông vïng ®Öm s©u ®Ó x¸c ®Þnh c¸c h×nh n»m sau c¸c h×nh kh¸c. Víi viÖc lµm
vïng ®Öm s©u thµnh chØ ®äc, b¹n ng¨n kh«ng cho OpenGL thay ®æi t×nh tr¹ng cña
vïng ®Öm s©u khi b¹n vÏ c¸c ®èi t−îng trong mê. NÕu OpenGL kh«ng thÓ thay ®æi

_ 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

glRotatef (4.0f, 1.0f, 0.0f, 0.0f);


glRotatef(40.0f, 0.0f, 1.0f, 0.0f);
auxSolidCube(1.0);
glFlush();
glDepthMask(GL_TRUE);
glDisble(GL_LIGHTING);
glDisble(GL_DEPTH_TEST);
glDisble(GL_BLEND);

4. Sö dông phÐp thö r¨ng c−a


Bëi v× c¸c ®−êng th¼ng trªn mµn h×nh m¸y tÝnh ®−îc vÏ bëi c¸c ®iÓm ¶nh ®−îc
chiÕu s¸ng, chØ c¸c ®−êng th¼ng ngang vµ ®øng míi ®−îc vÏ hoµn toµn tr¬n.
4.1. Lµm cã thÓ khö r¨ng c−a
Nh− víi sù pha trén, ®iÒu ®Çu tiªn b¹n ph¶i lµm ®Ó sö dông antialiasing lµ lµm
cho cã thÓ khö r¨ng c−a. B¹n lµm ®iÒu nµy bëi viÖc gäi hµm glEnable() nh− sau:
glEnable(GL_LINE_SMOOTH);
H»ng GL_LINE_SMOOTH b¶o víi OpenGL lµm cã thÓ khö r¨ng c−a cho c¸c
®−êng th¼ng. B¹n còng cã thÓ lµm cã thÓ khö r¨ng c−a cho c¸c ®iÓm hoÆc ®a gi¸c nhê
sö dông GL_POINT_SMOOTH hoÆc GL_POLYGON_SMOOTH.
4.2. Lµm cã thÓ pha trén cho sù khö r¨ng c−a
Bëi v× sù khö r¨ng c−a lµ mét kÕt qu¶ pha trén, b¹n còng ph¶i lµm cho cã thÓ
pha trén còng nh− lùa viÖc chän hµm pha trén. B¹n cã thÓ sö dông ®o¹n m· nh− sau:
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
B¹n cã thÓ thö víi c¸c hµm pha trén kh¸c theo trËt tù ®Ó t¹o c¸c kÕt qu¶ khö
r¨ng c−a kh¸c nhau. Dï vËy, b¹n sÏ cã thÓ sö dông c¸c hµm pha trén nguån vµ ®Ých
GL_SRC_ALPHA vµ GL_ONE_MINUS_SRC_ALPHA. Nhí r»ng nÕu b¹n chän
GL_SRC_ALPHA vµ GL_ONE_MINUS_SRC_ALPHA, thµnh phÇn mµu alpha cña
®èi t−îng còng cÇn ®−îc cung cÊp.
4.3. Lµm tr¬n dÊu vÕt OpenGL
glHint (GL_LINE_SMOOTH_HINT, GL_DON’T_CARE);
§èi môc ®Çu x¸c ®Þnh c¸ch mµ b¹n muèn lµm tr¬n dÊu vÕt vµ cã thÓ lµ mét
trong c¸c h»ng sau:
GL_FOG_HINT

_ 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).

5. Sö dông viÖc lµm mê


Kh«ng khÝ còng gièng nh− bÊt kú vËt liÖu nµo, nã kh«ng hoµn toµn trong suèt.
¸nh s¸ng ®i qua kh«ng khÝ, mét phÇn cña c¸c thµnh phÇn mÇu cña ¸nh s¸ng sÏ cã
mét phÇn hoÆc bÞ hÊp thô hoµn toµn.
5.1. Lµm cã thÓ lµm mê
Nh− b¹n cã thÓ ®· dù ®o¸n, b−íc ®Çu tiªn trong sö dông s−¬ng mê lµ b¶o víi
OpenGL lµm cho cã thÓ lµm mê. B¹n lu«n ph¶i lµm ®iÒu nµy bëi viÖc gäi hµm
glEnable() nh− sau:
glEnable(GL_FOG);
GL_FOG lµ h»ng b¶o víi OpenGL lµm cho cã thÓ lµm mê.
5.2. Chän hµm lµm mê
Nh− víi sù pha trén, OpenGL cã thÓ ¸p dông lµm mê theo nhiÒu c¸ch. Nã
®−îc ®Æt trong ch−¬ng tr×nh cña b¹n ®Ó b¶o víi OpenGL c¸c hµm lµm mê ®−îc sö
dông khi nã x¸c ®Þnh mÇu cuèi cïng cña mét ®iÓm ¶nh ®−îc thÓ hiÖn. B¹n lµm ®iÒu
nµy bëi viÖc gäi hµm glFogf() nh− sau:
glFogf(GL_FOG_MODE, GL_LINEAR);
§èi môc ®Çu cña hµm nµy x¸c ®Þnh tham sè lµm mê b¹n muèn ®Æt vµ cã thÓ lµ:
GL_FOG_DENSITY, GL_FOG_END, GL_FOG_INDEX, GL_FOG_MODE hoÆc
GL_FOG_START. §èi môc thø hai lµ gi¸ trÞ tham sè ®−îc ®Æt. Trong tr−êng hîp cña
GL_FOG_MODE gi¸ trÞ cã thÓ cho trong ®èi môc thø hai lµ: GL_EXP, GL_EXP2 vµ
GL_LINEAR. Hµm glFog() cã 4 phiªn b¶n phô thuéc vµo kiÓu cña ®èi môc ®−îc sö
dông.
GL_EXP vµ GL_EXP2 sö dông c¸c hµm sè mò ®Ó x¸c ®Þnh mÇu ®iÓm ¶nh
®−îc lµm mê, víi hµm GL_EXP2 cã kÕt qu¶ lín h¬n GL_EXP. Bëi v× OpenGL ®iÒu
khiÓn hÇu hÕt c¸c chi tiÕt, c¸c hµm GL_EXP vµ GL_EXP2 lµ dÔ nhÊt ®Ó sö dông
trong ch−¬ng tr×nh cña b¹n. Dï vËy hµm GL_LINEAR, mµ viÖc ¸p dông hµm mê dùa
trªn kÝch th−íc cña vïng ®−îc lµm mê, ®−a cho b¹n hÇu hÕt c¸c ®iÒu khiÓn. B¹n b¶o
víi OpenGL, sù lµm mê b¾t ®Çu vµ kÕt thóc chÝnh x¸c ë ®©u trong c¶nh vÏ cña b¹n.
B¹n lµm viÖc nµy chØ bëi gäi hµm glFogf() nh− sau:

_ 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

Ch−¬ng 4 : Ch−¬ng tr×nh OpenGL tèi thiÓu 12


1. C¸c kiÓu d÷ liÖu 12
2. Ng÷ c¶nh diÔn t¶ 12
3. C¸c ®Þnh d¹ng ®iÓm ¶nh 13
4. CÊu tróc PIXELFORMATDESCRIPTOR 13
5. Khëi t¹o cÊu tróc PIXELFORMATDESCRIPTOR 16
6. T¹o lËp mét ng÷ c¶nh diÔn t¶ 18
7. C¸c hµm ng÷ c¶nh diÔn t¶ kh¸c 21

Ch−¬ng 5 : VÏ h×nh vµ sö dông mÇu 22


1. Có ph¸p cña c¸c hµm OpenGL 22
2. OpenGL vµ c¸c tr¹ng th¸i 23
3. §Þnh nghÜa vµ vÏ c¸c ®iÓm 26
4. §Þnh nghÜa vµ vÏ c¸c ®−êng 28

Ch−¬ng 6 : C¸c phÐp biÕn h×nh OpenGL 38


1. Lùa chän ma trËn chiÕu 38
2. Khëi t¹o ma trËn 38
3. §Þnh nghÜa mét khèi quan s¸t 38
4. PhÐp biÕn ®æi m« h×nh quan s¸t 39
5. PhÐp chuyÓn ®æi khung nh×n 42

Ch−¬ng 7 : ChiÕu s¸ng c¸c ®èi t−îng 3D 44


1. C¸c kiÓu cña ¸nh s¸ng 44
2. §Þnh nghÜa mét nguån s¸ng 44
3. Lµm cho c¸c nguån s¸ng lµm viÖc 45
4. §Þnh nghÜa c¸c ®Æc tÝnh vËt liÖu 45
5. §Þnh nghÜa c¸c chuÈn 46
6. X¸c ®Þnh m« h×nh t« bãng vµ kiÓm tra ®é s©u cã thÓ 48
7. §Þnh nghÜa mét ®èm s¸ng 48
8. BiÓu diÔn c¸c ®èi t−îng 3D ®· ®−îc chiÕu s¸ng 48

_ 76 _
§å ho¹ 3D víi OpenGL

Ch−¬ng 8 : T¹o lËp h×nh thÓ 3D 51


1. Sö dông c¸c ng¨n xÕp ma trËn 51
2. Vïng ®Öm kÐp trong OpenGL 51
3. KÕt hîp c¸c vïng ®Öm kÐp 51

Ch−¬ng 9 : ¶nh vµ d¸n ¶nh (texture mapping) 53


1. C¸c ¶nh Bitmap vµ c¸c ¶nh kh¸c trong ch−¬ng tr×nh OpenGL 53
2. §äc c¸c ¶nh OpenGL 54
3. VÏ c¸c ¶nh OpenGL 54
4. T×m hiÓu thao t¸c ¶nh 55
5. Mét sè hµm kh¸c 55
6. §Þnh d¹ng DIB 56
7. Giíi thiÖu líp CDib 58
8. ¸p dông ¸nh x¹ ¶nh lªn mét ®a gi¸c 62
9. §Þnh nghÜa c¸c ®Þnh vµ c¸c texture cña chóng 66

Ch−¬ng 10 : Sö dông sù pha trén, khö r¨ng c−a vµ s−¬ng mï 68


1. Sö dông pha trén 68
2. Pha trén c¸c ®a gi¸c 70
3. Pha trén c¸c ®æi t−îng 3D 71
4. Sö dông phÐp khö r¨ng c−a 73
5. Sö dông viÖc lµm mê 74

_ 77 _

You might also like