void PaletteRenderer::uploadTexture3D(VolumeRenderer::DataItem* dataItem) const
	{
	/* Get pointer to our own data item: */
	DataItem* myDataItem=static_cast<DataItem*>(dataItem);
	
	if(myDataItem->setParameters)
		{
		/* Set the OpenGL texturing parameters: */
		glTexParameteri(GL_TEXTURE_3D,GL_TEXTURE_BASE_LEVEL,0);
		glTexParameteri(GL_TEXTURE_3D,GL_TEXTURE_MAX_LEVEL,0);
		glTexParameteri(GL_TEXTURE_3D,GL_TEXTURE_WRAP_S,GL_CLAMP);
		glTexParameteri(GL_TEXTURE_3D,GL_TEXTURE_WRAP_T,GL_CLAMP);
		glTexParameteri(GL_TEXTURE_3D,GL_TEXTURE_WRAP_R,GL_CLAMP);
		glTexParameteri(GL_TEXTURE_3D,GL_TEXTURE_MAG_FILTER,interpolationMode);
		glTexParameteri(GL_TEXTURE_3D,GL_TEXTURE_MIN_FILTER,interpolationMode);
		}
	
	/* Upload a color map only if necessary: */
	if(myDataItem->renderingPath==PalettedTexture&&myDataItem->uploadColorMap)
		{
		/* Set the texture's color map: */
		#ifdef __SGI_IRIX__
		glColorTableSGI(GL_TEXTURE_COLOR_TABLE_SGI,GL_RGBA,256,GL_RGBA,GL_FLOAT,colorMap->getColors());
		#else
		glColorTableEXT(GL_TEXTURE_3D,GL_RGBA,256,GL_RGBA,GL_FLOAT,colorMap->getColors());
		#endif
		}
	
	if(myDataItem->uploadData)
		{
		/* Determine the texture's format: */
		GLenum internalFormat=GL_INTENSITY8;
		GLenum uploadFormat=GL_LUMINANCE;
		
		#ifndef __SGI_IRIX__
		if(myDataItem->renderingPath==PalettedTexture)
			{
			internalFormat=GL_COLOR_INDEX8_EXT;
			uploadFormat=GL_COLOR_INDEX;
			}
		#endif
		
		/* Upload the texture block: */
		glPixelStorei(GL_UNPACK_ALIGNMENT,1);
		glPixelStorei(GL_UNPACK_SKIP_PIXELS,0);
		glPixelStorei(GL_UNPACK_ROW_LENGTH,0); // increments[1]); // Seems to be a bug in OpenGL - consistent across SGI/nVidia platforms
		glPixelStorei(GL_UNPACK_SKIP_ROWS,0);
		glPixelStorei(GL_UNPACK_IMAGE_HEIGHT,0); // increments[0]);
		glPixelStorei(GL_UNPACK_SKIP_IMAGES,0);
		#ifdef __SGI_IRIX__
		glTexImage3D(GL_TEXTURE_3D,0,internalFormat,textureSize[2],textureSize[1],textureSize[0],0,uploadFormat,GL_UNSIGNED_BYTE,values);
		#else
		glTexImage3DEXT(GL_TEXTURE_3D,0,internalFormat,textureSize[2],textureSize[1],textureSize[0],0,uploadFormat,GL_UNSIGNED_BYTE,0);
		glTexSubImage3DEXT(GL_TEXTURE_3D,0,0,0,0,size[2],size[1],size[0],uploadFormat,GL_UNSIGNED_BYTE,values);
		#endif
		}
	}
