1. Trang chủ
  2. » Công Nghệ Thông Tin

beginning opengl game programming 2004 phần 9 pps

26 370 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 26
Dung lượng 570,18 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Next is the RenderFontmethod, which displays a string of text using the selected bitmap font at a specified raster position: void CGfxOpenGL::RenderFontint xPos, int yPos, unsigned int b

Trang 1

setting up the bitmap font for use with Windows through the wglUseFontBitmaps()

func-tion, the CreateBitmapFont()method returns the base ID for the character display list

Next is the RenderFont()method, which displays a string of text using the selected bitmap

font at a specified raster position:

void CGfxOpenGL::RenderFont(int xPos, int yPos, unsigned int base, char *str)

{

if ((base == 0) || (!str)) return;

TheRenderFont()method is very simple in that it verifies the base ID and string it receives

before setting the raster position and rendering the text display list Finally, we have the

ReleaseFont()method, which simply cleans up the font display list:

void CGfxOpenGL::ReleaseFont(unsigned int base)

{

if (base != 0) glDeleteLists(base, 96);

}

The rest of the code uses these functions to display the screenshot shown in Figure 11.1

The example is set up in orthographic projection We recommend orthographic

projec-tion when rendering with bitmap fonts because it enables you to specify the raster

posi-tion coordinates in window coordinates, and you don’t need to worry about the

perspective projection affecting the raster position

That’s all for bitmap fonts! Let’s look at another technique for putting text on the screen:

outline fonts

Outline Fonts

Outline fonts are very similar to the bitmap fonts we just discussed, but they are much

more fun to play around with! Outline fonts define characters in a font as a series of lines

and curves, which means they can be scaled up and down without a loss in quality With

Trang 2

OpenGL, you can move outline font text around the screen in 3D, give the font text somethickness, and essentially turn any font on the current system into a 3D font with all thefunctionality of other 3D objects.

To use outline fonts, you first need to declare an array of 256 GLYPHMETRICSFLOATvariables,which hold information about the placement and orientation of a glyph in a charactercell TheGLYPHMETRICSFLOATstructure is a special structure created specifically for using textwith OpenGL It is defined as:

typedef struct _GLYPHMETRICSFLOAT { // gmf FLOAT gmfBlackBoxX;

You’ll pass the GLYPHMETRICSFLOATvariable you create to the wglUseFontOutlines()function

This function creates a set of display lists, one for each glyph of the current outline font,which you can use to render text to the screen This function is defined as:

BOOL wglUseFontOutlines(

HDC hdc, // device context of the outline font DWORD first, // first glyph to be turned into a display list DWORD count, // number of glyphs to be turned into display lists DWORD listBase, // specifies the starting display list

FLOAT deviation, // specifies the maximum chordal deviation from the

// true outlines FLOAT extrusion, // extrusion value in the negative-z direction int format, // specifies line segments or polygons in display lists LPGLYPHMETRICSFLOAT lpgmf // address of buffer to receive glyph metric data );

Creation of the outline font is essentially the same as the bitmap font with the addition ofthese two items For instance, compare the CreateBitmapFont()function we showed earlierwith this CreateOutlineFont()function:

unsigned int CreateOutlineFont(char *fontName, int fontSize, float depth) {

HFONT hFont; // windows font unsigned int base;

base = glGenLists(256); // create storage for 256 characters

if (stricmp(fontName, “symbol”) == 0)

Chapter 11 ■ Displaying Text254

Trang 3

{ hFont = CreateFont(fontSize, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE,

SYMBOL_CHARSET, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY, FF_DONTCARE | DEFAULT_PITCH, fontName);

} else { hFont = CreateFont(fontSize, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE,

ANSI_CHARSET, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY, FF_DONTCARE | DEFAULT_PITCH, fontName);

}

if (!hFont) return 0;

SelectObject(g_HDC, hFont);

wglUseFontOutlines(g_HDC, 0, 255, base, 0.0f, depth, WGL_FONT_POLYGONS, gmf);

return base;

}

As you can see, this function is very similar to the CreateBitmapFont()method we showed

earlier, but there are a few differences The first difference you might notice is the addition

of the depth parameter, which is used by the wglUseFontOutlines()function to define the

length of the outline font text along the z-axis (or essentially the depth of the font) The

next difference is that you create 256 display lists instead of 96 This is because you

want to provide support for all the 256 available ASCII codes And lastly, you use the

wglUseFontOutlines()function to finalize the setup of the outline fonts for OpenGL

Displaying outline font text is exactly the same as displaying bitmap font text Because you

used all 256 ASCII codes when initializing the outline font, here is how the display code

On the CD included with this book you will find the OutlineFont example for Chapter 11

This example renders text as an outline font to the window and rotates it A screenshot is

shown in Figure 11.2

Trang 4

The majority of the code for this example is the same as the BitmapFont example, so wewill focus only on the RenderFont()method because it is the most different:

void CGfxOpenGL::RenderFont(float xPos, float yPos, float zPos, unsigned int base, char *str)

{ float length = 0.0;

if ((base == 0) || (!str)) return;

// center the text for (int idx = 0; idx < (int)strlen(str); idx++) // find length of text {

length += gmf[str[idx]].gmfCellIncX; // increase length by character’s width }

glTranslatef(-length/2.0f, yPos, zPos);

Trang 5

TheRenderFont()method includes some code that centers the text on the point in space to

which the text is being drawn This is accomplished through a loop that goes through each

character in the text string that you are displaying During each iteration of the loop, you

add the character’s width, which you obtain from the GLYPHMETRICSFLOATvariable, to a

vari-able that stores the sum of all the characters’ widths You then translate your coordinate

system along the negative x-axis by half the total length of the text string, resulting in the

text being centered on the (xPos,yPos, zPos) point in 3D space.

Also, the glRotatef()calls you see in the method are there only for demonstration

pur-poses and should not be in the RenderFont()method during normal use

You can also texture map outline fonts since they are constructed of polygons Instead of

trying to figure out the texture coordinates on your own, you can use OpenGL’s automatic

texture-coordinate generation functionality to texture map the text You can find more

information on texture-coordinate generation in Chapter 9, “More on Texture Mapping.”

Using glFont

glFontis both a program executable and an API with source code that takes any Windows

TrueType font and turns it into an OpenGL texture.glFontdetermines the appropriate

texture coordinates and displays text with correct spacing and size on an OpenGL

quadri-lateral Its design is not for 3D text, but rather for 2D text for use in games and other

graphics applications where 3D text is overkill

You can find glFonton the CD included with this book, or you can get it from the glFont

Web site at http://students.cs.byu.edu/~bfish/glfont.php

The Executable

The program included with glFontis glFont.exe, which is a simple-to-use program for

creating font textures that the glFontAPI code can read and display The process for using

Trang 6

4 Generate the texture.

5 Save the texture to a GLF file

Explore and experiment!

Summary

In this chapter you learned how to display and position 2D text with bitmap fonts usingthe wglUseFontBitmaps() function and display lists You also learned how to display andposition 3D text with outline fonts using the wglUseFontOutlines()function Finally, weintroduced the glFontOpenGL font library, which you can use and modify to suit yourtext rendering purposes

What You Have Learned

■ ThewglUseFontBitmaps()function generates bitmap fonts from the font files loaded

on the execution system

Chapter 11 ■ Displaying Text258

Trang 7

■ Display lists can be used to render each character of a font.

■ When rendering bitmap fonts, you should use an orthographic perspective tion to simplify positioning the text

projec-■ ThewglUseFontOutlines()function creates a set of display lists, one for each glyph

of the current outline font

■ TheGLYPHMETRICSFLOATstruct is used when creating outline fonts This struct isincluded particularly for rendering text with OpenGL

■ You can texture map outline fonts and specify texture coordinates with the matic texture coordinate generation functionality provided with OpenGL

auto-■ glFontis both a program executable and an API with source code that takes anyWindows TrueType font and turns it into an OpenGL texture

Review Questions

1 What “wiggle” function is used to create bitmap fonts?

2 What “wiggle” function is used to create outline fonts?

3 How do you texture map outline fonts?

Trang 8

This page intentionally left blank

Trang 9

OpenGL Buffers

chapter 12

We’ve been discussing buffers is some form for quite some time now but

haven’t really taken the time to discuss them in detail For instance, we’veused the color and depth buffers in nearly every example thus far for func-tions such as double-buffering and hidden surface removal In this chapter, we’ll extend

beyond these basic functionalities while also looking at two more buffers, called the

sten-cil buffer and the accumulation buffer

In this chapter, you’ll learn:

■ What the framebuffer is

■ What general operations can be performed on buffers

■ How to use the alpha test, color masking, and logic ops

■ How to use the depth buffer

■ How to use the stencil buffer

■ How to use the accumulation buffer

What Is an OpenGL Buffer?

There are several buffers in OpenGL that you can use and manipulate, but just what exactly

is a buffer? Simply put, a buffer is a set of sequential locations in memory In OpenGL, a

buffer is section of memory that is used to represent some aspect of the display For

exam-ple, the color buffer stores RGBA data for each pixel on the screen or window

All the buffers in a system are collectively referred to as the framebuffer So with OpenGL,

the color buffer, depth buffer, stencil buffer, and accumulation buffer combine to give you

Trang 10

a single framebuffer When you operate on any OpenGL buffer, you are operating on theframebuffer.

Before discussing individual buffer types, we’ll first look at a couple of operations thatapply to all of the buffers: clearing and scissoring

Clearing the Buffers

The most basic operation you can perform on a buffer is to clear out the previous tents This is done using glClear():

con-void glClear(GLbitfield mask);

You’ve already seen this in action in all ofthe demos presented so far, so it shouldlook familiar The mask parameter is thebitwise logical ORof a combination of thevalues listed in Table 12.1

Each buffer has a default value, and whenyou clear it, each element in the buffer isset to that value As with most areas ofOpenGL, you can set the default clearvalues to your own custom values You do so with the following APIs:

void glClearColor(GLclampf red, GLclampf green, GLclampf green, GLclampf alpha);

void glClearDepth(GLclampd depth);

void glClearStencil(GLint i);

void glClearAccum(GLclampf red, GLclampf green, GLclampf green, GLclampf alpha);

TheGLclamptypes are used for parameters that are internally clamped to fall within 0.0 and1.0 The default values for all buffers are 0, except for the depth buffer, which is 1.0, cor-responding to the value that represents elements that are farthest away from the camera

Scissor Boxes

OpenGL allows you to define a scissor box that limits rendering to a sub-region of the

screen When scissoring is enabled, any pixel writes outside of the box are ignored Thisapplies to not only color values, but depth, stencil, and accumulation buffer values as well

Scissoring is one of the few operations that also affect the operation ofglClear(); when it

is enabled, only pixels inside of the scissor box will be cleared

You can enable scissoring by passing GL_SCISSOR_TESTto glEnable() The size of the scissorbox is defined using:

void glScissor(GLint x, GLint y, GLsizei width, GLsizei height);

Chapter 12 ■ OpenGL Buffers262

Table 12.1 Clear Mask Values

GL_COLOR_BUFFER_BIT RGBA color buffer

GL_DEPTH_BUFFER_BIT Depth buffer

GL_STENCIL_BUFFER_BIT Stencil buffer

GL_ACCUM_BUFFER_BIT Accumulation buffer

Trang 11

Thexandyvalues correspond to the screen coordinates of the lower left corner of the box

(the lower left corner of the screen is at (0, 0)) widthandheightare the dimensions of the

box in pixels The scissor box is set to the size of the window when a rendering context is

first attached to it

The following code shows an example of setting up a scissor box such as that shown in

Figure 12.1

glEnable(GL_SCISSOR_TEST);

glScissor(200, 250, 240, 180);

The Color Buffer

The color buffer stores RGBA data for each pixel on the screen Almost everything discussed

in this book relates to the color buffer in some way There are a few operations in addition

to those that we’ve already discussed that affect the color buffer on a per-fragment basis,

and those will be described in this section

Alpha Test

Every incoming fragment has an alpha value associated with it Even if you don’t specify

it yourself, it gets set to the default value of 1 The alpha test can be used to discard

frag-ments based on their alpha value Practical applications for this include being able to

dis-card transparent components of images

Figure 12.1 An example of a scissor box.

Trang 12

For example, say you are using the image in Figure12.2 for billboarding, in which you apply the image

as a texture to a screen-oriented quad to cheaplyfake a 3D cactus When applying the texture map,you would want to draw only the pixels that make

up the cactus Drawing the black area around itwould ruin the effect Alpha testing is the best way

to do this

The first step is to initialize the texture with priate values, such as an alpha of 0 in the blackareas and 1 everywhere else The next step is toenable the alpha test, which you would do with:

appro-glEnable(GL_ALPHA_TEST);

Then you need to set up the alpha function The alpha function controls exactly how thecomparison is done It is specified by using:

void glAlphaFunc(GLenum func, GLclampf reference);

funcis an enumeration specifying the comparison function Valid values are listed in Table12.2 The incoming fragment alpha is compared against the referencevalue Continuingwith the cactus example, setting up the alpha function as follows would reject the blackpixels (with an alpha of 0) and accept everything else

glAlphaFunc(GL_GREATER, 0.0);

The alpha test is an easy to use tool that has many practical applications in games

Chapter 12 ■ OpenGL Buffers264

Table 12.2 Alpha Test Functions

Function Description

GL_NEVER Never pass, regardless of the fragment or reference alpha values.

GL_ALWAYS Always pass, regardless of the fragment or reference alpha values This is the default.

GL_LESS Pass if the fragment alpha is less than the reference value.

GL_LEQUAL Pass if the fragment alpha is less than or equal to the reference value.

GL_EQUAL Pass if the fragment alpha is equal to the reference value.

GL_GEQUAL Pass if the fragment alpha is greater than or equal to the reference value.

GL_GREATER Pass if the fragment alpha is greater than the reference value.

GL_NOTEQUAL Pass if the fragment alpha not equal to the reference value.

Figure 12.2 An image used as a

billboard texture

Trang 13

Color Masking

OpenGL allows you to disable writing to specific color channels This can be used to

cre-ate some interesting effects For example, some multipass rendering algorithms require

you to modify the depth buffer without actually writing color values Another use might

be to disable writing to everything but the green channel to create a cheap night vision

effect

This is known as color masking, and it is controlled through the following API:

void glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);

PassingGL_FALSEas the red,green, blue, or alphaparameter will disable writes for that

chan-nel.GL_TRUEis used to enable writes By default, all of the channels are enabled, as you’d

expect

The color mask affects all operations that may potentially modify the color buffer,

includ-ing clears

Logical Operations

OpenGL allows you to create some

interest-ing effects by performinterest-ing logical operations

between the incoming fragment and the

value in the color buffer These are executed

as bitwise logical operations between each

of the individual red, green, blue, and alpha

components of the two colors The

result-ing value is then stored in the color buffer

Logic ops are enabled by passing

GL_COLOR_LOGIC_OP to glEnable() You can

specify which specific operation to perform

by using:

void glLogicOp(GLenum op);

op can be any of the enumerants listed in

Table 12.3, where the fragment color is

rep-resented as s, the value in the color buffer is

d, and the resulting color is c The notation

used corresponds to the C/C++ notation

for bitwise operations

Table 12.3 Logical Operations

GL_AND c = s & d GL_AND_REVERSE c = s & (~d)

Ngày đăng: 05/08/2014, 10:20

TỪ KHÓA LIÊN QUAN