You can use OpenGL from within pvserver. The output is shown in a QGLWidget custom widget in pvbrowser.
typedef struct { int i; }DATA; static PARAM *myparam; static GLuint object; static GLdouble frustSize = 0.5; static GLdouble frustNear = 1.0; static GLdouble frustFar = 200.0; static GLfloat scale = 1.5f; static GLfloat xRot = 0.0f; static GLfloat yRot = 0.0f; static GLfloat zRot = 0.0f; static GLfloat mat_specular[] = {1.0,1.0,1.0,1.0}; static GLfloat mat_shininess[] = {50.0}; static GLfloat light_position[] = {1.0,1.0,1.0,1.0}; static GLfloat white_light[] = {1.0,1.0,1.0,1.0}; static void initializeGL() { GLuint list; glClearColor(0.0,1.0,0.0,0.0); // Let OpenGL clear to green glEnable(GL_DEPTH_TEST); glClear(GL_COLOR_BUFFER_BIT); glShadeModel(GL_SMOOTH); glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess); glLightfv(GL_LIGHT0, GL_POSITION, light_position); glLightfv(GL_LIGHT0, GL_DIFFUSE, white_light); glLightfv(GL_LIGHT0, GL_SPECULAR, white_light); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_DEPTH_TEST); list = glGenLists(1); glNewList(list, GL_COMPILE); //pvSendFile(myparam,"scene.gl"); //pvSendFile(myparam,"scene1.gl"); //pvSendFile(myparam,"scene2.gl"); pvSendFile(myparam,"r.gl"); //pvSendFile(myparam,"cherry.gl"); glEndList(); object = list; /* glClearColor(0.0,1.0,0.0,0.0); // Let OpenGL clear to green glEnable(GL_DEPTH_TEST); glClear(GL_COLOR_BUFFER_BIT); list = glGenLists(1); glNewList( list, GL_COMPILE ); glColor3f(1.0,0.0,0.0); glOrtho(0.0,1.0,0.0,1.0,-1.0,1.0); glBegin(GL_POLYGON); glVertex3f(0.25,0.25,0.0); glVertex3f(0.75,0.25,0.0); glVertex3f(0.75,0.75,0.0); glVertex3f(0.25,0.75,0.0); glEnd(); glEndList(); object = list; */ } static void resizeGL(int w, int h) { glViewport( 0, 0, (GLint)w, (GLint)h ); glMatrixMode(GL_PROJECTION); glLoadIdentity(); //glFrustum(-1.0, 1.0, -1.0, 1.0, 1.0, 200.0); //glFrustum(-0.5, 0.5, -0.5, 0.5, 1.0, 200.0); } static void paintGL() { glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glFrustum(-frustSize, frustSize, -frustSize, frustSize, frustNear, frustFar); glTranslatef( 0.0, 0.0, -3.0 ); glScalef( scale, scale, scale ); glRotatef( xRot, 1.0, 0.0, 0.0 ); glRotatef( yRot, 0.0, 1.0, 0.0 ); glRotatef( zRot, 0.0, 0.0, 1.0 ); glCallList(object); } static int slotInit(PARAM *p, DATA *d) { if(p == NULL || d == NULL) return -1; /* define a OpenGL Widget */ pvQGL(p,ID_GL,0); pvSetGeometry(p,ID_GL,100,0,640,480); pvGlBegin(p,ID_GL); initializeGL(); resizeGL(640,480); pvGlEnd(p); return 0; } static int slotNullEvent(PARAM *p, DATA *d) { if(p == NULL || d == NULL) return -1; xRot += 1.0f; if(xRot > 360.0f) xRot = 0.0f; yRot += 1.0f; if(yRot > 360.0f) yRot = 0.0f; zRot += 1.0f; if(zRot > 360.0f) zRot = 0.0f; pvGlBegin(p,ID_GL); paintGL(); pvGlEnd(p); pvGlUpdate(p,ID_GL); return 0; } static int slotGlInitializeEvent(PARAM *p, int id, DATA *d) { if(p == NULL || id == 0 || d == NULL) return -1; initializeGL(); return 0; } static int slotGlPaintEvent(PARAM *p, int id, DATA *d) { if(p == NULL || id == 0 || d == NULL) return -1; paintGL(); return 0; } static int slotGlResizeEvent(PARAM *p, int id, DATA *d, int width, int height) { if(p == NULL || id == 0 || d == NULL || width < 0 || height < 0) return -1; resizeGL(width,height); return 0; } static int slotGlIdleEvent(PARAM *p, int id, DATA *d) { if(p == NULL || id == 0 || d == NULL) return -1; return 0; }