void PaletteRenderer::uploadTexture2D(VolumeRenderer::DataItem* dataItem,int axis,int index) const
{
    if(dataItem->setParameters)
    {
        /* Set the OpenGL texturing parameters: */
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_BASE_LEVEL,0);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAX_LEVEL,0);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,interpolationMode);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,interpolationMode);
    }

    #if 1
    /* Upload a color map only if necessary: */
    if(static_cast<DataItem*>(dataItem)->uploadColorMap)
    {
        /* Set the texture's color map: */
        #ifdef __SGI_IRIX__
        glColorTableSGI(GL_TEXTURE_COLOR_TABLE_SGI,GL_RGBA,256,GL_RGBA,GL_FLOAT,colorMap->getColors());
        #else
        glColorTable(GL_TEXTURE_2D,GL_RGBA,256,GL_RGBA,GL_FLOAT,colorMap->getColors());
        #endif
    }
    #endif

    if(dataItem->uploadData)
    {
        /* Some workaround for SGI's non-compliance of OpenGL (what a shame): */
        #if (__SGI_IRIX__ || __APPLE__)
        const GLenum internalFormat=GL_INTENSITY8;
        const GLenum uploadFormat=GL_LUMINANCE;
        #else
        // use non-ARB extension 78
        const GLenum internalFormat=GL_COLOR_INDEX8_EXT;
        const GLenum uploadFormat=GL_COLOR_INDEX;
        #endif

        /* Upload a texture slice: */
        const Voxel* slicePtr=values+index*increments[axis];
        switch(axis)
        {
            case 0:
                glTexImage2D(GL_TEXTURE_2D,0,internalFormat,textureSize[2],textureSize[1],0,uploadFormat,GL_UNSIGNED_BYTE,0);
                glTexSubImage2D(GL_TEXTURE_2D,0,0,0,size[2],size[1],increments[2],increments[1],uploadFormat,GL_UNSIGNED_BYTE,slicePtr);
                break;
            case 1:
                glTexImage2D(GL_TEXTURE_2D,0,internalFormat,textureSize[2],textureSize[0],0,uploadFormat,GL_UNSIGNED_BYTE,0);
                glTexSubImage2D(GL_TEXTURE_2D,0,0,0,size[2],size[0],increments[2],increments[0],uploadFormat,GL_UNSIGNED_BYTE,slicePtr);
                break;
            case 2:
                glTexImage2D(GL_TEXTURE_2D,0,internalFormat,textureSize[1],textureSize[0],0,uploadFormat,GL_UNSIGNED_BYTE,0);
                glTexSubImage2D(GL_TEXTURE_2D,0,0,0,size[1],size[0],increments[1],increments[0],uploadFormat,GL_UNSIGNED_BYTE,slicePtr);
                break;
        }
    }
}
void PaletteRenderer::prepareRenderAxisAligned(VolumeRenderer::DataItem* dataItem) const
	{
	DataItem* myDataItem=static_cast<DataItem*>(dataItem);
	
	/* Manage color palette uploads: */
	if(myDataItem->renderingPath==FragmentProgram)
		{
		/* Bind the color map texture to texture unit 1: */
		glActiveTextureARB(GL_TEXTURE1_ARB);
		glBindTexture(GL_TEXTURE_2D,myDataItem->paletteTextureObjectId);
		if(myDataItem->cachedColorMapVersion!=colorMapVersion)
			{
			/* Upload the color map as a 2D texture: */
			glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
			glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);
			glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
			glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
			glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA8,256,1,0,GL_RGBA,GL_FLOAT,colorMap->getColors());
			
			/* Mark the cached color map as up-to-date: */
			myDataItem->cachedColorMapVersion=colorMapVersion;
			}
		glActiveTextureARB(GL_TEXTURE0_ARB);
		}
	else if(myDataItem->renderingPath==TextureShader)
		{
		/* Bind the color map texture to texture unit 1: */
		glActiveTextureARB(GL_TEXTURE1_ARB);
		glBindTexture(GL_TEXTURE_2D,myDataItem->paletteTextureObjectId);
		if(myDataItem->cachedColorMapVersion!=colorMapVersion)
			{
			/* Upload the color map as a 2D texture: */
			glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
			glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);
			glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
			glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
			glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA8,256,1,0,GL_RGBA,GL_FLOAT,colorMap->getColors());
			
			/* Mark the cached color map as up-to-date: */
			myDataItem->cachedColorMapVersion=colorMapVersion;
			}
		glTexEnvi(GL_TEXTURE_SHADER_NV,GL_SHADER_OPERATION_NV,GL_DEPENDENT_AR_TEXTURE_2D_NV);
		glTexEnvi(GL_TEXTURE_SHADER_NV,GL_PREVIOUS_TEXTURE_INPUT_NV,GL_TEXTURE0_ARB);
		glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,textureFunction);
		glActiveTextureARB(GL_TEXTURE0_ARB);
		}
	else if(!textureCachingEnabled)
		{
		/* Sufficient to upload palette right here: */
		#ifdef __SGI_IRIX__
		glColorTableSGI(GL_TEXTURE_COLOR_TABLE_SGI,GL_RGBA,256,GL_RGBA,GL_FLOAT,colorMap->getColors());
		#else
		glColorTableEXT(GL_TEXTURE_2D,GL_RGBA,256,GL_RGBA,GL_FLOAT,colorMap->getColors());
		#endif
		}
	}
