// Author:
// Module : VISU
-//#include "GL/glew.h"
#include "VISU_OpenGLPointSpriteMapper.hxx"
#include "vtkCellArray.h"
#include "GL/glext.h"
+#include <stdio.h>
+#include <stdio_ext.h>
#include <cmath>
+#include <string>
+#define ARB_PROGRAM
#ifndef VTK_IMPLEMENT_MESA_CXX
vtkCxxRevisionMacro(VISU_OpenGLPointSpriteMapper, "$Revision$");
#define VTK_PDPSM_NORMAL_TYPE_DOUBLE 0x0020
#define VTK_PDPSM_OPAQUE_COLORS 0x0040
#define VTK_PDPSM_ALPHA_ARRAY 0x0080
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define GL_POINT_SPRITE_ARB 0x8861
+#define GL_COORD_REPLACE_ARB 0x8862
+
+#define GL_ARB_point_parameters 1
+GLAPI void APIENTRY glPointParameterfARB (GLenum, GLfloat);
+GLAPI void APIENTRY glPointParameterfvARB (GLenum, const GLfloat *);
+
+GLAPI void APIENTRY glBindProgramARB (GLenum, GLuint);
+GLAPI void APIENTRY glGenProgramsARB (GLsizei, GLuint *);
+GLAPI void APIENTRY glProgramStringARB (GLenum, GLenum, GLsizei, const GLvoid *);
+GLAPI void APIENTRY glProgramEnvParameter4fARB (GLenum, GLuint, GLfloat, GLfloat, GLfloat, GLfloat);
+
+GLAPI void APIENTRY glBindProgramNV (GLenum, GLuint);
+GLAPI void APIENTRY glGenProgramsNV (GLsizei, GLuint *);
+GLAPI void APIENTRY glLoadProgramNV (GLenum, GLuint, GLsizei, const GLubyte *);
+GLAPI void APIENTRY glProgramParameter4fNV (GLenum, GLuint, GLfloat, GLfloat, GLfloat, GLfloat);
+
+#ifdef __cplusplus
+}
+#endif
+
+unsigned int shaderId;
+
//-----------------------------------------------------------------------------
vtkCxxSetObjectMacro(VISU_OpenGLPointSpriteMapper, ParticleImage, vtkImageData);
//-----------------------------------------------------------------------------
{
this->bmpReader = vtkBMPReader::New();
}
- this->DefaultPointSize = 25.0;//-1.0;
- this->MaximumSupportedSize = 0.0;
+ this->DefaultPointSize = 10.0; //-1.0;
+ this->MaximumSupportedSize = 0.0;
this->QuadraticPointDistanceAttenuation[0] = 1.0;
this->QuadraticPointDistanceAttenuation[1] = 0.0;
this->QuadraticPointDistanceAttenuation[2] = 0.0;
- //
- this->NVidiaMode = 0;
- this->Texture3D = 0;
- this->TextureDimension = 2;
- //
- this->RenderMode = VISU_OpenGLPointSpriteMapper::Accumulate;
- this->XMLImageDataReader = vtkXMLImageDataReader::New();
- TextureIntensity = 0;
- TextureAlphaChannel = 0;
+ this->RenderMode = VISU_OpenGLPointSpriteMapper::Accumulate;
+
+ this->XMLImageDataReader = vtkXMLImageDataReader::New();
+ TextureIntensity = 0;
+ TextureAlphaChannel = 0;
+
+ this->IsUsingOpenGLMapper = false;
}
//-----------------------------------------------------------------------------
// Destructor (don't call ReleaseGraphicsResources() since it is virtual
}
}
//-----------------------------------------------------------------------------
-void VISU_OpenGLPointSpriteMapper::InitializeExtensions()
+// Name: readShaderFile()
+// Desc:
+//-----------------------------------------------------------------------------
+unsigned char *readShaderFile( std::string fileName )
+{
+ FILE* file = fopen( fileName.c_str(), "r" );
+
+ unsigned char* buffer = new unsigned char[ 2000 ];
+ int bytes = fread( buffer, 1, 2000, file );
+ buffer[bytes] = 0;
+
+ unsigned char* shader = new unsigned char[ bytes ];
+ for( int i = 0; i < bytes; i++ )
+ shader[i] = buffer[i];
+
+ fclose( file );
+
+ delete buffer;
+
+ return shader;
+}
+//-----------------------------------------------------------------------------
+// Name: initShader()
+// Desc: Assemble the shader
+//-----------------------------------------------------------------------------
+void initShader()
{
+ std::string aResDir = std::string( getenv( "VISU_ROOT_DIR") ) +"/share/salome/resources/";
+
+#ifdef ARB_PROGRAM
+ unsigned char* shader = readShaderFile( aResDir + "Vertex_Program_ARB.txt" );
+ int size = strlen( (char*)shader );
/*
- //
- // Glew initialization
- //
- GLenum err = glewInit();
- if (GLEW_OK != err)
- {
- std::cout << "glew Initialization Error: " << glewGetErrorString(err) << std::endl;
- return;
- }
- //
- // GL_ARB_point_sprite
- //
- if (glewIsSupported("GL_ARB_point_sprite") && GLEW_ARB_point_sprite &&
- glewIsSupported("GL_ARB_point_parameters") && GLEW_ARB_point_parameters)
- {
- this->ExtensionsOK = 1;
- std::cout << "GL_ARB_point_sprite OK" << std::endl;
- }
- //
- // GL_NV_point_sprite
- //
- this->NVidiaMode = 0;
- if (glewIsSupported("GL_NV_point_sprite") && GLEW_NV_point_sprite &&
- glewIsSupported("GL_EXT_point_parameters") && GLEW_EXT_point_parameters)
- {
- this->NVidiaMode = 1;
- this->ExtensionsOK = 1;
- std::cout << "GL_NV_point_sprite OK" << std::endl;
- }
+ cout << "Shader :" << endl;
+ for( int i = 0; i < size; i++ )
+ cout << shader[i];
+ cout << endl;
+ */
+ glGenProgramsARB( 1, &shaderId );
+ glBindProgramARB( GL_VERTEX_PROGRAM_ARB, shaderId );
+
+ glProgramStringARB( GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
+ size, shader );
+#else
+ unsigned char* shader = readShaderFile( aResDir + "Vertex_Program_NV.txt" );
+ int size = strlen( (char*)shader );
+ /*
+ cout << "Shader :" << endl;
+ for( int i = 0; i < size; i++ )
+ cout << shader[i];
+ cout << endl;
*/
+ glGenProgramsNV( 1, &shaderId );
- this->ExtensionsOK = 1;
- //std::cout << "GL_ARB_point_sprite OK" << std::endl;
-
- //
- // if we didn't find either point sprite mode, then exit
- //
- if (!this->ExtensionsOK)
- {
- //std::cout << "GL_ARB_point_sprite or GL_NV_point_sprite not found" << std::endl;
- vtkErrorMacro( << "GL_ARB_point_sprite or GL_NV_point_sprite not found" );
- return;
- }
+ glLoadProgramNV( GL_VERTEX_PROGRAM_NV, shaderId,
+ size, ( const GLubyte* )shader );
+ glBindProgramNV( GL_VERTEX_PROGRAM_NV, shaderId );
+#endif
/*
- //
- // glTexImage3D
- //
- if (glTexImage3D)
- {
- this->Texture3D = 1;
- }
+ if( glGetError() == GL_NO_ERROR )
+ cout << "Loading vertex program... ok" << endl << endl;
else
- {
- vtkDebugMacro( << "VISU_OpenGLPointSpriteMapper::glTexImage3D not found" );
- this->Texture3D = 0;
- }
+ cout << "Loading vertex program... failed" << endl << endl;
*/
- //
- if (this->ExtensionsOK) this->ExtensionsInitialized = 1;
+ delete shader;
+}
+//-----------------------------------------------------------------------------
+// Name: setShaderConstants()
+// Desc:
+//-----------------------------------------------------------------------------
+void setShaderConstants()
+{
+ glMatrixMode( GL_MODELVIEW );
+ glLoadIdentity();
+ glTranslatef( 0.0f, 0.0f, -4.0f );
+ glRotatef( 0.0f, 1.0f, 0.0f, 0.0f );
+ glRotatef( 0.0f, 0.0f, 1.0f, 0.0f );
+
+#ifdef ARB_PROGRAM
+ glProgramEnvParameter4fARB( GL_VERTEX_PROGRAM_ARB, 0, 1.0f, 1.0f, 1.0f, 1.0f );
+ glProgramEnvParameter4fARB( GL_VERTEX_PROGRAM_ARB, 1, 1.0f, 10.0f, 100.0f, 1000.0f );
+#else
+ glProgramParameter4fNV( GL_VERTEX_PROGRAM_NV, 0, 1.0f, 1.0f, 1.0f, 1.0f );
+ glProgramParameter4fNV( GL_VERTEX_PROGRAM_NV, 1, 100.0f, 1.0f, 1.0f, 1.0f );
+#endif
}
//-----------------------------------------------------------------------------
// Release the graphics resources used by this mapper. In this case, release
}
}
//-----------------------------------------------------------------------------
+void VISU_OpenGLPointSpriteMapper::InitializeExtensions()
+{
+ char* ext = (char*)glGetString( GL_EXTENSIONS );
+ //cout << "OpenGL extensions : " << ext << endl;
+
+ if( strstr( ext, "GL_ARB_point_sprite" ) == NULL ||
+ strstr( ext, "GL_ARB_vertex_program" ) == NULL )
+ {
+ vtkErrorMacro(<<"Initializing ARB extensions failed");
+
+ this->IsUsingOpenGLMapper = true;
+
+ return;
+ }
+
+ initShader();
+ setShaderConstants();
+
+ this->ExtensionsOK = 1;
+ this->ExtensionsInitialized = 1;
+}
+//-----------------------------------------------------------------------------
//
// Receives from Actor -> maps data to primitives
//
void VISU_OpenGLPointSpriteMapper::RenderPiece(vtkRenderer *ren, vtkActor *act)
{
+ if( !this->ExtensionsInitialized && !this->IsUsingOpenGLMapper )
+ {
+ this->InitializeExtensions();
+ act->GetProperty()->SetPointSize( 10.0f );
+ }
+
+ if( this->IsUsingOpenGLMapper )
+ {
+ //cout << "Using OpenGLMapper" << endl;
+ MAPPER_SUPERCLASS::RenderPiece( ren, act );
+ return;
+ }
+
+ //cout << "Using OpenGLPointSpriteMapper" << endl;
+
vtkIdType numPts;
vtkPolyData *input= this->GetInput();
vtkPlaneCollection *clipPlanes;
// make sure our window is current
ren->GetRenderWindow()->MakeCurrent();
-
+ /*
// Make sure open GL extensions are initialized
if (!this->ExtensionsInitialized)
{
{
return;
}
+ */
vtkImageData *particlesource = NULL;
if (this->ParticleImageFileName && !this->ParticleImage)
glEnd(); \
}
//-----------------------------------------------------------------------------
-// Configure vertex array:
-/*
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- glEnableClientState(GL_VERTEX_ARRAY);
- glTexCoordPointer(1, GL_FLOAT, SizeOf(TPointSprite), @points[0].S);
- glVertexPointer(3, GL_FLOAT, SizeOf(TPointSprite), @points[0].X);
-*/
-
-// Configure 3D texture
-/*
- glEnable(GL_TEXTURE_3D);
- glGenTextures(1, @tex);
- glBindTexture(GL_TEXTURE_3D, tex);
- SetLength(buf, 64*64*3*4);
- for i := 0 to 3 do
- begin
- AssignFile(f, Format('frame%d.tga', [i+1]));
- Reset(f, 1);
- Seek(f, 17);
- BlockRead(f, buf[64*64*3*i], 64*64*3);
- CloseFile(f);
- end;
- glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB8, 64, 64, 4, 0, GL_RGB, GL_UNSIGNED_BYTE, buf);
- glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- 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_REPEAT);
-*/
-//-----------------------------------------------------------------------------
void VISU_OpenGLPointSpriteMapper::cleanupSprites()
{
- //
- // Set GL params back to normal to stop other vtkMappers diusplaying wrongly
- //
- glEnable(GL_DEPTH_TEST);
- glEnable(GL_LIGHTING);
- glEnable( GL_BLEND );
-
- if (this->NVidiaMode)
- {
- glDisable( GL_POINT_SPRITE_ARB );
- }
- else
- {
- glDisable( GL_POINT_SPRITE_NV );
- }
-
- glEnable( GL_DEPTH_TEST );
-}
-//-----------------------------------------------------------------------------
-int FindPowerOfTwo(int i)
-{
- int size;
-
- for ( i--, size=1; i > 0; size*=2 )
- {
- i /= 2;
- }
-
- // [these lines added by Tim Hutton (implementing Joris Vanden Wyngaerd's suggestions)]
- // limit the size of the texture to the maximum allowed by OpenGL
- // (slightly more graceful than texture failing but not ideal)
- GLint maxDimGL;
- glGetIntegerv(GL_MAX_TEXTURE_SIZE,&maxDimGL);
- if ( size > maxDimGL )
- {
- size = maxDimGL ;
- }
- // end of Tim's additions
-
- return size;
-}
-//-----------------------------------------------------------------------------
-// Creates resampled unsigned char texture map that is a power of two in bith x and y.
-unsigned char* ResampleToPowerOfTwo(int &xs, int &ys, unsigned char *dptr, int bpp)
-{
- unsigned char *tptr, *p, *p1, *p2, *p3, *p4;
- int xsize, ysize, i, j, k, jOffset, iIdx, jIdx;
- float pcoords[3], hx, hy, rm, sm, w0, w1, w2, w3;
-
- xsize = FindPowerOfTwo(xs);
- ysize = FindPowerOfTwo(ys);
-
- hx = (float)(xs - 1.0) / (xsize - 1.0);
- hy = (float)(ys - 1.0) / (ysize - 1.0);
-
- tptr = p = new unsigned char[xsize*ysize*bpp];
-
- //Resample from the previous image. Compute parametric coordinates and interpolate
- for (j=0; j < ysize; j++)
- {
- pcoords[1] = j*hy;
-
- jIdx = (int)pcoords[1];
- if ( jIdx >= (ys-1) ) //make sure to interpolate correctly at edge
- {
- jIdx = ys - 2;
- pcoords[1] = 1.0;
- }
- else
- {
- pcoords[1] = pcoords[1] - jIdx;
- }
- jOffset = jIdx*xs;
- sm = 1.0 - pcoords[1];
-
- for (i=0; i < xsize; i++)
- {
- pcoords[0] = i*hx;
- iIdx = (int)pcoords[0];
- if ( iIdx >= (xs-1) )
- {
- iIdx = xs - 2;
- pcoords[0] = 1.0;
- }
- else
- {
- pcoords[0] = pcoords[0] - iIdx;
- }
- rm = 1.0 - pcoords[0];
-
- // Get pointers to 4 surrounding pixels
- p1 = dptr + bpp*(iIdx + jOffset);
- p2 = p1 + bpp;
- p3 = p1 + bpp*xs;
- p4 = p3 + bpp;
-
- // Compute interpolation weights interpolate components
- w0 = rm*sm;
- w1 = pcoords[0]*sm;
- w2 = rm*pcoords[1];
- w3 = pcoords[0]*pcoords[1];
- for (k=0; k < bpp; k++)
- {
- *p++ = (unsigned char) (p1[k]*w0 + p2[k]*w1 + p3[k]*w2 + p4[k]*w3);
- }
- }
- }
+ // Set GL params back to normal to stop other vtkMappers diusplaying wrongly
+ glEnable(GL_DEPTH_TEST);
+ glEnable(GL_LIGHTING);
+ glEnable( GL_BLEND );
- xs = xsize;
- ys = ysize;
-
- return tptr;
+ glDisable( GL_VERTEX_PROGRAM_POINT_SIZE_ARB );
+ glDisable( GL_POINT_SPRITE_ARB );
}
//-----------------------------------------------------------------------------
GLuint VISU_OpenGLPointSpriteMapper::LoadTexture( vtkImageData* imageData )
glPointSize( CurrentPointSize );
glEnable( GL_POINT_SPRITE_ARB );
+ glEnable( GL_VERTEX_PROGRAM_POINT_SIZE_ARB );
/*
- //
- // Set up the OpenGL state machine for using point sprites...
- //
- if (this->NVidiaMode)
- {
- //
- // NVidia Point Sprites initialization
- //
- glEnable(GL_POINT_SPRITE_NV);
-
- //
- // Set Quadratic Attenuation parameters Use GL_EXT_point_parameters to control the sprite size.
- //
- glPointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT, this->QuadraticPointDistanceAttenuation);
-
- //
- // Set Point Fade Threshold size
- //
- // The alpha of a point is calculated to allow the fading of points
- // instead of shrinking them past a defined threshold size. The threshold
- // is defined by GL_POINT_FADE_THRESHOLD_SIZE_ARB and is not clamped to
- // the minimum and maximum point sizes.
- glPointParameterfEXT(GL_POINT_FADE_THRESHOLD_SIZE_EXT, 1.0);
- glPointParameterfEXT(GL_POINT_SIZE_MIN_EXT, 1.0);
- glPointParameterfEXT(GL_POINT_SIZE_MAX_EXT, CurrentPointSize);
-
- if (this->Texture3D && this->TextureDimension==3)
- {
- // The texture is an animation that we load from a sequence of TGAs, and then
- // pack into the slices of a volume texture. The R texture coordinate can be
- // used to loop through the animation frames (with free tweening), but we
- // can't specify it directly.
-
- // The following two lines will tell the GL to take the supplied S texture
- // coordinate (see TPointSprite above), and copy it into R. _After_ this is
- // done, it will generate the texture coordinates for the sprite itself.
-
- glTexEnvi(GL_POINT_SPRITE_NV, GL_COORD_REPLACE_NV, GL_TRUE);
- glPointParameteriNV(GL_POINT_SPRITE_R_MODE_NV, GL_S);
- }
- else
- {
- // Enable texture coord replacement, but only 2D : no R coord
- glTexEnvi(GL_POINT_SPRITE_NV, GL_COORD_REPLACE_NV, GL_TRUE);
- glPointParameteriNV(GL_POINT_SPRITE_R_MODE_NV, GL_ZERO);
- }
- }
- else
- {
- //
- // GL ARB Point Sprites initialization
- //
- glEnable( GL_POINT_SPRITE_ARB );
-
- //
- // Set Quadratic Attenuation parameters
- //
- glPointParameterfvARB( GL_POINT_DISTANCE_ATTENUATION_ARB, this->QuadraticPointDistanceAttenuation );
-
- //
- // Set Point Fade Threshold size
- //
- // The alpha of a point is calculated to allow the fading of points
- // instead of shrinking them past a defined threshold size. The threshold
- // is defined by GL_POINT_FADE_THRESHOLD_SIZE_ARB and is not clamped to
- // the minimum and maximum point sizes.
- glPointParameterfARB( GL_POINT_FADE_THRESHOLD_SIZE_ARB, 1.0f );
- glPointParameterfARB( GL_POINT_SIZE_MIN_ARB, 1.0f );
- glPointParameterfARB( GL_POINT_SIZE_MAX_ARB, CurrentPointSize );
-
- //
- // Specify point sprite texture coordinate replacement mode for each texture unit
- //
- glTexEnvf( GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE );
- }
+ // Set Quadratic Attenuation parameters
+ glPointParameterfvARB( GL_POINT_DISTANCE_ATTENUATION_ARB, this->QuadraticPointDistanceAttenuation );
+
+ // Set Point Fade Threshold size
+ // The alpha of a point is calculated to allow the fading of points
+ // instead of shrinking them past a defined threshold size. The threshold
+ // is defined by GL_POINT_FADE_THRESHOLD_SIZE_ARB and is not clamped to
+ // the minimum and maximum point sizes.
+ glPointParameterfARB( GL_POINT_FADE_THRESHOLD_SIZE_ARB, 1.0f );
+ glPointParameterfARB( GL_POINT_SIZE_MIN_ARB, 1.0f );
+ glPointParameterfARB( GL_POINT_SIZE_MAX_ARB, CurrentPointSize );
+
+ // Specify point sprite texture coordinate replacement mode for each texture unit
+ glTexEnvf( GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE );
*/
}
//-----------------------------------------------------------------------------
initSprites();
+
+#ifdef ARB_PROGRAM
+ glEnable( GL_VERTEX_PROGRAM_ARB );
+
+ glColor4f( 1.0, 1.0, 1.0, 1.0 );
+
+ glBindProgramARB( GL_VERTEX_PROGRAM_ARB, shaderId );
+#else
+ glEnable( GL_VERTEX_PROGRAM_NV );
+
+ glColor4f( 1.0, 1.0, 1.0, 1.0 );
+
+ glBindProgramARB( GL_VERTEX_PROGRAM_NV, shaderId );
+#endif
+
vtkIdType *pts = 0;
vtkIdType npts = 0;
unsigned short count = 0;
++cellNum;
}
glEnd();
+
+#ifdef ARB_PROGRAM
+ glDisable( GL_VERTEX_PROGRAM_ARB );
+#else
+ glDisable( GL_VERTEX_PROGRAM_NV );
+#endif
}
}
//
// Draw method for OpenGL.
int VISU_OpenGLPointSpriteMapper::Draw(vtkRenderer *aren, vtkActor *act)
{
+ if( this->IsUsingOpenGLMapper )
+ return MAPPER_SUPERCLASS::Draw( aren, act );
+
vtkOpenGLRenderer *ren = (vtkOpenGLRenderer *)aren;
vtkUnsignedCharArray *colors = NULL;
vtkFloatArray *alpha = NULL;