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(); }
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(); } }