void VariableManager::bindColorMap(int scalarVariableIndex,GLRenderState& renderState) const
	{
	/* Get the context data item: */
	DataItem* dataItem=renderState.getContextData().retrieveDataItem<DataItem>(this);
	
	/* Set up 1D texture mapping: */
	renderState.setTextureLevel(1);
	
	/* Bind the color texture object: */
	renderState.bindTexture(dataItem->colorMapTextureIds[scalarVariableIndex]);
	
	/* Check if the texture object is outdated: */
	const ScalarVariable& sv=scalarVariables[scalarVariableIndex];
	if(dataItem->colorMapVersions[scalarVariableIndex]!=sv.colorMapVersion)
		{
		/* Set the texture object's parameters: */
		glTexParameteri(GL_TEXTURE_1D,GL_TEXTURE_BASE_LEVEL,0);
		glTexParameteri(GL_TEXTURE_1D,GL_TEXTURE_MAX_LEVEL,0);
		glTexParameteri(GL_TEXTURE_1D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
		glTexParameteri(GL_TEXTURE_1D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
		glTexParameteri(GL_TEXTURE_1D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
		
		/* Upload the changed color map into the texture object: */
		glPixelStorei(GL_UNPACK_SKIP_PIXELS,0);
		glPixelStorei(GL_UNPACK_ALIGNMENT,1);
		glTexImage1D(GL_TEXTURE_1D,0,GL_RGBA8,256,0,GL_RGBA,GL_FLOAT,sv.colorMap->getColors());
		
		/* Mark the texture object as up-to-date: */
		dataItem->colorMapVersions[scalarVariableIndex]=sv.colorMapVersion;
		}
	
	/* Set up the texture matrix to convert scalar variable values to color map indices: */
	renderState.setMatrixMode(2);
	if(dataItem->lastBoundScalarVariableIndex!=scalarVariableIndex||dataItem->textureMatrixVersion!=renderState.getMatrixVersion())
		{
		glLoadIdentity();
		double mapMin=double(sv.colorMapRange.first);
		double mapRange=double(sv.colorMapRange.second)-mapMin;
		glScaled(1.0/mapRange,1.0,1.0);
		glTranslated(-mapMin,0.0,0.0);
		renderState.updateMatrix();
		
		/* Mark the texture matrix as up to date: */
		dataItem->lastBoundScalarVariableIndex=scalarVariableIndex;
		dataItem->textureMatrixVersion=renderState.getMatrixVersion();
		}
	}
void VectorEvaluationLocator::highlightLocator(GLRenderState& renderState) const
	{
	/* Call the base class method: */
	EvaluationLocator::highlightLocator(renderState);
	
	/* Render the evaluated vector value if valid: */
	if(valueValid)
		{
		/* Set up OpenGL state for arrow rendering: */
		renderState.enableCulling(GL_BACK);
		renderState.setLighting(true);
		renderState.setTwoSidedLighting(false);
		glColor((*colorMap)(currentScalarValue));
		renderState.enableColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);
		renderState.setTextureLevel(0);
		renderState.setSeparateSpecularColor(false);
		
		/* Render an arrow glyph: */
		Scalar arrowShaftRadius=Scalar((Vrui::Scalar(0.5)*Vrui::getUiSize())/Vrui::getNavigationTransformation().getScaling());
		Visualization::Wrappers::renderArrow(point,currentValue*arrowLengthScale,arrowShaftRadius,arrowShaftRadius*Scalar(3),arrowShaftRadius*Scalar(6),16);
		}
	}