图形学樱花飞舞
初二 记叙文 6175字 257人浏览 clx207903

操作指导6贴图-樱花飞舞

一、建立工程

二、添加函数和变量

public:

void mir();//定义镜面显示函数

void un2();//定义花瓣

void bmptomap();//定义纹理映射方式

void mysky();//定义背景贴图

FILE * myf;//定义一个贴图文件

GLubyte image1[512][512][3];定义读取贴图的变量

BOOL lkey;//定义动画开关

int si;//定义落花瓣的数目

float psnow[60][6];//定义60片花瓣的位置、角度

CClientDC *my_pDC;

CRect my_oldRect;

BOOL mytbar;

BOOL mysbar;

三、添加消息响应函数OnTimer()。

四、初始化变量

CCmyView::CCmyView()

{

// TODO: add construction code here

my_pDC=NULL;

mytbar=FALSE;

mysbar=FALSE;

lkey=TRUE;

for(int i=0;i<60;i++){

psnow[i][1]=1.0f*(rand()-rand())/RAND_MAX;

psnow[i][2]=1.0f*(rand()-rand())/RAND_MAX;

psnow[i][0]=1.0f*(-rand())/RAND_MAX;

psnow[i][3]=90.0f*(rand()-rand())/RAND_MAX;

psnow[i][4]=90.0f*(rand()-rand())/RAND_MAX;

psnow[i][5]=90.0f*(rand()-rand())/RAND_MAX;

};

si=-59;

//打开文件j 。bmp ,从位图的第54个字节开始是图像信息,将色彩传给imagel //位图要求为23位521*512。

if(!(myf=fopen("j.bmp","rb"))){return;}else{

fseek(myf,54,SEEK_SET);

fread(image1,sizeof(unsigned char),512*512*3,myf);};

}

五、建工具栏 ID_BUTTONyh 并添加响应函数: void CCmyView::OnButtonyh()

{

// TODO: Add your command handler code here if(lkey){

SetTimer(1, 120, NULL);

}else{

KillTimer(1);

};

lkey=!lkey;

Invalidate(FALSE);

}

六、加上

// cmyView.cpp : implementation of the CCmyView class //

#include "stdafx.h"

#include "cmy.h"

#include "MainFrm.h"

#include "Math.h"

#include "cmyDoc.h"

#include "cmyView.h"

#define ABS(x) ((x)<0 ? -(x) : (x)>0 ? (x) : 0)

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

七、在OnDraw ()中改背景glClearColor(0.2f,0.2f,0.2f,0.9f);

八、在OnCreat ()中建立花瓣的显示列表语句

int CCmyView::OnCreate(LPCREATESTRUCT lpCreateStruct) {

if (CView::OnCreate(lpCreateStruct) == -1)

return -1;

// TODO: Add your specialized creation code here myfirst();

glNewList(1,GL_COMPILE);

un2();

glEndList();

return 0;

}

九、void CCmyView::OnDestroy()

{

CView::OnDestroy();

// TODO: Add your message handler code here

KillTimer(1);

HGLRC hrc;

hrc = ::wglGetCurrentContext();

::wglMakeCurrent(NULL, NULL);

if (hrc)

::wglDeleteContext(hrc);

if (my_pDC)

delete my_pDC;

}

十、void CCmyView::OnTimer(UINT nIDEvent)

{

// TODO: Add your message handler code here and/or call default if(nIDEvent==1){

if(si==59){si=-59;};//定义花瓣的数目不超过60 for(int i=0;i<(60-ABS(si));i++){//花瓣的位置变化 if(psnow[i][1]<=-0.8f){//花瓣落到底部,重新定义 si++;//一片片落下,花瓣增加

psnow[i][0]=1.0f*(-rand())/RAND_MAX;

psnow[i][1]=1.0f*(rand())/RAND_MAX;

psnow[i][2]=1.0f*(rand()-rand())/RAND_MAX;

psnow[i][3]=90.0f*(rand()-rand())/RAND_MAX;

psnow[i][4]=90.0f*(rand()-rand())/RAND_MAX;

psnow[i][5]=90.0f*(rand()-rand())/RAND_MAX;

}else{//花瓣边落下边变化

psnow[i][0]=psnow[i][0]+0.02f*(rand()-rand())/RAND_MAX; psnow[i][1]=psnow[i][1]-0.02f;

psnow[i][2]=psnow[i][2]+0.02f*(rand()-rand())/RAND_MAX; psnow[i][3]=psnow[i][5]+60.0f*(rand()-rand())/RAND_MAX; psnow[i][4]=psnow[i][6]+60.0f*(rand()-rand())/RAND_MAX; psnow[i][5]=psnow[i][6]+60.0f*(rand()-rand())/RAND_MAX;

};

};

};

Invalidate(FALSE);//更新显示

CView::OnTimer(nIDEvent);

}

十一、绘画

void CCmyView::mydraw()

