particles.cpp
上传用户:qccn516
上传日期:2013-05-02
资源大小:3382k
文件大小:6k
源码类别:

游戏引擎

开发平台:

Visual C++

  1. /* Particles
  2.  *
  3.  * Copyright (C) 2003-2004, Alexander Zaprjagaev <frustum@frustum.org>
  4.  *
  5.  * This program is free software; you can redistribute it and/or modify
  6.  * it under the terms of the GNU General Public License as published by
  7.  * the Free Software Foundation; either version 2 of the License, or
  8.  * (at your option) any later version.
  9.  *
  10.  * This program is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  * GNU General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU General Public License
  16.  * along with this program; if not, write to the Free Software
  17.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18.  */
  19. #include <stdlib.h>
  20. #ifdef _WIN32
  21. #include <windows.h>
  22. #endif
  23. #include <GL/gl.h>
  24. #include <GL/glext.h>
  25. #include "engine.h"
  26. #include "particles.h"
  27. vec3 Particles::OFF = vec3(0,0,1000000.0);
  28. /*
  29.  */
  30. Particles::Particles(int num,const vec3 &pos,float speed,float rotation,const vec3 &force,float time,float radius,const vec4 &color) :
  31. num_particles(num), pos(pos), speed(speed), rotation(rotation), force(force), time(time), radius(radius), color(color) {
  32. xyz = new vec3[num_particles];
  33. speeds = new vec3[num_particles];
  34. rotations = new float[num_particles];
  35. times = new float[num_particles];
  36. for(int i = 0; i < num_particles; i++) {
  37. xyz[i] = OFF;
  38. speeds[i] = vec3(0,0,0);
  39. rotations[i] = 0;
  40. times[i] = (float)i / (float)num_particles * time;
  41. }
  42. num_vertex = num_particles * 4;
  43. vertex = new Vertex[num_vertex];
  44. for(int i = 0; i < num_vertex; i++) {
  45. vertex[i].xyz = xyz[i / 4];
  46. int j = i % 4;
  47. if(j == 0) vertex[i].attrib = vec4(-0.5,0.5,-radius,-radius);
  48. else if(j == 1) vertex[i].attrib = vec4(0.5,0.5,radius,-radius);
  49. else if(j == 2) vertex[i].attrib = vec4(0.5,-0.5,radius,radius);
  50. else if(j == 3) vertex[i].attrib = vec4(-0.5,-0.5,-radius,radius);
  51. vertex[i].color = vec4(0,0,0,0);
  52. vertex[i].sincos = vec2(0,0);
  53. }
  54. }
  55. Particles::~Particles() {
  56. delete xyz;
  57. delete speeds;
  58. delete rotations;
  59. delete times;
  60. delete vertex;
  61. }
  62. /*****************************************************************************/
  63. /*                                                                           */
  64. /* render                                                                    */
  65. /*                                                                           */
  66. /*****************************************************************************/
  67. void Particles::update(float ifps) {
  68. min = vec3(1000000,1000000,1000000);
  69. max = vec3(-1000000,-1000000,-1000000);
  70. for(int i = 0; i < num_particles; i++) {
  71. int j = i * 4;
  72. speeds[i] += force * ifps;
  73. xyz[i] += speeds[i] * ifps;
  74. times[i] -= ifps;
  75. if(times[i] < 0) {
  76. xyz[i] = pos;
  77. speeds[i] = vec3(rand(),rand(),rand()) * speed;
  78. rotations[i] = rand() * rotation;
  79. times[i] += time;
  80. speeds[i] += force * ifps * 2.0f;
  81. xyz[i] += speeds[i] * ifps * 2.0f;
  82. }
  83. // update position
  84. vertex[j + 0].xyz = xyz[i];
  85. vertex[j + 1].xyz = vertex[j + 0].xyz;
  86. vertex[j + 2].xyz = vertex[j + 0].xyz;
  87. vertex[j + 3].xyz = vertex[j + 0].xyz;
  88. // update color
  89. vertex[j + 0].color = color * times[i] / time;
  90. vertex[j + 1].color = vertex[j + 0].color;
  91. vertex[j + 2].color = vertex[j + 0].color;
  92. vertex[j + 3].color = vertex[j + 0].color;
  93. // update rotation
  94. vertex[j + 0].sincos = vec2(sin(rotations[i] * times[i] * PI * 2.0),cos(rotations[i] * times[i] * PI * 2.0));
  95. vertex[j + 1].sincos = vertex[j + 0].sincos;
  96. vertex[j + 2].sincos = vertex[j + 0].sincos;
  97. vertex[j + 3].sincos = vertex[j + 0].sincos;
  98. // bound box
  99. if(xyz[i].z < OFF.z - 1000.0) {
  100. if(max.x < xyz[i].x) max.x = xyz[i].x;
  101. if(min.x > xyz[i].x) min.x = xyz[i].x;
  102. if(max.y < xyz[i].y) max.y = xyz[i].y;
  103. if(min.y > xyz[i].y) min.y = xyz[i].y;
  104. if(max.z < xyz[i].z) max.z = xyz[i].z;
  105. if(min.z > xyz[i].z) min.z = xyz[i].z;
  106. }
  107. }
  108. if(min.z > OFF.z - 1000.0) {
  109. max = OFF;
  110. min = OFF;
  111. } else {
  112. max += vec3(radius,radius,radius);
  113. min -= vec3(radius,radius,radius);
  114. }
  115. center = (min + max) / 2.0f;
  116. }
  117. /*
  118.  */
  119. void Particles::set(const vec3 &p) {
  120. pos = p;
  121. }
  122. void Particles::setForce(const vec3 &f) {
  123. force = f;
  124. }
  125. void Particles::setColor(const vec4 &c) {
  126. color = c;
  127. }
  128. /*****************************************************************************/
  129. /*                                                                           */
  130. /* render                                                                    */
  131. /*                                                                           */
  132. /*****************************************************************************/
  133. int Particles::render() {
  134. glEnableVertexAttribArrayARB(0);
  135. glEnableVertexAttribArrayARB(1);
  136. glEnableVertexAttribArrayARB(2);
  137. glEnableVertexAttribArrayARB(3);
  138. glVertexAttribPointerARB(0,3,GL_FLOAT,0,sizeof(Vertex),vertex->xyz);
  139. glVertexAttribPointerARB(1,4,GL_FLOAT,0,sizeof(Vertex),vertex->attrib);
  140. glVertexAttribPointerARB(2,4,GL_FLOAT,0,sizeof(Vertex),vertex->color);
  141. glVertexAttribPointerARB(3,2,GL_FLOAT,0,sizeof(Vertex),vertex->sincos);
  142. glDrawArrays(GL_QUADS,0,num_vertex);
  143. glDisableVertexAttribArrayARB(3);
  144. glDisableVertexAttribArrayARB(2);
  145. glDisableVertexAttribArrayARB(1);
  146. glDisableVertexAttribArrayARB(0);
  147. return num_particles * 2;
  148. }
  149. /*****************************************************************************/
  150. /*                                                                           */
  151. /* IO functions                                                              */
  152. /*                                                                           */
  153. /*****************************************************************************/
  154. const vec3 &Particles::getMin() {
  155. return min;
  156. }
  157. const vec3 &Particles::getMax() {
  158. return max;
  159. }
  160. const vec3 &Particles::getCenter() {
  161. return center;
  162. }
  163. float Particles::getRadius() {
  164. return (max - center).length();
  165. }
  166. /*****************************************************************************/
  167. /*                                                                           */
  168. /* normal law                                                                */
  169. /*                                                                           */
  170. /*****************************************************************************/
  171. float Particles::rand() {
  172. return sqrt(-2.0 * log((float)::rand() / RAND_MAX)) * sin(2.0 * PI * (float)::rand() / RAND_MAX);
  173. }