OpenGL display list

Source: Internet
Author: User

Original article: Lesson 12: Display lists
Translated by: marhoo

This time I will teach you how to use the display list. displaying the list will speed up the program and reduce the code length.
When you are creating an in-game minor scenario, at least two planets are required on each layer. You can use the polygon in OpenGL to construct each planet. The clever way to do this is to create a loop where each cycle draws a plane of the planet, and you finally draw a planet with dozens of statements. It is very difficult to draw a planet on the screen every time. When you face more complex objects, you will understand.
So what is the solution? To use the reality list, you only need to create an object at a time. You can map objects, use colors, and get what you want. Name the real list. For example, name the display list of the Minor Planet "asteroid ". Now, whenever I want to draw a planet on the screen, I just need to call glcalllist (asteroid ). The previously prepared minor will be immediately displayed on the screen. Because the minor has been built in the display list, OpenGL no longer calculates how to construct it. It has been built in the memory. This will greatly reduce the CPU usage and make your program run faster.
Then, start learning. I call this demo Q-Bert to display the list. In the end, this demo will plot 15 cubes on the screen. Each cube consists of a box and a top. The top is a separate display list without a top.
This course is based on the Sixth lesson. I will rewrite most of the Code to make it easy to understand. The following code is almost used in all courses.

# Include <windows. h> // header file for Windows
# Include <stdio. h> // header file for standard input/output
# Include <Gl/Gl. h> // header file for the opengl32 Library
# Include <Gl/Glu. h> // header file for the glu32 Library
# Include <Gl/Glaux. h> // header file for the Glaux Library

HDC = NULL; // Private GDI device context
Hglrc HRC = NULL; // permanent rendering context
Hwnd = NULL; // holds our window handle
Hinstance; // the instance of the application

Bool keys [256]; // Array Used for the keyboard routine
Bool active = true; // window active flag set to true by default
Bool fullscreen = true; // fullscreen flag set to fullscreen mode by default

Set the variables below. The first is to store the texture variables, and then two new variables are used to display the list. These variables are pointers to the display list in the memory. Name box and top.
Then, xloop is used to represent the position of the cube on the screen. xrot and yrot represent the rotation of the cube.

Gluint texture [1]; // storage for one texture
Gluint box; // storage for the display list
Gluint top; // storage for the second display list
Gluint xloop; // loop for X axis
Gluint yloop; // loop for Y axis

Glfloat xrot; // rotates cube on the X axis
Glfloat yrot; // rotates cube on the Y axis

Next, we will create two color arrays.

Static glfloat boxcol [5] [3] = // array for Box colors
{
// Bright: red, orange, yellow, green, blue
{1.0f, 0.0f, 0.0f}, {1.0f, 0.5f, 0.0f}, {1.0f, 1.0f, 0.0f}, {0.0f, 1.0f, 0.0f}, {0.0f, 1.0f, 1.0f}
};

Static glfloat topcol [5] [3] = // array for top colors
{
// Dark: red, orange, yellow, green, blue
{. 5f, 0.0f, 0.0f}, {0.5f, 0.25f, 0.0f}, {0.5f, 0.5f, 0.0f}, {0.0f, 0.5f, 0.0f}, {0.0f, 0.5f, 0.5f}
};

Lresult callback wndproc (hwnd, uint, wparam, lparam); // Declaration for wndproc

Now, create a display list. You may notice that all the code for creating the box is in the first display list, and all the code for creating the top is in another list. I will try to explain these details.