{

glTranslatef(0.0f,0.0f,-7.0f);//移动到视区内显示 glEnable(GL_LINE_SMOOTH);//线与多边形反走样 glPushMatrix();

glScalef(0.9f,0.9f,0.9f);//调整充满画面

mysky();//绘制背景贴图

glPopMatrix();

for(int i=0;i<(60-ABS(si));i++){//绘制60片花瓣 glPushMatrix();

glTranslatef(psnow[i][0],psnow[i][1],psnow[i][2]); glRotated(psnow[i][3],1.0,0.0,0.0);

glRotated(psnow[i][4],0.0,1.0,0.0);

glRotated(psnow[i][5],0.0,0.0,1.0);

glCallList(1);//调用花瓣列表

glPopMatrix();

};

glPushMatrix();

glScalef(0.8f,1.0f,0.8f);//缩放为长方形

glTranslatef(0.8f,0.22f,0.4f);//移动

glRotated(-30,0.0,1.0,0.0);//转动

mir();//绘制镜子

glPopMatrix();

glDisable(GL_LINE_SMOOTH);//关闭反走样 }

void CCmyView::mysky()

{

glPushMatrix();

glRotated(90,1.0,0.0,0.0);

glTexImage2D(GL_TEXTURE_2D,0,3,512,512,

0,GL_BGR_EXT,GL_UNSIGNED_BYTE,image1);

bmptomap();

glBegin(GL_QUADS);

glTexCoord2f(0.0f,1.0f);glVertex3f(-2.2f,0.0f,-1.50f);

glTexCoord2f(0.0f,0.0f);glVertex3f(-2.2f,0.0f,1.50f);

glTexCoord2f(1.0f,0.0f);glVertex3f(2.2f,0.0f,1.5f);

glTexCoord2f(1.0f,1.0f);glVertex3f(2.2f,0.0f,-1.5f);

glEnd();

glPopMatrix();

glDisable(GL_TEXTURE_2D);

}

十二、花瓣

void CCmyView::un2()

{

float rx=1.0f;

float ange1=3.1416f/3.0f;

float ange2=0.0f;

float k=-14.5;

glPushMatrix();

glScalef(0.04f,0.04f,0.12f);

glTranslatef(-0.5f,-0.5,0.0f);///

for(float i=0;i<30;i++){

ange2=3.1416f/180.0f*i;

glShadeModel(GL_SMOOTH);

glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);

glBegin(GL_QUAD_STRIP);

for(float j=0;j<35;j++){

ange1=3.1416f/3.0f+3.1416f/190.0f*((k*k)/14-14)+3.1416f/180.0f*j;

if(ange1>=1.5708f){}else{

rx=1.0f-0.01f*((k*k)/14-14)*(1-j/35);

glColor3f(rx*rx*sinf(ange1),rx*cosf(ange1)*cosf(ange2)/2,rx*cosf(ange1)*cosf(ange2)); glVertex3f(rx*cosf(ange1)*cosf(ange2),

rx*sinf(ange1),

-rx*cosf(ange1)*sinf(ange2));

ange1=3.1416f/3.0f+3.1416f/190.0f*((k+1.0f)*(k+1.0f)/14-14)+3.1416f/180.0f*j; rx=1.0f-0.01f*((k+1.0f)*(k+1.0f)/14-14)*(1-j/35);

glVertex3f(rx*cosf(ange1)*cosf(ange2+3.1416f/180.0f),

rx*sinf(ange1),

-rx*cosf(ange1)*sinf(ange2+3.1416f/180.0f)); };

};

glEnd();

k=k+1;

if(k>=15.5){

k=-14.5f;

};

};

glPopMatrix();

}

十三、镜子的绘制

void CCmyView::mir()

{

glPushMatrix();

GLubyte image3[512][512][3];//定义一个临时变量

glReadPixels(0,0, //读取屏幕坐标的图像到变量中

512,512,GL_RGB,GL_UNSIGNED_BYTE,image3); //将变量映射为纹理

glTexImage2D(GL_TEXTURE_2D,0,3,512,512,

0,GL_RGB,GL_UNSIGNED_BYTE,image3);

//调用纹理控制定义与融合定义函数

bmptomap();

//开始绘制镜子

//定义纹理坐标的同时定义顶点

glBegin(GL_QUADS);

glTexCoord2f(1.0f,0.0f);glVertex3f(0.0f,-1.0f,1.0f);

glTexCoord2f(1.0f,1.0f);glVertex3f(0.0f,0.0f,1.0f);

glTexCoord2f(0.0f,1.0f);glVertex3f(1.0f,0.0f,1.0f);

glTexCoord2f(0.0f,0.0f);glVertex3f(1.0f,-1.0f,1.0f);

glEnd();

//关闭纹理

glDisable(GL_TEXTURE_2D);

//绘制镜子边,采用平滑渲染

glShadeModel(GL_SMOOTH);

glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);//边线模式 glLineWidth(4.0f);//线宽

//绘制镜子边

glBegin(GL_QUADS);

glColor3f(0.5f,0.5f,0.0f);

glVertex3f(0.0f,-1.0f,1.0f);

glVertex3f(0.0f,0.0f,1.0f);

glColor3f(1.0f,0.5f,0.0f);

glVertex3f(1.0f,0.0f,1.0f);

glVertex3f(1.0f,-1.0f,1.0f);

glEnd();

//恢复平面绘制模式

glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);

glPopMatrix();

}

十四、定义纹理控制与融合显示方式

void CCmyView::bmptomap()

{

//纹理控制方式定义

glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP); glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP); glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_NEAREST);

glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_NEAREST);

//纹理与融合显示控制方式

glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_DECAL); //启动纹理并启动平滑渲染

glEnable(GL_TEXTURE_2D);

glShadeModel(GL_SMOOTH);

}