OpenGL 噴泉效果部分解釋


<span style="color:#3333ff;">一、頭文件:MyFountainView.h</span>
#if !defined(AFX_MYFOUNTAINVIEW_H__E05402FF_323D_4CD3_A3C7_0BA99ECE1187__INCLUDED_)#define AFX_MYFOUNTAINVIEW_H__E05402FF_323D_4CD3_A3C7_0BA99ECE1187__INCLUDED_#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000#define PI 3.1415926struct particle{    float t;	float v;	float d;	float x,y,z;	float xd,zd;	char type;	float a;	struct particle *next,*prev;};struct point{      float x,y,z;};class CMyFountainView : public CView{protected: // create from serialization only	CMyFountainView();	DECLARE_DYNCREATE(CMyFountainView)// Attributespublic:	CMyFountainDoc* GetDocument();// Operationspublic:	public:	virtual void OnDraw(CDC* pDC);  // overridden to draw this view	virtual BOOL PreCreateWindow(CREATESTRUCT& cs);	protected:	virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);	virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);	virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);	//}}AFX_VIRTUAL// Implementationpublic:
        ///////////////////<span style="color:#ff6666;">這里是基本的內容,顯示畫面的窗體</span>
	virtual ~CMyFountainView();        BOOL RenderScene();	BOOL SetupPixelFormat(void);	void SetLogicalPalette(void);	BOOL InitializeOpenGL(CDC* pDC);	HGLRC m_hRC;	HPALETTE m_hPalette;	CDC* m_pDC;