void PaletteRenderer::uploadTexture3D(VolumeRenderer::DataItem* dataItem) const
{
    if(dataItem->setParameters)
    {
        /* Set the OpenGL texturing parameters: */
        glTexParameteri(GL_TEXTURE_3D,GL_TEXTURE_BASE_LEVEL,0);
        glTexParameteri(GL_TEXTURE_3D,GL_TEXTURE_MAX_LEVEL,0);
        glTexParameteri(GL_TEXTURE_3D,GL_TEXTURE_WRAP_S,GL_CLAMP);
        glTexParameteri(GL_TEXTURE_3D,GL_TEXTURE_WRAP_T,GL_CLAMP);
        glTexParameteri(GL_TEXTURE_3D,GL_TEXTURE_WRAP_R,GL_CLAMP);
        glTexParameteri(GL_TEXTURE_3D,GL_TEXTURE_MAG_FILTER,interpolationMode);
        glTexParameteri(GL_TEXTURE_3D,GL_TEXTURE_MIN_FILTER,interpolationMode);
    }

    #if 1
    /* Upload a color map only if necessary: */
    if(static_cast<DataItem*>(dataItem)->uploadColorMap)
    {
        /* Set the texture's color map: */
        #ifdef __SGI_IRIX__
        glColorTableSGI(GL_TEXTURE_COLOR_TABLE_SGI,GL_RGBA,256,GL_RGBA,GL_FLOAT,colorMap->getColors());
        #else
        glColorTable(GL_TEXTURE_3D,GL_RGBA,256,GL_RGBA,GL_FLOAT,colorMap->getColors());
        #endif
    }
    #endif
    
    if(dataItem->uploadData)
    {
        /* Some workaround for SGI's non-compliance of OpenGL (what a shame): */
        #if (__SGI_IRIX__ || __APPLE__)
        const GLenum internalFormat=GL_INTENSITY8;
        const GLenum uploadFormat=GL_LUMINANCE;
        #else
        // use non-ARB extension 78
        const GLenum internalFormat=GL_COLOR_INDEX8_EXT;
        const GLenum uploadFormat=GL_COLOR_INDEX;
        #endif

        /* Upload the texture block: */
        glPixelStorei(GL_UNPACK_ALIGNMENT,1);
        glPixelStorei(GL_UNPACK_SKIP_PIXELS,0);
        glPixelStorei(GL_UNPACK_ROW_LENGTH,0); // increments[1]); // Seems to be a bug in OpenGL - consistent across SGI/nVidia platforms
        glPixelStorei(GL_UNPACK_SKIP_ROWS,0);
        glPixelStorei(GL_UNPACK_IMAGE_HEIGHT,0); // increments[0]);
        glPixelStorei(GL_UNPACK_SKIP_IMAGES,0);
        #ifdef __SGI_IRIX__
        glTexImage3D(GL_TEXTURE_3D,0,internalFormat,textureSize[2],textureSize[1],textureSize[0],0,uploadFormat,GL_UNSIGNED_BYTE,values);
        #else
        glTexImage3D(GL_TEXTURE_3D,0,internalFormat,textureSize[2],textureSize[1],textureSize[0],0,uploadFormat,GL_UNSIGNED_BYTE,0);
        glTexSubImage3D(GL_TEXTURE_3D,0,0,0,0,size[2],size[1],size[0],uploadFormat,GL_UNSIGNED_BYTE,values);
        #endif
    }
}
void PaletteRenderer::setGlobalColorMap(const GLColorMap* newGlobalColorMap)
	{
	if(newGlobalColorMap->getNumEntries()==256)
		{
		/* Sufficient to upload palette right here: */
		#ifdef __SGI_IRIX__
		glColorTableSGI(GL_TEXTURE_COLOR_TABLE_SGI,GL_RGBA,256,GL_RGBA,GL_FLOAT,newGlobalColorMap->getColors());
		#else
		glColorTableEXT(GL_SHARED_TEXTURE_PALETTE_EXT,GL_RGBA,256,GL_RGBA,GL_FLOAT,newGlobalColorMap->getColors());
		#endif
		}
	}
