⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.cpp

📁 粒子效果演示(附代码) 利用C++所提供的一些标准容器很容易实现粒子效果. 简单的说就是,将粒子数据写在一个类里面,有一个粒子源,不停地生成粒子,然后放入一个stl::list中(push
💻 CPP
📖 第 1 页 / 共 3 页
字号:
#include <windows.h>		// Header File For Windows
#include <gl\gl.h>			// Header File For The OpenGL32 Library
#include <gl\glu.h>			// Header File For The GLu32 Library
#include <gl\glaux.h>		// Header File For The Glaux Library
#include <stdio.h>
#include <olectl.h>              
#include <math.h>

#include <list>

#include "3DS.h"            //Header File For Display Models
GLuint particle;
bool stop(false);

int ParticleCount(0);


float eyePosition[3];

struct Pos
{
	float x;
	float y;
	float z;
};

struct Color
{
	float R;
	float G;
	float B;
};

struct Direction
{
	float x;
	float y;
	float z;
};






class Dot
{
public:
	bool dead;
	void Init(float x, float y, float z)
	{
		position.x = x;
		position.y = y;
		position.z = z;
		color.R = 1.0f;
		color.G = 1.0f;
		color.B = 1.0f;
		direction.x = (rand()/32767.0f-0.5f)*2.0f;
		direction.y = (rand()/32767.0f-0.5f)*2.0f;
		direction.z = (rand()/32767.0f-0.5f)*2.0f;
		speed = rand()/32767.0f+1.0f;
		acc = rand()/327670.0f+1.0f;
		dcc = rand()/32767.0f/10.0f+0.01f;
		alpha = 1.0f;
		dead = false;
	}
	~Dot()
	{
	}
	void Render()
	{
		if(dead==true) return;
		
		ParticleCount++;

		position.x += direction.x * speed * acc;
		position.y += direction.y * speed * acc+2.0f;
		position.z += direction.z * speed * acc;
		alpha -=dcc;

		if(alpha<0.0f) dead = true;

		glColor4f(color.R, (1-2.0f*alpha)*color.G, (1-8.0f*alpha)*color.B, alpha);
		glEnable(GL_TEXTURE_2D);
		glDepthMask(GL_FALSE);
		glBindTexture(GL_TEXTURE_2D, particle);
		glBlendFunc(GL_SRC_ALPHA, GL_ONE);
		glEnable(GL_BLEND);
		
		glPushMatrix();
			glTranslatef(position.x,
				         position.y,
						 position.z);
			glBegin(GL_QUADS);
				glTexCoord2i(0, 1);	glVertex3f(-13.0f, 13.0f, 0.0f);
				glTexCoord2i(0, 0);	glVertex3f(13.0f, 13.0f, 0.0f);
				glTexCoord2i(1, 0);	glVertex3f(13.0f, -13.0f, 0.0f);
				glTexCoord2i(1, 1);	glVertex3f(-13.0f, -13.0f, 0.0f);
			glEnd();
			glBegin(GL_QUADS);
				glTexCoord2i(0, 1);	glVertex3f(0.0f, 13.0f, -13.0f);
				glTexCoord2i(0, 0);	glVertex3f(0.0f, 13.0f, 13.0f);
				glTexCoord2i(1, 0);	glVertex3f(0.0f, -13.0f, 13.0f);
				glTexCoord2i(1, 1);	glVertex3f(0.0f, -13.0f, -13.0f);
			glEnd();
			glBegin(GL_QUADS);
				glTexCoord2i(0, 1);	glVertex3f(13.0f, 0.0f, -13.0f);
				glTexCoord2i(0, 0);	glVertex3f(13.0f, 0.0f, 13.0f);
				glTexCoord2i(1, 0);	glVertex3f(-13.0f, -0.0f, 13.0f);
				glTexCoord2i(1, 1);	glVertex3f(-13.0f, -0.0f, -13.0f);
			glEnd();
		glPopMatrix();
		glDepthMask(GL_TRUE);
		glDisable(GL_BLEND);
		glDisable(GL_TEXTURE_2D);		
	}
private:
	Pos position;
	Color color;
	Direction direction;
	float speed;
	float acc;
	float alpha;
	float dcc;
};

class DotSource
{
public:
	DotSource(float x, float y, float z)
	{
		for(int i=0;i<400;i++)
			dots[i].Init(x, y, z);
		dead = false;
	}
	void Render()
	{
		if(dead == true) return;
		dead = true;
		for(int i=0;i<400;i++)
		{
			if(dots[i].dead == false)
				dead = false;
			dots[i].Render();
		}
	}
	bool dead;
private:
	Pos position;
	Dot dots[400];
};

list<DotSource> ParticleSystem;

float posx, posy, posz;

float GetTime();
void DrawParticle()
{
	posx = 300.0f*sin(GetTime()*2.0f);
	posy = 300.0f*cos(GetTime()*2.0f)*sin(GetTime());
	posz = 300.0f*cos(GetTime()*2.0f);
	
	static count=0;
	list<DotSource>::iterator pointer;
	for(pointer=ParticleSystem.begin();pointer!=ParticleSystem.end();pointer++)
	{
		pointer->Render();	
		if(pointer->dead == true)
		{
			pointer = ParticleSystem.erase(pointer);
		}
	}
	
	if(count>=0)
	{
		if(stop==false)
		{
		DotSource dotsource(posx, posy, posz);
		ParticleSystem.push_back(dotsource);
		}
		count=0;
	}

	
	count++;

}


HDC			hDC=NULL;		// Private GDI Device Context
HGLRC		hRC=NULL;		// Permanent Rendering Context
HWND		hWnd=NULL;		// Holds Our Window Handle
HINSTANCE	hInstance;		// Holds The Instance Of The Application

bool	keys[256];			// Array Used For The Keyboard Routine
bool	active=TRUE;		// Window Active Flag Set To TRUE By Default
bool	fullscreen=TRUE;	// Fullscreen Flag Set To Fullscreen Mode By Default

char* brand=NULL;		//显卡型号
char* vendor=NULL;		//显卡制造商
char* version=NULL;		//版本号

int fps(72);			//帧数

GLuint cubeface[6];


///////////////// 创建纹理 //////////////////////////////////

BOOL BuildTexture(char *szPathName, GLuint &texid)
{
  HDC      hdcTemp;                        // The DC To Hold Our Bitmap
  HBITMAP    hbmpTemp;                        // Holds The Bitmap Temporarily
  IPicture  *pPicture;                        // IPicture Interface
  OLECHAR    wszPath[MAX_PATH+1];                  // Full Path To Picture (WCHAR)
  char    szPath[MAX_PATH+1];                    // Full Path To Picture
  long    lWidth;                          // Width In Logical Units
  long    lHeight;                        // Height In Logical Units
  long    lWidthPixels;                      // Width In Pixels
  long    lHeightPixels;                      // Height In Pixels
  GLint    glMaxTexDim ;                      // Holds Maximum Texture Size

  if (strstr(szPathName, "http://"))                  // If PathName Contains http:// Then...
  {
    strcpy(szPath, szPathName);                    // Append The PathName To szPath
  }
  else                                // Otherwise... We Are Loading From A File
  {
    GetCurrentDirectory(MAX_PATH, szPath);              // Get Our Working Directory
    strcat(szPath, "\\");                      // Append "\" After The Working Directory
    strcat(szPath, szPathName);                    // Append The PathName
  }

  MultiByteToWideChar(CP_ACP, 0, szPath, -1, wszPath, MAX_PATH);    // Convert From ASCII To Unicode
  HRESULT hr = OleLoadPicturePath(wszPath, 0, 0, 0, IID_IPicture, (void**)&pPicture);

  if(FAILED(hr))                            // If Loading Failed
    return FALSE;                          // Return False

  hdcTemp = CreateCompatibleDC(GetDC(0));                // Create The Windows Compatible Device Context
  if(!hdcTemp)                            // Did Creation Fail?
  {
    pPicture->Release();                      // Decrements IPicture Reference Count
    return FALSE;                          // Return False (Failure)
  }

  glGetIntegerv(GL_MAX_TEXTURE_SIZE, &glMaxTexDim);          // Get Maximum Texture Size Supported
  
  pPicture->get_Width(&lWidth);                    // Get IPicture Width (Convert To Pixels)
  lWidthPixels  = MulDiv(lWidth, GetDeviceCaps(hdcTemp, LOGPIXELSX), 2540);
  pPicture->get_Height(&lHeight);                    // Get IPicture Height (Convert To Pixels)
  lHeightPixels  = MulDiv(lHeight, GetDeviceCaps(hdcTemp, LOGPIXELSY), 2540);

  // Resize Image To Closest Power Of Two
  if (lWidthPixels <= glMaxTexDim) // Is Image Width Less Than Or Equal To Cards Limit
    lWidthPixels = 1 << (int)floor((log((double)lWidthPixels)/log(2.0f)) + 0.5f); 
  else // Otherwise Set Width To "Max Power Of Two" That The Card Can Handle
    lWidthPixels = glMaxTexDim;
 
  if (lHeightPixels <= glMaxTexDim) // Is Image Height Greater Than Cards Limit
    lHeightPixels = 1 << (int)floor((log((double)lHeightPixels)/log(2.0f)) + 0.5f);
  else // Otherwise Set Height To "Max Power Of Two" That The Card Can Handle
    lHeightPixels = glMaxTexDim;
  
  //  Create A Temporary Bitmap
  BITMAPINFO  bi = {0};                        // The Type Of Bitmap We Request
  DWORD    *pBits = 0;                        // Pointer To The Bitmap Bits

  bi.bmiHeader.biSize      = sizeof(BITMAPINFOHEADER);        // Set Structure Size
  bi.bmiHeader.biBitCount    = 32;                  // 32 Bit
  bi.bmiHeader.biWidth    = lWidthPixels;              // Power Of Two Width
  bi.bmiHeader.biHeight    = lHeightPixels;            // Make Image Top Up (Positive Y-Axis)
  bi.bmiHeader.biCompression  = BI_RGB;                // RGB Encoding
  bi.bmiHeader.biPlanes    = 1;                  // 1 Bitplane

  //  Creating A Bitmap This Way Allows Us To Specify Color Depth And Gives Us Imediate Access To The Bits
  hbmpTemp = CreateDIBSection(hdcTemp, &bi, DIB_RGB_COLORS, (void**)&pBits, 0, 0);
  
  if(!hbmpTemp)                            // Did Creation Fail?
  {
    DeleteDC(hdcTemp);                        // Delete The Device Context
    pPicture->Release();                      // Decrements IPicture Reference Count
    return FALSE;                          // Return False (Failure)
  }

  SelectObject(hdcTemp, hbmpTemp);                  // Select Handle To Our Temp DC And Our Temp Bitmap Object

  // Render The IPicture On To The Bitmap
  pPicture->Render(hdcTemp, 0, 0, lWidthPixels, lHeightPixels, 0, lHeight, lWidth, -lHeight, 0);

  // Convert From BGR To RGB Format And Add An Alpha Value Of 255
  for(long i = 0; i < lWidthPixels * lHeightPixels; i++)        // Loop Through All Of The Pixels
  {
    BYTE* pPixel  = (BYTE*)(&pBits[i]);              // Grab The Current Pixel
    BYTE temp    = pPixel[0];                  // Store 1st Color In Temp Variable (Blue)
    pPixel[0]    = pPixel[2];                  // Move Red Value To Correct Position (1st)
    pPixel[2]    = temp;                      // Move Temp Value To Correct Blue Position (3rd)

    // This Will Make Any Black Pixels, Completely Transparent    (You Can Hardcode The Value If You Wish)
    if ((pPixel[0]==0) && (pPixel[1]==0) && (pPixel[2]==0))      // Is Pixel Completely Black
      pPixel[3]  = 0;                      // Set The Alpha Value To 0
    else                              // Otherwise
      pPixel[3]  = 255;                      // Set The Alpha Value To 255
  }

  glGenTextures(1, &texid);                      // Create The Texture

  // Typical Texture Generation Using Data From The Bitmap
  glBindTexture(GL_TEXTURE_2D, texid);                // Bind To The Texture ID
  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);    // (Modify This For The Type Of Filtering You Want)
  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); // (Modify This For The Type Of Filtering You Want)
  gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, lWidthPixels, lHeightPixels, GL_RGBA, GL_UNSIGNED_BYTE, pBits);
  //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, lWidthPixels, lHeightPixels, 0, GL_RGBA, GL_UNSIGNED_BYTE, pBits);  // (Modify This If You Want Mipmaps)
  
  DeleteObject(hbmpTemp);                        // Delete The Object
  DeleteDC(hdcTemp);                          // Delete The Device Context

  pPicture->Release();                        // Decrements IPicture Reference Count

  return TRUE;                            // Return True (All Good)
}

