Выбрать главу

 glPrint(200,48,1,(char *)glGetString(GL_VENDOR)); // Display Vendor Name

 glPrint(200,80,1,(char *)glGetString(GL_VERSION)); // Display Version

 glColor3f(0.5f,0.5f,1.0f); // Set Color To Bright Blue

 glPrint(192,432,1,"NeHe Productions"); // Write NeHe Productions At The Bottom Of The Screen

Now we draw a nice white border around the screen, and around the text. We start off by resetting the modelview matrix. Because we've been printing text to the screen, and we might not be at 0,0 on the screen, it's a safe thing to do.

We then set the color to white, and start drawing our borders. A line strip is actually pretty easy to use. You tell OpenGL you want to draw a line strip with glBegin(GL_LINE_STRIP). Then we set the first vertex. Our first vertex will be on the far right side of the screen, and about 63 pixels up from the bottom of the screen (639 on the x axis, 417 on the y axis). Then we set the second vertex. We stay at the same location on the y axis (417), but we move to the far left side of the screen on the x axis (0). A line will be drawn from the right side of the screen (639,417) to the left side of the screen (0,417).

You need to have at least two vertices in order to draw a line (common sense). From the left side of the screen, we move down, right, and then straight up (128 on the y axis).

We then start another line strip, and draw a second box at the top of the screen. If you need to draw ALOT of connected lines, line strips can definitely cut down on the amount of code required as opposed to using regular lines (GL_LINES).

 glLoadIdentity(); // Reset The ModelView Matrix

 glColor3f(1.0f,1.0f,1.0f); // Set The Color To White

 glBegin(GL_LINE_STRIP); // Start Drawing Line Strips (Something New)

  glVertex2d(639,417); // Top Right Of Bottom Box

  glVertex2d( 0,417); // Top Left Of Bottom Box

  glVertex2d( 0,480); // Lower Left Of Bottom Box

  glVertex2d(639,480); // Lower Right Of Bottom Box

  glVertex2d(639,128); // Up To Bottom Right Of Top Box

 glEnd(); // Done First Line Strip

 glBegin(GL_LINE_STRIP); // Start Drawing Another Line Strip

  glVertex2d( 0,128); // Bottom Left Of Top Box

  glVertex2d(639,128); // Bottom Right Of Top Box

  glVertex2d(639, 1); // Top Right Of Top Box

  glVertex2d( 0, 1); // Top Left Of Top Box

  glVertex2d( 0,417); // Down To Top Left Of Bottom Box

 glEnd(); // Done Second Line Strip

Now for something new. A wonderful GL command called glScissor(x,y,w,h). What this command does is creates almost what you would call a window. When GL_SCISSOR_TEST is enabled, the only portion of the screen that you can alter is the portion inside the scissor window. The first line below creates a scissor window starting at 1 on the x axis, and 13.5% (0.135…f) of the way from the bottom of the screen on the y axis. The scissor window will be 638 pixels wide (swidth-2), and 59.7% (0.597…f) of the screen tall.

In the next line we enable scissor testing. Anything we draw OUTSIDE the scissor window will not show up. You could draw a HUGE quad on the screen from 0,0 to 639,480, and you would only see the quad inside the scissor window, the rest of the screen would be unaffected. Very nice command!

The third line of code creates a variable called text that will hold the characters returned by glGetString(GL_EXTENSIONS). malloc(strlen((char *)glGetString(GL_EXTENSIONS))+1) allocates enough memory to hold the entire string returned +1 (so if the string was 50 characters, text would be able to hold all 50 characters).

The next line copies the GL_EXTENSIONS information to text. If we modify the GL_EXTENSIONS information directly, big problems will occur, so instead we copy the information into text, and then manipulate the information stored in text. Basically we're just taking a copy, and storing it in the variable text.

 glScissor(1, int(0.135416f*sheight), swidth-2, int(0.597916f*sheight)); // Define Scissor Region

 glEnable(GL_SCISSOR_TEST); // Enable Scissor Testing

 char* text=(char*)malloc(strlen((char *)glGetString(GL_EXTENSIONS))+1); // Allocate Memory For Our Extension String

 strcpy (text, (char *)glGetString(GL_EXTENSIONS)); // Grab The Extension List, Store In Text

Now for something new. Lets pretend that after grabbing the extension information from the video card, the variable text had the following string of text stored in it… "GL_ARB_multitexture GL_EXT_abgr GL_EXT_bgra". strtok(TextToAnalyze,TextToFind) will scan through the variable text until it finds a " " (space). Once it finds a space, it will copy the text UP TO the space into the variable token. So in our little example, token would be equal to "GL_ARB_multitexture". The space is then replaced with a marker . More about this in a minute.

Next we create a loop that stops once there is no more information left in text. If there is no information in text, token will be equal to nothing (NULL) and the loop will stop.

We increase the counter variable (cnt) by one, and then check to see if the value in cnt is higher than the value of maxtokens. If cnt is higher than maxtokens we make maxtokens equal to cnt. That way if the counter hits 20, maxtokens will also equal 20. It's an easy way to keep track of the maximum value of cnt.

 token=strtok(text, " "); // Parse 'text' For Words, Seperated By " " (spaces)

 while (token!=NULL) // While The Token Isn't NULL

 {

  cnt++; // Increase The Counter

  if (cnt>maxtokens) // Is 'maxtokens' Less Than 'cnt'

  {

   maxtokens=cnt; // If So, Set 'maxtokens' Equal To 'cnt'

  }

So we have stored the first extension from our list of extensions in the variable token. Next thing to do is set the color to bright green. We then print the variable cnt on the left side of the screen. Notice that we print at 0 on the x axis. This should erase the left (white) border that we drew, but because scissor testing is on, pixels drawn at 0 on the x axis wont be modified. The border can't be drawn over.

The variable is drawn on the far left side of the screen (0 on the x axis). We start drawing at 96 on the y axis. To keep all the text from drawing to the same spot on the screen, we add (cnt*32) to 96. So if we are displaying the first extension, cnt will equal 1, and the text will be drawn at 96+(32*1) (128) on the y axis. If we display the second extension, cnt will equal 2, and the text will be drawn at 96+(32*2) (160) on the y axis.

Notice I also subtract scroll. When the program first runs, scroll will be equal to 0. So our first line of text is drawn at 96+(32*1)-0. If you press the DOWN ARROW, scroll is increased by 2. If scroll was 4, the text would be drawn at 96+(32*1)-4. That means the text would be drawn at 124 instead of 128 on the y axis because of scroll being equal to 4. The top of our scissor window ends at 128 on the y axis. Any part of the text drawn from lines 124-127 on the y axis will not appear on the screen.

Same thing with the bottom of the screen. If cnt was equal to 11 and scroll was equal to 0, the text would be drawn at 96+(32*11)-0 which is 448 on the y axis. Because the scissor window only allows us to draw as far as line 416 on the y axis, the text wouldn't show up at all.

The final result is that we end up with a scrollable window that only allows us to look at 288/32 (9) lines of text. 288 is the height of our scissor window. 32 is the height of the text. By changing the value of scroll we can move the text up or down (offset the text).

The effect is similar to a movie projector. The film rolls by the lens, and all you see is the current frame. You don't see the area above or below the frame. The lens acts as a window similar to the window created by the scissor test.