void PaletteRenderer::prepareRenderAxisAligned(VolumeRenderer::DataItem* dataItem) const
{
    //DataItem* myDataItem=static_cast<DataItem*>(dataItem);

    #if 1
    /* Manage color palette uploads: */
    if(!textureCachingEnabled)
    {
        /* Sufficient to upload palette right here: */
        #ifdef __SGI_IRIX__
        glColorTableSGI(GL_TEXTURE_COLOR_TABLE_SGI,GL_RGBA,256,GL_RGBA,GL_FLOAT,colorMap->getColors());
        #else
        glColorTable(GL_TEXTURE_2D,GL_RGBA,256,GL_RGBA,GL_FLOAT,colorMap->getColors());
        #endif
    }
    #endif
}
void PaletteRenderer::setGLState(GLContextData& contextData) const
{
    VolumeRenderer::setGLState(contextData);

    #ifdef __SGI_IRIX__
    glEnable(GL_TEXTURE_COLOR_TABLE_SGI);
    #endif
    if(sharePalette)
        glEnable(GL_SHARED_TEXTURE_PALETTE_EXT);

    #if 0
    /* Sufficient to upload palette right here: */
    #ifdef __SGI_IRIX__
    glColorTableSGI(GL_TEXTURE_COLOR_TABLE_SGI,GL_RGBA,256,GL_RGBA,GL_FLOAT,colorMap->getColors());
    #else
    glColorTable(GL_TEXTURE_2D,GL_RGBA,256,GL_RGBA,GL_FLOAT,colorMap->getColors());
    #endif
    #endif
}
void PaletteRenderer::uploadTexture2D(VolumeRenderer::DataItem* dataItem,int axis,int index) const
	{
	/* Get pointer to our own data item: */
	DataItem* myDataItem=static_cast<DataItem*>(dataItem);
	
	if(myDataItem->setParameters)
		{
		/* Set the OpenGL texturing parameters: */
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_BASE_LEVEL,0);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAX_LEVEL,0);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,interpolationMode);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,interpolationMode);
		}
	
	/* Upload a color map only if necessary: */
	if(myDataItem->renderingPath==PalettedTexture&&myDataItem->uploadColorMap)
		{
		/* Set the texture's color map: */
		#ifdef __SGI_IRIX__
		glColorTableSGI(GL_TEXTURE_COLOR_TABLE_SGI,GL_RGBA,256,GL_RGBA,GL_FLOAT,colorMap->getColors());
		#else
		glColorTableEXT(GL_TEXTURE_2D,GL_RGBA,256,GL_RGBA,GL_FLOAT,colorMap->getColors());
		#endif
		}
	
	if(myDataItem->uploadData)
		{
		/* Determine the texture's format: */
		GLenum internalFormat=GL_INTENSITY8;
		GLenum uploadFormat=GL_LUMINANCE;
		
		#ifndef __SGI_IRIX__
		if(myDataItem->renderingPath==PalettedTexture)
			{
			internalFormat=GL_COLOR_INDEX8_EXT;
			uploadFormat=GL_COLOR_INDEX;
			}
		#endif
		
		/* Upload a texture slice: */
		const Voxel* slicePtr=values+index*increments[axis];
		switch(axis)
			{
			case 0:
				glTexImage2D(GL_TEXTURE_2D,0,internalFormat,textureSize[2],textureSize[1],0,uploadFormat,GL_UNSIGNED_BYTE,0);
				glTexSubImage2D(GL_TEXTURE_2D,0,0,0,size[2],size[1],increments[2],increments[1],uploadFormat,GL_UNSIGNED_BYTE,slicePtr);
				break;
			
			case 1:
				glTexImage2D(GL_TEXTURE_2D,0,internalFormat,textureSize[2],textureSize[0],0,uploadFormat,GL_UNSIGNED_BYTE,0);
				glTexSubImage2D(GL_TEXTURE_2D,0,0,0,size[2],size[0],increments[2],increments[0],uploadFormat,GL_UNSIGNED_BYTE,slicePtr);
				break;
			
			case 2:
				glTexImage2D(GL_TEXTURE_2D,0,internalFormat,textureSize[1],textureSize[0],0,uploadFormat,GL_UNSIGNED_BYTE,0);
				glTexSubImage2D(GL_TEXTURE_2D,0,0,0,size[1],size[0],increments[1],increments[0],uploadFormat,GL_UNSIGNED_BYTE,slicePtr);
				break;
			}
		}
	}