下载地址教程 http://download.csdn.net/detail/utopiachn/5214613
From Utopia-CHN http://weibo.com/gejunwei110
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 |
#include "stdafx.h" #include <iostream> #define GLUT_DISABLE_ATEXIT_HACK #include "glut.h" #include "glaux.h" using namespace std; GLfloat xrot=0; GLfloat yrot=0; GLfloat zrot=0; GLuint texture;// 存储一个纹理 AUX_RGBImageRec *TextureImage=new AUX_RGBImageRec; //辅助函数 AUX_RGBImageRec *LoadBMP(char* FileName) { FILE *file = 0; if(!FileName) return 0; file = fopen(FileName,"r"); if(file) { fclose(file); cout<<"start open!"; return auxDIBImageLoad(FileName); //如果此处出现Fail to open DIB是字符串的问题 //修改项目配置,字符集中将Unicode改成多级字符即可 } return 0; } void LoadTexture() { //图像的宽和高必须是2的n次方 memset(TextureImage,0,sizeof(void *)*1); //现在载入位图,并将其转换为纹理。 TextureImage = LoadBMP("E:\\pic\\lena256.bmp"); if(0 == TextureImage) { cout<<"error bmp"<<endl; return; } //告诉OpenGL我们想生成一个纹理名字( 如果您想载入多个纹理,加大数字) 。 glGenTextures(1,&texture); glBindTexture(GL_TEXTURE_2D, texture); // 告诉OpenGL将纹理名字texture绑定到纹理目标上。 //告诉OpenGL此纹理是一个2D纹理 ( GL_TEXTURE_2D ) 。参 //数“0”代表图像的详细程度,通常就由它为零去了。参数三是数据的成分数。因为图像是由红色数 //据,绿色数据,蓝色数据三种组分组成。 TextureImage->sizeX 是纹理的宽度。如果您知道宽 //度,您可以在这里填入,但计算机可以很容易的为您指出此值。 TextureImage->sizey 是纹理的高 //度。参数零是边框的值,一般就是“0”。 GL_RGB 告诉OpenGL图像数据由红、绿、蓝三色数据组成。 // GL_UNSIGNED_BYTE 意味着组成图像的数据是无符号字节类型的。最后... TextureImage->data //告诉OpenGL纹理数据的来源。此例中指向存放在 TextureImage记录中的数据。 glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage->sizeX, TextureImage->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage->data); //下面的两行告诉OpenGL在显示图像时,当它比放大得原始的纹理大 ( //GL_TEXTURE_MAG_FILTER ) 或缩小得比原始得纹理小( GL_TEXTURE_MIN_FILTER //) 时OpenGL采用的滤波方式。通常这两种情况下我都采用 GL_LINEAR 。这使得纹理从很远处到离 //屏幕很近时都平滑显示。使用 GL_LINEAR 需要CPU 和显卡做更多的运算。如果您的机器很慢,您 //也许应该采用 GL_NEAREST 。过滤的纹理在放大的时候,看起来斑驳的很『译者注:马赛克 //啦』。您也可以结合这两种滤波方式。在近处时使用 GL_LINEAR ,远处时 GL_NEAREST 。 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);//线形滤波 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);//线形滤波 //释放前面用来存放位图数据的内存 if(TextureImage) { if(TextureImage->data) { free(TextureImage->data); } free(TextureImage); } } void MainDisplay(void) { glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);//清除屏幕及其缓存 glLoadIdentity();//重置当前模型观察矩阵 glTranslatef(0.0f,0.0f,-5.0f); // 移入屏幕5个单位 glRotatef(xrot,1.0f,0.0f,0.0f);// 绕X轴旋转 glRotatef(yrot,0.0f,1.0f,0.0f);// 绕Y轴旋转 glRotatef(zrot,0.0f,0.0f,1.0f);// 绕Z轴旋转 // 下一行代码选择我们使用的纹理。如果您在您的场景中使用多个纹理,您应该使用来 // glBindTexture(GL_TEXTURE_2D, texture[ 所使用纹理对应的数字 ]) 选择要绑定的纹理。当您想改变 // 纹理时,应该绑定新的纹理。有一点值得指出的是,您不能在 glBegin() 和 glEnd() 之间绑定纹理, // 必须在 glBegin() 之前或 glEnd() 之后绑定。注意我们在后面是如何使用 glBindTexture 来指定和绑定纹理的。 glBindTexture(GL_TEXTURE_2D, texture);// 选择纹理 // 为了将纹理正确的映射到四边形上,您必须将纹理的右上角映射到四边形的右上角,纹理的左上角 // 映射到四边形的左上角,纹理的右下角映射到四边形的右下角,纹理的左下角映射到四边形的左下 // 角。如果映射错误的话,图像显示时可能上下颠倒,侧向一边或者什么都不是。 // glTexCoord2f 的第一个参数是X 坐标。 0.0f 是纹理的左侧。 0.5f 是纹理的中点, 1.0f 是纹理的右 // 侧。 glTexCoord2f 的第二个参数是Y 坐标。 0.0f 是纹理的底部。 0.5f 是纹理的中点, 1.0f 是纹理的顶部。 glBegin(GL_QUADS);//////////////////////////// //前面 glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // 纹理和四边形的左下 glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);// 纹理和四边形的右下 glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);//左下 glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);//右下 // 后面 glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); //右下 glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);//右上 glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); // 纹理和四边形的左上 glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); // 纹理和四边形的左下 // 顶面 glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); // 纹理和四边形的左上 glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // 纹理和四边形的左下 glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // 纹理和四边形的右下 glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); // 纹理和四边形的右上 // 底面 glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f); // 纹理和四边形的右上 glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f); // 纹理和四边形的左上 glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); // 纹理和四边形的左下 glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // 纹理和四边形的右下 // 右面 glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); // 纹理和四边形的右下 glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); // 纹理和四边形的右上 glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // 纹理和四边形的左上 glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); // 纹理和四边形的左下 // 左面 glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); // 纹理和四边形的左下 glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // 纹理和四边形的右下 glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // 纹理和四边形的右上 glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); // 纹理和四边形的左上 glEnd();/////////////////////////////// glFlush(); } void ReSizeFunc(int width,int height) { glViewport(0,0,width,height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45,width/height,0.1,100); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void KeyBoardFunc(unsigned char key, int x, int y) { if(0x1B == key) { exit(0); } // 现在增加 xrot , yrot 和 zrot 的值。尝试变化每次各变量的改变值来调节立方体的旋转速度,或改 // 变+/-号来调节立方体的旋转方向。 xrot+=0.3f;// X 轴旋转 yrot+=0.2f;// Y 轴旋转 zrot+=0.4f;// Z 轴旋转 MainDisplay(); } int Init() { LoadTexture(); glEnable(GL_TEXTURE_2D);// 启用纹理映射 glShadeModel(GL_SMOOTH);// 启用阴影平滑 glClearColor(0,0,0,0); // 黑色背景 glClearDepth(1); // 设置深度缓存 glEnable(GL_DEPTH_TEST);// 启用深度测试 glDepthFunc(GL_LEQUAL); // 所作深度测试的类型 glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);// 真正精细的透视修正 return 0; } int main(int argc, char *argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE); glutInitWindowPosition(100, 100); glutInitWindowSize(500, 500); glutCreateWindow("第六个OpenGL程序"); glutReshapeFunc(ReSizeFunc); glutDisplayFunc(MainDisplay); glutKeyboardFunc(KeyBoardFunc); Init(); glutMainLoop(); return 0; } |