《飘荡的旗子源代码》由会员分享,可在线阅读,更多相关《飘荡的旗子源代码(6页珍藏版)》请在金锄头文库上搜索。
1、#include GLee.h#include glut.h#include #include void selectFont(int size, int charset, const char* face) HFONT hFont = CreateFontA(size, 0, 0, 0, FW_MEDIUM, 0, 0, 0,charset, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, face);HFONT hOldFont = (HFONT)SelectObject(
2、wglGetCurrentDC(), hFont);DeleteObject(hOldFont);#define FONT_SIZE 64#define TEXTURE_SIZE FONT_SIZEGLuint drawChar_To_Texture(const char* s) wchar_t w;HDC hDC = wglGetCurrentDC();/ 选择字体字号、颜色/ 不指定字体名字,操作系统提供默认字体/ 设置颜色为白色selectFont(FONT_SIZE, DEFAULT_CHARSET, );glColor3f(1.0f, 1.0f, 1.0f);/ 转化为宽字符Mult
3、iByteToWideChar(CP_ACP, MB_PRECOMPOSED, s, 2, &w, 1);/ 计算绘制的位置int width, x, y;GetCharWidth32W(hDC, w, w, &width); / 取得字符的宽度x = (TEXTURE_SIZE - width) / 2;y = FONT_SIZE / 8;glWindowPos2iARB(x,y);/ glutInitWindowPosition(x,y);/ 绘制字符/ 绘制前应该将各种可能影响字符颜色的效果关闭/ 以保证能够绘制出白色的字符GLuint list = glGenLists(1); glD
4、isable(GL_DEPTH_TEST);glDisable(GL_LIGHTING);glDisable(GL_FOG);glDisable(GL_TEXTURE_2D);wglUseFontBitmaps(hDC, w, 1, list);glCallList(list);glDeleteLists(list, 1);/ 复制字符像素到纹理/ 注意纹理的格式/ 不使用通常的 GL_RGBA,而使用 GL_LUMINANCE4/ 因为字符本来只有一种颜色,使用 GL_RGBA浪费了存储空间/ GL_RGBA可能占 16位或者 32位,而 GL_LUMINANCE4只占 4位GLuint t
5、exID;glGenTextures(1, &texID);glBindTexture(GL_TEXTURE_2D, texID);glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE4,0, 0, TEXTURE_SIZE, TEXTURE_SIZE, 0);glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR);glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR);return texID;/ 设置法线向
6、量/ 三个不在同一直线上的点可以确定一个平面/ 先计算这个平面的法线向量,然后指定到 OpenGLvoid setNormal(const GLfloat v13,const GLfloat v23,const GLfloat v33) / 首先根据三个点坐标,相减计算出两个向量const GLfloat s1 = v20-v10, v21-v11, v22-v12;const GLfloat s2 = v30-v10, v31-v11, v32-v12;/ 两个向量叉乘得到法线向量的方向GLfloat n = s11*s22 - s12*s21,s12*s20 - s10*s22,s10*s
7、21 - s11*s20;/ 把法线向量缩放至单位长度GLfloat abs = sqrt(n0*n0 + n1*n1 + n2*n2);n0 /= abs;n1 /= abs;n2 /= abs;/ 指定到 OpenGLglNormal3fv(n);#define PI (3.1415926f)#define MIN_X (-0.5f)#define MAX_X (0.5f)#define MIN_Y (-0.5f)#define MAX_Y (0.5f)#define SEGS (int)(MAX_X - MIN_X) * (512/2)#define RANGE (0.05f)#defi
8、ne CIRCLES (2.0f)#define SPEED (5.0f)GLfloat theta = 0.0f;/ 绘制一面旗帜void draw(void) int i;/ 每绘制一段,坐标 x应该增加的量const GLfloat x_inc = (MAX_X - MIN_X) / SEGS;/ 每绘制一段,纹理坐标 s应该增加的量const GLfloat t_inc = 1.0f / SEGS;/ 每绘制一段,常数 theta应该增加的量const GLfloat theta_inc = 2 * PI * CIRCLES / SEGS;/ 用 GL_QUAD_STRIP来绘制相连的
9、四边形glBegin(GL_QUAD_STRIP);for(i=0; i=SEGS; +i) / 按照 z = sin(t * c1 + c2) * c3 + c4的公式计算 z坐标const GLfloat z = RANGE * sin(i*theta_inc + theta); / 一段只需要指定两个点/ 第三个点其实是下一段的第一个点/ 之所以使用三个点,是为了构成一个平面/ 便于计算法线向量const GLfloatv1 = i*x_inc + MIN_X, MAX_Y, z,v2 = i*x_inc + MIN_X, MIN_Y, z,v3 = (i+1)*x_inc + MIN_
10、X,MAX_Y,RANGE * sin(i+1)*theta_inc + theta);/ 调用一个函数来计算法线向量setNormal(v1, v2, v3);/ 设置合适的纹理坐标和顶点坐标glTexCoord2f(i*t_inc, 1.0f);glVertex3fv(v1);glTexCoord2f(i*t_inc, 0.0f);glVertex3fv(v2);glEnd();void display(void) static int isFirstCall = 1;static GLuint texID = 0;if( isFirstCall ) / 第一次调用,产生一个纹理isFir
11、stCall = 0;texID = drawChar_To_Texture(石);/ 深度测试glEnable(GL_DEPTH_TEST);glDepthFunc(GL_LEQUAL);/ 文字的颜色GLfloat color = 1.0f, 1.0f, 0.0f, 1.0f;glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);/ 光照 GLfloatlight_position = 2.0f, 3.0f, 5.0f,
12、 0.0f,light_ambient = 0.0f, 0.0f, 0.0f, 1.0f,light_specular = 1.0f, 1.0f, 1.0f, 1.0f,mat_ambient = 0.0f, 0.0f, 1.0f, 1.0f,mat_specular = 0.5f, 0.5f, 0.5f, 1.0f,mat_emission = 0.0f, 0.0f, 0.3f, 1.0f;glEnable(GL_LIGHTING);glEnable(GL_LIGHT0);glLightfv(GL_LIGHT0, GL_POSITION, light_position);glLightfv(
13、GL_LIGHT0, GL_AMBIENT_AND_DIFFUSE, light_ambient);glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);glMaterialf(GL_FRONT, GL_SHININESS, 64.0f);glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mat_ambient);glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);glMaterialfv(GL_FRONT, GL_EMISSION, mat_emissio
14、n);glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);/ 设置观察点glMatrixMode(GL_PROJECTION);glLoadIdentity();gluPerspective(45.0, 1.0, 0.1, 5.0);glMatrixMode(GL_MODELVIEW);glLoadIdentity();gluLookAt(1.0, -1.0, 2.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glEnab
15、le(GL_TEXTURE_2D);draw();glutSwapBuffers();void idle(void) theta += (SPEED * PI / 180.0f);glutPostRedisplay();void main(int argc, char* argv) glutInit(&argc, argv);glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);glutInitWindowPosition(100, 100);glutInitWindowSize(512, 512);glutCreateWindow(OpenGL);glutDisplayFunc(&display);glutIdleFunc(&idle);glutMainLoop();