Equalizer 1.0

render_particles.cpp

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 }
Generated on Sun May 8 2011 19:11:07 for Equalizer 1.0 by  doxygen 1.7.3