////////////////////////////////////////<span style="color:#ff0000;">這里面是噴選相關函數和參數的說明</span>	void Init();	void LoadTexture(char *fn,int t_num);        void DrawFountain();	void normalize(struct point *V);	void vect_mult(struct point *A,struct point *B,struct point *C);	void AddParticles();	void MoveParticles();	void DeleteParticles();		unsigned *teximage;	GLuint texture[3];	float a;        struct point upv,cam;	int fCount;		struct particle *fn[3];/////////////////////////////////////////#ifdef _DEBUG	virtual void AssertValid() const;	virtual void Dump(CDumpContext& dc) const;#endifprotected:// Generated message map functionsprotected:	//{{AFX_MSG(CMyFountainView)	afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);	afx_msg void OnDestroy();	afx_msg void OnSize(UINT nType, int cx, int cy);	afx_msg void OnTimer(UINT nIDEvent);	//}}AFX_MSG	DECLARE_MESSAGE_MAP()};#ifndef _DEBUG  // debug version in MyFountainView.cppinline CMyFountainDoc* CMyFountainView::GetDocument()   { return (CMyFountainDoc*)m_pDocument; }#endif
<span style="font-family: Arial, Helvetica, sans-serif;"></span>
<span style="font-family: Arial, Helvetica, sans-serif;"><span style="color:#6600cc;">二、源文件:MyFountainView.cpp</span></span>
#include "stdafx.h"#include "MyFountain.h"#include "MyFountainDoc.h"#include "MyFountainView.h"#include <math.h>#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endifIMPLEMENT_DYNCREATE(CMyFountainView, CView)BEGIN_MESSAGE_MAP(CMyFountainView, CView)	//{{AFX_MSG_MAP(CMyFountainView)	ON_WM_CREATE()	ON_WM_DESTROY()	ON_WM_SIZE()	ON_WM_TIMER()	//}}AFX_MSG_MAP	// Standard printing commands	ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)	ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)END_MESSAGE_MAP()CMyFountainView::CMyFountainView(){	// TODO: add construction code here}CMyFountainView::~CMyFountainView(){}BOOL CMyFountainView::PreCreateWindow(CREATESTRUCT& cs){	// TODO: Modify the Window class or styles here by modifying	//  the CREATESTRUCT cs	return CView::PreCreateWindow(cs);}void CMyFountainView::OnDraw(CDC* pDC){	CMyFountainDoc* pDoc = GetDocument();	ASSERT_VALID(pDoc);	// TODO: add draw code for native data here	<span style="color:#ff0000;">RenderScene();</span>}BOOL CMyFountainView::OnPreparePrinting(CPrintInfo* pInfo){	// default preparation	return DoPreparePrinting(pInfo);}void CMyFountainView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/){	// TODO: add extra initialization before printing}void CMyFountainView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/){	// TODO: add cleanup after printing}#ifdef _DEBUGvoid CMyFountainView::AssertValid() const{	CView::AssertValid();}void CMyFountainView::Dump(CDumpContext& dc) const{	CView::Dump(dc);}CMyFountainDoc* CMyFountainView::GetDocument() // non-debug version is inline{	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMyFountainDoc)));	return (CMyFountainDoc*)m_pDocument;}#endif //_DEBUGint CMyFountainView::OnCreate(LPCREATESTRUCT lpCreateStruct) {	if (CView::OnCreate(lpCreateStruct) == -1)		return -1;	m_pDC=new CClientDC(this);	SetTimer(1,20,NULL);	<span style="color:#ff0000;">InitializeOpenGL(m_pDC);</span>	// TODO: Add your specialized creation code here	<span style="color:#ff0000;">Init();</span>	return 0;}void CMyFountainView::OnDestroy() {	CView::OnDestroy();		// TODO: Add your message handler code here	::wglMakeCurrent(0,0);	::wglDeleteContext(m_hRC);	if(m_hPalette) DeleteObject(m_hPalette);	if(m_pDC) delete m_pDC;	KillTimer(1);}void CMyFountainView::OnSize(UINT nType, int cx, int cy) {	CView::OnSize(nType, cx, cy);		// TODO: Add your message handler code here    glViewport(0,0,cx,cy);	glMatrixMode(GL_PROJECTION);	glLoadIdentity();	glFrustum(-0.5,0.5,-0.5,0.5,1,1000);	glMatrixMode(GL_MODELVIEW);}void CMyFountainView::OnTimer(UINT nIDEvent) {	// TODO: Add your message handler code here and/or call default	Invalidate(FALSE);	CView::OnTimer(nIDEvent);}BOOL CMyFountainView::InitializeOpenGL(CDC* pDC){        m_pDC=pDC;	SetupPixelFormat();	m_hRC=::wglCreateContext(m_pDC->GetSafeHdc());	::wglMakeCurrent(m_pDC->GetSafeHdc(),m_hRC);	return TRUE;}BOOL CMyFountainView::SetupPixelFormat(){PIXELFORMATDESCRIPTOR pfd = { 	    sizeof(PIXELFORMATDESCRIPTOR),    // pfd結構的大小 	    1,                                // 版本號 	    PFD_DRAW_TO_WINDOW |              // 支持在窗口中繪圖 	    PFD_SUPPORT_OPENGL |              // 支持 OpenGL 	    PFD_DOUBLEBUFFER,                 // 雙緩存模式 	    PFD_TYPE_RGBA,                    // RGBA 顏色模式 	    24,                               // 24 位顏色深度 	    0, 0, 0, 0, 0, 0,                 // 忽略顏色位 	    0,                                // 沒有非透明度緩存 	    0,                                // 忽略移位位 	    0,                                // 無累加緩存 	    0, 0, 0, 0,                       // 忽略累加位 	    32,                               // 32 位深度緩存     	    0,                                // 無模板緩存 	    0,                                // 無輔助緩存 	    PFD_MAIN_PLANE,                   // 主層 	    0,                                // 保留 	    0, 0, 0                           // 忽略層,可見性和損毀掩模 	}; 		int pixelformat;	pixelformat = ::ChoosePixelFormat(m_pDC->GetSafeHdc(), &pfd);//選擇像素格式	::SetPixelFormat(m_pDC->GetSafeHdc(), pixelformat, &pfd);	//設置像素格式	if(pfd.dwFlags & PFD_NEED_PALETTE)		SetLogicalPalette();	//設置邏輯調色板	return TRUE;}void CMyFountainView::SetLogicalPalette(void){ struct    {        WORD Version;        WORD NumberOfEntries;        PALETTEENTRY aEntries[256];    } logicalPalette = { 0x300, 256 };	BYTE reds[] = {0, 36, 72, 109, 145, 182, 218, 255};	BYTE greens[] = {0, 36, 72, 109, 145, 182, 218, 255};	BYTE blues[] = {0, 85, 170, 255};    for (int colorNum=0; colorNum<256; ++colorNum)    {        logicalPalette.aEntries[colorNum].peRed =            reds[colorNum & 0x07];        logicalPalette.aEntries[colorNum].peGreen =            greens[(colorNum >> 0x03) & 0x07];        logicalPalette.aEntries[colorNum].peBlue =            blues[(colorNum >> 0x06) & 0x03];        logicalPalette.aEntries[colorNum].peFlags = 0;    }    m_hPalette = CreatePalette ((LOGPALETTE*)&logicalPalette);}void CMyFountainView::Init(){    a=0;	fn[0]=NULL;	fn[1]=NULL;	fn[2]=NULL;	fCount=3;	upv.x=-5;	upv.y=5;	upv.z=-5;	cam.x=200;	cam.y=200;	cam.z=200;	glGenTextures(3,texture);	glClearColor(0,0,0,0);	glBlendFunc(GL_SRC_ALPHA,GL_ONE);	glEnable(GL_BLEND);	glEnable(GL_TEXTURE_2D);	LoadTexture("particle.rgb",0);	LoadTexture("ground1.rgb",1);	LoadTexture("ground2.rgb",2);}BOOL CMyFountainView::RenderScene(){        glClear(GL_COLOR_BUFFER_BIT);        glLoadIdentity();	glBindTexture(GL_TEXTURE_2D,texture[1]);        a+=0.2;        gluLookAt(cam.x,cam.y,cam.z,0,0,0,upv.x,upv.y,upv.z);	       <span style="color:#ff0000;"> DrawFountain();//噴泉函數</span>	glFlush();	::SwapBuffers(m_pDC->GetSafeHdc());<span style="color:#ff0000;">//動畫刷新,不然動不起來</span>	return TRUE;}void CMyFountainView::DrawFountain(){	int j;	struct particle *tempp;	struct point vectd,vectl;	float alpha,ttx,ttz;	glBindTexture(GL_TEXTURE_2D,texture[0]);	AddParticles();	MoveParticles();	DeleteParticles();	glPushMatrix();		for(j=0;j<fCount;j++){		glBegin(GL_QUADS);		tempp=fn[j];		while(tempp){				// 旋轉噴泉			alpha = ((j*360/fCount+a)*PI)/180;//<span style="color:#ff0000;">a是整個噴泉旋轉,<span style="font-family: Arial, Helvetica, sans-serif;">j*360/fCount:噴泉是一束一束的,這是每一束所占的角度</span></span>
<span style="font-family:Arial, Helvetica, sans-serif;color:#ff0000;">                                              //下面是平面坐標轉換,要想到矩陣。</span>			ttx = tempp->x*cos(alpha)-tempp->z*sin(alpha);			ttz = tempp->x*sin(alpha)+tempp->z*cos(alpha);			// 計算方向矢量			vectd.x = ttx - cam.x;			vectd.y = tempp->y - cam.y;			vectd.z = ttz - cam.z;			vect_mult(&vectd, &upv, &vectl);			normalize(&vectl);			vectl.x *= 5;			vectl.y *= 5;			vectl.z *= 5;			glColor4f(0.5, 0.5, 1, tempp->a);			// 繪制多邊形和粒子紋理映射
                       	   		glTexCoord2f(0, 0); <span style="color:#ff0000;">glVertex3f((ttx-vectl.x), (tempp->y-upv.y), (ttz-vectl.z));//這是一個點</span>			glTexCoord2f(1, 0); glVertex3f((ttx+vectl.x), (tempp->y-upv.y), (ttz+vectl.z));			glTexCoord2f(1, 1); glVertex3f((ttx+vectl.x), (tempp->y+upv.y), (ttz+vectl.z));			glTexCoord2f(0, 1); glVertex3f((ttx-vectl.x), (tempp->y+upv.y), (ttz-vectl.z));			tempp = tempp->next; // 繪制下一個粒子列表			}		glEnd();	}	glPopMatrix();}void CMyFountainView::AddParticles(){	struct particle *tempp;	int i,j;	for(j=0;j<fCount;j++){        for(i=0;i<2;i++){			tempp=(struct particle *)malloc(sizeof(struct particle));            if(fn[j])fn[j]->prev=tempp;			tempp->next=fn[j];			fn[j]=tempp;			tempp->t=-9.9;			tempp->v=(float)(rand()%200000)/100000+1;			tempp->d=(float)(rand()%400)/100-2;			tempp->x=0;	        tempp->y = 0;			tempp->z = 0;			tempp->xd = cos((tempp->d*PI)/180)*tempp->v/4;			tempp->zd = sin((tempp->d*PI)/180)*tempp->v;			tempp->type = 0; 			tempp->a = 1;   		}	}}void CMyFountainView::MoveParticles(){	struct particle *tempp;	int j;	for(j=0;j<fCount;j++){        tempp=fn[j];		while(tempp){			if(tempp->type==0){			tempp->x+=tempp->xd;			tempp->z+=tempp->zd;            tempp->y=122.5-(9.8*(tempp->t*tempp->t/4))/2;			tempp->t+=0.1;			if(tempp->y<0)tempp->type=1;			}else{              tempp->a-=0.1;			}			tempp=tempp->next;		}	}}void CMyFountainView::DeleteParticles(){	struct particle *tempp,*temp1;	int j;	for(j=0;j<fCount;j++){		tempp=fn[j];		while(tempp){			if((tempp->type==1)&&(tempp->a<=0)){				if(tempp->prev==NULL){					tempp=tempp->next;					tempp->prev=NULL;				}else{					temp1=tempp->prev;					tempp->prev->next=tempp->next;					if(tempp->next)tempp->next->prev=temp1;					free(tempp);					tempp=temp1;				}			}			tempp=tempp->next;		}	}}void CMyFountainView::normalize(struct point *V){	float d;	d=sqrt(V->x*V->x+V->y*V->y+V->z*V->z);	V->x/=d;	V->y/=d;	V->z/=d;}void CMyFountainView::vect_mult(struct point *A,struct point *B,struct point *C){	C->x = A->y*B->z - A->z*B->y;	C->y = A->z*B->x - A->x*B->z;	C->z = A->x*B->y - A->y*B->x;}void CMyFountainView::LoadTexture(char *fn,int t_num){	int texwid, texht;	int texcomps;	teximage = m_Tex->read_texture(fn, &texwid, &texht, &texcomps);	if (!teximage)	{		MessageBox("Sorry, can't read texture file...","ERROR",MB_OK);		exit(0);	}	glBindTexture(GL_TEXTURE_2D, texture[t_num]);	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);	glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, texwid, texht, 0, GL_RGBA, GL_UNSIGNED_BYTE, teximage);	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 	if ((t_num == 0) || (t_num == 2)) glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 	if (t_num == 1)	{		// 對於地面紋理,重復紋理參數		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 	}	free(teximage);}

噴泉效果:


問題:在程序中用到了particle.rgb文件。我不知道用什么軟件可以生產這樣的圖片格式文件。希望知道的朋友告知一下。


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com