Glvoid buildlists () // build box display list
{

At the beginning, we told OpenGL that we wanted to create two display lists. Glgenlists (2) creates two display lists and returns the pointer to the first display list. "Box" points to the first display list. When "box" is called, The first display list is displayed.

Box = glgenlists (2); // building two lists

Create the first display list. We have applied for two display list spaces, and the box Pointer Points to the first display list. So now we should tell OpenGL what type of display list to create.
We use the glnewlist () command to do this. You must note that box is the first parameter, which means OpenGL will store the list to the memory space pointed to by box. The second parameter gl_compile tells OpenGL that we want to construct this list in memory in advance, so that we do not have to re-Calculate how to construct the object each time we draw it.
Gl_compile is similar to programming. When you write a program, load it into the compiler. Every time you run the program, you need to re-compile it. If he has already compiled the. exe file, you can click the. exe file to run it every time without compiling. After OpenGL compiles the display list, it does not need to be re-compiled every time it is displayed. This is why displaying a list can speed up.

Glnewlist (box, gl_compile); // New Compiled box display list

The code below draws a box without a top, which will not appear on the screen and will only be stored in the display list.
You can add any code you want to add between glnewlist () and glengist. You can set colors, textures, and so on. The only code that cannot be added is the code that will change the display list. Once a list is created, you cannot change it.
For example, you want to add glcolor3ub (RAND () % 255, Rand () % 255, Rand () % 255) so that each painting will have a different color. However, because the display list is only created once, the color of each object is not changed. The object will remain the color when the list is created for the first time. If you want to change the color of the display list, you only need to change the color before calling the display list. This will be explained in detail later.

Glbegin (gl_quads); // start drawing quads

// Bottom face
Gltexcoord2f (1.0f, 1.0f); glvertex3f (-1.0f,-1.0f,-1.0f); // top right of the texture and quad
Gltexcoord2f (0.0f, 1.0f); glvertex3f (1.0f,-1.0f,-1.0f); // top left of the texture and quad
Gltexcoord2f (0.0f, 0.0f); glvertex3f (1.0f,-1.0f, 1.0f); // bottom left of the texture and quad
Gltexcoord2f (1.0f, 0.0f); glvertex3f (-1.0f,-1.0f, 1.0f); // bottom right of the texture and quad

// Front face
Gltexcoord2f (0.0f, 0.0f); glvertex3f (-1.0f,-1.0f, 1.0f); // bottom left of the texture and quad
Gltexcoord2f (1.0f, 0.0f); glvertex3f (1.0f,-1.0f, 1.0f); // bottom right of the texture and quad
Gltexcoord2f (1.0f, 1.0f); glvertex3f (1.0f, 1.0f, 1.0f); // top right of the texture and quad
Gltexcoord2f (0.0f, 1.0f); glvertex3f (-1.0f, 1.0f, 1.0f); // top left of the texture and quad

// Back face
Gltexcoord2f (1.0f, 0.0f); glvertex3f (-1.0f,-1.0f,-1.0f); // bottom right of the texture and quad
Gltexcoord2f (1.0f, 1.0f); glvertex3f (-1.0f, 1.0f,-1.0f); // top right of the texture and quad
Gltexcoord2f (0.0f, 1.0f); glvertex3f (1.0f, 1.0f,-1.0f); // top left of the texture and quad
Gltexcoord2f (0.0f, 0.0f); glvertex3f (1.0f,-1.0f,-1.0f); // bottom left of the texture and quad

// Right face
Gltexcoord2f (1.0f, 0.0f); glvertex3f (1.0f,-1.0f,-1.0f); // bottom right of the texture and quad
Gltexcoord2f (1.0f, 1.0f); glvertex3f (1.0f, 1.0f,-1.0f); // top right of the texture and quad
Gltexcoord2f (0.0f, 1.0f); glvertex3f (1.0f, 1.0f, 1.0f); // top left of the texture and quad
Gltexcoord2f (0.0f, 0.0f); glvertex3f (1.0f,-1.0f, 1.0f); // bottom left of the texture and quad

// Left face
Gltexcoord2f (0.0f, 0.0f); glvertex3f (-1.0f,-1.0f,-1.0f); // bottom left of the texture and quad
Gltexcoord2f (1.0f, 0.0f); glvertex3f (-1.0f,-1.0f, 1.0f); // bottom right of the texture and quad
Gltexcoord2f (1.0f, 1.0f); glvertex3f (-1.0f, 1.0f, 1.0f); // top right of the texture and quad
Gltexcoord2f (0.0f, 1.0f); glvertex3f (-1.0f, 1.0f,-1.0f); // top left of the texture and quad

Glend (); // done drawing quads

Using the glenglist () command, we tell OpenGL that we have completed a display list. Anything between glnewlist () and glengist () is part of the display list.

Glendlist (); // done building the box list

Now let's create the second display list. Add 1 to the pointer of the previous display list to get the pointer of the second display list. The pointer to the second display list is named "TOP ".

Top = Box + 1; // top list value is box list value + 1

Now that we know the pointer to the second display list, we can create it.

Glnewlist (top, gl_compile); // New Compiled top display list

The following code draws the top of the box.

Glbegin (gl_quads); // start drawing quad

// Top face
Gltexcoord2f (0.0f, 1.0f); glvertex3f (-1.0f, 1.0f,-1.0f); // top left of the texture and quad
Gltexcoord2f (0.0f, 0.0f); glvertex3f (-1.0f, 1.0f, 1.0f); // bottom left of the texture and quad
Gltexcoord2f (1.0f, 0.0f); glvertex3f (1.0f, 1.0f, 1.0f); // bottom right of the texture and quad
Gltexcoord2f (1.0f, 1.0f); glvertex3f (1.0f, 1.0f,-1.0f); // top right of the texture and quad

Glend (); // done drawing quad

Then, it tells OpenGL that the second display list has been created.

Glendlist (); // done building the top display list
}

The texture map code is the same as the code in the previous tutorial. We need a texture that can be attached to the cube. I decided to use mipmapping to smooth the texture, because I hate to see pixels. The texture file name is cube.bmp, which is stored in the data directory.

