最近看到不少学弟学妹们为了学习OpenGL而忙的一塌糊涂,就把去年我做的一个程序发出来 给大家共同学习一下。看到这个程序,我心里既高兴又痛苦,痛并着快乐吧,快乐的是这个 程序是我一手做出来的,不骗你们,里面所有的程序代码全是我一个人写的,让我相当有成就感。 痛苦的是,和我一组的其他几位同学没几个真正关心这个程序(程序占总分40分啊,还有额外的加分),只是在最后几个星期假情假意做了个文档 以示自己尽了分力,个别的重头到尾问都没问一句,挂个名而已。后来程序被老师看好,说是要进什么国家库,于是又到外面炫耀。 唉,要不是我很想把程序给做出来,看看效果,我真的不想做了,大不了一齐挂了,明年都重修去。 我不图名利,但我怕心寒。 不发牢骚了,言归正传。本程序编译环境:Borland C++build6.0 由于引入了粒子系统(共60000个粒子),而且为了达到很好的效果粒子用的是三棱锥而不是点,所以运算量很大 ,对电脑要求有点高,配置不好的电脑可以在头文件中将粒子个数改少一些。由于我将说明文档整和在了程序中, 有大量的图片要处理,所以编译时会很慢(我的电脑要50多秒 CPU p4 2.4G DDR400 512M 七彩虹 Radom9800se) 请耐心等待。 因为不是最终版所以有些BUG没改(编译没有问题,只是某些功能无法实现): 程序中由于按钮控制与键盘有冲突,所以键盘控制部分的语句不能被执行。只要在按钮函数中的开头和结尾加上2个函数就能解决.具体函数现在忘了,具体方法是先让按钮判别为无,再在点击按钮时激活按钮,按钮函数执行完时再判别为无,过几天再发出来。 有时候运行程序时看不到图形,但将窗口还原再最大化就又出现了(我的机子上没出现过这个问题,但在比较差的机子上出现过,估计是显卡问题,刷新不够)。这是因为在TFormMain(TComponent* Sender)中少了几句话,没有重建窗口,请大家参考紧跟着的FormResize(TObject *Sender)后自行添加。自己不试试是不会记住的。 因为音乐打包比较大,所以把音乐删除了,但保留了音乐控制语句,请大家自行添加. 还有什么问题的话请指出。 附件中包括完整源代码和一个已经编译好的可执行文件,直接运行可执行文件就可以看到效果了。注意,源代码不能用VC++6.0直接运行,因为格式不同,要修改一些地方才可以。
下面我把主要的头文件和函数发出来 //Unit1.h //--------------------------------------------------------------------------- #ifndef Unit1H #define Unit1H //--------------------------------------------------------------------------- #define Max 20000 //粒子数1 有3种不同的粒子 #define Max1 20000 //粒子数2 #define Max2 20000 //粒子数3 //-------------------------------------------- #include <Classes.hpp> #include <Controls.hpp> #include <StdCtrls.hpp> #include <Forms.hpp> #include <ExtCtrls.hpp> #include <Menus.hpp> #include <gl\gl.h> #include <gl\glu.h> #include <math.h> //--------------------------------------------------------------------------- typedef struct //粒子系统所用的结构体 { bool active; GLfloat life; GLfloat fade; GLfloat r; GLfloat g; GLfloat b; GLfloat x; GLfloat y; GLfloat z; GLfloat xi; GLfloat yi; GLfloat zi; GLfloat xg; GLfloat yg; GLfloat zg; } particles;
//--------------------------------------------------------------------- class TFormMain : public TForm { __published: // IDE-managed Components TPanel *Control_Zone; TButton *Button5; TButton *Button6; TButton *Button7; TButton *Button8; TButton *Button9; TButton *Button10; TButton *Button11; TTimer *Timer1; TButton *Button12; TStaticText *StaticText5; TStaticText *StaticText7; TStaticText *StaticText8; TStaticText *StaticText9; TStaticText *StaticText10; TStaticText *StaticText11; TStaticText *StaticText12; TStaticText *StaticText13; TButton *Button13; TStaticText *StaticText14; TStaticText *StaticText15; TStaticText *StaticText16; TButton *Button14; TButton *Button15; TMainMenu *MainMenu1; TMenuItem *File1; TMenuItem *Exit1; TMenuItem *Help2; TMenuItem *About2; TMenuItem *SearchforHelpOn2; TMenuItem *Contents2; TMenuItem *File2; TMenuItem *PrintSetup1; TMenuItem *N2; TMenuItem *SaveAs1; TMenuItem *N1; TMenuItem *N3; TMenuItem *N4; TStaticText *StaticText6; TLabel *Label1; TButton *Button1; TButton *Button2; TButton *Button3; TButton *Button4; TButton *Button16; TButton *Button17;
void __fastcall FormResize( TObject *Sender); void __fastcall FormCreate( TObject *Sender); void __fastcall FormKeyDown( TObject *Sender, WORD &Key, TShiftState Shift); void __fastcall FormMouseMove( TObject *Sender, TShiftState Shift, int X,int Y); void __fastcall FormMouseDown( TObject *Sender, TMouseButton Button,TShiftState Shift, int X, int Y ); void __fastcall FormMouseUp( TObject *Sender, TMouseButton Button,TShiftState Shift, int X, int Y ); void __fastcall FormMouseWheelDown( TObject *Sender, TShiftState Shift, TPoint &MousePos, bool &Handled ); void __fastcall FormMouseWheelUp( TObject *Sender, TShiftState Shift, TPoint &MousePos, bool &Handled ); void __fastcall Button1Click(TObject *Sender);
void __fastcall Button5Click(TObject *Sender); void __fastcall Button6Click(TObject *Sender); void __fastcall Button7Click(TObject *Sender); void __fastcall Button8Click(TObject *Sender); void __fastcall Button9Click(TObject *Sender); void __fastcall Button10Click(TObject *Sender);
void __fastcall Timer1Timer(TObject *Sender); void __fastcall Button12Click(TObject *Sender); void __fastcall Button11Click(TObject *Sender); void __fastcall Button13Click(TObject *Sender); void __fastcall Button14Click(TObject *Sender); void __fastcall Button15Click(TObject *Sender); void __fastcall Exit1Click(TObject *Sender); void __fastcall SaveAs1Click(TObject *Sender); void __fastcall PrintSetup1Click(TObject *Sender); void __fastcall Contents2Click(TObject *Sender); void __fastcall N1Click(TObject *Sender); void __fastcall SearchforHelpOn2Click(TObject *Sender); void __fastcall About2Click(TObject *Sender); void __fastcall N3Click(TObject *Sender); void __fastcall N4Click(TObject *Sender);
void __fastcall Button2Click(TObject *Sender); void __fastcall Button17Click(TObject *Sender); void __fastcall Button4Click(TObject *Sender); void __fastcall Button3Click(TObject *Sender); void __fastcall Button16Click(TObject *Sender);
private: // User declarations HDC hdc; float w, h; int PixelFormat,x,y; int I,XX; float zoom,M,J,K,n,N,V,Angle,L,O,P; HGLRC hrc; GLuint list_of_objects,waike; Graphics::TBitmap* bitmap; BOOL Left_Button_Down,inclined,key_and_mouse_down;
int loop;
public: // User declarations __fastcall TFormMain(TComponent* Sender); void __fastcall IdleLoop(TObject*, bool&); void __fastcall SetPixelFormatDescriptor(); void __fastcall SetupLighting(); void __fastcall SetupTextures(); void __fastcall FormPaint( TObject *Sender ); void __fastcall FormDestroy( TObject *Sender );
void __fastcall Prepare_All(); void __fastcall Prepare_Wolun1(); void __fastcall Prepare_Top(); void __fastcall Prepare_FireRoom(); void __fastcall Prepare_Wolun2(); void __fastcall Prepare_WeiPen(); void __fastcall Prepare_Waike1(); void __fastcall Prepare_Waike2(); void __fastcall Prepare_Waike3(); void __fastcall Prepare_Smoke1(); void __fastcall Prepare_Smoke2(); void __fastcall Prepare_Smoke3(); void __fastcall Prepare_Waike11(); void __fastcall Prepare_Waike21(); void __fastcall Prepare_Waike31(); void __fastcall Normal(float*p1,float*p2,float*p3,float*n); void __fastcall Draw_Out_All(); void __fastcall Draw_Out_Wolun1(); void __fastcall Draw_Out_Top(); void __fastcall Draw_Out_FireRoom(); void __fastcall Draw_Out_Wolun2(); void __fastcall Draw_Out_WeiPen(); void __fastcall Draw_Out_Waike1(); void __fastcall Draw_Out_Waike2(); void __fastcall Draw_Out_Waike3(); void __fastcall Draw_Out_Waike11(); void __fastcall Draw_Out_Waike21(); void __fastcall Draw_Out_Waike31(); void __fastcall polarView(); void __fastcall Draw_Out_Smoke1(); void __fastcall Draw_Out_Smoke2(); void __fastcall Draw_Out_Smoke3(); void __fastcall ShowM(); particles particle[Max]; particles particle1[Max]; particles particle2[Max]; }; //--------------------------------------------------------------------------- extern PACKAGE TFormMain *FormMain; //--------------------------------------------------------------------------- #endif //Unit1.cpp //------------------------------------------------------------------------------ #include "stdio.h" #include <vcl.h> #include "Unit1.h" #include "Unit2.h" #include "Unit6.h" #include "Unit12.h" #include "Unit14.h" #include "Unit15.h" #include "math.h" //--------------------------------------------------------------------------- #pragma hdrstop #pragma package(smart_init) #pragma resource "*.dfm" TFormMain *FormMain; //------------------------------------------------------------------------------
//--------------------------------------------------------------------------- GLfloat Throttle=5; GLfloat glow=.4; GLfloat glowp=0; //------------------------------------------------------ __fastcall TFormMain::TFormMain(TComponent* Sender) //初始化窗口 : TForm(Sender) { hdc = GetDC(Handle); Control_Zone->Top = 100; Control_Zone->Left =3* FormMain->Width/4 + 1; Control_Zone->Width = FormMain->Width/4 - 32; Control_Zone->Height = FormMain->Height -32;
Application->OnIdle = IdleLoop; Left_Button_Down = FALSE; key_and_mouse_down = FALSE; inclined = TRUE;//FALSE; zoom = 0.99; } //--------------------------------------------------------------------------- void __fastcall TFormMain::FormResize(TObject *Sender) //重置窗口 { Control_Zone->Top = 0; Control_Zone->Left =ClientWidth-150; //3*ClientWidth/4+ Control_Zone->Width = 150; //ClientWidth/4- Control_Zone->Height= ClientHeight;
float nRange =75.0; w = 3*ClientWidth/4-1; h = ClientHeight; if( h==0 ) h = 1;
glViewport(0, 0, w, h); glMatrixMode( GL_PROJECTION ); glLoadIdentity();
if ( w<=h ) glOrtho( -nRange, nRange, -nRange*h/w,nRange*h/w,-nRange,nRange ); else glOrtho( -nRange*w/h,nRange*w/h,-nRange, nRange, -nRange,nRange );
glMatrixMode( GL_MODELVIEW ); glLoadIdentity(); inclined = TRUE; key_and_mouse_down = FALSE; } void __fastcall TFormMain::IdleLoop(TObject*, bool& done) //系统空闲的时候做什么 { done = false;
if( inclined==FALSE ) { glRotatef( 15.0, 1.0, 0.0, 0.0 ); glRotatef( -45,0.0,1.0, 0.0 ); inclined = TRUE; } if( key_and_mouse_down==FALSE ) glRotatef( 0.05, 0,1.0, 0.0);
Draw_Out_All();
SwapBuffers(hdc); } //------------------------------------------------------------------------------ void __fastcall TFormMain::SetPixelFormatDescriptor() { PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR),1, PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_DOUBLEBUFFER, PFD_TYPE_RGBA,24, 0,0,0,0,0,0, 0,0, 0,0,0,0,0, 32, 0, 0, PFD_MAIN_PLANE, 0, 0,0,0 }; PixelFormat = ChoosePixelFormat(hdc, &pfd); SetPixelFormat( hdc, PixelFormat, &pfd ); } void __fastcall TFormMain::SetupLighting() //设置光源 { float MaterialAmbient[] = { 0.6, 0.6, 0.6, 1.0 }; float MaterialDiffuse[] = { 0.8, 0.8, 0.8, 1.0 }; float MaterialSpecular[] = { 1.0, 1.0, 1.0, 1.0 }; float MaterialShininess[] = { 80.0 }; glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT, MaterialAmbient ); glMaterialfv( GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialDiffuse ); glMaterialfv( GL_FRONT_AND_BACK, GL_SPECULAR, MaterialSpecular ); glMaterialfv( GL_FRONT_AND_BACK, GL_SHININESS, MaterialShininess);
float AmbientLightPosition[] = { 0, 0, 30.0, 0.0 }; float LightAmbient[] = { 0.5, 0.5, 0.5, 1.0 }; glLightfv(GL_LIGHT0, GL_POSITION, AmbientLightPosition);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, LightAmbient); glLightModelf(GL_LIGHT_MODEL_TWO_SIDE,GL_TRUE); //双面反光
glEnable( GL_LIGHTING ); glEnable( GL_LIGHT0 ); glEnable( GL_COLOR_MATERIAL );
glColorMaterial( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE );
glShadeModel( GL_SMOOTH ); glEnable(GL_POLYGON_SMOOTH); } void __fastcall TFormMain::FormPaint( TObject *Sender ) { glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); glFlush(); }
void __fastcall TFormMain::FormDestroy( TObject *Sender ) {
} void __fastcall TFormMain::FormCreate(TObject *Sender) { hdc = GetDC( Handle ); SetPixelFormatDescriptor();
hrc = wglCreateContext( hdc ); if( hrc == NULL ) ShowMessage("对不起,GL设备描述表是空的。"); if( wglMakeCurrent(hdc, hrc) == false ) ShowMessage("对不起 MakeCurrent() 执行不了。"); w = ClientWidth; h = ClientHeight;
glEnable( GL_DEPTH_TEST ); glDisable( GL_CULL_FACE ); glClearColor(0.1f,0.1f, 0.3f, 0.0f); SetupLighting(); //********************************** Control_Zone->Top = 0; Control_Zone->Left =ClientWidth-150; //3*ClientWidth/4+ Control_Zone->Width = 150; // ClientWidth/4- Control_Zone->Height= ClientHeight;
float nRange =75.0; w = 3*ClientWidth/4-1; h = ClientHeight; if( h==0 ) h = 1;
glViewport(0, 0, w, h); glMatrixMode( GL_PROJECTION ); glLoadIdentity();
if ( w<=h ) glOrtho( -nRange, nRange, -nRange*h/w,nRange*h/w,-nRange,nRange ); else glOrtho( -nRange*w/h,nRange*w/h,-nRange, nRange, -nRange,nRange );
glMatrixMode( GL_MODELVIEW ); glLoadIdentity(); inclined = TRUE; key_and_mouse_down = FALSE; //********************************** Prepare_All(); Prepare_Smoke1(); Prepare_Smoke2(); Prepare_Smoke3(); ShowM(); } //---------------------------------------------------------------------------
[此贴子已经被作者于2005-10-20 10:27:41编辑过]