Equalizer 1.0
|
00001 /* 00002 * Copyright 1993-2006 NVIDIA Corporation. All rights reserved. 00003 * 00004 * NOTICE TO USER: 00005 * 00006 * This source code is subject to NVIDIA ownership rights under U.S. and 00007 * international Copyright laws. 00008 * 00009 * NVIDIA MAKES NO REPRESENTATION ABOUT THE SUITABILITY OF THIS SOURCE 00010 * CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR 00011 * IMPLIED WARRANTY OF ANY KIND. NVIDIA DISCLAIMS ALL WARRANTIES WITH 00012 * REGARD TO THIS SOURCE CODE, INCLUDING ALL IMPLIED WARRANTIES OF 00013 * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE. 00014 * IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL, 00015 * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS 00016 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 00017 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE 00018 * OR PERFORMANCE OF THIS SOURCE CODE. 00019 * 00020 * U.S. Government End Users. This source code is a "commercial item" as 00021 * that term is defined at 48 C.F.R. 2.101 (OCT 1995), consisting of 00022 * "commercial computer software" and "commercial computer software 00023 * documentation" as such terms are used in 48 C.F.R. 12.212 (SEPT 1995) 00024 * and is provided to the U.S. Government only as a commercial end item. 00025 * Consistent with 48 C.F.R.12.212 and 48 C.F.R. 227.7202-1 through 00026 * 227.7202-4 (JUNE 1995), all U.S. Government End Users acquire the 00027 * source code with only those rights set forth herein. 00028 */ 00029 00030 /* 00031 * Slightly adapted 2009 by Ph. Robert wrt the Equalizer port 00032 */ 00033 00034 #include "render_particles.h" 00035 #include <eq/eq.h> 00036 00037 #include <math.h> 00038 #include <assert.h> 00039 00040 #define GL_POINT_SPRITE_ARB 0x8861 00041 #define GL_COORD_REPLACE_ARB 0x8862 00042 #define GL_VERTEX_PROGRAM_POINT_SIZE_NV 0x8642 00043 #define glewContext glewGetContext() 00044 00045 namespace eqNbody 00046 { 00047 void _checkGLErrors(char const* s) 00048 { 00049 GLenum error; 00050 while ((error = glGetError()) != GL_NO_ERROR) 00051 { 00052 EQERROR << s << "error - " << std::endl; // << (char *) gluErrorString(error) 00053 exit(EXIT_FAILURE); 00054 } 00055 } 00056 00057 00058 ParticleRenderer::~ParticleRenderer() 00059 { 00060 m_pos = 0; 00061 } 00062 00063 void ParticleRenderer::setPositions(float *pos, int numParticles) 00064 { 00065 m_pos = pos; 00066 m_numParticles = numParticles; 00067 } 00068 00069 void ParticleRenderer::setColors(float *color, int numParticles) 00070 { 00071 glBindBuffer(GL_ARRAY_BUFFER_ARB, m_vboColor); 00072 glBufferData(GL_ARRAY_BUFFER_ARB, numParticles * 4 * sizeof(float), color, GL_STATIC_DRAW_ARB); 00073 glBindBuffer( GL_ARRAY_BUFFER_ARB, 0); 00074 } 00075 00076 void ParticleRenderer::setPBO(unsigned int pbo, int numParticles) 00077 { 00078 m_pbo = pbo; 00079 m_numParticles = numParticles; 00080 } 00081 00082 void ParticleRenderer::_drawPoints(bool color) 00083 { 00084 if (!m_pbo) 00085 { 00086 glBegin(GL_POINTS); 00087 { 00088 int k = 0; 00089 for (int i = 0; i < m_numParticles; ++i) 00090 { 00091 glVertex3fv(&m_pos[k]); 00092 k += 4; 00093 } 00094 } 00095 glEnd(); 00096 } 00097 else 00098 { 00099 glEnableClientState(GL_VERTEX_ARRAY); 00100 00101 glBindBufferARB(GL_ARRAY_BUFFER_ARB, m_pbo); 00102 glVertexPointer(4, GL_FLOAT, 0, 0); 00103 00104 if (color) 00105 { 00106 glEnableClientState(GL_COLOR_ARRAY); 00107 glBindBufferARB(GL_ARRAY_BUFFER_ARB, m_vboColor); 00108 glColorPointer(4, GL_FLOAT, 0, 0); 00109 } 00110 00111 glDrawArrays(GL_POINTS, 0, m_numParticles); 00112 glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); 00113 glDisableClientState(GL_VERTEX_ARRAY); 00114 00115 if (color) 00116 glDisableClientState(GL_COLOR_ARRAY); 00117 00118 } 00119 } 00120 00121 void ParticleRenderer::draw(DisplayMode mode) 00122 { 00123 switch (mode) 00124 { 00125 case PARTICLE_POINTS: 00126 glColor3f(1, 1, 1); 00127 glPointSize(m_pointSize); 00128 _drawPoints(); 00129 break; 00130 case PARTICLE_SPRITES_COLOR: 00131 { 00132 // setup point sprites 00133 glEnable(GL_POINT_SPRITE_ARB); 00134 glTexEnvi(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE); 00135 glEnable(GL_VERTEX_PROGRAM_POINT_SIZE_NV); 00136 glPointSize(m_spriteSize); 00137 glBlendFunc(GL_SRC_ALPHA, GL_ONE); 00138 glEnable(GL_BLEND); 00139 glDepthMask(GL_FALSE); 00140 00141 glUseProgram(m_program); 00142 GLuint texLoc = glGetUniformLocation(m_program, "splatTexture"); 00143 glUniform1i(texLoc, 0); 00144 00145 glActiveTextureARB(GL_TEXTURE0_ARB); 00146 glBindTexture(GL_TEXTURE_2D, m_texture); 00147 00148 glColor3f(1, 1, 1); 00149 _drawPoints(true); 00150 00151 glUseProgram(0); 00152 glDisable(GL_POINT_SPRITE_ARB); 00153 glDisable(GL_BLEND); 00154 glDepthMask(GL_TRUE); 00155 break; 00156 } 00157 case PARTICLE_SPRITES: 00158 default: 00159 { 00160 // setup point sprites 00161 glEnable(GL_POINT_SPRITE_ARB); 00162 glTexEnvi(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE); 00163 glEnable(GL_VERTEX_PROGRAM_POINT_SIZE_NV); 00164 glPointSize(m_spriteSize); 00165 glBlendFunc(GL_SRC_ALPHA, GL_ONE); 00166 glEnable(GL_BLEND); 00167 glDepthMask(GL_FALSE); 00168 00169 glUseProgram(m_program); 00170 GLuint texLoc = glGetUniformLocation(m_program, "splatTexture"); 00171 glUniform1i(texLoc, 0); 00172 00173 glActiveTextureARB(GL_TEXTURE0_ARB); 00174 glBindTexture(GL_TEXTURE_2D, m_texture); 00175 00176 glColor3f(1, 1, 1); 00177 00178 _drawPoints(); 00179 glUseProgram(0); 00180 00181 glDisable(GL_POINT_SPRITE_ARB); 00182 glDisable(GL_BLEND); 00183 glDepthMask(GL_TRUE); 00184 break; 00185 } 00186 } 00187 00188 _checkGLErrors("GL error in draw"); 00189 } 00190 00191 const char vertexShader[] = 00192 { 00193 "void main() \n" 00194 "{ \n" 00195 " float pointSize = 500.0 * gl_Point.size; \n" 00196 " vec4 vert = gl_Vertex; \n" 00197 " vert.w = 1.0; \n" 00198 " vec3 pos_eye = vec3 (gl_ModelViewMatrix * vert); \n" 00199 " gl_PointSize = max(1.0, pointSize / (1.0 - pos_eye.z)); \n" 00200 " gl_TexCoord[0] = gl_MultiTexCoord0; \n" 00201 " gl_Position = ftransform(); \n" 00202 " gl_FrontColor = gl_Color; \n" 00203 "} \n" 00204 }; 00205 00206 const char pixelShader[] = 00207 { 00208 "uniform sampler2D splatTexture; \n" 00209 00210 "void main() \n" 00211 "{ \n" 00212 " vec4 color = (0.6 + 0.4 * gl_Color) * texture2D(splatTexture, gl_TexCoord[0].st); \n" 00213 " gl_FragColor = \n" 00214 " color * mix(vec4(0.1, 0.0, 0.0, color.w), vec4(1.0, 0.7, 0.3, color.w), color.w);\n" 00215 "} \n" 00216 }; 00217 00218 void ParticleRenderer::init() 00219 { 00220 m_vertexShader = glCreateShader(GL_VERTEX_SHADER); 00221 m_pixelShader = glCreateShader(GL_FRAGMENT_SHADER); 00222 00223 const char* v = vertexShader; 00224 const char* p = pixelShader; 00225 00226 glShaderSource(m_vertexShader, 1, &v, 0); 00227 glShaderSource(m_pixelShader, 1, &p, 0); 00228 00229 glCompileShader(m_vertexShader); 00230 glCompileShader(m_pixelShader); 00231 00232 m_program = glCreateProgram(); 00233 00234 glAttachShader(m_program, m_vertexShader); 00235 glAttachShader(m_program, m_pixelShader); 00236 00237 glLinkProgram(m_program); 00238 00239 _createTexture(32); 00240 00241 glGenBuffers(1, (GLuint*)&m_vboColor); 00242 glBindBuffer( GL_ARRAY_BUFFER_ARB, m_vboColor); 00243 glBufferData( GL_ARRAY_BUFFER_ARB, m_numParticles * 4 * sizeof(float), 0, GL_STATIC_DRAW_ARB); 00244 glBindBuffer( GL_ARRAY_BUFFER_ARB, 0); 00245 } 00246 00247 //------------------------------------------------------------------------------ 00248 // Function : EvalHermite 00249 // Description : 00250 //------------------------------------------------------------------------------ 00255 inline float evalHermite(float pA, float pB, float vA, float vB, float u) 00256 { 00257 float u2=(u*u), u3=u2*u; 00258 float B0 = 2*u3 - 3*u2 + 1; 00259 float B1 = -2*u3 + 3*u2; 00260 float B2 = u3 - 2*u2 + u; 00261 float B3 = u3 - u; 00262 return( B0*pA + B1*pB + B2*vA + B3*vB ); 00263 } 00264 00265 unsigned char* createGaussianMap(int N) 00266 { 00267 float *M = new float[2*N*N]; 00268 unsigned char *B = new unsigned char[4*N*N]; 00269 float X,Y,Y2,Dist; 00270 float Incr = 2.0f/N; 00271 int i=0; 00272 int j = 0; 00273 Y = -1.0f; 00274 //float mmax = 0; 00275 for (int y=0; y<N; y++, Y+=Incr) 00276 { 00277 Y2=Y*Y; 00278 X = -1.0f; 00279 for (int x=0; x<N; x++, X+=Incr, i+=2, j+=4) 00280 { 00281 Dist = (float)sqrtf(X*X+Y2); 00282 if (Dist>1) Dist=1; 00283 M[i+1] = M[i] = evalHermite(1.0f,0,0,0,Dist); 00284 B[j+3] = B[j+2] = B[j+1] = B[j] = (unsigned char)(M[i] * 255); 00285 } 00286 } 00287 delete [] M; 00288 return(B); 00289 } 00290 00291 void ParticleRenderer::_createTexture(int resolution) 00292 { 00293 unsigned char* data = createGaussianMap(resolution); 00294 glGenTextures(1, (GLuint*)&m_texture); 00295 glBindTexture(GL_TEXTURE_2D, m_texture); 00296 glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_TRUE); 00297 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); 00298 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 00299 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, resolution, resolution, 0, 00300 GL_RGBA, GL_UNSIGNED_BYTE, data); 00301 00302 } 00303 }