If (textureimage [0] = loadbmp ("Data/cube.bmp") // load the bitmap

The code for changing the window size is the same as that in Lesson 6.
The initialization code has only one change, and a line of buildlist () is added (). Pay attention to the code order. First, read the texture, and then create a display list. Then, when we create a display list, we can paste the texture to the cube.

Int initgl (glvoid) // all setup for OpenGL goes here
{
If (! Loadgltextures () // jump to texture loading routine
{
Return false; // If texture didn't load return false
}
Buildlists (); // jump to the code that creates our display lists
Glable (gl_texture_2d); // enable Texture Mapping
Glshademodel (gl_smooth); // enable smooth Shading
Glclearcolor (0.0f, 0.0f, 0.0f, 0.5f); // black background
Glcleardepth (1.0f); // depth buffer setup
Glable (gl_depth_test); // enables depth Testing
Gldepthfunc (gl_lequal); // The type of depth testing to do

The next three lines make the light effective. Generally, light0 is pre-defined in the video card. If light0 does not work, comment out the following line.
The gl_color_material of the last line enables us to paste textures with colors. Without this line of code, the texture will always keep the original color, and glcolor3f (R, G, B) will be useless. In short, this line of code is very useful.

Glable (gl_light0); // quick and dirty lighting (assumes light0 is set up)
Glable (gl_lighting); // enable Lighting
Glable (gl_color_material); // enable material coloring

Finally, set projection correction and return true.

Glhint (gl_perspective_correction_hint, gl_nicest); // nice perspective correction
Return true; // initialization went OK

Now let's look at the painting code. I have always been a big math. I don't have sin or cos, but it still looks strange (I believe readers won't think it's big ). First, clear the screen and depth buffering as usual.
Then bind the texture to the cube (I know the word bundling is not very professional, ......). You can put this line in the display list, but outside it, you can modify it at any time.

Int drawglscene (glvoid) // here's where we do all the drawing
{
Glclear (gl_color_buffer_bit | gl_depth_buffer_bit); // clear the screen and the depth buffer
Glbindtexture (gl_texture_2d, texture [0]); // select the texture

Now it's really interesting. Use a cycle variable to change the position of the Y axis and draw five cubes on the Y axis. Therefore, use a cycle from 1 to 5.

For (yloop = 1; yloop <6; yloop ++) // loop through the Y plane
{

In addition, a loop variable is used to change the position of the X axis. The number of cubes on each row depends on the number of rows, so the cycle is as follows.

For (xloop = 0; xloop <yloop; xloop ++) // loop through the X plane
{
Glloadidentity (); // reset the view

The code below is to move and rotate the current coordinate system to the position where the cube needs to be drawn. (The original article has a very long story. I believe everyone has a good math skills, so I will not translate it)

Glloadidentity (); // reset the view
// Position the cubes on the screen
Gltranslatef (1.4f + (float (xloop) * 2.8f)-(float (yloop) * 1.4f), (6.0f-float (yloop) * 2.4f)-7.0f, -20366f );

Glrotatef (45.0f-(2.0f * yloop) + xrot, 1.0f, 0.0f, 0.0f); // tilt the cubes up and down
Glrotatef (45.0f + yrot, 0.0f, 1.0f, 0.0f); // spin cubes left and right

Then set the color before the box is officially painted. Each box is in a different color.

Glcolor3fv (boxcol [yloop-1]); // select a box color

Okay, set the color. What we need to do now is to draw a box. You do not need to write the code for drawing a polygon. You only need to use the glcalllist (box) command to call the display list. The box will be painted with the color set by glcolor3fv.

Glcalllist (box); // draw the box

Then draw the top with another color. Done.

Glcolor3fv (topcol [yloop-1]); // select the top color

Glcalllist (top); // draw the top
}
}
Return true; // jump back
}

The following code controls the keyboard.

Swapbuffers (HDC); // swap buffers (double buffering)
If (Keys [vk_left]) // left arrow being pressed?
{
Yrot-= 0.2f; // if so spin cubes left
}
If (Keys [vk_right]) // right arrow being pressed?
{
Yrot + = 0.2f; // if so spin cubes right
}
If (Keys [vk_up]) // Up Arrow being pressed?
{
Xrot-= 0.2f; // If So tilt cubes up
}
If (Keys [vk_down]) // Down Arrow being pressed?
{
Xrot + = 0.2f; // If So tilt cubes down
}

As with the previous guide, make sure that the title at the top of the window is correct.

If (Keys [vk_f1]) // is F1 being pressed?
{
Keys [vk_f1] = false; // if so make key false
Killglwindow (); // kill our current window
Fullscreen =! Fullscreen; // toggle fullscreen/appswed Mode
// Recreate our OpenGL window
If (! Createglwindow ("nehe's display list tutorial ",
640,480, 16, fullscreen ))
{
Return 0; // quit if window was not created
}
}
}
}
}

This article from the csdn blog, reproduced please indicate the source: http://blog.csdn.net/lovetangtang/archive/2006/01/16/580599.aspx

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.