OpenGL学习三十九:飘动的旗帜

时间:2022-12-13 16:13:17

(此节内容对应NEHE教程第11课)

 

目前为止我们做的例子都是平面的,这个例子是带有波动效果的,

2维图形包括X,Y两个坐标系。因此看到的是平面的。
3维图形由X,Y,Z三个坐标系构成,当Z坐标不为0时,可以产生3维的效果。一个图片或图形由许多个3维图形构成是,并且Z是变化的 就会产生波动的效果


for(int x=0; x<45; x++)
{
// 沿Y平面循环
for(int y=0; y<45; y++)
{
// 向表面添加波浪效果
points[x][y][0]=float((x/5.0f)-4.5f);
points[x][y][1]=float((y/5.0f)-4.5f);
points[x][y][2]=float(sin((((x/5.0f)*40.0f)/360.0f)*3.141592654*2.0f));
}
}

多边形填充方式,glPolygonMode()


glPolygonMode( GL_BACK, GL_FILL );   // 后表面完全填充
glPolygonMode( GL_FRONT, GL_LINE );   // 前表面使用线条绘制


#include "header.h"

float points[45][45][3];
int wiggle_count = 0;

GLfloat xrot;
GLfloat yrot;
GLfloat zrot;
GLfloat hold;

GLuint texture[1];

AUX_RGBImageRec *LoadBMP(char *Filename)
{
FILE *File=NULL;

if (!Filename)
{
return NULL;
}

File=fopen(Filename,"r");

if (File)
{
fclose(File);
return auxDIBImageLoad(Filename);
}

return NULL;
}

int LoadGLTextures()
{
int Status=FALSE;

AUX_RGBImageRec *TextureImage[1];

memset(TextureImage,0,sizeof(void *)*1);

// Load The Bitmap, Check For Errors, If Bitmap's Not Found Quit
if (TextureImage[0]=LoadBMP("Data/Tim.bmp"))
{
Status=TRUE;

glGenTextures(1, &texture[0]);

// Typical Texture Generation Using Data From The Bitmap
glBindTexture(GL_TEXTURE_2D, texture[0]);
glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
}

if (TextureImage[0])
{
if (TextureImage[0]->data)
{
free(TextureImage[0]->data);
}

free(TextureImage[0]);
}

return Status;
}

void ReSizeGLScene(GLsizei width, GLsizei height)
{
if (height==0)
{
height=1;
}

glViewport(0,0,width,height);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();

// Calculate The Aspect Ratio Of The Window
gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}

int InitGL(void)
{
if (!LoadGLTextures())
{
return FALSE;
}

glEnable(GL_TEXTURE_2D);
glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glPolygonMode( GL_BACK, GL_FILL );
glPolygonMode( GL_FRONT, GL_LINE );

for(int x=0; x<45; x++)
{
for(int y=0; y<45; y++)
{
points[x][y][0]=float((x/5.0f)-4.5f);
points[x][y][1]=float((y/5.0f)-4.5f);
points[x][y][2]=float(sin((((x/5.0f)*40.0f)/360.0f)*3.141592654*2.0f));
}
}

return TRUE;
}

void DrawGLScene(void)
{
int x, y;
float float_x, float_y, float_xb, float_yb;

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();

glTranslatef(0.0f,0.0f,-12.0f);

glRotatef(xrot,1.0f,0.0f,0.0f);
glRotatef(yrot,0.0f,1.0f,0.0f);
glRotatef(zrot,0.0f,0.0f,1.0f);

glBindTexture(GL_TEXTURE_2D, texture[0]);

glBegin(GL_QUADS);
for( x = 0; x < 44; x++ )
{
for( y = 0; y < 44; y++ )
{
float_x = float(x)/44.0f;
float_y = float(y)/44.0f;
float_xb = float(x+1)/44.0f;
float_yb = float(y+1)/44.0f;

glTexCoord2f( float_x, float_y);
glVertex3f( points[x][y][0], points[x][y][1], points[x][y][2] );

glTexCoord2f( float_x, float_yb );
glVertex3f( points[x][y+1][0], points[x][y+1][1], points[x][y+1][2] );

glTexCoord2f( float_xb, float_yb );
glVertex3f( points[x+1][y+1][0], points[x+1][y+1][1], points[x+1][y+1][2] );

glTexCoord2f( float_xb, float_y );
glVertex3f( points[x+1][y][0], points[x+1][y][1], points[x+1][y][2] );
}
}
glEnd();

if( wiggle_count == 2 )
{
for( y = 0; y < 45; y++ )
{
hold=points[0][y][2];
for( x = 0; x < 44; x++)
{
points[x][y][2] = points[x+1][y][2];
}
points[44][y][2]=hold;
}
wiggle_count = 0;
}

wiggle_count++;

glFlush();
}


void rotate()
{
xrot+=0.3f;
yrot+=0.2f;
zrot+=0.4f;

glutPostRedisplay();
}
void keyboard(unsigned char key,int x,int y)
{
switch (key)
{

case 'S':
glutIdleFunc(rotate);
break;
case 'R':
glutIdleFunc(NULL);
break;
}

}


int main(int argc,char **argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB|GLUT_DEPTH);
glutInitWindowSize(800,600);
glutInitWindowPosition(100,100);
glutCreateWindow("飘动的旗帜");
InitGL();
glutDisplayFunc(DrawGLScene);
glutKeyboardFunc(keyboard);
glutReshapeFunc(ReSizeGLScene);
glutMainLoop();
}