////////////////////////// 绘制模型 ///////////////////////////////////////////////////
//画这个模型

void DrawModel(t3DModel& Model)
{
  // 遍历模型中所有的对象
  for(int i = 0; i < Model.numOfObjects; i++)
  {
    // 如果对象的大小小于0,则退出
    if(Model.pObject.size() <= 0) break;

    // 获得当前显示的对象
    t3DObject *pObject = &Model.pObject[i];
      
    // 判断该对象是否有纹理映射
    if(pObject->bHasTexture) {

      // 打开纹理映射
      glEnable(GL_TEXTURE_2D);
      glColor3ub(255, 255, 255);
      glBindTexture(GL_TEXTURE_2D, Model.texture[pObject->materialID]);
    } else {

      // 关闭纹理映射
      glDisable(GL_TEXTURE_2D);
      glColor3ub(255, 255, 255);
    }
    // 开始以g_ViewMode模式绘制
    glBegin(GL_TRIANGLES);          
      // 遍历所有的面
      for(int j = 0; j < pObject->numOfFaces; j++)
      {
        // 遍历三角形的所有点
        for(int whichVertex = 0; whichVertex < 3; whichVertex++)
        {
          // 获得面对每个点的索引
          int index = pObject->pFaces[j].vertIndex[whichVertex];
      
          // 给出法向量
          glNormal3f(pObject->pNormals[ index ].x, pObject->pNormals[ index ].y, pObject->pNormals[ index ].z);
        
          // 如果对象具有纹理
          if(pObject->bHasTexture) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -