以文本方式查看主题 - 计算机科学论坛 (http://bbs.xml.org.cn/index.asp) -- 『 C/C++编程思想 』 (http://bbs.xml.org.cn/list.asp?boardid=61) ---- [推荐]NeHe OpenGL教程(中英文版附带VC++源码)Lesson 05-lesson 06 (http://bbs.xml.org.cn/dispbbs.asp?boardid=61&rootid=&id=53706) |
-- 作者:一分之千 -- 发布时间:10/13/2007 9:54:00 AM -- Lesson 05 Expanding on the last tutorial, we'll now make the object into TRUE 3D object, rather than 2D objects in a 3D world. We will do this by adding a left, back, and right side to the triangle, and a left, right, back, top and bottom to the square. By doing this, we turn the triangle into a pyramid, and the square into a cube. We'll blend the colors on the pyramid, creating a smoothly colored object, and for the square we'll color each face a different color. int DrawGLScene(GLvoid) // Here's Where We Do All The Drawing glRotatef(rtri,0.0f,1.0f,0.0f); // Rotate The Pyramid On It's Y Axis glBegin(GL_TRIANGLES); // Start Drawing The Pyramid The following code will create the pyramid around a central axis. The top of the pyramid is one high from the center, the bottom of the pyramid is one down from the center. The top point is right in the middle (zero), and the bottom points are one left from center, and one right from center. Note that all triangles are drawn in a counterclockwise rotation. This is important, and will be explained in a future tutorial, for now, just know that it's good practice to make objects either clockwise or counterclockwise, but you shouldn't mix the two unless you have a reason to. We start off by drawing the Front Face. Because all of the faces share the top point, we will make this point red on all of the triangles. The color on the bottom two points of the triangles will alternate. The front face will have a green left point and a blue right point. Then the triangle on the right side will have a blue left point and a green right point. By alternating the bottom two colors on each face, we make a common colored point at the bottom of each face. glColor3f(1.0f,0.0f,0.0f); // Red Notice the left point is drawn blue this time. By drawing it blue, it will be the same color as the right bottom corner of the front face. Blending blue outwards from that one corner across both the front and right face of the pyramid. Notice how the remaining three faces are included inside the same glBegin(GL_TRIANGLES) and glEnd() as the first face. Because we're making this entire object out of triangles, OpenGL will know that every three points we plot are the three points of a triangle. Once it's drawn three points, if there are three more points, it will assume another triangle needs to be drawn. If you were to put four points instead of three, OpenGL would draw the first three and assume the fourth point is the start of a new triangle. It would not draw a Quad. So make sure you don't add any extra points by accident. glColor3f(1.0f,0.0f,0.0f); // Red glColor3f(1.0f,0.0f,0.0f); // Red We're done drawing the pyramid. Because the pyramid only spins on the Y axis, we will never see the bottom, so there is no need to put a bottom on the pyramid. If you feel like experimenting, try adding a bottom using a quad, then rotate on the X axis to see if you've done it correctly. Make sure the color used on each corner of the quad matches up with the colors being used at the four corners of the pyramid. glColor3f(1.0f,0.0f,0.0f); // Red Notice we move the cube a little further into the screen in this lesson. By doing this, the size of the cube appears closer to the size of the pyramid. If you were to move it only 6 units into the screen, the cube would appear much larger than the pyramid, and parts of it might get cut off by the sides of the screen. You can play around with this setting, and see how moving the cube further into the screen makes it appear smaller, and moving it closer makes it appear larger. The reason this happens is perspective. Objects in the distance should appear smaller :) glLoadIdentity(); glRotatef(rquad,1.0f,1.0f,1.0f); // Rotate The Cube On X, Y & Z glBegin(GL_QUADS); // Start Drawing The Cube glColor3f(0.0f,1.0f,0.0f); // Set The Color To Green If you didn't really care about the order the polygons were drawn in (clockwise or not), you could just copy the same code for the top quad, move it down on the Y axis to -1, and it would work, but ignoring the order the quad is drawn in can cause weird results once you get into fancy things such as texture mapping. glColor3f(1.0f,0.5f,0.0f); // Set The Color To Orange glColor3f(1.0f,0.0f,0.0f); // Set The Color To Red glColor3f(1.0f,1.0f,0.0f); // Set The Color To Yellow glColor3f(0.0f,0.0f,1.0f); // Set The Color To Blue Or if you felt like experimenting, you could always try changing the color of each point on the cube to make it blend the same way the pyramid blends. You can see an example of a blended cube by downloading Evil's first GL demo from my web page. Run it and press TAB. You'll see a beautifully colored cube, with colors flowing across all the faces. glColor3f(1.0f,0.0f,1.0f); // Set The Color To Violet rtri+=0.2f; // Increase The Rotation Variable For The Triangle If you're having a hard time understanding 3D space, don't get frustrated. It can be difficult to grasp right off the start. An object like the cube is a good example to learn from. If you notice, the back face is drawn exactly the same as the front face, it's just further into the screen. Play around with the code, and if you just can't grasp it, email me, and I'll try to answer your questions. Jeff Molofee (NeHe) |
-- 作者:一分之千 -- 发布时间:10/13/2007 9:57:00 AM -- 第六课 在这一课里,我将教会你如何把纹理映射到立方体的六个面。 #include <stdio.h> // 标准输入/输出库的头文件 GLfloat xrot; // X 旋转量 GLuint texture[1]; // 存储一个纹理 AUX_RGBImageRec *LoadBMP(char *Filename) // 载入位图图象 if (!Filename) // 确保文件名已提供 File=fopen(Filename,"r"); // 尝试打开文件 if (File) // 文件存在么? return NULL; // 如果载入失败,返回 NULL int LoadGLTextures() // 载入位图(调用上面的代码)并转换成纹理 int Status=FALSE; // 状态指示器 AUX_RGBImageRec *TextureImage[1]; // 创建纹理的存储空间 memset(TextureImage,0,sizeof(void *)*1); // 将指针设为 NULL // 载入位图,检查有无错误,如果位图没找到则退出 glGenTextures(1, &texture[0]); // 创建纹理 // 使用来自位图数据生成 的典型纹理 // 生成纹理 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); // 线形滤波 if (TextureImage[0]) // 纹理是否存在 free(TextureImage[0]); // 释放图像结构 return Status; // 返回 Status int InitGL(GLvoid) // 此处开始对OpenGL进行所有设置 glEnable(GL_TEXTURE_2D); // 启用纹理映射 int DrawGLScene(GLvoid) // 从这里开始进行所有的绘制 glRotatef(xrot,1.0f,0.0f,0.0f); // 绕X轴旋转 glBindTexture(GL_TEXTURE_2D, texture[0]); // 选择纹理 所以纹理的左上坐标是 X:0.0f,Y:1.0f ,四边形的左上顶点是 X: -1.0f,Y:1.0f 。其余三点依此类推。 试着玩玩 glTexCoord2f 的X,Y坐标参数。把 1.0f 改为 0.5f 将只显示纹理的左半部分,把 0.0f 改为 0.5f 将只显示纹理的右半部分。 glBegin(GL_QUADS); xrot+=0.3f; // X 轴旋转 |
-- 作者:一分之千 -- 发布时间:10/13/2007 10:03:00 AM -- Lesson 06 Learning how to texture map has many benefits. Lets say you wanted a missile to fly across the screen. Up until this tutorial we'd probably make the entire missile out of polygons, and fancy colors. With texture mapping, you can take a real picture of a missile and make the picture fly across the screen. Which do you think will look better? A photograph or an object made up of triangles and squares? By using texture mapping, not only will it look better, but your program will run faster. The texture mapped missile would only be one quad moving across the screen. A missile made out of polygons could be made up of hundreds or thousands of polygons. The single texture mapped quad will use alot less processing power. Lets start off by adding five new lines of code to the top of lesson one. The first new line is #include <stdio.h>. Adding this header file allows us to work with files. In order to use fopen() later in the code we need to include this line. Then we add three new floating point variables... xrot, yrot and zrot. These variables will be used to rotate the cube on the x axis, the y axis, and the z axis. The last line GLuint texture[1] sets aside storage space for one texture. If you wanted to load in more than one texture, you would change the number one to the number of textures you wish to load. #include <windows.h> // Header File For Windows HDC hDC=NULL; // Private GDI Device Context bool keys[256]; // Array Used For The Keyboard Routine GLfloat xrot; // X Rotation ( NEW ) GLuint texture[1]; // Storage For One Texture ( NEW ) LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // Declaration For WndProc First thing we do is create a file handle. A handle is a value used to identify a resource so that our program can access it. We set the handle to NULL to start off. AUX_RGBImageRec *LoadBMP(char *Filename) // Loads A Bitmap Image if (!Filename) // Make Sure A Filename Was Given File=fopen(Filename,"r"); // Check To See If The File Exists if (File) // Does The File Exist? return NULL; // If Load Failed Return NULL int LoadGLTextures() // Load Bitmaps And Convert To Textures int Status=FALSE; // Status Indicator AUX_RGBImageRec *TextureImage[1]; // Create Storage Space For The Texture memset(TextureImage,0,sizeof(void *)*1); // Set The Pointer To NULL // Load The Bitmap, Check For Errors, If Bitmap's Not Found Quit The second line glBindTexture(GL_TEXTURE_2D, texture[0]) tells OpenGL to bind the named texture texture[0] to a texture target. 2D textures have both height (on the Y axes) and width (on the X axes). The main function of glBindTexture is to assign a texture name to texture data. In this case we're telling OpenGL there is memory available at &texture[0]. When we create the texture, it will be stored in the memory that &texture[0] references. glGenTextures(1, &texture[0]); // Create The Texture // Typical Texture Generation Using Data From The Bitmap // Generate The Texture glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); // Linear Filtering if (TextureImage[0]) // If Texture Exists free(TextureImage[0]); // Free The Image Structure return Status; // Return The Status int InitGL(GLvoid) // All Setup For OpenGL Goes Here glEnable(GL_TEXTURE_2D); // Enable Texture Mapping ( NEW ) int DrawGLScene(GLvoid) // Here's Where We Do All The Drawing glRotatef(xrot,1.0f,0.0f,0.0f); // Rotate On The X Axis glBindTexture(GL_TEXTURE_2D, texture[0]); // Select Our Texture The first value of glTexCoord2f is the X coordinate. 0.0f is the left side of the texture. 0.5f is the middle of the texture, and 1.0f is the right side of the texture. The second value of glTexCoord2f is the Y coordinate. 0.0f is the bottom of the texture. 0.5f is the middle of the texture, and 1.0f is the top of the texture. So now we know the top left coordinate of a texture is 0.0f on X and 1.0f on Y, and the top left vertex of a quad is -1.0f on X, and 1.0f on Y. Now all you have to do is match the other three texture coordinates up with the remaining three corners of the quad. Try playing around with the x and y values of glTexCoord2f. Changing 1.0f to 0.5f will only draw the left half of a texture from 0.0f (left) to 0.5f (middle of the texture). Changing 0.0f to 0.5f will only draw the right half of a texture from 0.5f (middle) to 1.0f (right). glBegin(GL_QUADS); xrot+=0.3f; // X Axis Rotation Texture mapping isn't to difficult to understand once you understand texture coordinates. If you're having problems understanding any part of this tutorial, let me know. Either I'll rewrite that section of the tutorial, or I'll reply back to you in email. Have fun creating texture mapped scenes of your own :) Jeff Molofee (NeHe) |
-- 作者:skflip -- 发布时间:2/13/2009 12:39:00 PM -- 好好好!没下载一份都觉得特感激,楼主真的是辛苦了! |
-- 作者:jisuanjituxingxue -- 发布时间:4/11/2009 4:35:00 PM -- 非常感谢,努力学习中 |
-- 作者:guhl112233 -- 发布时间:9/14/2010 2:45:00 PM -- 如果六个面要六个不同的纹理,楼主该怎么弄啊? |
-- 作者:陆仁贾 -- 发布时间:8/19/2012 12:42:00 AM -- TextureImage[0]=LoadBMP("Data/NeHe.bmp") loadbmp(),()中的部分该怎么写啊,为什么自己编写的,不行,求指导 |
W 3 C h i n a ( since 2003 ) 旗 下 站 点 苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》 |
328.125ms |