Example #1
0
void ParticleSprayerTool::render(DTS::DataItem* dataItem) const
{
   // draw all emitter objects
   drawEmitters();

   // save current attribute state
   #ifdef MESA
   // GL_POINT_BIT causes GL enum error
   glPushAttrib(GL_LIGHTING_BIT | GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
   #else
   glPushAttrib(GL_LIGHTING_BIT | GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_POINT_BIT);
   #endif

   glDisable(GL_LIGHTING);
   glDepthMask(GL_FALSE);

   glEnable(GL_POINT_SMOOTH);
   glEnable(GL_BLEND);
   glBlendFunc(GL_SRC_ALPHA, GL_ONE);

   glEnable(GL_TEXTURE_2D);
   glBindTexture(GL_TEXTURE_2D, dataItem->spriteTextureObjectId);
   glTexEnvf(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE);
   glEnable(GL_POINT_SPRITE_ARB);

   float particleRadius=data.point_radius;//*1000.0;

   // Query the OpenGL viewing frustrum
   GLFrustum<float> frustum;
   frustum.setFromGL();   

   #ifdef GHETTO
   if (0)
   #else
   if (dataItem->hasShaders)
   #endif
   {
      /* Calculate the scaled point size for this frustum: */
      GLfloat scaledParticleRadius=frustum.getPixelSize() * particleRadius / frustum.getEyeScreenDistance();

      /* Enable the vertex/fragment shader: */
      glEnable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB);
      glUseProgramObjectARB(dataItem->programObject);
      glUniform1fARB(dataItem->scaledParticleRadiusLocation, scaledParticleRadius);
      glUniform1iARB(dataItem->tex0Location, 0);
   }
   else
   {
      glPointSize(particleRadius
            * Vrui::getNavigationTransformation().getScaling());

      GLfloat linear[3]= { 0.0, 1 / 5.0, 0.0 };
      glPointParameterfvARB(GL_POINT_DISTANCE_ATTENUATION_ARB, linear);

      //
      // NOTE::the following scaling calculation does not work properly
      // in the CAVE. This is due to changes in the OpenGL library and
      // cannot be fixed. On a 2D screen the scaling should look correct.
      //

      // Calculate the nominal pixel size for particles
      float pointSizeCounter=frustum.getPixelSize() * 2.0f * particleRadius;

      float pointSizeDenominator=frustum.getEyeScreenDistance();

      // Query the maximum point size accepted by glPointSize(...)
      GLfloat pointSizeRange[2];
      glGetFloatv(GL_SMOOTH_POINT_SIZE_RANGE, pointSizeRange);

      // Enable point parameters
      glPointSize(pointSizeRange[1]); // select the maximum point size
      pointSizeCounter/=pointSizeRange[1]; // adjust the point size numerator
      GLfloat attenuation[3]= { 0.0f, 0.0f, 0.0f };
      attenuation[2]=Math::sqr(pointSizeDenominator / pointSizeCounter);
      glPointParameterfvARB(GL_POINT_DISTANCE_ATTENUATION_ARB, attenuation);

   }

   glBindBufferARB(GL_ARRAY_BUFFER_ARB, dataItem->vertexBufferId);
   glEnableClientState(GL_VERTEX_ARRAY);
   glEnableClientState(GL_COLOR_ARRAY);

   if (dataItem->versionDS != data.currentVersion)
   {
      dataItem->numParticlesDS = data.particles.size();
      glBufferDataARB(GL_ARRAY_BUFFER_ARB, dataItem->numParticlesDS * sizeof(PointParticle), &data.particles[0], GL_DYNAMIC_DRAW_ARB);
      dataItem->versionDS = data.currentVersion;
   }

   glInterleavedArrays(GL_C4UB_V3F, sizeof(PointParticle), 0);


   // Care needed if particle number has changed but we haven't updated buffer.
   glDrawArrays(GL_POINTS, 0, dataItem->numParticlesDS);

   glDisableClientState(GL_COLOR_ARRAY);
   glDisableClientState(GL_VERTEX_ARRAY);

   #ifndef GHETTO
   if (dataItem->hasShaders)
   #endif
   {
      glUseProgramObjectARB(0);
      glDisable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB);
   }

   glBindTexture(GL_TEXTURE_2D, 0);
   glDisable(GL_TEXTURE_2D);
   glDisable(GL_POINT_SPRITE_ARB);

   // restore previous attribute state
   glPopAttrib();
}
Example #2
0
void DotSpreaderTool::render(DTS::DataItem* dataItem) const
{
   // if dragging locator render release sphere
   if (active and !data.running)
   {
      // save current attribute state
      #ifdef MESA
      // GL_POINT_BIT causes GL enum error
      glPushAttrib(GL_LIGHTING_BIT | GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
      #else
      glPushAttrib(GL_LIGHTING_BIT | GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_POINT_BIT);
      #endif

      glDisable(GL_LIGHTING);

      // save current location
      glPushMatrix();

      // move to center of sphere
      glTranslatef(org[0], org[1], org[2]);

      // compute radius of sphere
      float radius=Math::sqrt((pos[0] - org[0]) * (pos[0] - org[0]) + (pos[1]
            - org[1]) * (pos[1] - org[1]) + (pos[2] - org[2]) * (pos[2]
            - org[2]));

      GLUquadricObj *quadric=gluNewQuadric();

      // draw transparent sphere
      gluQuadricDrawStyle(quadric, GLU_FILL);
      glDepthMask(GL_FALSE);
      glEnable(GL_BLEND);
      glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

      glColor4f(0.0f, 0.6f, 1.0f, 0.2f);

      gluSphere(quadric, radius, 10, 15);
      glDisable(GL_BLEND);

      // draw surrounding wireframe (solid)
      gluQuadricDrawStyle(quadric, GLU_LINE);
      glDepthMask(GL_TRUE);
      glColor4f(0.0f, 0.8f, 1.0f, 1.0f);

      gluSphere(quadric, radius, 10, 15);
      glDepthMask(GL_FALSE);

      gluDeleteQuadric(quadric);

      // restore previous position
      glPopMatrix();
      // restore previous attribute state
      glPopAttrib();
   }
   // if simulation is running draw particles
   else if (data.running)
   {
      // save current attribute state
      #ifdef MESA
      // GL_POINT_BIT causes GL enum error
      glPushAttrib(GL_LIGHTING_BIT | GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
      #else
      glPushAttrib(GL_LIGHTING_BIT | GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_POINT_BIT);
      #endif

      glDisable(GL_LIGHTING);
      glDepthMask(GL_FALSE);

      glEnable(GL_POINT_SMOOTH);
      glEnable(GL_BLEND);
      glBlendFunc(GL_SRC_ALPHA, GL_ONE);

      glEnable(GL_TEXTURE_2D);
      glBindTexture(GL_TEXTURE_2D, dataItem->spriteTextureObjectId);
      glTexEnvf(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE);
      glEnable(GL_POINT_SPRITE_ARB);

      float particleRadius=data.point_radius;

      // Query the OpenGL viewing frustum
      GLFrustum<float> frustum;
      frustum.setFromGL();

      #ifdef GHETTO
      if (0)
      #else
      if (dataItem->hasShaders)
      #endif
      {
         /* Calculate the scaled point size for this frustum: */
         GLfloat scaledParticleRadius=frustum.getPixelSize() * particleRadius
               / frustum.getEyeScreenDistance();

         /* Enable the vertex/fragment shader: */
         glEnable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB);
         glUseProgramObjectARB(dataItem->programObject);
         glUniform1fARB(dataItem->scaledParticleRadiusLocation, scaledParticleRadius);
         glUniform1iARB(dataItem->tex0Location, 0);
      }
      else
      {
         glPointSize(particleRadius
               * Vrui::getNavigationTransformation().getScaling());

         GLfloat linear[3]= { 0.0, 1 / 5.0, 0.0 };
         glPointParameterfvARB(GL_POINT_DISTANCE_ATTENUATION_ARB, linear);

         //
         // NOTE::the following scaling calculation does not work properly
         // in the CAVE. This is due to changes in the OpenGL library and
         // cannot be fixed. On a 2D screen the scaling should look correct.
         //

         // Query the OpenGL viewing frustum
         GLFrustum<float> frustum;
         frustum.setFromGL();

         // Calculate the nominal pixel size for particles
         float pointSizeCounter=frustum.getPixelSize() * 2.0f * particleRadius;

         float pointSizeDenominator=frustum.getEyeScreenDistance();

         // Query the maximum point size accepted by glPointSize(...)
         GLfloat pointSizeRange[2];
         glGetFloatv(GL_SMOOTH_POINT_SIZE_RANGE, pointSizeRange);

         // Enable point parameters
         glPointSize(pointSizeRange[1]); // select the maximum point size
         pointSizeCounter/=pointSizeRange[1]; // adjust the point size numerator
         GLfloat attenuation[3]= { 0.0f, 0.0f, 0.0f };
         attenuation[2]=Math::sqr(pointSizeDenominator / pointSizeCounter);
         glPointParameterfvARB(GL_POINT_DISTANCE_ATTENUATION_ARB, attenuation);
      }

      glBindBufferARB(GL_ARRAY_BUFFER_ARB, dataItem->vertexBufferId);
      glEnableClientState(GL_VERTEX_ARRAY);
      glEnableClientState(GL_COLOR_ARRAY);

      // If data has been modified, send to graphics card
      if (dataItem->versionDS != data.currentVersion)
      {
         dataItem->numParticlesDS = data.numPoints;
         glBufferDataARB(GL_ARRAY_BUFFER_ARB, dataItem->numParticlesDS
               * sizeof(ColorPoint), &data.particles[0], GL_DYNAMIC_DRAW_ARB);

         dataItem->versionDS = data.currentVersion;
      }

      glInterleavedArrays(GL_C4UB_V3F, sizeof(ColorPoint), 0);

      glDrawArrays(GL_POINTS, 0, dataItem->numParticlesDS);

      glDisableClientState(GL_COLOR_ARRAY);
      glDisableClientState(GL_VERTEX_ARRAY);

      #ifndef GHETTO
      if (dataItem->hasShaders)
      #endif
      {
         glUseProgramObjectARB(0);
         glDisable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB);
      }

      glBindTexture(GL_TEXTURE_2D, 0);
      glDisable(GL_TEXTURE_2D);
      glDisable(GL_POINT_SPRITE_ARB);
      glDisable(GL_BLEND);

      // restore previous attribute state
      glPopAttrib();
   }
}