This example sets base colors using vgl_DrawFunColor. The point, line and polygon primitives are generated using the simplest form of these primitive calls. The point size and line width are set so that the points and lines in this example are more easily seen.
A C++ version of this example is in file exam1cc.cxx.
#include "base/base.h" #include "vgl/vgl.h" /* point data */ static Vfloat xpoint[2][3] = { {-.5, .5, 0.}, {.5, .5, 0.} }; /* line data */ static Vfloat xline[3][3] = { {-.5, 0., 0.}, {0.,.1,0.}, {.5, 0., 0.} }; /* triangle data */ static Vfloat xtris[6][3] = { {-.5, -.7, 0.}, {-.1,-.7,0.}, {-.3, -.3, 0.}, { .1, -.7, 0.}, { .5,-.7,0.}, { .3, -.3, 0.} }; /*---------------------------------------------------------------------- Drawing Basic Point, Line and Polygon Primitives ----------------------------------------------------------------------*/ int main() { Vfloat c[3]; #ifdef VKI_WIND_X11 Display *display; int screen; #endif vgl_OpenGLDev *opengldev; vgl_DrawFun *df; /* connect to X or Windows */ #ifdef VKI_WIND_X11 display = XOpenDisplay (0); screen = DefaultScreen (display); vgl_OpenGLDevConnectX (display,screen); #else vgl_OpenGLDevConnectWIN (); #endif /* create drawing functions */ df = vgl_DrawFunBegin(); /* create device objects and load drawing functions */ opengldev = vgl_OpenGLDevBegin(); vgl_OpenGLDevDrawFun (opengldev,df); /* turn on multisampling */ vgl_DrawFunVisualWindow (df,VGL_VISUAL_MULTISAMPLE); /* open window */ vgl_DrawFunPositionWindow (df,200,200,400,400); #ifdef VKI_WIND_X11 vgl_DrawFunOpenWindow (df,"X Windows"); #else vgl_DrawFunOpenWindow (df,"Microsoft Windows"); #endif /* default projection limits are bi-unit cube */ /* clear frame buffer and depth buffers */ vgl_DrawFunClear (df); /* set current color to white */ c[0] = 1.; c[1] = 1.; c[2] = 1.; vgl_DrawFunColor (df,c); /* set current point size to 4 pixels */ vgl_DrawFunPointSize (df,4); /* draw two points */ vgl_DrawFunPolyPoint (df,2,xpoint); /* set current line width to 2 */ vgl_DrawFunLineWidth (df,2); /* draw linestrip with 3 points */ vgl_DrawFunPolyLine (df,VGL_LINESTRIP,3,xline); /* set current color to red */ c[0] = 1.; c[1] = 0.; c[2] = 0.; vgl_DrawFunColor (df,c); /* draw 2 triangles */ vgl_DrawFunPolygon (df,VGL_TRIANGLES,6,xtris,VGL_NOSHADE,NULL); /* swap buffers */ vgl_DrawFunSwap (df); /* wait 10 seconds */ vgl_DrawFunDelay (df,10.); /* close windows */ vgl_DrawFunCloseWindow (df); /* free objects */ vgl_OpenGLDevEnd (opengldev); vgl_DrawFunEnd (df); /* disconnect from X or Windows */ vgl_OpenGLDevDisconnect (); /* close X display */ #ifdef VKI_WIND_X11 XCloseDisplay (display); #endif return 0; }
#include "base/base.h" #include "vgl/vgl.h" /* point data */ static Vfloat xpoint[2][3] = { {-.5, .5, 0.}, {.5, .5, 0.} }; static Vfloat cpoint[2][3] = { {1., 0., 0.}, {0., 0., 1.} }; /* line data */ static Vfloat xline[3][3] = { {-.5, 0., 0.}, {0.,.1,0.}, {.5, 0., 0.} }; static Vfloat cline[3][3] = { {1., 0., 0.}, {0.,1.,0.}, {0., 0., 1.} }; /* triangle data */ static Vfloat xtris[6][3] = { {-.5, -.7, 0.}, {-.1,-.7,0.}, {-.3, -.3, 0.}, { .1, -.7, 0.}, { .5,-.7,0.}, { .3, -.3, 0.} }; static Vfloat ctris[6][3] = { {1., 0., 0.}, {0.,1.,0.}, {0., 0., 1.}, {1., 0., 0.}, {0.,1.,0.}, {0., 0., 1.} }; /*---------------------------------------------------------------------- Drawing Vertex Color Point, Line and Polygon Primitives ----------------------------------------------------------------------*/ int main() { #ifdef VKI_WIND_X11 Display *display; int screen; #endif vgl_OpenGLDev *opengldev; vgl_DrawFun *df; /* connect to X or Windows */ #ifdef VKI_WIND_X11 display = XOpenDisplay (0); screen = DefaultScreen (display); vgl_OpenGLDevConnectX (display,screen); #else vgl_OpenGLDevConnectWIN (); #endif /* create drawing functions */ df = vgl_DrawFunBegin(); /* create device objects and load drawing functions */ opengldev = vgl_OpenGLDevBegin(); vgl_OpenGLDevDrawFun (opengldev,df); /* open window */ vgl_DrawFunPositionWindow (df,200,200,400,400); #ifdef VKI_WIND_X11 vgl_DrawFunOpenWindow (df,"X Windows"); #else vgl_DrawFunOpenWindow (df,"Microsoft Windows"); #endif /* default projection limits are bi-unit cube */ /* clear frame buffer and depth buffers */ vgl_DrawFunClear (df); /* set current point size to 4 pixels */ vgl_DrawFunPointSize (df,4); /* draw two points */ vgl_DrawFunPolyPointColor (df,2,xpoint,cpoint); /* set current line width to 2 */ vgl_DrawFunLineWidth (df,2); /* draw linestrip with 3 points */ vgl_DrawFunPolyLineColor (df,VGL_LINESTRIP,3,xline,cline); /* draw 2 triangles */ vgl_DrawFunPolygonColor (df,VGL_TRIANGLES,6,xtris,ctris,VGL_NOSHADE,NULL); /* swap buffers */ vgl_DrawFunSwap (df); /* wait 10 seconds */ vgl_DrawFunDelay (df,10.); /* close windows */ vgl_DrawFunCloseWindow (df); /* free objects */ vgl_OpenGLDevEnd (opengldev); vgl_DrawFunEnd (df); /* disconnect from X or Windows */ vgl_OpenGLDevDisconnect (); /* close X display */ #ifdef VKI_WIND_X11 XCloseDisplay (display); #endif return 0; }
Three scenes are drawn. The first scene draws the points, lines and triangles using various options for the vertex color input. The triangles are drawn with varying transparency across the triangles. The second scene draws dashed lines and stippled triangles. Note the use of the Bitmap object to set the stipple pattern. The third scene draws a textured linestrip and textured triangles using a 1 dimensional texture using the Texture object. It is typical to draw textured primitives in a base color of white so that the primitive is drawn in exactly the texture color.
#include "base/base.h" #include "vgl/vgl.h" /* point data */ static Vfloat xpoint[2][3] = { {-.5, .5, 0.}, {.5, .5, 0.} }; static Vfloat cpoint[2][3] = { {1., 0., 0.}, {0., 0., 1.} }; /* line data */ static Vfloat xline[3][3] = { {-.5, 0., 0.}, {0.,.1,0.}, {.5, 0., 0.} }; static Vuchar cline[3][4] = { {255,0,0,255}, {0,255,0,255}, {0,0,255,255} }; static Vfloat tline[3] = { 0.,.5,1. }; /* triangle data */ static Vfloat xtris[6][3] = { {-.5, -.7, 0.}, {-.1,-.7,0.}, {-.3, -.3, 0.}, { .1, -.7, 0.}, { .5,-.7,0.}, { .3, -.3, 0.} }; static Vuchar ctris[6][4] = { {255,0,0,255}, {0,255,0,0}, {0,0,255,255}, {255,0,0,255}, {0,255,0,0}, {0,0,255,255} }; static Vfloat ttris[6] = { 0.,1.,1., 0.,1.,1. }; /*---------------------------------------------------------------------- Drawing Vertex Array Point, Line and Polygon Primitives ----------------------------------------------------------------------*/ int main() { Vfloat c[3]; #ifdef VKI_WIND_X11 Display *display; int screen; #endif vgl_OpenGLDev *opengldev; vgl_DrawFun *df; vgl_Bitmap *bitmap; vgl_Texture *texture; /* connect to X or Windows */ #ifdef VKI_WIND_X11 display = XOpenDisplay (0); screen = DefaultScreen (display); vgl_OpenGLDevConnectX (display,screen); #else vgl_OpenGLDevConnectWIN (); #endif /* create drawing functions */ df = vgl_DrawFunBegin(); /* create device objects and load drawing functions */ opengldev = vgl_OpenGLDevBegin(); vgl_OpenGLDevDrawFun (opengldev,df); /* open window */ vgl_DrawFunPositionWindow (df,200,200,400,400); #ifdef VKI_WIND_X11 vgl_DrawFunOpenWindow (df,"X Windows"); #else vgl_DrawFunOpenWindow (df,"Microsoft Windows"); #endif /* default projection limits are bi-unit cube */ /* clear frame buffer and depth buffers */ vgl_DrawFunClear (df); /* set current point size to 4 pixels */ vgl_DrawFunPointSize (df,4); /* draw two points */ vgl_DrawFunPolyArray (df,VGL_POINTS,2,xpoint,VGL_COLOR_3F,cpoint, 0,NULL,0,NULL,0,NULL); /* set current line width to 2 */ vgl_DrawFunLineWidth (df,2); /* draw linestrip with 3 points */ vgl_DrawFunPolyArray (df,VGL_LINESTRIP,3,xline,VGL_COLOR_4B,cline, 0,NULL,0,NULL,0,NULL); /* draw 2 triangles */ vgl_DrawFunSetMode (df,VGL_BLENDTRANSMODE,VGL_ON); vgl_DrawFunPolyArray (df,VGL_TRIANGLES,6,xtris,VGL_COLOR_4B,ctris, 0,NULL,0,NULL,0,NULL); /* swap buffers */ vgl_DrawFunSwap (df); /* wait 5 seconds */ vgl_DrawFunDelay (df,5.); /* now draw dashed lines and stippled polygons */ /* define bitmap */ bitmap = vgl_BitmapBegin (); vgl_BitmapLoad (bitmap,BITMAP_SQUARE4); vgl_DrawFunBitmapDefine (df,1,bitmap); vgl_DrawFunClear (df); /* set current line type to dashed */ vgl_DrawFunLineStyle (df,VGL_LINESTYLE_DASH); /* draw linestrip with 3 points */ vgl_DrawFunPolyArray (df,VGL_LINESTRIP,3,xline,VGL_COLOR_4B,cline, 0,NULL,0,NULL,0,NULL); /* draw 2 triangles */ vgl_DrawFunBitmapSelect (df,1); vgl_DrawFunPolyArray (df,VGL_TRIANGLES,6,xtris,VGL_COLOR_4B,ctris, 0,NULL,0,NULL,0,NULL); vgl_DrawFunSwap (df); vgl_DrawFunDelay (df,5.); /* now draw textured lines and triangles */ /* define texture */ /* built-in is index 1 */ texture = vgl_TextureBegin (); vgl_TextureLoad (texture,TEXTURE_HUE_BANDED); vgl_DrawFunTextureDefine (df,1,texture); vgl_DrawFunClear (df); /* select texture and draw a base color of white */ vgl_DrawFunTextureSelect (df,1); c[0] = 1.; c[1] = 1.; c[2] = 1.; vgl_DrawFunColor (df,c); /* set current line type to solid */ vgl_DrawFunLineStyle (df,VGL_LINESTYLE_SOLID); /* draw linestrip with 3 points */ vgl_DrawFunPolyArray (df,VGL_LINESTRIP,3,xline,0,NULL, 0,NULL,VGL_1DTEXTURE,tline,0,NULL); /* draw 2 triangles */ vgl_DrawFunBitmapSelect (df,0); vgl_DrawFunPolyArray (df,VGL_TRIANGLES,6,xtris,0,NULL, 0,NULL,VGL_1DTEXTURE,ttris,0,NULL); vgl_DrawFunSwap (df); vgl_DrawFunDelay (df,5.); /* close windows */ vgl_DrawFunCloseWindow (df); /* free objects */ vgl_OpenGLDevEnd (opengldev); vgl_DrawFunEnd (df); /* disconnect from X or Windows */ vgl_OpenGLDevDisconnect (); /* close X display */ #ifdef VKI_WIND_X11 XCloseDisplay (display); #endif return 0; }
All of the vertex coordinates, color, normals, textures and data are copied explicitly to graphics memory from client memory. A block of graphics memory if first allocated using vgl_DrawFunInitBuffer. this function returns a vertex buffer object identifier, vboid. Note that it is possible that this memory allocation may fail. If this is the case, a complete application would need to be able to revert to the equivalent "Array" graphics primitives which would use client memory. It also possible that vgl_DrawFunCopyBuffer may fail if the amount of data to be copied to the vertex buffer exceeds the size of the vertex buffer. In this case an offset of -1 is returned and another vertex buffer would need to be allocated using vgl_DrawFunInitBuffer to be used to hold the vertex data.
All the vertex data is copied to the vertex buffer and an offset into the vertex buffer is returned for each set of vertex data. The graphics memory to be used for each drawing primitive is addressed using the vertex buffer identifier and respective offsets. After drawing is completed, the graphics memory associated with the vertex buffer is freed using vgl_DrawFunTermBuffer.
#include "base/base.h" #include "vgl/vgl.h" /* point data */ static Vfloat xpoint[2][3] = { {-.5, .5, 0.}, {.5, .5, 0.} }; static Vfloat cpoint[2][3] = { {1., 0., 0.}, {0., 0., 1.} }; /* line data */ static Vfloat xline[3][3] = { {-.5, 0., 0.}, {0.,.1,0.}, {.5, 0., 0.} }; static Vuchar cline[3][4] = { {255,0,0,255}, {0,255,0,255}, {0,0,255,255} }; static Vfloat tline[3] = { 0.,.5,1. }; /* triangle data */ static Vfloat xtris[6][3] = { {-.5, -.7, 0.}, {-.1,-.7,0.}, {-.3, -.3, 0.}, { .1, -.7, 0.}, { .5,-.7,0.}, { .3, -.3, 0.} }; static Vuchar ctris[6][4] = { {255,0,0,255}, {0,255,0,0}, {0,0,255,255}, {255,0,0,255}, {0,255,0,0}, {0,0,255,255} }; static Vfloat ttris[6] = { 0.,1.,1., 0.,1.,1. }; /*---------------------------------------------------------------------- Drawing Vertex Buffer Point, Line and Polygon Primitives ----------------------------------------------------------------------*/ int main() { Vfloat c[3]; Vint vboid; Vint vboof1, vboof2, vboof3, vboof4, vboof5; #ifdef VKI_WIND_X11 Display *display; int screen; #endif vgl_OpenGLDev *opengldev; vgl_DrawFun *df; vgl_Bitmap *bitmap; vgl_Texture *texture; /* connect to X or Windows */ #ifdef VKI_WIND_X11 display = XOpenDisplay (0); screen = DefaultScreen (display); vgl_OpenGLDevConnectX (display,screen); #else vgl_OpenGLDevConnectWIN (); #endif /* create drawing functions */ df = vgl_DrawFunBegin(); /* create device objects and load drawing functions */ opengldev = vgl_OpenGLDevBegin(); vgl_OpenGLDevDrawFun (opengldev,df); /* open window */ vgl_DrawFunPositionWindow (df,200,200,400,400); #ifdef VKI_WIND_X11 vgl_DrawFunOpenWindow (df,"X Windows"); #else vgl_DrawFunOpenWindow (df,"Microsoft Windows"); #endif /* default projection limits are bi-unit cube */ /* clear frame buffer and depth buffers */ vgl_DrawFunClear (df); /* assume a buffer object of 100K bytes is large enough */ vgl_DrawFunInitBuffer (df,100000,&vboid); /* check to see if vertex buffer is created */ if(vboid == 0) { fprintf(stderr,"Can not create buffer\n"); exit(0); } /* copy two points */ vgl_DrawFunCopyBuffer (df,vboid,2,xpoint,VGL_COLOR_3F,cpoint, 0,NULL,0,NULL,0,NULL,&vboof1); /* copy linestrip with 3 points */ vgl_DrawFunCopyBuffer (df,vboid,3,xline,VGL_COLOR_4B,cline, 0,NULL,0,NULL,0,NULL,&vboof2); /* copy 2 triangles */ vgl_DrawFunCopyBuffer (df,vboid,6,xtris,VGL_COLOR_4B,ctris, 0,NULL,0,NULL,0,NULL,&vboof3); /* now copy textured lines and triangles */ vgl_DrawFunCopyBuffer (df,vboid,3,xline,0,NULL,0,NULL,VGL_1DTEXTURE,tline, 0,NULL,&vboof4); vgl_DrawFunCopyBuffer (df,vboid,6,xtris,0,NULL,0,NULL,VGL_1DTEXTURE,ttris, 0,NULL,&vboof5); /* now draw */ /* set current point size to 4 pixels */ vgl_DrawFunPointSize (df,4); vgl_DrawFunPolyBuffer (df,vboid,vboof1,VGL_POINTS,2,VGL_COLOR_3F,0,0,0); /* set current line width to 2 */ vgl_DrawFunLineWidth (df,2); vgl_DrawFunPolyBuffer (df,vboid,vboof2, VGL_LINESTRIP,3,VGL_COLOR_4B,0,0,0); /* turn on blend transparency */ vgl_DrawFunSetMode (df,VGL_BLENDTRANSMODE,VGL_ON); vgl_DrawFunPolyBuffer (df,vboid,vboof3, VGL_TRIANGLES,6,VGL_COLOR_4B,0,0,0); /* swap buffers */ vgl_DrawFunSwap (df); /* wait 5 seconds */ vgl_DrawFunDelay (df,5.); /* now draw dashed lines and stippled polygons */ /* define bitmap */ bitmap = vgl_BitmapBegin (); vgl_BitmapLoad (bitmap,BITMAP_SQUARE4); vgl_DrawFunBitmapDefine (df,1,bitmap); vgl_DrawFunClear (df); /* set current line type to dashed */ vgl_DrawFunLineStyle (df,VGL_LINESTYLE_DASH); /* draw linestrip with 3 points */ vgl_DrawFunPolyBuffer (df,vboid,vboof2, VGL_LINESTRIP,3,VGL_COLOR_4B,0,0,0); /* draw 2 triangles */ vgl_DrawFunBitmapSelect (df,1); vgl_DrawFunPolyBuffer (df,vboid,vboof3, VGL_TRIANGLES,6,VGL_COLOR_4B,0,0,0); vgl_DrawFunSwap (df); vgl_DrawFunDelay (df,5.); /* now draw textured lines and triangles */ /* define texture */ /* built-in is index 1 */ texture = vgl_TextureBegin (); vgl_TextureLoad (texture,TEXTURE_HUE_BANDED); vgl_DrawFunTextureDefine (df,1,texture); vgl_DrawFunClear (df); /* select texture and draw a base color of white */ vgl_DrawFunTextureSelect (df,1); c[0] = 1.; c[1] = 1.; c[2] = 1.; vgl_DrawFunColor (df,c); /* set current line type to solid */ vgl_DrawFunLineStyle (df,VGL_LINESTYLE_SOLID); /* draw linestrip with 3 points */ vgl_DrawFunPolyBuffer (df,vboid,vboof4, VGL_LINESTRIP,3,0,0,VGL_1DTEXTURE,0); /* draw 2 triangles */ vgl_DrawFunBitmapSelect (df,0); vgl_DrawFunPolyBuffer (df,vboid,vboof5, VGL_TRIANGLES,6,0,0,VGL_1DTEXTURE,0); vgl_DrawFunSwap (df); vgl_DrawFunDelay (df,5.); /* free buffer memory */ vgl_DrawFunTermBuffer (df,vboid); /* close windows */ vgl_DrawFunCloseWindow (df); /* free objects */ vgl_BitmapEnd (bitmap); vgl_TextureEnd (texture); vgl_OpenGLDevEnd (opengldev); vgl_DrawFunEnd (df); /* disconnect from X or Windows */ vgl_OpenGLDevDisconnect (); /* close X display */ #ifdef VKI_WIND_X11 XCloseDisplay (display); #endif return 0; }
All primitive types allow color, normal, texture and data arrays. The color and normal arrays may be typed as either floats or bytes. The data arrays are not used in this example. The use of the ElemArray primitives is recommended for drawing large numbers of graphics primitives which share vertices. For example, in the limit, a large triangle mesh will contain almost the same number of unique vertices as triangles. When drawing such a mesh only the index array needs to be 3 times the number of triangles. The vertex attributes will be on the order of the number of triangles.
Three unique scenes are drawn. The first scene is redrawn after the third scene using a display list restored from an object file. It is redrawn again in software using a RendBuf object.
#include "base/base.h" #include "vgl/vgl.h" static Vfloat xs[4][3] = { {-.5,-.5, 0.}, { .5,-.5, 0.}, { .5, .5, 0.}, {-.5, .5, 0.} }; static Vfloat ts[4] = { 0.,1.,1.,0. }; static Vfloat cpoint[4][3] = { {1., 0., 0.}, {0., 0., 1.}, {0., 1., 0.}, {1., 1., 1.} }; static Vuchar cline[4][4] = { {255,255,255,255}, {255,255,255,255}, {255,255,255,255}, {255,255,255,255} }; static Vuchar ctri[4][4] = { {255,0,0,255}, {0,255,0,255}, {0,0,255,255}, {255,225,255,0} }; static Vuint ixpoint[4] = {0,1,2,3}; static Vuint ixline[5] = {0,1,2,3,0}; static Vuint ixtri[6] = {0,1,2,0,2,3}; static Vfloat xtext[3] = {-.7,.8,0.}; static Vfloat xtext1[3] = {-.7,.7,0.}; static Vfloat ctext[3] = {1.,1.,1.}; /*---------------------------------------------------------------------- Drawing Element Indexed Array Primitives ----------------------------------------------------------------------*/ int main() { Vfloat c[3]; #ifdef VKI_WIND_X11 Display *display; int screen; #endif vgl_OpenGLDev *opengldev; vgl_DList *dlist; vgl_DrawFun *df, *dfl, *dfr; vgl_Bitmap *bitmap; vgl_Texture *texture; vgl_RendBuf *rendbuf; vgl_FBuffer *fbuffer; /* connect to X or Windows */ #ifdef VKI_WIND_X11 display = XOpenDisplay (0); screen = DefaultScreen (display); vgl_OpenGLDevConnectX (display,screen); #else vgl_OpenGLDevConnectWIN (); #endif /* create drawing functions */ df = vgl_DrawFunBegin(); dfl = vgl_DrawFunBegin(); /* create device objects and load drawing functions */ opengldev = vgl_OpenGLDevBegin(); vgl_OpenGLDevDrawFun (opengldev,df); /* open window */ vgl_DrawFunPositionWindow (df,200,200,400,400); #ifdef VKI_WIND_X11 vgl_DrawFunOpenWindow (df,"X Windows"); #else vgl_DrawFunOpenWindow (df,"Microsoft Windows"); #endif /* load dlist drawing functions */ dlist = vgl_DListBegin(); vgl_DListDrawFun (dlist,dfl); vgl_DListSetObject (dlist,VGL_DRAWFUN,df); /* draw first display to DList */ /* default projection limits are bi-unit cube */ vgl_DrawFunColor (dfl,ctext); vgl_DrawFunText (dfl,xtext,"PolyElemArray"); /* set current point size to 8 pixels */ vgl_DrawFunPointSize (dfl,8); /* draw four points */ vgl_DrawFunPolyElemArray (dfl,VGL_POINTS,4,ixpoint,xs, VGL_COLOR_3F,cpoint,0,NULL,0,NULL,0,NULL); /* set current line width to 4 */ vgl_DrawFunLineWidth (dfl,4); /* draw lineloop */ vgl_DrawFunPolyElemArray (dfl,VGL_LINELOOP,4,ixline,xs, VGL_COLOR_4B,cline,0,NULL,0,NULL,0,NULL); /* draw triangles, white point is fully transparent */ vgl_DrawFunSetMode (dfl,VGL_BLENDTRANSMODE,VGL_ON); vgl_DrawFunPolyElemArray (dfl,VGL_TRIANGLES,6,ixtri,xs, VGL_COLOR_4B,ctri,0,NULL,0,NULL,0,NULL); /* write display list to file, render again later */ vgl_DListWrite (dlist,SYS_ASCII,"exam1d.asc"); printf("Write first frame object to exam1d.asc\n"); /* now render */ vgl_DrawFunClear (df); vgl_DListCall (dlist); vgl_DrawFunSwap (df); /* wait 5 seconds */ vgl_DrawFunDelay (df,5.); /* now draw dashed lines and stippled polygons */ /* define bitmap */ bitmap = vgl_BitmapBegin (); vgl_BitmapLoad (bitmap,BITMAP_SQUARE4); vgl_DrawFunBitmapDefine (df,1,bitmap); vgl_DrawFunClear (df); vgl_DrawFunColor (df,ctext); vgl_DrawFunText (df,xtext,"PolyElemArray"); vgl_DrawFunText (df,xtext1,"Dashed lines, stippled polygons"); /* set current line type to dashed */ vgl_DrawFunLineStyle (df,VGL_LINESTYLE_DASH); /* draw linestrip with 5 points */ vgl_DrawFunPolyElemArray (df,VGL_LINESTRIP,5,ixline,xs, VGL_COLOR_4B,cline,0,NULL,0,NULL,0,NULL); /* draw triangles */ vgl_DrawFunBitmapSelect (df,1); vgl_DrawFunPolyElemArray (df,VGL_TRIANGLES,6,ixtri,xs, VGL_COLOR_4B,ctri,0,NULL,0,NULL,0,NULL); vgl_DrawFunSwap (df); vgl_DrawFunDelay (df,5.); /* now draw textured lines and triangles */ /* define texture */ /* built-in is index 1 */ texture = vgl_TextureBegin (); vgl_TextureLoad (texture,TEXTURE_HUE_BANDED); vgl_DrawFunTextureDefine (df,1,texture); vgl_DrawFunClear (df); vgl_DrawFunText (df,xtext,"PolyElemArray"); vgl_DrawFunText (df,xtext1,"Textured lines and polygons"); /* select texture and draw a base color of white */ vgl_DrawFunTextureSelect (df,1); c[0] = 1.; c[1] = 1.; c[2] = 1.; vgl_DrawFunColor (df,c); /* set current line type to solid */ vgl_DrawFunLineStyle (df,VGL_LINESTYLE_SOLID); /* draw linestrip with 5 points */ vgl_DrawFunPolyElemArray (df,VGL_LINESTRIP,5,ixline,xs, 0,NULL,0,NULL,VGL_1DTEXTURE,ts,0,NULL); /* draw triangles */ vgl_DrawFunBitmapSelect (df,0); vgl_DrawFunPolyElemArray (df,VGL_TRIANGLES,6,ixtri,xs, 0,NULL,0,NULL,VGL_1DTEXTURE,ts,0,NULL); vgl_DrawFunSwap (df); vgl_DrawFunDelay (df,5.); vgl_DrawFunTextureSelect (df,0); /* redraw first frame, restore from file */ vgl_DListErase (dlist); vgl_DListRead (dlist,SYS_ASCII,"exam1d.asc"); vgl_DrawFunClear (df); vgl_DrawFunColor (df,ctext); vgl_DrawFunText (df,xtext1,"Redraw first frame"); vgl_DListCall (dlist); vgl_DrawFunSwap (df); vgl_DrawFunDelay (df,5.); /* now redraw first frame with RendBuf */ rendbuf = vgl_RendBufBegin(); dfr = vgl_DrawFunBegin(); vgl_RendBufDrawFun (rendbuf,dfr); vgl_DListSetObject (dlist,VGL_DRAWFUN,dfr); vgl_DrawFunPositionWindow (dfr,200,200,400,400); vgl_DrawFunOpenWindow (dfr,"exam1d"); vgl_DrawFunClear (dfr); vgl_DrawFunColor (dfr,ctext); vgl_DrawFunText (dfr,xtext1,"Redraw first frame with RendBuf"); vgl_DListCall (dlist); vgl_DrawFunSwap (dfr); /* get image buffer and write to file */ vgl_RendBufGetFBuffer (rendbuf,&fbuffer); vgl_FBufferWriteBMP (fbuffer,"exam1d.bmp"); vgl_DrawFunCloseWindow (dfr); printf("Redraw first frame with RendBuf, write image to exam1d.bmp\n"); /* close window */ vgl_DrawFunCloseWindow (df); /* free objects */ vgl_OpenGLDevEnd (opengldev); vgl_DListEnd (dlist); vgl_DrawFunEnd (df); vgl_DrawFunEnd (dfl); vgl_DrawFunEnd (dfr); vgl_BitmapEnd (bitmap); vgl_TextureEnd (texture); vgl_RendBufEnd (rendbuf); /* disconnect from X or Windows */ vgl_OpenGLDevDisconnect (); /* close X display */ #ifdef VKI_WIND_X11 XCloseDisplay (display); #endif return 0; }
Three unique scenes are drawn. After the third scene is drawn, the first scene is redrawn using RendBuf using the display list created of the first scene. The drawing function connected to the underlying OpenGLDev object must be set in the RendBuf so that it can read the OpenGLDev dependent vertext buffers.
The display list is restored from the file and now contains array style primitive versions of the vertex buffer primitives. It is redrawn using OpenGLDev.
#include "base/base.h" #include "vgl/vgl.h" static Vfloat xs[4][3] = { {-.5,-.5, 0.}, { .5,-.5, 0.}, { .5, .5, 0.}, {-.5, .5, 0.} }; static Vfloat ts[4] = { 0.,1.,1.,0. }; static Vfloat cs[4][3] = { {1., 0., 0.}, {0., 0., 1.}, {0., 1., 0.}, {1., 1., 1.} }; static Vuint ix[6] = {0,1,2,3,0,2}; static Vfloat xtext[3] = {-.7,.8,0.}; static Vfloat xtext1[3] = {-.7,.7,0.}; static Vfloat ctext[3] = {1.,1.,1.}; /*---------------------------------------------------------------------- Drawing Element Indexed Buffer Primitives ----------------------------------------------------------------------*/ int main() { Vfloat c[3]; Vint vboid, evboid; Vint evboof; Vint vboof1, vboof2; #ifdef VKI_WIND_X11 Display *display; int screen; #endif vgl_OpenGLDev *opengldev; vgl_DList *dlist; vgl_DrawFun *df, *dfl, *dfr; vgl_Bitmap *bitmap; vgl_Texture *texture; vgl_RendBuf *rendbuf; vgl_FBuffer *fbuffer; /* connect to X or Windows */ #ifdef VKI_WIND_X11 display = XOpenDisplay (0); screen = DefaultScreen (display); vgl_OpenGLDevConnectX (display,screen); #else vgl_OpenGLDevConnectWIN (); #endif /* create drawing functions */ df = vgl_DrawFunBegin(); dfl = vgl_DrawFunBegin(); /* create device objects and load drawing functions */ opengldev = vgl_OpenGLDevBegin(); vgl_OpenGLDevDrawFun (opengldev,df); /* open window */ vgl_DrawFunPositionWindow (df,200,200,400,400); #ifdef VKI_WIND_X11 vgl_DrawFunOpenWindow (df,"X Windows"); #else vgl_DrawFunOpenWindow (df,"Microsoft Windows"); #endif /* load dlist drawing functions */ dlist = vgl_DListBegin(); vgl_DListDrawFun (dlist,dfl); vgl_DListSetObject (dlist,VGL_DRAWFUN,df); /* assume a buffer object of 100K bytes is large enough */ vgl_DrawFunInitBuffer (df,100000,&vboid); /* elem index buffer */ vgl_DrawFunInitBuffer (df,100000,&evboid); /* check to see if vertex buffer is created */ if(vboid == 0) { fprintf(stderr,"Can not create buffer\n"); exit(0); } /* copy four points, coordinates, color */ vgl_DrawFunCopyBuffer (df,vboid,4,xs,VGL_COLOR_3F,cs, 0,NULL,0,NULL,0,NULL,&vboof1); /* copy four points, coordinates, texture */ vgl_DrawFunCopyBuffer (df,vboid,4,xs,0,NULL, 0,NULL,VGL_1DTEXTURE,ts,0,NULL,&vboof2); vgl_DrawFunCopyElemBuffer (df,evboid,6,ix,&evboof); /* default projection limits are bi-unit cube */ vgl_DrawFunColor (dfl,ctext); vgl_DrawFunText (dfl,xtext,"PolyElemBuffer"); /* set current point size to 8 pixels */ vgl_DrawFunPointSize (dfl,8); /* draw four corner points */ vgl_DrawFunPolyElemBuffer (dfl,evboid,evboof,vboid,vboof1, VGL_POINTS,4,VGL_COLOR_3F,0,0,0); /* set current line width to 4 */ vgl_DrawFunLineWidth (dfl,4); /* draw lineloop */ vgl_DrawFunPolyElemBuffer (dfl,evboid,evboof,vboid,vboof1, VGL_LINELOOP,4,VGL_COLOR_3F,0,0,0); /* draw triangles */ vgl_DrawFunPolyElemBuffer (dfl,evboid,evboof,vboid,vboof1, VGL_TRIANGLES,6,VGL_COLOR_3F,0,0,0); /* write display list to file, render again later */ /* Buffer primitives written as Array primitives */ vgl_DListWrite (dlist,SYS_ASCII,"exam1e.asc"); printf("Write first frame object to exam1e.asc\n"); /* now render */ vgl_DrawFunClear (df); vgl_DListCall (dlist); vgl_DrawFunSwap (df); /* wait 5 seconds */ vgl_DrawFunDelay (df,5.); /* now draw dashed lines and stippled polygons */ /* define bitmap */ bitmap = vgl_BitmapBegin (); vgl_BitmapLoad (bitmap,BITMAP_SQUARE4); vgl_DrawFunBitmapDefine (df,1,bitmap); vgl_DrawFunClear (df); vgl_DrawFunColor (df,ctext); vgl_DrawFunText (df,xtext,"PolyElemBuffer"); vgl_DrawFunText (df,xtext1,"Dashed lines, stippled polygons"); /* set current line type to dashed */ vgl_DrawFunLineStyle (df,VGL_LINESTYLE_DASH); /* draw linestrip with 5 points */ vgl_DrawFunPolyElemBuffer (df,evboid,evboof,vboid,vboof1, VGL_LINESTRIP,5,VGL_COLOR_3F,0,0,0); /* draw triangles */ vgl_DrawFunBitmapSelect (df,1); vgl_DrawFunPolyElemBuffer (df,evboid,evboof,vboid,vboof1, VGL_TRIANGLES,6,VGL_COLOR_3F,0,0,0); vgl_DrawFunSwap (df); vgl_DrawFunDelay (df,5.); /* now draw textured lines and triangles */ /* define texture */ /* built-in is index 1 */ texture = vgl_TextureBegin (); vgl_TextureLoad (texture,TEXTURE_HUE_BANDED); vgl_DrawFunTextureDefine (df,1,texture); vgl_DrawFunClear (df); vgl_DrawFunText (df,xtext,"PolyElemBuffer"); vgl_DrawFunText (df,xtext1,"Textured lines and polygons"); /* select texture and draw a base color of white */ /* use second CopyBuffer set of data */ vgl_DrawFunTextureSelect (df,1); c[0] = 1.; c[1] = 1.; c[2] = 1.; vgl_DrawFunColor (df,c); /* set current line type to solid */ vgl_DrawFunLineStyle (df,VGL_LINESTYLE_SOLID); /* draw linestrip with 5 points */ vgl_DrawFunPolyElemBuffer (df,evboid,evboof,vboid,vboof2, VGL_LINESTRIP,5,0,0,VGL_1DTEXTURE,0); /* draw triangles */ vgl_DrawFunBitmapSelect (df,0); vgl_DrawFunPolyElemBuffer (df,evboid,evboof,vboid,vboof2, VGL_TRIANGLES,6,0,0,VGL_1DTEXTURE,0); vgl_DrawFunSwap (df); vgl_DrawFunDelay (df,5.); vgl_DrawFunTextureSelect (df,0); /* now redraw first frame with RendBuf */ rendbuf = vgl_RendBufBegin(); dfr = vgl_DrawFunBegin(); vgl_RendBufDrawFun (rendbuf,dfr); /* install OpenGLDev drawing function to access buffers */ vgl_RendBufSetObject (rendbuf,VGL_DRAWFUN,df); vgl_DListSetObject (dlist,VGL_DRAWFUN,dfr); vgl_DrawFunPositionWindow (dfr,200,200,400,400); vgl_DrawFunOpenWindow (dfr,"exam1d"); vgl_DrawFunClear (dfr); vgl_DrawFunColor (dfr,ctext); vgl_DrawFunText (dfr,xtext1,"Redraw first frame with RendBuf"); vgl_DListCall (dlist); vgl_DrawFunSwap (dfr); /* get image buffer and write to file */ vgl_RendBufGetFBuffer (rendbuf,&fbuffer); vgl_FBufferWriteBMP (fbuffer,"exam1e.bmp"); vgl_DrawFunCloseWindow (dfr); printf("Redraw first frame with RendBuf, write image to exam1e.bmp\n"); /* redraw first frame, restore from file */ vgl_DListErase (dlist); vgl_DListRead (dlist,SYS_ASCII,"exam1e.asc"); vgl_DListSetObject (dlist,VGL_DRAWFUN,df); vgl_DrawFunClear (df); vgl_DrawFunColor (df,ctext); vgl_DrawFunText (df,xtext1,"Redraw first frame as PolyElemArray"); vgl_DListCall (dlist); vgl_DrawFunSwap (df); vgl_DrawFunDelay (df,5.); /* close windows */ vgl_DrawFunCloseWindow (df); /* free objects */ vgl_OpenGLDevEnd (opengldev); vgl_DListEnd (dlist); vgl_DrawFunEnd (df); vgl_DrawFunEnd (dfl); vgl_DrawFunEnd (dfr); vgl_BitmapEnd (bitmap); vgl_TextureEnd (texture); vgl_RendBufEnd (rendbuf); /* disconnect from X or Windows */ vgl_OpenGLDevDisconnect (); /* close X display */ #ifdef VKI_WIND_X11 XCloseDisplay (display); #endif return 0; }
#include "base/base.h" #include "vgl/vgl.h" /* point data, back face */ static Vfloat xpoints[4][3] = { {-3.,-3.,-3.}, { 3.,-3.,-3.}, {-3., 3.,-3.}, { 3., 3.,-3.} }; static Vfloat vpoints[4][3] = { {0.,0.,-1.}, {0.,0.,-1.}, {0.,0.,-1.}, {0.,0.,-1.} }; /* line data, right face */ static Vfloat xlineloop[4][3] = { {4.,-4.,4.}, { 4.,-4.,-4.}, {4., 4.,-4.}, {4., 4., 4.} }; static Vfloat vlineloop[4][3] = { {1.,0.,0.}, {1.,0.,0.}, {1.,0.,0.}, {1.,0.,0.} }; /* triangle data, front face */ static Vfloat xtristrip[4][3] = { {-5.,-5.,5.}, { 5.,-5.,5.}, {-5., 5.,5.}, { 5.,5.,5.} }; static Vfloat vtristrip[4][3] = { {0.,0.,1.}, {0.,0.,1.}, {0.,0.,1.}, {0.,0.,1.} }; /* light properties */ static Vfloat camb[3] = { .3,.3,.3 }; static Vfloat cdis[3] = { .7,.7,.7 }; static Vfloat xdis[3] = { 1.,0.,0. }; /*---------------------------------------------------------------------- Drawing 3D, Lighted Point, Line and Polygon Primitives ----------------------------------------------------------------------*/ int main() { Vint i; Vfloat c[3]; Vfloat tm4[4][4]; #ifdef VKI_WIND_X11 Display *display; int screen; #endif vgl_OpenGLDev *opengldev; vgl_DrawFun *df; vgl_Xfm *xfm; /* connect to X or Windows */ #ifdef VKI_WIND_X11 display = XOpenDisplay (0); screen = DefaultScreen (display); vgl_OpenGLDevConnectX (display,screen); #else vgl_OpenGLDevConnectWIN (); #endif /* create drawing functions */ df = vgl_DrawFunBegin(); /* create device objects and load drawing functions */ opengldev = vgl_OpenGLDevBegin(); vgl_OpenGLDevDrawFun (opengldev,df); /* open window */ vgl_DrawFunPositionWindow (df,200,200,400,300); #ifdef VKI_WIND_X11 vgl_DrawFunOpenWindow (df,"X Windows"); #else vgl_DrawFunOpenWindow (df,"Microsoft Windows"); #endif /* set viewing volume to match window aspect ratio */ vgl_DrawFunProjOrtho (df,-13.333,13.333,-10.,10.,-10.,10.); /* set lights */ vgl_DrawFunLight (df,0,VGL_LIGHT_AMBIENT,camb,NULL); vgl_DrawFunLight (df,1,VGL_LIGHT_DISTANT,cdis,xdis); vgl_DrawFunSetMode (df,VGL_LIGHTMODE,VGL_ON); /* enable zbuffering */ vgl_DrawFunSetMode (df,VGL_ZBUFFERMODE,VGL_ON); /* create transform object */ xfm = vgl_XfmBegin(); /* clear frame buffer and depth buffers */ for(i = 0; i < 100; i++) { vgl_XfmRotate (xfm,(Vfloat)(3.14159/25.*i),XFM_YAXIS); vgl_XfmGetMatrix (xfm,tm4); vgl_DrawFunXfmLoad (df,tm4); /* first rotation, points, lines in lighted vertex color */ if(i == 0) { vgl_DrawFunSetMode (df,VGL_POINTARRAYLIGHTMODE,VGL_ON); vgl_DrawFunSetMode (df,VGL_LINEARRAYLIGHTMODE,VGL_ON); /* second rotation, points, lines in vertex color */ } else if(i == 50) { vgl_DrawFunSetMode (df,VGL_POINTARRAYLIGHTMODE,VGL_OFF); vgl_DrawFunSetMode (df,VGL_LINEARRAYLIGHTMODE,VGL_OFF); } vgl_DrawFunClear (df); /* set current color to magenta */ c[0] = 1.; c[1] = 0.; c[2] = 1.; vgl_DrawFunColor (df,c); vgl_DrawFunPointSize (df,4); vgl_DrawFunPolyArray (df,VGL_POINTS,4,xpoints,0,NULL, VGL_NORMAL_3F,vpoints,0,NULL,0,NULL); /* set current color to cyan */ c[0] = 0.; c[1] = 1.; c[2] = 1.; vgl_DrawFunColor (df,c); vgl_DrawFunLineWidth (df,2); vgl_DrawFunPolyArray (df,VGL_LINELOOP,4,xlineloop,0,NULL, VGL_NORMAL_3F,vlineloop,0,NULL,0,NULL); /* set current color to yellow */ c[0] = 1.; c[1] = 1.; c[2] = 0.; vgl_DrawFunColor (df,c); vgl_DrawFunPolyArray (df,VGL_TRISTRIP,4,xtristrip,0,NULL, VGL_NORMAL_3F,vtristrip,0,NULL,0,NULL); /* swap buffers */ vgl_DrawFunSwap (df); vgl_DrawFunDelay (df,.2); } /* wait 5 seconds */ vgl_DrawFunDelay (df,5.); /* close windows */ vgl_DrawFunCloseWindow (df); /* free objects */ vgl_OpenGLDevEnd (opengldev); vgl_DrawFunEnd (df); vgl_XfmEnd (xfm); /* disconnect from X or Windows */ vgl_OpenGLDevDisconnect (); /* close X display */ #ifdef VKI_WIND_X11 XCloseDisplay (display); #endif return 0; }
The superposition of point and line primitives onto polygon primitives requires enabling polygon depth mode to distinctly draw point and line primitives in front of polygons so that no bleeding artifacts occur while rendering.
#include "base/base.h" #include "vgl/vgl.h" /* point data, back face */ static Vfloat xpoints[4][3] = { {-3.,-3.,-3.}, { 3.,-3.,-3.}, {-3., 3.,-3.}, { 3., 3.,-3.} }; static Vfloat vpoints[4][3] = { {0.,0.,-1.}, {0.,0.,-1.}, {0.,0.,-1.}, {0.,0.,-1.} }; /* line data, right face */ static Vfloat xlineloop[4][3] = { {4.,-4.,4.}, { 4.,-4.,-4.}, {4., 4.,-4.}, {4., 4., 4.} }; static Vfloat vlineloop[4][3] = { {1.,0.,0.}, {1.,0.,0.}, {1.,0.,0.}, {1.,0.,0.} }; /* triangle data, front face */ static Vfloat xtristrip[4][3] = { {-5.,-5.,5.}, { 5.,-5.,5.}, {-5., 5.,5.}, { 5.,5.,5.} }; static Vfloat vtristrip[4][3] = { {0.,0.,1.}, {0.,0.,1.}, {0.,0.,1.}, {0.,0.,1.} }; static Vfloat xoutline[4][3] = { {-5.,-5.,5.}, { 5.,-5.,5.}, { 5.,5.,5.}, {-5., 5.,5.} }; /* DC anchor */ static Vfloat xdc[3] = {-3.,-3.,-3.}; /* DC rectangle */ Vint dcrect[4][3] = { {5,5,0}, {50,5,0}, {50,30,0}, {5,30,0} }; Vint dctext[3] = {10,10,0}; /* light properties */ static Vfloat camb[3] = { .3,.3,.3 }; static Vfloat cdis[3] = { .7,.7,.7 }; static Vfloat xdis[3] = { 1.,0.,0. }; /*---------------------------------------------------------------------- Drawing Mixed 3D and "DC" primitives ----------------------------------------------------------------------*/ int main() { Vint i; Vfloat c[3]; Vfloat tm4[4][4]; #ifdef VKI_WIND_X11 Display *display; int screen; #endif vgl_OpenGLDev *opengldev; vgl_DrawFun *df; vgl_Xfm *xfm; /* connect to X or Windows */ #ifdef VKI_WIND_X11 display = XOpenDisplay (0); screen = DefaultScreen (display); vgl_OpenGLDevConnectX (display,screen); #else vgl_OpenGLDevConnectWIN (); #endif /* create drawing functions */ df = vgl_DrawFunBegin(); /* create device objects and load drawing functions */ opengldev = vgl_OpenGLDevBegin(); vgl_OpenGLDevDrawFun (opengldev,df); /* open window */ vgl_DrawFunPositionWindow (df,200,200,400,300); #ifdef VKI_WIND_X11 vgl_DrawFunOpenWindow (df,"X Windows"); #else vgl_DrawFunOpenWindow (df,"Microsoft Windows"); #endif /* set viewing volume to match window aspect ratio */ vgl_DrawFunProjOrtho (df,-13.333,13.333,-10.,10.,-10.,10.); /* set lights */ vgl_DrawFunLight (df,0,VGL_LIGHT_AMBIENT,camb,NULL); vgl_DrawFunLight (df,1,VGL_LIGHT_DISTANT,cdis,xdis); vgl_DrawFunSetMode (df,VGL_LIGHTMODE,VGL_ON); /* enable zbuffering */ vgl_DrawFunSetMode (df,VGL_ZBUFFERMODE,VGL_ON); /* enable polygon offset */ vgl_DrawFunPolygonOffset (df,1.,2.); vgl_DrawFunSetMode (df,VGL_POLYGONDEPTHMODE,VGL_ON); /* create transform object */ xfm = vgl_XfmBegin(); /* clear frame buffer and depth buffers */ for(i = 0; i < 50; i++) { vgl_XfmRotate (xfm,(Vfloat)(3.14159/25.*i),XFM_YAXIS); vgl_XfmGetMatrix (xfm,tm4); vgl_DrawFunXfmLoad (df,tm4); vgl_DrawFunClear (df); /* draw points on corners of back face */ /* set current color to magenta */ c[0] = 1.; c[1] = 0.; c[2] = 1.; vgl_DrawFunColor (df,c); vgl_DrawFunPointSize (df,4); vgl_DrawFunPolyArray (df,VGL_POINTS,4,xpoints,0,NULL, VGL_NORMAL_3F,vpoints,0,NULL,0,NULL); /* draw line loop for right face */ /* set current color to cyan */ c[0] = 0.; c[1] = 1.; c[2] = 1.; vgl_DrawFunColor (df,c); vgl_DrawFunLineWidth (df,2); vgl_DrawFunPolyArray (df,VGL_LINELOOP,4,xlineloop,0,NULL, VGL_NORMAL_3F,vlineloop,0,NULL,0,NULL); /* draw outlined quadrilateral for front face */ /* set current color to white */ c[0] = 1.; c[1] = 1.; c[2] = 1.; vgl_DrawFunColor (df,c); vgl_DrawFunPolyLineArray (df,VGL_LINELOOP,4,xoutline,0,NULL, 0,NULL,0,NULL,0,NULL); /* set current color to yellow */ c[0] = 1.; c[1] = 1.; c[2] = 0.; vgl_DrawFunColor (df,c); vgl_DrawFunPolyArray (df,VGL_TRISTRIP,4,xtristrip,0,NULL, VGL_NORMAL_3F,vtristrip,0,NULL,0,NULL); /* draw a "billboard" using DC primitives */ c[0] = 1.; c[1] = 1.; c[2] = 1.; vgl_DrawFunColor (df,c); vgl_DrawFunLineWidth (df,1); vgl_DrawFunPolyLineDC (df,VGL_LINELOOP,4,xdc,dcrect); c[0] = 1.; c[1] = 0.; c[2] = 0.; vgl_DrawFunColor (df,c); vgl_DrawFunPolygonDC (df,VGL_QUADS,4,xdc,dcrect); c[0] = 1.; c[1] = 1.; c[2] = 1.; vgl_DrawFunColor (df,c); vgl_DrawFunTextDC (df,xdc,dctext,"Text"); /* swap buffers */ vgl_DrawFunSwap (df); vgl_DrawFunDelay (df,.2); } /* wait 5 seconds */ vgl_DrawFunDelay (df,5.); /* close windows */ vgl_DrawFunCloseWindow (df); /* free objects */ vgl_OpenGLDevEnd (opengldev); vgl_DrawFunEnd (df); vgl_XfmEnd (xfm); /* disconnect from X or Windows */ vgl_OpenGLDevDisconnect (); /* close X display */ #ifdef VKI_WIND_X11 XCloseDisplay (display); #endif return 0; }
#include "base/base.h" #include "vgl/vgl.h" /*---------------------------------------------------------------------- Hello World in OpenGLDev ----------------------------------------------------------------------*/ int main() { Vfloat x[3], c[3]; #ifdef VKI_WIND_X11 Display *display; int screen; #endif vgl_OpenGLDev *opengldev; vgl_DrawFun *df; /* connect to X or Windows */ #ifdef VKI_WIND_X11 display = XOpenDisplay (0); screen = DefaultScreen (display); vgl_OpenGLDevConnectX (display,screen); #else vgl_OpenGLDevConnectWIN (); #endif /* create drawing functions */ df = vgl_DrawFunBegin(); /* create device objects and load drawing functions */ opengldev = vgl_OpenGLDevBegin(); vgl_OpenGLDevDrawFun (opengldev,df); /* open windows */ vgl_DrawFunPositionWindow (df,400,400,400,300); #ifdef VKI_WIND_X11 vgl_DrawFunOpenWindow (df,"OpenGL X Windows"); #else vgl_DrawFunOpenWindow (df,"OpenGL Microsoft Windows"); #endif /* draw hello world in raster font */ vgl_DrawFunClear (df); c[0] = 1.; c[1] = 1.; c[2] = 1.; vgl_DrawFunColor (df,c); x[0] = 0.; x[1] = 0.; x[2] = 0.; vgl_DrawFunText (df,x,"Hello World"); vgl_DrawFunSwap (df); /* wait */ vgl_DrawFunDelay (df,10.); /* close windows */ vgl_DrawFunCloseWindow (df); /* free objects */ vgl_OpenGLDevEnd (opengldev); vgl_DrawFunEnd (df); /* disconnect from X or Windows */ vgl_OpenGLDevDisconnect (); /* close X display */ #ifdef VKI_WIND_X11 XCloseDisplay (display); #endif return 0; }
In this example, three RasFont objects are created to hold two built-in fonts and one font loaded from the window system. The X windows font is loaded using vgl_RasFontLoadXFont. The Microsoft Windows font is loaded by first creating an HFONT object and using vgl_RasFontLoadWINFont with the HFONT object as an argument.
The RASFONT_NORMAL7X11 font is scaled by a factor of 2 using vgl_RasFontSetSize. The function vgl_DrawFunRasFontDefine is used to associate a raster font with a raster font index. The RasFont object is copied by this operation. Any subsequent changes to the RasFont object are not detected by the graphics device interface until vgl_DrawFunRasFontDefine is called again with the RasFont object as an argument. Once defined, a raster font may be selected as the current raster font for drawing using vgl_DrawFunRasFontSelect. The default raster font is always raster font index 0 and is predefined.
This example also illustrates drawing the strings to OpenGLDev and X11Dev or GDIDev modules. Set the variable dev to select a device, it is set to 1 (OpenGLDev) by default.
#include "base/base.h" #include "vgl/vgl.h" /*---------------------------------------------------------------------- Hello World ----------------------------------------------------------------------*/ int main() { Vint i; Vfloat x[3], c[3]; Vint italic, weight, length; Vint width, height, offset, base; Vchar fontname[256]; Vfloat path[3], plane[3]; Vint dev; Vchar devname[256]; Vint rasfontnumber, rasfontindices[10]; #ifdef VKI_WIND_X11 Display *display; int screen; #else HFONT hfont; #endif vgl_OpenGLDev *ogldev; vgl_SVGDev *svgdev; #ifdef VKI_WIND_X11 vgl_X11Dev *x11dev; #else vgl_GDIDev *gdidev; #endif vgl_RasFont *rasfont[4]; vgl_DrawFun *df; /* 1 = OpenGLDev, 2 = GDIDev or X11Dev */ /* 4 = SVGDev */ dev = 2; /* connect to X or Windows */ #ifdef VKI_WIND_X11 display = XOpenDisplay (0); screen = DefaultScreen (display); if(dev == 1 || dev == 2) { } if(dev == 1) { vgl_OpenGLDevConnectX (display,screen); } else if(dev == 2) { vgl_X11DevConnectX (display,screen); } #else if(dev == 1) { vgl_OpenGLDevConnectWIN (); } else if(dev == 2) { vgl_GDIDevConnectWIN (); } #endif /* create drawing functions */ df = vgl_DrawFunBegin(); /* create device objects and load drawing functions */ if(dev == 1) { ogldev = vgl_OpenGLDevBegin(); vgl_OpenGLDevDrawFun (ogldev,df); strcpy(devname,"OpenGL"); } else if(dev == 2) { #ifdef VKI_WIND_X11 x11dev = vgl_X11DevBegin(); vgl_X11DevDrawFun (x11dev,df); strcpy(devname,"X11"); #else gdidev = vgl_GDIDevBegin(); vgl_GDIDevDrawFun (gdidev,df); strcpy(devname,"GDI"); #endif } else if(dev == 4) { svgdev = vgl_SVGDevBegin(); vgl_SVGDevDrawFun (svgdev,df); strcpy(devname,"exam3a.svg"); } /* open windows */ vgl_DrawFunPositionWindow (df,200,300,600,450); vgl_DrawFunOpenWindow (df,devname); vgl_DrawFunProjOrtho (df,-1.3333,1.3333,-1.,1.,-1.,1.); /* create raster font object */ rasfont[0] = vgl_RasFontBegin(); vgl_RasFontLoad (rasfont[0],RASFONT_NORMAL7X11); vgl_RasFontSetSize (rasfont[0],2); vgl_DrawFunRasFontDefine (df,1,rasfont[0]); rasfont[1] = vgl_RasFontBegin(); vgl_RasFontLoad (rasfont[1],RASFONT_NORMALBOLD8X14); vgl_DrawFunRasFontDefine (df,2,rasfont[1]); rasfont[2] = vgl_RasFontBegin(); #ifdef VKI_WIND_X11 vgl_RasFontLoadXFont (rasfont[2],display,"9x15"); #else hfont = CreateFont(15,9,0,0,0,0,0,0,0,0,0,0,FIXED_PITCH|FF_DONTCARE,"Arial"); vgl_RasFontSetParami (rasfont[2],RASFONT_ANTIALIAS,SYS_ON); vgl_RasFontLoadWINFont (rasfont[2],hfont); #endif /* query and print some inherent font properties */ vgl_RasFontGetString (rasfont[2],RASFONT_FONTNAME,fontname); vgl_RasFontGetMetrics (rasfont[2],&width,&height,&offset,&base); vgl_RasFontGetInteger (rasfont[2],RASFONT_WEIGHT,&weight); vgl_RasFontGetInteger (rasfont[2],RASFONT_ITALIC,&italic); printf("Font name = %s\n",fontname); printf("width = %d, height= %d\n",width,height); printf("weight= %d\n",weight); printf("italic= %d\n",italic); /* query length of string */ vgl_RasFontLength (rasfont[2],"Hello World",&length); printf("length= %d\n",length); vgl_DrawFunRasFontDefine (df,3,rasfont[2]); /* orientable raster font */ rasfont[3] = vgl_RasFontBegin(); vgl_RasFontLoad (rasfont[3],RASFONT_QUALITY9X13); vgl_RasFontSetParami (rasfont[3],RASFONT_TEXTPLANE,SYS_ON); vgl_RasFontSetParami (rasfont[3],RASFONT_DEVICESIZE,SYS_OFF); vgl_RasFontSetPixelSize (rasfont[3],.01); vgl_DrawFunRasFontDefine (df,4,rasfont[3]); /* query number of raster fonts defined */ /* this query will include the default font index 0 */ vgl_DrawFunGetInteger (df,VGL_RASFONTNUMBER,&rasfontnumber); printf("number of defined raster fonts= %d\n",rasfontnumber); vgl_DrawFunGetInteger (df,VGL_RASFONTINDICES,rasfontindices); printf("indices of defined raster fonts\n"); for(i = 0; i < rasfontnumber; i++) { printf("index= %d\n",rasfontindices[i]); } /* draw text in each raster font */ vgl_DrawFunClear (df); c[0] = 1.; c[1] = 1.; c[2] = 1.; vgl_DrawFunColor (df,c); x[0] = -1.3; x[1] = .8; x[2] = 0.; vgl_DrawFunText (df,x,"Hello World, Default"); vgl_DrawFunRasFontSelect (df,1); x[0] = -1.3; x[1] -= .2; x[2] = 0.; vgl_DrawFunText (df,x,"Hello World, RASFONT_NORMAL7X11"); vgl_DrawFunRasFontSelect (df,2); x[0] = -1.3; x[1] -= .2; x[2] = 0.; vgl_DrawFunText (df,x,"Hello World, RASFONT_NORMALBOLD8X14"); vgl_DrawFunRasFontSelect (df,3); x[0] = -1.3; x[1] -= .2; x[2] = 0.; vgl_DrawFunText (df,x,"Hello World, 9x15"); x[0] = -1.3; x[1] -= .15; x[2] = 0.; vgl_DrawFunText (df,x,"the quick brown fox jumps over the lazy dog"); x[0] = -1.3; x[1] -= .15; x[2] = 0.; vgl_DrawFunText (df,x,"THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG"); x[0] = -1.3; x[1] -= .15; x[2] = 0.; vgl_DrawFunText (df,x,"0123456789 !\"#$%&\\'()*+,-./:;<=>?@[]^_`{|}~"); vgl_DrawFunRasFontSelect (df,4); x[0] = -1.3; x[1] -= .25; x[2] = 0.; path[0] = 2.; path[1] = -.2; path[2] = 0.; plane[0] = 0.; plane[1] = 1.; plane[2] = 0.; vgl_DrawFunTextPlane (df,path,plane); vgl_DrawFunText (df,x,"Hello World, TextPlane"); /* vary anchor */ vgl_DrawFunRasFontSelect (df,0); x[0] = -.5; x[1] -= .25; x[2] = 0.; vgl_DrawFunSetMode (df,VGL_TEXTANCHORMODE,VGL_LEFT); vgl_DrawFunText (df,x,"Hello World, Default"); x[0] = -.5; x[1] -= .08; x[2] = 0.; vgl_DrawFunSetMode (df,VGL_TEXTANCHORMODE,VGL_CENTER); vgl_DrawFunText (df,x,"Hello World, Default"); x[0] = -.5; x[1] -= .08; x[2] = 0.; vgl_DrawFunSetMode (df,VGL_TEXTANCHORMODE,VGL_RIGHT); vgl_DrawFunText (df,x,"Hello World, Default"); vgl_DrawFunSetMode (df,VGL_TEXTANCHORMODE,VGL_BOTTOMLEFT); /* now vertical text */ vgl_DrawFunRasFontSelect (df,2); vgl_DrawFunSetMode (df,VGL_TEXTDIRECTIONMODE,VGL_TOP); x[0] = 1.; x[1] = -.8; x[2] = 0.; vgl_DrawFunText (df,x,"Hello World, vertical RASFONT_NORMALBOLD8X14"); vgl_DrawFunSwap (df); /* wait */ vgl_DrawFunDelay (df,10.); /* close windows */ vgl_DrawFunCloseWindow (df); /* free objects */ if(dev == 1) { vgl_OpenGLDevEnd (ogldev); } else if(dev == 2) { #ifdef VKI_WIND_X11 vgl_X11DevEnd (x11dev); #else vgl_GDIDevEnd (gdidev); #endif } else if(dev == 4) { vgl_SVGDevEnd (svgdev); } vgl_DrawFunEnd (df); vgl_RasFontEnd (rasfont[0]); vgl_RasFontEnd (rasfont[1]); vgl_RasFontEnd (rasfont[2]); vgl_RasFontEnd (rasfont[3]); /* disconnect */ if(dev == 1) { vgl_OpenGLDevDisconnect (); } else if(dev == 2) { #ifdef VKI_WIND_X11 vgl_X11DevDisconnect (); #else vgl_GDIDevDisconnect (); #endif } /* clean up */ #ifdef VKI_WIND_X11 XCloseDisplay (display); #else DeleteObject (hfont); #endif return 0; }
The string variable euro contains the Euro symbol and is drawn in a wide character font which contains the symbol.
This example also illustrates drawing the strings to OpenGLDev, X11Dev and RendBuf modules. Set the variable dev to select a device, it is set to 1 (OpenGLDev) by default.
#include "base/base.h" #include "vgl/vgl.h" #include <stdio.h> #include <wchar.h> /*---------------------------------------------------------------------- Hello World, Wide Characters ----------------------------------------------------------------------*/ int main() { Vfloat x[3], c[3]; Vint italic, weight, length; Vfloat path[3], plane[3]; static wchar_t euro[] = { L'U',L'n',L'i',L'c',L'o',L'd',L'e',L' ',L'E',L'u',L'r',L'o',L'=',L' ', 0x20ac,L'\0'}; Vint dev; Vchar ftfile[256]; Vint scalableflag, ierr; #ifdef VKI_WIND_X11 Display *display; int screen; vgl_X11Dev *x11dev; #else HFONT hfont; vgl_GDIDev *gdidev; #endif vgl_OpenGLDev *ogldev; vgl_RendBuf *rendbuf; vgl_FBuffer *fbuffer; vgl_RasFont *rasfont[4], *rasft; vgl_DrawFun *df; /* 0= RendBuf, 1= OpenGLDev, 2= X11Dev or GDIDev */ dev = 1; /* connect to X or Windows */ #ifdef VKI_WIND_X11 display = XOpenDisplay (0); screen = DefaultScreen (display); if(dev == 1) { vgl_OpenGLDevConnectX (display,screen); } else if(dev == 2) { vgl_X11DevConnectX (display,screen); } #else if(dev == 1) { vgl_OpenGLDevConnectWIN (); } else if(dev == 2) { vgl_GDIDevConnectWIN (); } #endif /* create drawing functions */ df = vgl_DrawFunBegin(); /* create device objects and load drawing functions */ if(dev == 1) { ogldev = vgl_OpenGLDevBegin(); vgl_OpenGLDevDrawFun (ogldev,df); } else if(dev == 2) { #ifdef VKI_WIND_X11 x11dev = vgl_X11DevBegin(); vgl_X11DevDrawFun (x11dev,df); #else gdidev = vgl_GDIDevBegin(); vgl_GDIDevDrawFun (gdidev,df); #endif } else if(dev == 0) { rendbuf = vgl_RendBufBegin(); vgl_RendBufDrawFun (rendbuf,df); } /* open windows */ vgl_DrawFunPositionWindow (df,400,400,480,360); if(dev == 1) { vgl_DrawFunOpenWindow (df,"OpenGL Window"); } else if(dev == 2) { #ifdef VKI_WIND_X11 vgl_DrawFunOpenWindow (df,"X11 Window"); #else vgl_DrawFunOpenWindow (df,"GDI Window"); #endif } else if(dev == 0) { vgl_DrawFunOpenWindow (df,"RendBuf Window"); } vgl_DrawFunProjOrtho (df,-1.3333,1.3333,-1.,1.,-1.,1.); /* create raster font object */ rasfont[0] = vgl_RasFontBegin(); vgl_RasFontLoad (rasfont[0],RASFONT_NORMAL7X11); vgl_DrawFunRasFontDefine (df,1,rasfont[0]); rasfont[1] = vgl_RasFontBegin(); vgl_RasFontLoad (rasfont[1],RASFONT_NORMALBOLD8X14); vgl_DrawFunRasFontDefine (df,2,rasfont[1]); rasfont[2] = vgl_RasFontBegin(); #ifdef VKI_WIND_X11 vgl_RasFontLoadXFont (rasfont[2],display, "-adobe-courier-bold-o-normal--14-100-100-100-m-90-iso10646-1"); /* if can not find font, try another */ if(vgl_RasFontError(rasfont[2])) { vgl_RasFontLoadXFont (rasfont[2],display, "-bitstream-bitstream charter-bold-i-normal--0-0-0-0-p-0-iso10646-1"); } #else hfont = CreateFont(15,9,0,0,0,0,0,0,0,0,0,0,FIXED_PITCH|FF_DONTCARE, TEXT("Arial")); vgl_RasFontLoadWINFont (rasfont[2],hfont); #endif /* query and print some inherent font properties */ vgl_RasFontGetInteger (rasfont[2],RASFONT_WEIGHT,&weight); vgl_RasFontGetInteger (rasfont[2],RASFONT_ITALIC,&italic); printf("weight= %d\n",weight); printf("italic= %d\n",italic); /* set size */ vgl_RasFontSetSize (rasfont[2],2); vgl_DrawFunRasFontDefine (df,3,rasfont[2]); /* orientable raster font */ rasfont[3] = vgl_RasFontBegin(); vgl_RasFontLoad (rasfont[3],RASFONT_QUALITY9X13); vgl_RasFontSetParami (rasfont[3],RASFONT_TEXTPLANE,SYS_ON); vgl_RasFontSetParami (rasfont[3],RASFONT_DEVICESIZE,SYS_OFF); vgl_RasFontSetPixelSize (rasfont[3],.01); vgl_DrawFunRasFontDefine (df,4,rasfont[3]); /* draw hello world in each raster font */ vgl_DrawFunClear (df); c[0] = 1.; c[1] = 1.; c[2] = 1.; vgl_DrawFunColor (df,c); x[0] = -.8; x[1] = 0.; x[2] = 0.; vgl_DrawFunText (df,x,L"Hello World, Default"); vgl_DrawFunRasFontSelect (df,1); x[0] = -.8; x[1] = -.1; x[2] = 0.; vgl_DrawFunText (df,x,L"Hello World, RASFONT_NORMAL7X11"); vgl_DrawFunRasFontSelect (df,2); x[0] = -.8; x[1] = -.2; x[2] = 0.; vgl_DrawFunText (df,x,L"Hello World, RASFONT_NORMALBOLD8X14"); vgl_DrawFunRasFontSelect (df,3); x[0] = -.8; x[1] = -.4; x[2] = 0.; /* query length of string */ vgl_RasFontLength (rasfont[2],euro,&length); printf("length= %d\n",length); vgl_DrawFunText (df,x,euro); vgl_DrawFunRasFontSelect (df,4); x[0] = -.8; x[1] = -.6; x[2] = 0.; path[0] = 2.; path[1] = -.2; path[2] = 0.; plane[0] = 0.; plane[1] = 1.; plane[2] = 0.; vgl_DrawFunTextPlane (df,path,plane); vgl_DrawFunText (df,x,L"Hello World, TextPlane"); vgl_DrawFunRasFontSelect (df,0); x[0] = -.8; x[1] = -.8; x[2] = 0.; vgl_DrawFunText (df,x,L"Hello World, Default"); /* create freetype raster font */ rasft = vgl_RasFontBegin(); strcpy(ftfile,"../fonts/DejaVuSerif-Bold.ttf"); strcpy(ftfile,"../fonts/OpenSans-Regular.ttf"); strcpy(ftfile,"/tmp/arial.ttf"); vgl_RasFontFreeTypeParam (rasft,ftfile,RASFONT_FREETYPE_SCALABLE, &scalableflag); ierr = vgl_RasFontError (rasfont[0]); if(ierr) { printf("Error loading FreeType file, %s\n",ftfile); scalableflag = 0; } c[0] = 0.; c[1] = 1.; c[2] = 1.; vgl_DrawFunColor (df,c); if(scalableflag) { vgl_RasFontLoadFreeType (rasft,14,ftfile); vgl_DrawFunRasFontDefine (df,1,rasft); vgl_DrawFunRasFontSelect (df,1); x[0] = -.8; x[1] = .6; x[2] = 0.; vgl_DrawFunText (df,x,L"FreeType scalable"); x[0] = -.8; x[1] = .5; x[2] = 0.; vgl_DrawFunText (df,x,euro); } vgl_RasFontEnd (rasft); vgl_DrawFunSwap (df); /* write out image */ if(dev == 0) { fbuffer = vgl_FBufferBegin (); vgl_DrawFunFBufferRead (df,0,0,0,0,fbuffer); vgl_FBufferWriteGIF (fbuffer,"exam3b.gif"); vgl_FBufferEnd (fbuffer); } /* wait */ vgl_DrawFunDelay (df,10.); /* close windows */ vgl_DrawFunCloseWindow (df); /* free objects */ if(dev == 1) { vgl_OpenGLDevEnd (ogldev); } else if(dev == 2) { #ifdef VKI_WIND_X11 vgl_X11DevEnd (x11dev); #else vgl_GDIDevEnd (gdidev); #endif } else if(dev == 0) { vgl_RendBufEnd (rendbuf); } vgl_DrawFunEnd (df); vgl_RasFontEnd (rasfont[0]); vgl_RasFontEnd (rasfont[1]); vgl_RasFontEnd (rasfont[2]); vgl_RasFontEnd (rasfont[3]); /* disconnect */ if(dev == 1) { vgl_OpenGLDevDisconnect (); } else if(dev == 2) { #ifdef VKI_WIND_X11 vgl_X11DevDisconnect (); #else vgl_GDIDevDisconnect (); #endif } /* clean up */ #ifdef VKI_WIND_X11 XCloseDisplay (display); #else DeleteObject (hfont); #endif return 0; }
#include <windows.h> #include "base/base.h" #include "vgl/vgl.h" LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); /*---------------------------------------------------------------------- Drawing Hello World in OpenGL and GDI to a Pixmap ----------------------------------------------------------------------*/ int main() { WNDCLASS wc; HWND hWnd; HDC hDC; MSG msg; BOOL quit = FALSE; HINSTANCE hInstance; vgl_OpenGLDev *opengldev; vgl_DrawFun *df; Vfloat c[3], x[3]; Vint iparams[4]; char stg[33]; int len, iref; COLORREF textcolor, backcolor; hInstance = GetModuleHandle (NULL); /* register window class */ wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon(NULL,IDI_APPLICATION); wc.hCursor = LoadCursor(NULL,IDC_ARROW); wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); wc.lpszMenuName = NULL; wc.lpszClassName = "exam3c"; RegisterClass( &wc ); /* create window */ hWnd = CreateWindow ("exam17","exam17", WS_OVERLAPPEDWINDOW|WS_CLIPSIBLINGS|WS_CLIPCHILDREN, 0,0,400,400, NULL,NULL,hInstance,NULL); ShowWindow (hWnd,SW_SHOWDEFAULT); /* get window device context */ hDC = GetDC (hWnd); vgl_OpenGLDevConnectWIN (); /* create drawing functions */ df = vgl_DrawFunBegin(); /* create device objects and load drawing functions */ opengldev = vgl_OpenGLDevBegin(); vgl_OpenGLDevDrawFun (opengldev,df); /* set visual for generic bitmap */ vgl_OpenGLDevVisualWindow (opengldev,VGL_VISUAL_PIXMAP|VGL_VISUAL_GENERIC); /* configure origin and size */ iparams[0] = 0; iparams[1] = 0; iparams[2] = 400; iparams[3] = 400; vgl_OpenGLDevConfigureWindow (opengldev,VGL_WINDOWORIGINSIZE,iparams); vgl_OpenGLDevConnectWindow (opengldev,(Vword)hDC); vgl_DrawFunProjOrtho (df,-1.,1.,-1.,1.,-1.,1.); /* count number of updates */ iref = 0; /* program loop */ while(!quit) { /* check for messages */ if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) { /* handle or dispatch messages */ if(msg.message == WM_QUIT) { quit = TRUE; } else { TranslateMessage(&msg); DispatchMessage(&msg); } } else { iref += 1; vgl_DrawFunClear (df); /* draw text in white using OpenGL */ c[0] = 1.; c[1] = 1.; c[2] = 1.; vgl_DrawFunColor (df,c); x[0] = 0.; x[1] = 0.; x[2] = 0.; vgl_DrawFunText (df,x,"Hello World OpenGL"); vgl_DrawFunFlush (df); /* draw text in red using GDI */ sprintf(stg,"Hello World GDI %d",iref); len = (int)strlen(stg); backcolor = RGB(255,255,255); textcolor = RGB(255,0,0); SetBkColor (hDC,backcolor); SetTextColor (hDC,textcolor); TextOut (hDC,30,30,stg,len); ShowWindow (hWnd,SW_SHOWDEFAULT); /* wait a second */ vgl_DrawFunDelay (df,1.); /* only let it go on for 100 iterations */ if(iref == 100) break; } } DestroyWindow (hWnd); return msg.wParam; } LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_CREATE: return 0; case WM_CLOSE: PostQuitMessage(0); return 0; case WM_DESTROY: return 0; case WM_KEYDOWN: switch (wParam) { case VK_ESCAPE: PostQuitMessage(0); return 0; } return 0; default: return DefWindowProc( hWnd, message, wParam, lParam ); } }
This example also illustrates drawing the strings to OpenGLDev, X11Dev and RendBuf modules. Set the variable dev to select a device, it is set to 1 (OpenGLDev) by default.
#include "base/base.h" #include "vgl/vgl.h" /*---------------------------------------------------------------------- Drawing Hello World with FreeType ----------------------------------------------------------------------*/ int main(int argc, char **argv) { Vint i; Vfloat x[3], c[3]; Vint dev; Vchar devname[256]; Vint numfixed, scalableflag, (*fixed)[2]; Vchar fontfile[256]; Vint ierr; #ifdef VKI_WIND_X11 Display *display; int screen; #else HFONT hfont; #endif vgl_OpenGLDev *ogldev; vgl_SVGDev *svgdev; vgl_RendBuf *rendbuf; #ifdef VKI_WIND_X11 vgl_X11Dev *x11dev; #else vgl_GDIDev *gdidev; #endif vgl_RasFont *rasfont[4]; vgl_DrawFun *df; vgl_FBuffer *fbuffer; /* check input arguments */ if(argc < 2) { fprintf(stderr,"Usage: %s fontfile\n",argv[0]); fprintf(stderr," fontfile is blank, '../fonts/DejaVuSerif-Bold.ttf' is assumed\n"); strcpy(fontfile,"../fonts/DejaVuSerif-Bold.ttf"); } else { strcpy(fontfile,argv[1]); } /* 0 = RendBuf, 1 = OpenGLDev, 2 = GDIDev or X11Dev, 4 = SVGDev */ dev = 0; /* connect to X or Windows */ #ifdef VKI_WIND_X11 if(dev == 1 || dev == 2) { display = XOpenDisplay (0); screen = DefaultScreen (display); } if(dev == 1) { vgl_OpenGLDevConnectX (display,screen); } else if(dev == 2) { vgl_X11DevConnectX (display,screen); } #else if(dev == 1) { vgl_OpenGLDevConnectWIN (); } else if(dev == 2) { vgl_GDIDevConnectWIN (); } #endif /* create drawing functions */ df = vgl_DrawFunBegin(); /* create device objects and load drawing functions */ if(dev == 0) { rendbuf = vgl_RendBufBegin(); vgl_RendBufDrawFun (rendbuf,df); strcpy(devname,"exam3d.bmp"); } else if(dev == 1) { ogldev = vgl_OpenGLDevBegin(); vgl_OpenGLDevDrawFun (ogldev,df); strcpy(devname,"OpenGL"); } else if(dev == 2) { #ifdef VKI_WIND_X11 x11dev = vgl_X11DevBegin(); vgl_X11DevDrawFun (x11dev,df); strcpy(devname,"X11"); #else gdidev = vgl_GDIDevBegin(); vgl_GDIDevDrawFun (gdidev,df); strcpy(devname,"GDI"); #endif } else if(dev == 4) { svgdev = vgl_SVGDevBegin(); vgl_SVGDevDrawFun (svgdev,df); strcpy(devname,"exam3d.svg"); } /* open windows */ vgl_DrawFunPositionWindow (df,200,300,600,450); vgl_DrawFunOpenWindow (df,devname); vgl_DrawFunProjOrtho (df,-1.3333,1.3333,-1.,1.,-1.,1.); /* create raster font object */ rasfont[0] = vgl_RasFontBegin(); /* query for font parameters */ vgl_RasFontFreeTypeParam (rasfont[0],fontfile,RASFONT_FREETYPE_NUMFIXED, &numfixed); ierr = vgl_RasFontError (rasfont[0]); if(ierr) { printf("Error loading FreeType file, %s\n",fontfile); return 1; } printf("numfixed= %d\n",numfixed); vgl_RasFontFreeTypeParam (rasfont[0],fontfile,RASFONT_FREETYPE_SCALABLE, &scalableflag); printf("scalableflag= %d\n",scalableflag); /* load fixed font */ if(numfixed) { fixed = (Vint(*)[2])malloc(2*numfixed*sizeof(Vint)); vgl_RasFontFixedFreeType (rasfont[0],fontfile,fixed); for(i = 0; i < numfixed; i++) { printf("width= %d, height= %d\n",fixed[i][0],fixed[i][1]); } /* load first fixed font */ vgl_RasFontLoadFixedFreeType (rasfont[0],fixed[0][1],fontfile); free(fixed); /* load scalable font */ } else { vgl_RasFontLoadFreeType (rasfont[0],16,fontfile); } vgl_DrawFunRasFontDefine (df,1,rasfont[0]); vgl_DrawFunRasFontSelect (df,1); vgl_DrawFunClear (df); c[0] = 1.; c[1] = 1.; c[2] = 1.; vgl_DrawFunColor (df,c); /* draw a pinwheel of strings */ vgl_DrawFunSetMode (df,VGL_TEXTANCHORMODE,VGL_LEFT); x[0] = .0; x[1] = 0.; x[2] = 0.; vgl_DrawFunSetMode (df,VGL_TEXTDIRECTIONMODE,VGL_RIGHT); vgl_DrawFunText (df,x,"Hello World, FREETYPE"); vgl_DrawFunSetMode (df,VGL_TEXTDIRECTIONMODE,VGL_LEFT); vgl_DrawFunText (df,x,"Hello World, FREETYPE"); vgl_DrawFunSetMode (df,VGL_TEXTDIRECTIONMODE,VGL_TOP); vgl_DrawFunText (df,x,"Hello World, FREETYPE"); vgl_DrawFunSetMode (df,VGL_TEXTDIRECTIONMODE,VGL_BOTTOM); vgl_DrawFunText (df,x,"Hello World, FREETYPE"); vgl_DrawFunSwap (df); if(dev == 0) { fbuffer = vgl_FBufferBegin (); vgl_DrawFunFBufferRead (df,0,0,0,0,fbuffer); vgl_FBufferWriteBMP (fbuffer,devname); vgl_FBufferEnd (fbuffer); } /* wait */ vgl_DrawFunDelay (df,10.); /* close windows */ vgl_DrawFunCloseWindow (df); /* free objects */ if(dev == 0) { vgl_RendBufEnd (rendbuf); } else if(dev == 1) { vgl_OpenGLDevEnd (ogldev); } else if(dev == 2) { #ifdef VKI_WIND_X11 vgl_X11DevEnd (x11dev); #else vgl_GDIDevEnd (gdidev); #endif } else if(dev == 4) { vgl_SVGDevEnd (svgdev); } vgl_DrawFunEnd (df); vgl_RasFontEnd (rasfont[0]); /* disconnect */ if(dev == 1) { vgl_OpenGLDevDisconnect (); } else if(dev == 2) { #ifdef VKI_WIND_X11 vgl_X11DevDisconnect (); #else vgl_GDIDevDisconnect (); #endif } /* clean up */ #ifdef VKI_WIND_X11 if(dev == 1 || dev == 2) { XCloseDisplay (display); } #else DeleteObject (hfont); #endif return 0; }
A drawing function object and device object is created for each of the devices. The drawing function objects, dfxw and dfgl are loaded with function pointers by vgl_X11DevDrawFun or vgl_GDIDevDrawFun and vgl_OpenGLDevDrawFun respectively. At this point all further drawing and control of the devices are handled through the appropriate drawing function.
Window dimensions are requested and two windows are opened. A Gouraud shaded triangle is drawn to each device, the system waits 10 seconds, closes each window and terminates.
#include "base/base.h" #include "vgl/vgl.h" static void draw_triangle(vgl_DrawFun *df); static Vfloat xtri[3][3] = { {0.,.5,0.}, {.5,-.5,0.}, {-.5,-.5,0.} }; static Vfloat ctri[3][3] = { {1.,0.,0.}, {0.,1.,0.}, {0.,0.,1.} }; /*---------------------------------------------------------------------- Draw a Gouraud shaded triangle ----------------------------------------------------------------------*/ int main() { #ifdef VKI_WIND_X11 Display *display; int screen; #endif #ifdef VKI_WIND_X11 vgl_X11Dev *x11dev; #else vgl_GDIDev *gdidev; #endif vgl_OpenGLDev *ogldev; vgl_DrawFun *dfgl, *dfxw; vgl_DrawFun *df; /* connect to X or Windows*/ #ifdef VKI_WIND_X11 display = XOpenDisplay (0); screen = DefaultScreen (display); vgl_X11DevConnectX (display,screen); vgl_OpenGLDevConnectX (display,screen); #else vgl_GDIDevConnectWIN (); vgl_OpenGLDevConnectWIN (); #endif /* create drawing functions */ dfgl = vgl_DrawFunBegin(); dfxw = vgl_DrawFunBegin(); /* create device objects and load drawing functions */ #ifdef VKI_WIND_X11 x11dev = vgl_X11DevBegin(); vgl_X11DevDrawFun (x11dev,dfxw); #else gdidev = vgl_GDIDevBegin(); vgl_GDIDevDrawFun (gdidev,dfxw); #endif ogldev = vgl_OpenGLDevBegin(); vgl_OpenGLDevDrawFun (ogldev,dfgl); /* open windows and file */ vgl_DrawFunPositionWindow (dfxw,100,100,300,200); vgl_DrawFunOpenWindow (dfxw,"System window"); vgl_DrawFunPositionWindow (dfgl,400,400,400,300); vgl_DrawFunOpenWindow (dfgl,"OpenGL window"); /* draw to X11 window first */ df = dfxw; draw_triangle (df); /* draw to OpenGL window second */ df = dfgl; draw_triangle (df); /* wait */ vgl_DrawFunDelay (df,10.); /* close windows and file */ vgl_DrawFunCloseWindow (dfxw); vgl_DrawFunCloseWindow (dfgl); /* disconnect and free objects */ #ifdef VKI_WIND_X11 vgl_X11DevEnd (x11dev); vgl_X11DevDisconnect (); #else vgl_GDIDevEnd (gdidev); vgl_GDIDevDisconnect (); #endif vgl_OpenGLDevEnd (ogldev); vgl_OpenGLDevDisconnect (); vgl_DrawFunEnd (dfgl); vgl_DrawFunEnd (dfxw); /* close X display */ #ifdef VKI_WIND_X11 XCloseDisplay (display); #endif return 0; } static void draw_triangle(vgl_DrawFun *df) { Vfloat c[3]; /* draw triangle */ vgl_DrawFunSetWindow (df); vgl_DrawFunClear (df); vgl_DrawFunPolygonColor (df,VGL_POLYGON,3,xtri,ctri,VGL_NOSHADE,NULL); c[0] = 1.; c[1] = 1.; c[2] = 1.; vgl_DrawFunColor (df,c); vgl_DrawFunPolyLine (df,VGL_LINELOOP,3,xtri); vgl_DrawFunSwap (df); }
In this example, the FBuffer object is used to read and write the entire contents of the X window. In general however, a FBuffer object supports reading and writing of any sub-rectangle of a graphics device.
#include "base/base.h" #include "vgl/vgl.h" static void draw_triangle(vgl_DrawFun *df); static Vfloat xtri[3][3] = { {0.,.5,0.}, {.5,-.5,0.}, {-.5,-.5,0.} }; static Vfloat ctri[3][3] = { {1.,0.,0.}, {0.,1.,0.}, {0.,0.,1.} }; /*---------------------------------------------------------------------- Draw a Gouraud shaded triangle ----------------------------------------------------------------------*/ int main() { #ifdef VKI_WIND_X11 Display *display; int screen; #endif #ifdef VKI_WIND_X11 vgl_X11Dev *x11dev; #else vgl_GDIDev *gdidev; #endif vgl_OpenGLDev *ogldev; vgl_FBuffer *fbuffer; vgl_DrawFun *dfgl, *dfxw; vgl_DrawFun *df; /* connect to X or Windows*/ #ifdef VKI_WIND_X11 display = XOpenDisplay (0); screen = DefaultScreen (display); vgl_X11DevConnectX (display,screen); vgl_OpenGLDevConnectX (display,screen); #else vgl_GDIDevConnectWIN (); vgl_OpenGLDevConnectWIN (); #endif /* create drawing functions */ dfgl = vgl_DrawFunBegin(); dfxw = vgl_DrawFunBegin(); /* create device objects and load drawing functions */ #ifdef VKI_WIND_X11 x11dev = vgl_X11DevBegin(); vgl_X11DevDrawFun (x11dev,dfxw); #else gdidev = vgl_GDIDevBegin(); vgl_GDIDevDrawFun (gdidev,dfxw); #endif ogldev = vgl_OpenGLDevBegin(); vgl_OpenGLDevDrawFun (ogldev,dfgl); /* create fbuffer object */ fbuffer = vgl_FBufferBegin (); /* open windows and file */ vgl_DrawFunPositionWindow (dfxw,100,100,300,200); vgl_DrawFunOpenWindow (dfxw,"System window"); vgl_DrawFunPositionWindow (dfgl,400,400,300,200); vgl_DrawFunOpenWindow (dfgl,"OpenGL window"); /* draw to System window */ df = dfxw; draw_triangle (df); vgl_DrawFunFBufferRead (df,0,0,0,0,fbuffer); /* write fbuffer to OpenGL window */ df = dfgl; vgl_DrawFunSetWindow (df); vgl_DrawFunClear (df); vgl_DrawFunFBufferWrite (df,0,0,0,0,fbuffer); vgl_DrawFunSwap (df); /* write fbuffer to a .gif file */ vgl_FBufferWriteGIF (fbuffer,"exam4a.gif"); /* wait */ vgl_DrawFunDelay (df,5.); /* close windows and file */ vgl_DrawFunCloseWindow (dfxw); vgl_DrawFunCloseWindow (dfgl); /* disconnect and free objects */ #ifdef VKI_WIND_X11 vgl_X11DevEnd (x11dev); vgl_X11DevDisconnect (); #else vgl_GDIDevEnd (gdidev); vgl_GDIDevDisconnect (); #endif vgl_OpenGLDevEnd (ogldev); vgl_OpenGLDevDisconnect (); vgl_DrawFunEnd (dfgl); vgl_DrawFunEnd (dfxw); vgl_FBufferEnd (fbuffer); /* close X display */ #ifdef VKI_WIND_X11 XCloseDisplay (display); #endif return 0; } static void draw_triangle(vgl_DrawFun *df) { Vfloat c[3]; /* draw triangle */ vgl_DrawFunSetWindow (df); vgl_DrawFunClear (df); vgl_DrawFunPolygonColor (df,VGL_POLYGON,3,xtri,ctri,VGL_NOSHADE,NULL); c[0] = 1.; c[1] = 1.; c[2] = 1.; vgl_DrawFunColor (df,c); vgl_DrawFunPolyLine (df,VGL_LINELOOP,3,xtri); vgl_DrawFunSwap (df); }
The cone is first drawn with no lighting in its basic 50% gray color. After a 5 second wait, it begins rotating to the right. The normal to the cone is directed radially outward so that the right hand surface of the cone initially produces diffuse and specular reflections from the distant light source. The left side of the cone does not reflect light from the distant light since its normal vector is always pointing away from the light. Note that as the cone rotates through 90 degrees, the backside of the right hand surface only produces diffuse reflections. This is the result of the normal vector pointing away from the viewer. The cone is drawn using a Quadric object.
#include "base/base.h" #include "vgl/vgl.h" static void draw_cone(vgl_DrawFun *df, vgl_Quadric *qu, Vfloat r, Vfloat h, Vint n); /* light properties */ static Vfloat camb[3] = { .5,.5,.5 }; static Vfloat cdis[3] = { .5,.5,.5 }; static Vfloat xdis[3] = { 1.,0.,0. }; /*---------------------------------------------------------------------- Draw a rotating, light source shaded cone ----------------------------------------------------------------------*/ int main() { int i; Vfloat tm4[4][4]; #ifdef VKI_WIND_X11 Display *display; int screen; #endif vgl_OpenGLDev *ogldev; vgl_Quadric *qu; vgl_DrawFun *df; vgl_Xfm *xfm; /* open X display */ #ifdef VKI_WIND_X11 display = XOpenDisplay (0); screen = DefaultScreen (display); vgl_OpenGLDevConnectX (display,screen); #else vgl_OpenGLDevConnectWIN (); #endif /* create drawing functions */ df = vgl_DrawFunBegin(); /* create device objects and load drawing functions */ ogldev = vgl_OpenGLDevBegin(); vgl_OpenGLDevDrawFun (ogldev,df); /* open window */ vgl_DrawFunPositionWindow (df,400,400,400,300); vgl_DrawFunOpenWindow (df,"OpenGL window"); /* set viewing volume to match window aspect ratio */ vgl_DrawFunProjOrtho (df,-1.3333,1.3333,-1.,1.,-1.,1.); /* turn on zbuffering */ vgl_DrawFunSetMode (df,VGL_ZBUFFERMODE,VGL_ON); /* generate quadric for drawing cone */ qu = vgl_QuadricBegin (); vgl_QuadricSetObject (qu,VGL_DRAWFUN,df); /* create transform object */ xfm = vgl_XfmBegin(); /* draw without lighting */ vgl_DrawFunClear (df); draw_cone (df,qu,.4,.6,17); vgl_DrawFunSwap (df); vgl_DrawFunDelay (df,1.); /* set lights */ vgl_DrawFunLight (df,0,VGL_LIGHT_AMBIENT,camb,NULL); vgl_DrawFunLight (df,1,VGL_LIGHT_DISTANT,cdis,xdis); vgl_DrawFunSetMode (df,VGL_LIGHTMODE,VGL_ON); /* rotate about y axis */ for(i = 0; i <= 25; i++) { vgl_DrawFunClear (df); vgl_XfmRotate (xfm,(Vfloat)(3.14159/25.*i),XFM_YAXIS); vgl_XfmGetMatrix (xfm,tm4); vgl_DrawFunXfmLoad (df,tm4); draw_cone (df,qu,.4,.6,17); vgl_DrawFunSwap (df); vgl_DrawFunDelay (df,1.); } vgl_DrawFunDelay (df,5.); /* free transform object */ vgl_XfmEnd (xfm); /* close window */ vgl_DrawFunCloseWindow (df); /* free objects */ vgl_OpenGLDevEnd (ogldev); vgl_DrawFunEnd (df); vgl_QuadricEnd (qu); /* disconnect from X */ vgl_OpenGLDevDisconnect (); /* close X display */ #ifdef VKI_WIND_X11 XCloseDisplay (display); #endif return 0; } /*---------------------------------------------------------------------- draw cone ----------------------------------------------------------------------*/ static void draw_cone(vgl_DrawFun *df, vgl_Quadric *qu, Vfloat r, Vfloat h, Vint n) { Vfloat c[3]; c[0] = .5; c[1] = .5; c[2] = .5; vgl_DrawFunColor (df,c); vgl_DrawFunSpecularity (df,.5,10.); vgl_QuadricSetParami (qu,QUADRIC_SLICES,n); vgl_QuadricSetParami (qu,QUADRIC_STACKS,2); vgl_QuadricCylinder (qu,r,0.,h); }
#include "base/base.h" #include "vgl/vgl.h" static void draw_cone(vgl_DrawFun *df, vgl_Quadric *qu, Vfloat r, Vfloat h, Vint n); /* light properties */ static Vfloat camb[3] = { .5,.5,.5 }; static Vfloat cdis[3] = { .5,.5,.5 }; static Vfloat xdis[3] = { 1.,0.,0. }; /*---------------------------------------------------------------------- Draw a rotating, light source shaded cone ----------------------------------------------------------------------*/ int main() { int i; Vfloat tm4[4][4]; Vfloat c[3]; #ifdef VKI_WIND_X11 Display *display; int screen; #endif vgl_DList *dlist; vgl_OpenGLDev *ogldev; vgl_Quadric *qu; vgl_DrawFun *dfGL, *dfDL; vgl_Xfm *xfm; #ifdef VKI_WIND_X11 display = XOpenDisplay (0); screen = DefaultScreen (display); vgl_OpenGLDevConnectX (display,screen); #else vgl_OpenGLDevConnectWIN (); #endif /* create GL device and drawing functions */ ogldev = vgl_OpenGLDevBegin(); dfGL = vgl_DrawFunBegin(); vgl_OpenGLDevDrawFun (ogldev,dfGL); /* create display list and drawing functions */ dlist = vgl_DListBegin(); dfDL = vgl_DrawFunBegin(); vgl_DListDrawFun (dlist,dfDL); /* set GL drawing functions in display list object */ vgl_DListSetObject(dlist,VGL_DRAWFUN,dfGL); /* open window */ vgl_DrawFunPositionWindow (dfGL,400,400,400,300); vgl_DrawFunOpenWindow (dfGL,"OpenGL window"); /* set viewing volume to match window aspect ratio */ vgl_DrawFunProjOrtho (dfGL,-1.3333,1.3333,-1.,1.,-1.,1.); /* turn on zbuffering */ vgl_DrawFunSetMode (dfGL,VGL_ZBUFFERMODE,VGL_ON); /* generate quadric for drawing cone */ qu = vgl_QuadricBegin (); vgl_QuadricSetObject (qu,VGL_DRAWFUN,dfDL); /* create transform object */ xfm = vgl_XfmBegin(); /* draw without lighting */ vgl_DrawFunClear (dfGL); draw_cone (dfDL,qu,.4,.6,17); vgl_DListCall (dlist); vgl_DrawFunSwap (dfGL); vgl_DrawFunDelay (dfGL,1.); /* set lights */ vgl_DrawFunLight (dfGL,0,VGL_LIGHT_AMBIENT,camb,NULL); vgl_DrawFunLight (dfGL,1,VGL_LIGHT_DISTANT,cdis,xdis); vgl_DrawFunSetMode (dfGL,VGL_LIGHTMODE,VGL_ON); /* rotate about y axis */ for(i = 0; i <= 25; i++) { vgl_DrawFunClear (dfGL); vgl_XfmRotate (xfm,(Vfloat)(3.14159/25.*i),XFM_YAXIS); vgl_XfmGetMatrix (xfm,tm4); vgl_DrawFunXfmLoad (dfGL,tm4); if(i == 7) { vgl_DListSetRendering (dlist,0,0,1); } if(i == 13) { vgl_DListSetLineWidth (dlist,VGL_ON,3); } if(i == 19) { vgl_DListSetRendering (dlist,0,0,0); vgl_DListSetLineWidth (dlist,VGL_OFF,1); c[0] = 1.; c[1] = 0.; c[2] = 0.; vgl_DListSetColor (dlist,VGL_ON,c); } vgl_DListCall (dlist); vgl_DrawFunSwap (dfGL); vgl_DrawFunDelay (dfGL,1.); } vgl_DrawFunDelay (dfGL,5.); /* free transform object */ vgl_XfmEnd (xfm); /* close window */ vgl_DrawFunCloseWindow (dfGL); /* free objects */ vgl_OpenGLDevEnd (ogldev); vgl_DrawFunEnd (dfGL); vgl_DListEnd (dlist); vgl_DrawFunEnd (dfDL); vgl_QuadricEnd (qu); /* disconnect from X */ vgl_OpenGLDevDisconnect (); /* close X display */ #ifdef VKI_WIND_X11 XCloseDisplay (display); #endif return 0; } /*---------------------------------------------------------------------- draw cone ----------------------------------------------------------------------*/ static void draw_cone(vgl_DrawFun *df, vgl_Quadric *qu, Vfloat r, Vfloat h, Vint n) { Vfloat c[3]; c[0] = .5; c[1] = .5; c[2] = .5; vgl_DrawFunColor (df,c); vgl_DrawFunSpecularity (df,.5,10.); vgl_QuadricSetParami (qu,QUADRIC_SLICES,n); vgl_QuadricSetParami (qu,QUADRIC_STACKS,2); vgl_QuadricCylinder (qu,r,0.,h); }
#include "base/base.h" #include "vgl/vgl.h" static void draw_cone(vgl_DrawFun *df, vgl_Quadric *qu, Vfloat r, Vfloat h, Vint n); /* light properties */ static Vfloat camb[3] = { .5,.5,.5 }; static Vfloat cdis[3] = { .5,.5,.5 }; static Vfloat xdis[3] = { 1.,0.,0. }; /*---------------------------------------------------------------------- Draw a rotating, light source shaded cylinder ----------------------------------------------------------------------*/ int main() { int i; Vfloat tm4[4][4]; Vfloat xamb[3]; #ifdef VKI_WIND_X11 Display *display; int screen; #endif vgl_DFile *dfile; vgl_OpenGLDev *ogldev; vgl_Quadric *qu; vgl_DrawFun *dfGL, *dfDF; vgl_Xfm *xfm; #ifdef VKI_WIND_X11 display = XOpenDisplay (0); screen = DefaultScreen (display); vgl_OpenGLDevConnectX (display,screen); #else vgl_OpenGLDevConnectWIN (); #endif /* create GL device and drawing functions */ ogldev = vgl_OpenGLDevBegin(); dfGL = vgl_DrawFunBegin(); vgl_OpenGLDevDrawFun (ogldev,dfGL); /* create display file and drawing functions */ dfile = vgl_DFileBegin(); dfDF = vgl_DrawFunBegin(); vgl_DFileDrawFun (dfile,dfDF); /* set GL drawing functions in display file object */ vgl_DFileSetObject(dfile,VGL_DRAWFUN,dfGL); /* specify display file format and file name */ vgl_DFileSetFileType (dfile,DFILE_ASCII); vgl_DFileSetFileType (dfile,DFILE_BINARY); vgl_DFileSetFileName (dfile,"exam.dfile"); /* open window */ vgl_DrawFunPositionWindow (dfGL,400,400,400,300); vgl_DrawFunOpenWindow (dfGL,"OpenGL window"); /* set viewing volume to match window aspect ratio */ vgl_DrawFunProjOrtho (dfGL,-1.3333,1.3333,-1.,1.,-1.,1.); /* turn on zbuffering */ vgl_DrawFunSetMode (dfGL,VGL_ZBUFFERMODE,VGL_ON); /* generate quadric for drawing cone */ qu = vgl_QuadricBegin (); vgl_QuadricSetObject (qu,VGL_DRAWFUN,dfDF); /* create transform object */ xfm = vgl_XfmBegin(); /* draw without lighting */ vgl_DrawFunClear (dfGL); vgl_DFileOpen (dfile); draw_cone (dfDF,qu,.4,.6,17); vgl_DFileClose (dfile); vgl_DFileRead (dfile); vgl_DrawFunSwap (dfGL); vgl_DrawFunDelay (dfGL,1.); /* set lights */ vgl_DrawFunLight (dfGL,0,VGL_LIGHT_AMBIENT,camb,xamb); vgl_DrawFunLight (dfGL,1,VGL_LIGHT_DISTANT,cdis,xdis); vgl_DrawFunSetMode (dfGL,VGL_LIGHTMODE,VGL_ON); /* rotate about y axis */ for(i = 0; i <= 25; i++) { vgl_DrawFunClear (dfGL); vgl_XfmRotate (xfm,(Vfloat)(3.14159/25.*i),XFM_YAXIS); vgl_XfmGetMatrix (xfm,tm4); vgl_DrawFunXfmLoad (dfGL,tm4); vgl_DFileRead (dfile); vgl_DrawFunSwap (dfGL); vgl_DrawFunDelay (dfGL,1.); } vgl_DrawFunDelay (dfGL,5.); /* free transform object */ vgl_XfmEnd (xfm); /* close window */ vgl_DrawFunCloseWindow (dfGL); /* free objects */ vgl_OpenGLDevEnd (ogldev); vgl_DrawFunEnd (dfGL); vgl_DFileEnd (dfile); vgl_DrawFunEnd (dfDF); vgl_QuadricEnd (qu); /* disconnect from X */ vgl_OpenGLDevDisconnect (); /* close X display */ #ifdef VKI_WIND_X11 XCloseDisplay (display); #endif return 0; } /*---------------------------------------------------------------------- draw cone ----------------------------------------------------------------------*/ static void draw_cone(vgl_DrawFun *df, vgl_Quadric *qu, Vfloat r, Vfloat h, Vint n) { Vfloat c[3]; c[0] = .5; c[1] = .5; c[2] = .5; vgl_DrawFunColor (df,c); vgl_DrawFunSpecularity (df,.5,10.); vgl_QuadricSetParami (qu,QUADRIC_SLICES,n); vgl_QuadricSetParami (qu,QUADRIC_STACKS,2); vgl_QuadricCylinder (qu,r,0.,h); }
The IActor object is prepared for object manipulation by setting the drawing function object for the display device as an attribute object and registering a display callback function which is invoked by the IActor object whenever the graphics display must be redrawn. In this example the 3 mouse buttons and control key are used to implement a total of 6 dragger actions. If the control key is not depressed; the left, middle and right mouse buttons provide for trackball rotation, translation and scaling respectively. If the control key is depressed the same mouse buttons are used for "rate" rotation, windowing and an alternate form of windowing which uses a free-hand form. A simple polling scheme is used to manage graphics input. An important point to note is that the use of IActor module is independent of the graphics input management. This allows the module to be integrated into the central event or message loop of the host application in a straight forward way. It is only necessary to call vgl_IActorDrag with a user supplied action, drag stage and cursor location.
The function vgl_IActorFit is used to set the projection viewing volume so that the cone object comfortably fills the graphics window. The function vgl_IActorSpin is called repeatedly if no dragger action is in effect. This reapplies the last rotation each time it is called causing the cone to spin. Depressing the shift key exits the program.
#include "base/base.h" #include "vgl/vgl.h" static void generate_cone(vgl_DrawFun *df, vgl_Quadric *qu, Vfloat r, Vfloat h, Vint n); static void draw_display(vgl_IActor *iactor, vgl_DList *dlist); /* light properties */ static Vfloat camb[3] = { .5,.5,.5 }; static Vfloat cdis[3] = { .5,.5,.5 }; static Vfloat xdis[3] = { 1.,0.,0. }; static Vfloat xopp[3] = { -1.,0.,0. }; static Vint butact[2][3] = { {IACTOR_TRACKBALL, IACTOR_TRANSLATE, IACTOR_SCALE}, {IACTOR_ROTATE, IACTOR_WINDOW, IACTOR_SQUIGGLE} }; /*---------------------------------------------------------------------- Draw a rotating, light source shaded cone ----------------------------------------------------------------------*/ int main() { int i; Vint ix, iy, but[3]; Vint ibut, icnt; Vint shft, cntl; #ifdef VKI_WIND_X11 Display *display; int screen; #endif vgl_OpenGLDev *ogldev; vgl_DList *dlist; vgl_Quadric *qu; vgl_DrawFun *dfGL; vgl_DrawFun *dfDL; vgl_IActor *iactor; /* open X display */ #ifdef VKI_WIND_X11 display = XOpenDisplay (0); screen = DefaultScreen (display); vgl_OpenGLDevConnectX (display,screen); #else vgl_OpenGLDevConnectWIN (); #endif /* create drawing functions */ dfGL = vgl_DrawFunBegin(); /* create device objects and load drawing functions */ ogldev = vgl_OpenGLDevBegin(); vgl_OpenGLDevDrawFun (ogldev,dfGL); /* open window */ vgl_DrawFunPositionWindow (dfGL,400,400,400,300); vgl_DrawFunOpenWindow (dfGL,"OpenGL window"); /* set viewing volume to match window aspect ratio */ vgl_DrawFunProjOrtho (dfGL,-1.3333,1.3333,-1.,1.,-1.,1.); /* turn on zbuffering */ vgl_DrawFunSetMode (dfGL,VGL_ZBUFFERMODE,VGL_ON); /* set lights */ vgl_DrawFunLight (dfGL,0,VGL_LIGHT_AMBIENT,camb,NULL); vgl_DrawFunLight (dfGL,1,VGL_LIGHT_DISTANT,cdis,xdis); vgl_DrawFunLight (dfGL,2,VGL_LIGHT_DISTANT,cdis,xopp); vgl_DrawFunSetMode (dfGL,VGL_LIGHTMODE,VGL_ON); /* create display list and drawing functions */ dlist = vgl_DListBegin(); dfDL = vgl_DrawFunBegin(); vgl_DListDrawFun (dlist,dfDL); /* set GL drawing functions in display list object */ vgl_DListSetObject(dlist,VGL_DRAWFUN,dfGL); /* generate quadric for drawing cone */ qu = vgl_QuadricBegin (); vgl_QuadricSetObject (qu,VGL_DRAWFUN,dfDL); /* instance IActor */ iactor = vgl_IActorBegin (); vgl_IActorSetObject (iactor,VGL_DRAWFUN,dfGL); /* set display callback */ vgl_IActorSetFunction (iactor,IACTOR_FUN_DISPLAY, (void(*)(vgl_IActor*,Vobject*))draw_display,dlist); /* generate display */ generate_cone (dfDL, qu,.4,.6,17); /* fit display to viewport */ vgl_IActorFit (iactor,NULL); /* implement a simple mouse polling loop */ while (1) { ibut = -1; icnt = 0; /* detect button press */ while (ibut == -1) { vgl_DrawFunPollMouse (dfGL,&ix,&iy,&but[0],&but[1],&but[2]); for(i = 0; i < 3; i++) { if(but[i]) { ibut = i; vgl_IActorDrag (iactor,butact[icnt][ibut],VGL_DRAG_INIT,ix,iy); break; } } /* jump out if shift key depressed */ vgl_DrawFunPollModifiers (dfGL,&cntl,&shft); if(shft) { goto done; } if(cntl) { icnt = 1; } else { icnt = 0; } /* spin while waiting */ if(ibut == -1) { vgl_IActorSpin (iactor,NULL); } } /* wait for button release */ while (ibut != -1) { vgl_DrawFunPollMouse (dfGL,&ix,&iy,&but[0],&but[1],&but[2]); if(but[ibut]) { vgl_IActorDrag (iactor,butact[icnt][ibut],VGL_DRAG_MOVE,ix,iy); } else { vgl_IActorDrag (iactor,butact[icnt][ibut],VGL_DRAG_TERM,ix,iy); ibut = -1; } } } /* jump point for exiting polling loop */ done:; /* close window */ vgl_DrawFunCloseWindow (dfGL); /* free objects */ vgl_OpenGLDevEnd (ogldev); vgl_DrawFunEnd (dfGL); vgl_DListEnd (dlist); vgl_DrawFunEnd (dfDL); vgl_IActorEnd (iactor); vgl_QuadricEnd (qu); /* disconnect from X */ vgl_OpenGLDevDisconnect (); /* close X display */ #ifdef VKI_WIND_X11 XCloseDisplay (display); #endif return 0; } /*---------------------------------------------------------------------- generate graphics primitive for cone ----------------------------------------------------------------------*/ static void generate_cone(vgl_DrawFun *df, vgl_Quadric *qu, Vfloat r, Vfloat h, Vint n) { Vfloat c[3]; /* color and specularity */ c[0] = .5; c[1] = .5; c[2] = .5; vgl_DrawFunColor (df,c); vgl_DrawFunSpecularity (df,.5,10.); /* polygons */ vgl_QuadricSetParami (qu,QUADRIC_SLICES,n); vgl_QuadricSetParami (qu,QUADRIC_STACKS,2); vgl_QuadricCylinder (qu,r,0.,h); } /*---------------------------------------------------------------------- display callback ----------------------------------------------------------------------*/ static void draw_display(vgl_IActor *iactor, vgl_DList *dlist) { Vint iparams[2]; Vint rflag; vgl_DrawFun *dfGL; Vfloat cbot[3] = {.4,.4,.4}; Vfloat ctop[3] = {0.,0.,.12}; vgl_IActorGetObject (iactor,VGL_DRAWFUN,(Vobject**)&dfGL); /* get render mode */ vgl_DrawFunGetInteger (dfGL,VGL_RENDERMODE,iparams); rflag = iparams[0]; /* clear graphics screen */ vgl_DrawFunClear (dfGL); /* do not include in "Fit" operation */ if(rflag == 0) { vgl_IActorDrawBackground (iactor,cbot,ctop); vgl_IActorDrawTrackBall (iactor); } /* draw contents of display list */ vgl_DListCall (dlist); /* swap graphics buffers */ vgl_DrawFunSwap (dfGL); }
The popup menu generated in this example contains examples of a title, toggle items, radio box items and one-shot items. The Popup and IActor modules together allow the user to implement a set of user object manipulation and display styles.
#include "base/base.h" #include "vgl/vgl.h" static void draw_cone(vgl_DrawFun *df, vgl_Quadric *qu, Vfloat r, Vfloat h, Vint n); static void draw_display(vgl_IActor *iactor, vgl_Quadric *qu); static void popup_callback(vgl_Popup *popup, vgl_IActor *iactor); /* light properties */ static Vfloat camb[3] = { .5,.5,.5 }; static Vfloat cdis[3] = { .5,.5,.5 }; static Vfloat xdis[3] = { 1.,0.,0. }; /* custom drop background from gray to dark blue */ static Vfloat cbot[3] = { .5,.5,.5 }; static Vfloat ctop[3] = { 0.,0.,.16 }; static Vint butaction[3] = { IACTOR_TRACKBALL, IACTOR_TRANSLATE, IACTOR_SCALE }; static Vint trackballflag; static Vint rotcenterflag = 1; static Vint fancybackflag; static Vint subdivisions = 17; /*---------------------------------------------------------------------- Draw a rotating, light source shaded cone ----------------------------------------------------------------------*/ int main() { int i; Vint ix, iy, but[3]; Vint ibut; Vint shft, cntl; #ifdef VKI_WIND_X11 Display *display; int screen; #endif vgl_OpenGLDev *ogldev; vgl_Quadric *qu; vgl_DrawFun *df; vgl_IActor *iactor; vgl_Popup *popup; #ifdef VKI_WIND_X11 display = XOpenDisplay (0); screen = DefaultScreen (display); vgl_OpenGLDevConnectX (display,screen); #else vgl_OpenGLDevConnectWIN (); #endif /* create drawing functions */ df = vgl_DrawFunBegin(); /* create device objects and load drawing functions */ ogldev = vgl_OpenGLDevBegin(); vgl_OpenGLDevDrawFun (ogldev,df); /* open window */ vgl_DrawFunPositionWindow (df,400,400,480,360); vgl_DrawFunOpenWindow (df,"OpenGL window"); /* set viewing volume to match window aspect ratio */ vgl_DrawFunProjOrtho (df,-1.3333,1.3333,-1.,1.,-1.,1.); /* turn on zbuffering */ vgl_DrawFunSetMode (df,VGL_ZBUFFERMODE,VGL_ON); /* set lights */ vgl_DrawFunLight (df,0,VGL_LIGHT_AMBIENT,camb,NULL); vgl_DrawFunLight (df,1,VGL_LIGHT_DISTANT,cdis,xdis); vgl_DrawFunSetMode (df,VGL_LIGHTMODE,VGL_ON); /* generate quadric for drawing cone */ qu = vgl_QuadricBegin (); vgl_QuadricSetObject (qu,VGL_DRAWFUN,df); /* instance IActor and set drawing functions */ iactor = vgl_IActorBegin (); vgl_IActorSetObject (iactor,VGL_DRAWFUN,df); /* set display callback */ vgl_IActorSetFunction (iactor,IACTOR_FUN_DISPLAY, (void(*)(vgl_IActor*,Vobject*))draw_display,qu); /* instance Popup and set drawing functions */ popup = vgl_PopupBegin(); vgl_PopupSetObject (popup,VGL_DRAWFUN,df); /* title */ vgl_PopupTitle (popup,"Display"); /* define contents of popup from top to bottom */ /* toggles */ vgl_PopupAddToggle (popup,1,"Trackball", (void(*)(vgl_Popup*,Vobject*))popup_callback,iactor); vgl_PopupAddToggle (popup,2,"Rotation Center", (void(*)(vgl_Popup*,Vobject*))popup_callback,iactor); vgl_PopupSetToggle (popup,2,rotcenterflag); vgl_PopupAddToggle (popup,3,"Fancy Background", (void(*)(vgl_Popup*,Vobject*))popup_callback,iactor); vgl_PopupAddToggle (popup,4,"Divisions Inactive", (void(*)(vgl_Popup*,Vobject*))popup_callback,iactor); vgl_PopupAddLine (popup); /* radio box */ vgl_PopupAddRadio (popup,5,1,"17 divisions", (void(*)(vgl_Popup*,Vobject*))popup_callback,iactor); vgl_PopupAddRadio (popup,5,2,"37 divisions", (void(*)(vgl_Popup*,Vobject*))popup_callback,iactor); vgl_PopupAddRadio (popup,5,3,"77 divisions", (void(*)(vgl_Popup*,Vobject*))popup_callback,iactor); vgl_PopupAddLine (popup); /* one-shot item */ vgl_PopupAddItem (popup,6,"Fit", (void(*)(vgl_Popup*,Vobject*))popup_callback,iactor); /* fit display to viewport */ vgl_IActorFit (iactor,NULL); /* implement a simple mouse polling loop */ while (1) { ibut = -1; /* detect button press */ while (ibut == -1) { vgl_DrawFunPollMouse (df,&ix,&iy,&but[0],&but[1],&but[2]); for(i = 0; i < 3; i++) { if(but[i]) { ibut = i; vgl_IActorDrag (iactor,butaction[ibut],VGL_DRAG_INIT,ix,iy); break; } } /* detect modifiers */ vgl_DrawFunPollModifiers (df,&cntl,&shft); /* done */ if(shft) { goto done; } /* popup menu */ if(cntl) { vgl_DrawFunPollMouse (df,&ix,&iy,&but[0],&but[1],&but[2]); vgl_PopupDrag (popup,VGL_DRAG_INIT,ix,iy); while (1) { vgl_DrawFunPollModifiers (df,&cntl,&shft); vgl_DrawFunPollMouse (df,&ix,&iy,&but[0],&but[1],&but[2]); if(cntl) { vgl_PopupDrag (popup,VGL_DRAG_MOVE,ix,iy); } else { vgl_PopupDrag (popup,VGL_DRAG_TERM,ix,iy); break; } } } /* spin while waiting */ if(ibut == -1) { vgl_IActorSpin (iactor,NULL); } } /* wait for button release */ while (ibut != -1) { vgl_DrawFunPollMouse (df,&ix,&iy,&but[0],&but[1],&but[2]); if(but[ibut]) { vgl_IActorDrag (iactor,butaction[ibut],VGL_DRAG_MOVE,ix,iy); } else { vgl_IActorDrag (iactor,butaction[ibut],VGL_DRAG_TERM,ix,iy); ibut = -1; } } } /* jump point for exiting polling loop */ done:; /* close window */ vgl_DrawFunCloseWindow (df); /* free objects */ vgl_OpenGLDevEnd (ogldev); vgl_DrawFunEnd (df); vgl_IActorEnd (iactor); vgl_PopupEnd (popup); vgl_QuadricEnd (qu); /* disconnect from X */ vgl_OpenGLDevDisconnect (); /* close X display */ #ifdef VKI_WIND_X11 XCloseDisplay (display); #endif return 0; } /*---------------------------------------------------------------------- draw cone ----------------------------------------------------------------------*/ static void draw_cone(vgl_DrawFun *df, vgl_Quadric *qu, Vfloat r, Vfloat h, Vint n) { Vfloat c[3]; c[0] = .5; c[1] = .5; c[2] = .5; vgl_DrawFunColor (df,c); vgl_DrawFunSpecularity (df,.5,10.); vgl_QuadricSetParami (qu,QUADRIC_SLICES,n); vgl_QuadricSetParami (qu,QUADRIC_STACKS,2); vgl_QuadricCylinder (qu,r,0.,h); } /*---------------------------------------------------------------------- display callback ----------------------------------------------------------------------*/ static void draw_display(vgl_IActor *iactor, vgl_Quadric *qu) { vgl_DrawFun *df; vgl_IActorGetObject (iactor,VGL_DRAWFUN,(Vobject**)&df); vgl_DrawFunClear (df); /* be sure to draw background first */ if(fancybackflag) { vgl_IActorDrawBackground (iactor,cbot,ctop); } if(trackballflag) { vgl_IActorDrawTrackBall (iactor); } if(rotcenterflag) { vgl_IActorDrawRotCenter (iactor,50); } draw_cone (df,qu,.4,.6,subdivisions); vgl_DrawFunSwap (df); } /*---------------------------------------------------------------------- popup callback ----------------------------------------------------------------------*/ static void popup_callback(vgl_Popup *popup, vgl_IActor *iactor) { Vint index, value; /* get item index */ vgl_PopupGetIndex (popup,&index); /* check item index */ if(index == 1) { vgl_PopupGetToggle (popup,index,&trackballflag); } else if(index == 2) { vgl_PopupGetToggle (popup,index,&rotcenterflag); } else if(index == 3) { vgl_PopupGetToggle (popup,index,&fancybackflag); } else if(index == 4) { vgl_PopupGetToggle (popup,index,&value); vgl_PopupSetActive (popup,5,!value); } else if(index == 5) { vgl_PopupGetRadio (popup,index,&value); if(value == 1) { subdivisions = 17; } else if(value == 2) { subdivisions = 37; } else if(value == 3) { subdivisions = 77; } } else if(index == 6) { vgl_IActorFit (iactor,NULL); } }
Rendering to an off-screen frame buffer in OpenGL is implemented in the buffer_cone function and requires using vgl_DrawFunRender to set the rendering mode to VGL_BUFFER_COLOR. The window size is queried and doubled and the off-screen buffer size is set using vgl_DrawFunBufferSize. The scene is rendered by calling vgl_IActorDisplay. The image is then read into a FBuffer object using vgl_DrawFunFBufferRead and the render mode is returned to standard rendering to the hardware frame buffer using vgl_DrawFunRender.
Rendering to a software frame buffer using RendBuf is illustrated in the function rendbuf_cone. Current attributes of the OpenGL device are queried and then specified in the RendBuf object. The window size for this example is doubled in each direction. The current projection and modelview matrix are installed. The lighting which was specified to the OpenGL device is also specified to RendBuf. Any relevant modes are queried and set in RendBuf. Then the drawing function to RendBuf is set in the IActor object and the display callback is invoked with vgl_IActorDisplay. The graphics will then be drawn to the RendBuf device rather than the OpenGL device. The internal FBuffer in RendBuf is queried using vgl_RendBufGetFBuffer. Finally the original drawing function to the OpenGL window is reset in IActor.
#include "base/base.h" #include "vgl/vgl.h" static void draw_cone(vgl_DrawFun *df, vgl_Quadric *qu, Vfloat r, Vfloat h, Vint n); static void draw_display(vgl_IActor *iactor, vgl_Quadric *qu); static void popup_callback(vgl_Popup *popup, vgl_IActor *iactor); static void rendbuf_cone(vgl_IActor *iactor); static void buffer_cone(vgl_IActor *iactor); /* light properties */ static Vfloat camb[3] = { .5,.5,.5 }; static Vfloat cdis[3] = { .5,.5,.5 }; static Vfloat xdis[3] = { 1.,0.,0. }; /* custom drop background from gray to dark blue */ static Vfloat cbot[3] = { .5,.5,.5 }; static Vfloat ctop[3] = { 0.,0.,.16 }; static Vint butaction[3] = { IACTOR_TRACKBALL, IACTOR_TRANSLATE, IACTOR_WINDOW }; static Vint trackballflag; static Vint rotcenterflag = 1; static Vint fancybackflag; static Vint subdivisions = 17; static Vint exitflag = 0; /*---------------------------------------------------------------------- Off-Screen Rendering ----------------------------------------------------------------------*/ int main() { int i; Vint ix, iy, but[3]; Vint ibut; Vint shft, cntl; #ifdef VKI_WIND_X11 Display *display; int screen; #endif vgl_OpenGLDev *ogldev; vgl_Quadric *qu; vgl_DrawFun *df; vgl_IActor *iactor; vgl_Popup *popup; #ifdef VKI_WIND_X11 display = XOpenDisplay (0); screen = DefaultScreen (display); vgl_OpenGLDevConnectX (display,screen); #else vgl_OpenGLDevConnectWIN (); #endif /* create drawing functions */ df = vgl_DrawFunBegin(); /* create device objects and load drawing functions */ ogldev = vgl_OpenGLDevBegin(); vgl_OpenGLDevDrawFun (ogldev,df); /* open window */ vgl_DrawFunPositionWindow (df,400,400,480,360); vgl_DrawFunOpenWindow (df,"OpenGL window"); /* set viewing volume to match window aspect ratio */ vgl_DrawFunProjOrtho (df,-1.3333,1.3333,-1.,1.,-1.,1.); /* turn on zbuffering */ vgl_DrawFunSetMode (df,VGL_ZBUFFERMODE,VGL_ON); /* set lights */ vgl_DrawFunLight (df,0,VGL_LIGHT_AMBIENT,camb,NULL); vgl_DrawFunLight (df,1,VGL_LIGHT_DISTANT,cdis,xdis); vgl_DrawFunSetMode (df,VGL_LIGHTMODE,VGL_ON); /* generate quadric for drawing cone */ qu = vgl_QuadricBegin (); /* instance IActor and set drawing functions */ iactor = vgl_IActorBegin (); vgl_IActorSetObject (iactor,VGL_DRAWFUN,df); /* set display callback */ vgl_IActorSetFunction (iactor,IACTOR_FUN_DISPLAY, (void(*)(vgl_IActor*,Vobject*))draw_display,qu); /* instance Popup and set drawing functions */ popup = vgl_PopupBegin(); vgl_PopupSetObject (popup,VGL_DRAWFUN,df); /* title */ vgl_PopupTitle (popup,"Display"); /* define contents of popup from top to bottom */ /* toggles */ vgl_PopupAddToggle (popup,1,"Trackball", (void(*)(vgl_Popup*,Vobject*))popup_callback,iactor); vgl_PopupAddToggle (popup,2,"Rotation Center", (void(*)(vgl_Popup*,Vobject*))popup_callback,iactor); vgl_PopupSetToggle (popup,2,rotcenterflag); vgl_PopupAddToggle (popup,3,"Fancy Background", (void(*)(vgl_Popup*,Vobject*))popup_callback,iactor); vgl_PopupAddToggle (popup,4,"Divisions Inactive", (void(*)(vgl_Popup*,Vobject*))popup_callback,iactor); vgl_PopupAddLine (popup); /* radio box */ vgl_PopupAddRadio (popup,5,1,"17 divisions", (void(*)(vgl_Popup*,Vobject*))popup_callback,iactor); vgl_PopupAddRadio (popup,5,2,"37 divisions", (void(*)(vgl_Popup*,Vobject*))popup_callback,iactor); vgl_PopupAddRadio (popup,5,3,"77 divisions", (void(*)(vgl_Popup*,Vobject*))popup_callback,iactor); vgl_PopupAddLine (popup); /* one-shot item */ vgl_PopupAddItem (popup,6,"Fit", (void(*)(vgl_Popup*,Vobject*))popup_callback,iactor); vgl_PopupAddItem (popup,7,"RendBuf", (void(*)(vgl_Popup*,Vobject*))popup_callback,iactor); vgl_PopupAddItem (popup,8,"Buffer", (void(*)(vgl_Popup*,Vobject*))popup_callback,iactor); vgl_PopupAddLine (popup); vgl_PopupAddItem (popup,9,"Exit", (void(*)(vgl_Popup*,Vobject*))popup_callback,iactor); /* fit display to viewport */ vgl_IActorFit (iactor,NULL); /* implement a simple mouse polling loop */ while (1) { ibut = -1; /* detect button press */ while (ibut == -1) { vgl_DrawFunPollMouse (df,&ix,&iy,&but[0],&but[1],&but[2]); for(i = 0; i < 3; i++) { if(but[i]) { ibut = i; vgl_IActorDrag (iactor,butaction[ibut],VGL_DRAG_INIT,ix,iy); break; } } /* detect modifiers */ vgl_DrawFunPollModifiers (df,&cntl,&shft); /* done */ if(shft) { goto done; } /* popup menu */ if(cntl) { vgl_DrawFunPollMouse (df,&ix,&iy,&but[0],&but[1],&but[2]); vgl_PopupDrag (popup,VGL_DRAG_INIT,ix,iy); while (1) { vgl_DrawFunPollModifiers (df,&cntl,&shft); vgl_DrawFunPollMouse (df,&ix,&iy,&but[0],&but[1],&but[2]); if(cntl) { vgl_PopupDrag (popup,VGL_DRAG_MOVE,ix,iy); } else { vgl_PopupDrag (popup,VGL_DRAG_TERM,ix,iy); break; } } if(exitflag) { goto done; } } /* spin while waiting */ if(ibut == -1) { vgl_IActorSpin (iactor,NULL); } } /* wait for button release */ while (ibut != -1) { vgl_DrawFunPollMouse (df,&ix,&iy,&but[0],&but[1],&but[2]); if(but[ibut]) { vgl_IActorDrag (iactor,butaction[ibut],VGL_DRAG_MOVE,ix,iy); } else { vgl_IActorDrag (iactor,butaction[ibut],VGL_DRAG_TERM,ix,iy); ibut = -1; } } } /* jump point for exiting polling loop */ done:; /* close window */ vgl_DrawFunCloseWindow (df); /* free objects */ vgl_OpenGLDevEnd (ogldev); vgl_DrawFunEnd (df); vgl_IActorEnd (iactor); vgl_PopupEnd (popup); vgl_QuadricEnd (qu); /* disconnect from X */ vgl_OpenGLDevDisconnect (); /* close X display */ #ifdef VKI_WIND_X11 XCloseDisplay (display); #endif return 0; } /*---------------------------------------------------------------------- draw cone ----------------------------------------------------------------------*/ static void draw_cone(vgl_DrawFun *df, vgl_Quadric *qu, Vfloat r, Vfloat h, Vint n) { Vfloat c[3]; c[0] = .5; c[1] = .5; c[2] = .5; vgl_DrawFunColor (df,c); vgl_DrawFunSpecularity (df,.5,10.); vgl_QuadricSetObject (qu,VGL_DRAWFUN,df); vgl_QuadricSetParami (qu,QUADRIC_LINE,VGL_ON); vgl_QuadricSetParami (qu,QUADRIC_SLICES,n); vgl_QuadricSetParami (qu,QUADRIC_STACKS,2); vgl_QuadricCylinder (qu,r,0.,h); } /*---------------------------------------------------------------------- display callback ----------------------------------------------------------------------*/ static void draw_display(vgl_IActor *iactor, vgl_Quadric *qu) { vgl_DrawFun *df; vgl_IActorGetObject (iactor,VGL_DRAWFUN,(Vobject**)&df); vgl_DrawFunClear (df); /* be sure to draw background first */ if(fancybackflag) { vgl_IActorDrawBackground (iactor,cbot,ctop); } if(trackballflag) { vgl_IActorDrawTrackBall (iactor); } if(rotcenterflag) { vgl_IActorDrawRotCenter (iactor,50); } draw_cone (df,qu,.4,.6,subdivisions); vgl_DrawFunSwap (df); } /*---------------------------------------------------------------------- popup callback ----------------------------------------------------------------------*/ static void popup_callback(vgl_Popup *popup, vgl_IActor *iactor) { Vint index, value; vgl_DrawFun *df; vgl_IActorGetObject (iactor,VGL_DRAWFUN,(Vobject**)&df); /* get item index */ vgl_PopupGetIndex (popup,&index); /* check item index */ if(index == 1) { vgl_PopupGetToggle (popup,index,&trackballflag); } else if(index == 2) { vgl_PopupGetToggle (popup,index,&rotcenterflag); } else if(index == 3) { vgl_PopupGetToggle (popup,index,&fancybackflag); } else if(index == 4) { vgl_PopupGetToggle (popup,index,&value); vgl_PopupSetActive (popup,5,!value); } else if(index == 5) { vgl_PopupGetRadio (popup,index,&value); if(value == 1) { subdivisions = 17; } else if(value == 2) { subdivisions = 37; } else if(value == 3) { subdivisions = 77; } } else if(index == 6) { vgl_IActorFit (iactor,NULL); } else if(index == 7) { rendbuf_cone (iactor); } else if(index == 8) { buffer_cone (iactor); } else if(index == 9) { exitflag = 1; } } /*---------------------------------------------------------------------- draw to RendBuf ----------------------------------------------------------------------*/ static void rendbuf_cone(vgl_IActor *iactor) { vgl_RendBuf *rendbuf; vgl_DrawFun *dfrb; vgl_FBuffer *fbuffer; vgl_DrawFun *df; Vint ip[4]; Vint projtype; Vfloat fp[6], tm[16]; Vint mode; /* get device drawing function */ vgl_IActorGetObject (iactor,VGL_DRAWFUN,(Vobject**)&df); /* create software rendering objects */ dfrb = vgl_DrawFunBegin (); rendbuf = vgl_RendBufBegin (); /* install drawing functions */ vgl_RendBufDrawFun (rendbuf,dfrb); /* open software window twice as large as device window */ vgl_DrawFunGetInteger (df,VGL_WINDOWSIZE,ip); vgl_DrawFunPositionWindow (dfrb,0,0,2*ip[0],2*ip[1]); vgl_DrawFunOpenWindow (dfrb,"RendBuf"); /* set lights */ vgl_DrawFunLight (dfrb,0,VGL_LIGHT_AMBIENT,camb,NULL); vgl_DrawFunLight (dfrb,1,VGL_LIGHT_DISTANT,cdis,xdis); /* set modes */ vgl_DrawFunGetMode (df,VGL_ZBUFFERMODE,&mode); vgl_DrawFunSetMode (dfrb,VGL_ZBUFFERMODE,mode); vgl_DrawFunGetMode (df,VGL_LIGHTMODE,&mode); vgl_DrawFunSetMode (dfrb,VGL_LIGHTMODE,mode); /* get depth range */ vgl_DrawFunGetFloat (df,VGL_DEPTHRANGE,fp); vgl_DrawFunDepthRange (dfrb,fp[0],fp[1]); /* get modelview matrix */ vgl_DrawFunGetFloat (df,VGL_MODELVIEWMATRIX,tm); vgl_DrawFunXfmLoad (dfrb,(Vfloat(*)[4])tm); /* get projection */ vgl_DrawFunGetInteger (df,VGL_PROJECTIONTYPE,&projtype); vgl_DrawFunGetFloat (df,VGL_PROJECTIONLIMITS,fp); if(projtype == VGL_PROJORTHO) { vgl_DrawFunProjOrtho (dfrb,fp[0],fp[1],fp[2],fp[3],fp[4],fp[5]); } else { vgl_DrawFunProjFrustum (dfrb,fp[0],fp[1],fp[2],fp[3],fp[4],fp[5]); } /* set software drawing functions in IActor */ vgl_IActorSetObject (iactor,VGL_DRAWFUN,dfrb); /* invoke display callback */ vgl_IActorDisplay (iactor,NULL); /* get image buffer */ vgl_RendBufGetFBuffer (rendbuf,&fbuffer); /* write image in gif format to file */ vgl_FBufferWriteBMP (fbuffer,"exam5eRendBuf.bmp"); printf("exam5eRendBuf.bmp written\n"); /* destroy software rendering objects */ vgl_DrawFunEnd (dfrb); vgl_RendBufEnd (rendbuf); /* restore device drawing function */ vgl_IActorSetObject (iactor,VGL_DRAWFUN,df); } /*---------------------------------------------------------------------- draw to color buffer ----------------------------------------------------------------------*/ static void buffer_cone(vgl_IActor *iactor) { vgl_FBuffer *fbuffer; vgl_DrawFun *df; Vint ip[2]; /* get device drawing function */ vgl_IActorGetObject (iactor,VGL_DRAWFUN,(Vobject**)&df); /* allocate FBuffer to hold final image */ fbuffer = vgl_FBufferBegin(); /* turn on off-screen rendering to color buffer */ vgl_DrawFunRender (df,VGL_BUFFER_COLOR); /* get window size and double it */ vgl_DrawFunGetInteger (df,VGL_WINDOWSIZE,ip); vgl_DrawFunBufferSize (df,2*ip[0],2*ip[1]); /* invoke display callback */ vgl_IActorDisplay (iactor,NULL); /* read off-screen frame buffer into FBuffer */ vgl_DrawFunFBufferRead (df,0,0,0,0,fbuffer); /* turn on normal rendering */ vgl_DrawFunRender (df,VGL_RENDER); vgl_FBufferWriteBMP (fbuffer,"exam5eBuffer.bmp"); printf("exam5eBuffer.bmp written\n"); vgl_FBufferEnd (fbuffer); }
In this example the left mouse button and control key are used to implement control of the clipping plane movement. The function vgl_IActorDrawClipCenter is used to draw a clipping plane icon and optionally detect the specific type of clipping plane movement to be performed. Initially the clipping plane location is defined and set in IActor using vgl_IActorSetParamfv. The function vgl_IActorDrawClipCenter is called repeatedly with action IACTOR_CLIPPLANEDETECT and the current mouse location. The icon is drawn differently depending upon the mouse location with respect to the center sphere and concentric circles which constitute the basic icon. When the control key and left mouse button are depressed, the current specific action returned by vgl_IActorDrawClipCenter is used as the input action to vgl_IActorDrag and if the specific action is a rotation, the rotation vector returned by vgl_IActorDrawClipCenter is specified using vgl_IActorSetParamfv. This specific action is also now input to all subsequent calls to vgl_IActorDrawClipCenter to draw the appropriate icon relative to the specific drag action being performed. The vgl_IActorDrag drag function does not call clipping plane graphics functions internally. The user must query for the current clipping plane center and normal using vgl_IActorGetFloat. These values will be continually changed during the vgl_IActorDrag movements. The center and normal must be converted to a clipping plane equation in the display callback function and specified to the graphics subsystem using vgl_DrawFunClipPlane. Note that the clipping plane associated with an icon should not be active while the icon is being drawn.
Depressing the shift key exits the program.
#include "base/base.h" #include "vgl/vgl.h" static void generate_cone(vgl_DrawFun *df, vgl_Quadric *qu, Vfloat r, Vfloat h, Vint n); static void draw_display(vgl_IActor *iactor, Vobject *obj); /* light properties */ static Vfloat camb[3] = { .5,.5,.5 }; static Vfloat cdis[3] = { .5,.5,.5 }; static Vfloat xdis[3] = { 1.,0.,0. }; static Vfloat xopp[3] = { -1.,0.,0. }; static Vint butact[2][3] = { {IACTOR_TRACKBALL, IACTOR_TRANSLATE, IACTOR_SCALE}, {IACTOR_CLIPPLANEDETECT, IACTOR_WINDOW, IACTOR_SQUIGGLE} }; typedef struct Tobj { vgl_DList *dlist; Vint clipplanedetect; Vint clipplaneaction; Vfloat rotvec[3]; } Tobj; /*---------------------------------------------------------------------- Draw a rotating, light source shaded cone ----------------------------------------------------------------------*/ int main(int argc, char **argv) { int i; Vint ix, iy, but[3]; Vint ibut, icnt, iact; Vint shft, cntl; Vchar devname[256]; #ifdef VKI_WIND_X11 Display *display; int screen; #endif #ifdef VKI_WIND_X11 vgl_X11Dev *x11dev; #else vgl_GDIDev *gdidev; #endif vgl_OpenGLDev *ogldev; vgl_DList *dlist; vgl_Quadric *qu; vgl_DrawFun *dfGL; vgl_DrawFun *dfDL; vgl_IActor *iactor; Vfloat nrm[3], cen[3]; Tobj tobj; Vint dev; /* dev=1 OpenGL, dev=2 X11 or GDI */ dev = 1; if(argc > 1) { sscanf(argv[1],"%d",&dev); } /* connect to X or Windows */ #ifdef VKI_WIND_X11 display = XOpenDisplay (0); screen = DefaultScreen (display); if(dev == 1) { vgl_OpenGLDevConnectX (display,screen); } else if(dev == 2) { vgl_X11DevConnectX (display,screen); } #else if(dev == 1) { vgl_OpenGLDevConnectWIN (); } else if(dev == 2) { vgl_GDIDevConnectWIN (); } #endif /* create drawing functions */ dfGL = vgl_DrawFunBegin(); /* create device objects and load drawing functions */ if(dev == 1) { ogldev = vgl_OpenGLDevBegin(); vgl_OpenGLDevDrawFun (ogldev,dfGL); strcpy(devname,"OpenGL"); } else if(dev == 2) { #ifdef VKI_WIND_X11 x11dev = vgl_X11DevBegin(); vgl_X11DevDrawFun (x11dev,dfGL); strcpy(devname,"X11"); #else gdidev = vgl_GDIDevBegin(); vgl_GDIDevDrawFun (gdidev,dfGL); strcpy(devname,"GDI"); #endif } /* open window */ vgl_DrawFunPositionWindow (dfGL,400,400,640,480); vgl_DrawFunOpenWindow (dfGL,devname); /* set viewing volume to match window aspect ratio */ vgl_DrawFunProjOrtho (dfGL,-1.3333,1.3333,-1.,1.,-1.,1.); /* turn on zbuffering */ vgl_DrawFunSetMode (dfGL,VGL_ZBUFFERMODE,VGL_ON); /* set lights */ vgl_DrawFunLight (dfGL,0,VGL_LIGHT_AMBIENT,camb,NULL); vgl_DrawFunLight (dfGL,1,VGL_LIGHT_DISTANT,cdis,xdis); vgl_DrawFunLight (dfGL,2,VGL_LIGHT_DISTANT,cdis,xopp); vgl_DrawFunSetMode (dfGL,VGL_LIGHTMODE,VGL_ON); /* create display list and drawing functions */ dlist = vgl_DListBegin(); dfDL = vgl_DrawFunBegin(); vgl_DListDrawFun (dlist,dfDL); /* set GL drawing functions in display list object */ vgl_DListSetObject(dlist,VGL_DRAWFUN,dfGL); /* generate quadric for drawing cone */ qu = vgl_QuadricBegin (); vgl_QuadricSetObject (qu,VGL_DRAWFUN,dfDL); /* instance IActor */ iactor = vgl_IActorBegin (); vgl_IActorSetObject (iactor,VGL_DRAWFUN,dfGL); tobj.dlist = dlist; tobj.clipplanedetect = IACTOR_CLIPPLANEDETECT; tobj.clipplaneaction = IACTOR_NONE; /* set display callback */ vgl_IActorSetFunction (iactor,IACTOR_FUN_DISPLAY, (void(*)(vgl_IActor*,Vobject*))draw_display,&tobj); /* specify clipplane to manage */ nrm[0] = 1.; nrm[1] = 0.; nrm[2] = 0.; cen[0] = 0.; cen[1] = 0.; cen[2] = 0.; vgl_IActorSetParamfv (iactor,IACTOR_CLIPPLANECENTER,cen); vgl_IActorSetParamfv (iactor,IACTOR_CLIPPLANENORMAL,nrm); vgl_IActorSetParami (iactor,IACTOR_CLIPPLANEICONRADIUS,80); /* generate display list */ generate_cone (dfDL, qu,.4,.6,17); /* fit display to viewport */ vgl_IActorFit (iactor,NULL); /* implement a simple mouse polling loop */ while (1) { ibut = -1; icnt = 0; iact = IACTOR_NONE; /* detect button press */ while (ibut == -1) { vgl_DrawFunPollMouse (dfGL,&ix,&iy,&but[0],&but[1],&but[2]); for(i = 0; i < 3; i++) { if(but[i]) { ibut = i; iact = butact[icnt][ibut]; if(iact == IACTOR_CLIPPLANEDETECT) { if(tobj.clipplaneaction != IACTOR_NONE) { if(tobj.clipplaneaction == IACTOR_CLIPPLANEROTATE || tobj.clipplaneaction == IACTOR_CLIPPLANEROTATE_DEGEN) { vgl_IActorSetParamfv (iactor,IACTOR_CLIPPLANEROTVEC, tobj.rotvec); } iact = tobj.clipplaneaction; tobj.clipplanedetect = tobj.clipplaneaction; } else { iact = IACTOR_NONE; } } else { tobj.clipplanedetect = IACTOR_NONE; } vgl_IActorDrag (iactor,iact,VGL_DRAG_INIT,ix,iy); break; } } /* jump out if shift key depressed */ vgl_DrawFunPollModifiers (dfGL,&cntl,&shft); if(shft) { goto done; } if(cntl) { icnt = 1; } else { icnt = 0; } /* spin while waiting */ if(ibut == -1) { vgl_IActorSpin (iactor,NULL); } } /* wait for button release */ while (ibut != -1) { vgl_DrawFunPollMouse (dfGL,&ix,&iy,&but[0],&but[1],&but[2]); if(but[ibut]) { vgl_IActorDrag (iactor,iact,VGL_DRAG_MOVE,ix,iy); } else { vgl_IActorDrag (iactor,iact,VGL_DRAG_TERM,ix,iy); ibut = -1; tobj.clipplanedetect = IACTOR_CLIPPLANEDETECT; } } } /* jump point for exiting polling loop */ done:; /* close window */ vgl_DrawFunCloseWindow (dfGL); /* free objects */ if(dev == 1) { vgl_OpenGLDevEnd (ogldev); } else if(dev == 2) { #ifdef VKI_WIND_X11 vgl_X11DevEnd (x11dev); #else vgl_GDIDevEnd (gdidev); #endif } vgl_DrawFunEnd (dfGL); vgl_DListEnd (dlist); vgl_DrawFunEnd (dfDL); vgl_IActorEnd (iactor); vgl_QuadricEnd (qu); /* disconnect */ if(dev == 1) { vgl_OpenGLDevDisconnect (); } else if(dev == 2) { #ifdef VKI_WIND_X11 vgl_X11DevDisconnect (); #else vgl_GDIDevDisconnect (); #endif } /* clean up */ #ifdef VKI_WIND_X11 XCloseDisplay (display); #endif return 0; } /*---------------------------------------------------------------------- generate graphics primitive for cone ----------------------------------------------------------------------*/ static void generate_cone(vgl_DrawFun *df, vgl_Quadric *qu, Vfloat r, Vfloat h, Vint n) { Vfloat c[3]; /* color and specularity */ c[0] = .5; c[1] = .5; c[2] = .5; vgl_DrawFunColor (df,c); vgl_DrawFunSpecularity (df,.5,10.); /* polygons */ vgl_QuadricSetParami (qu,QUADRIC_SLICES,n); vgl_QuadricSetParami (qu,QUADRIC_STACKS,2); vgl_QuadricCylinder (qu,r,0.,h); } /*---------------------------------------------------------------------- display callback ----------------------------------------------------------------------*/ static void draw_display(vgl_IActor *iactor, Vobject *obj) { Vint iparams[2]; Vint rflag; vgl_DrawFun *dfGL; Vfloat cbot[3] = {.4,.4,.4}; Vfloat ctop[3] = {0.,0.,.12}; Vint ix, iy, but[3]; Tobj *tobj; tobj = (Tobj*)obj; vgl_IActorGetObject (iactor,VGL_DRAWFUN,(Vobject**)&dfGL); /* get render mode */ vgl_DrawFunGetInteger (dfGL,VGL_RENDERMODE,iparams); rflag = iparams[0]; /* clear graphics screen */ vgl_DrawFunClear (dfGL); /* do not include in "Fit" operation */ if(rflag == 0) { vgl_DrawFunPollMouse (dfGL,&ix,&iy,&but[0],&but[1],&but[2]); vgl_IActorDrawBackground (iactor,cbot,ctop); vgl_IActorDrawTrackBall (iactor); vgl_IActorDrawClipCenter (iactor,tobj->clipplanedetect,ix,iy,0, &tobj->clipplaneaction,tobj->rotvec); } /* draw contents of display list */ vgl_DrawFunSetSwitch (dfGL,VGL_CLIPPLANE,0,VGL_ON); vgl_DListCall (tobj->dlist); vgl_DrawFunSetSwitch (dfGL,VGL_CLIPPLANE,0,VGL_OFF); /* swap graphics buffers */ vgl_DrawFunSwap (dfGL); }
#include "base/base.h" #include "vgl/vgl.h" static void draw_cone(vgl_DrawFun *df, vgl_Quadric *qu, Vfloat r, Vfloat h, Vint n); /* light properties */ static Vfloat camb[3] = { .5,.5,.5 }; static Vfloat cdis[3] = { .5,.5,.5 }; static Vfloat xdis[3] = { 1.,0.,0. }; /*---------------------------------------------------------------------- Unoptimized and optimized light source shaded cone ----------------------------------------------------------------------*/ int main() { int i; Vfloat tm4[4][4]; int usevbo; #ifdef VKI_WIND_X11 Display *display; int screen; #endif vgl_DList *dlist; vgl_DOpt *dopt; vgl_Quadric *qu; vgl_DrawFun *dfGL, *dfDL, *dfDO; vgl_Xfm *xfm; vgl_OpenGLDev *ogldev; /* open X display */ #ifdef VKI_WIND_X11 display = XOpenDisplay (0); screen = DefaultScreen (display); vgl_OpenGLDevConnectX (display,screen); #else vgl_OpenGLDevConnectWIN (); #endif /* create GL device and drawing functions */ ogldev = vgl_OpenGLDevBegin(); dfGL = vgl_DrawFunBegin(); vgl_OpenGLDevDrawFun (ogldev,dfGL); /* create display list and drawing functions */ dlist = vgl_DListBegin(); dfDL = vgl_DrawFunBegin(); vgl_DListDrawFun (dlist,dfDL); /* use VGL_ON to enable graphics buffer memory in DList */ usevbo = VGL_OFF; vgl_DListSetParami (dlist,DLIST_USEBUFFERS,usevbo); /* set GL drawing functions in display list object */ vgl_DListSetObject (dlist,VGL_DRAWFUN,dfGL); /* open window */ vgl_DrawFunPositionWindow (dfGL,400,400,400,300); vgl_DrawFunOpenWindow (dfGL,"OpenGL window"); /* set viewing volume to match window aspect ratio */ vgl_DrawFunProjOrtho (dfGL,-1.3333,1.3333,-1.,1.,-2.,2.); vgl_DrawFunDepthRange (dfGL,0.,1.); /* turn on zbuffering */ vgl_DrawFunSetMode (dfGL,VGL_ZBUFFERMODE,VGL_ON); /* generate quadric for drawing cone */ qu = vgl_QuadricBegin (); /* create transform object */ xfm = vgl_XfmBegin(); /* first render drawing to display list */ /* set lights */ vgl_DrawFunLight (dfDL,0,VGL_LIGHT_AMBIENT,camb,NULL); vgl_DrawFunLight (dfDL,1,VGL_LIGHT_DISTANT,cdis,xdis); vgl_DrawFunSetMode (dfDL,VGL_LIGHTMODE,VGL_ON); /* draw cone with 1,000,000 independent quads */ draw_cone (dfDL,qu,.8,1.2,1001); vgl_DrawFunDelay (dfGL,1.); /* rotate once about y axis */ for(i = 0; i <= 50; i++) { vgl_DrawFunClear (dfGL); vgl_XfmRotate (xfm,(Vfloat)(3.14159/25.*i),XFM_YAXIS); vgl_XfmGetMatrix (xfm,tm4); vgl_DrawFunXfmLoad (dfGL,tm4); vgl_DListCall (dlist); vgl_DrawFunSwap (dfGL); } vgl_DrawFunDelay (dfGL,1.); /* erase contents of display list */ vgl_DListErase (dlist); /* instance optimizer and set input drawing functions */ dopt = vgl_DOptBegin(); dfDO = vgl_DrawFunBegin(); vgl_DOptDrawFun (dopt,dfDO); /* link optimizer output to display list */ vgl_DOptSetObject (dopt,VGL_DRAWFUN,dfDL); /* repeat rendering process drawing to optimizer */ /* explicitly reset */ vgl_DOptReset (dopt); /* draw cone */ draw_cone (dfDO,qu,.8,1.2,1001); /* explicitly flush so the optimizer empties its buffers */ vgl_DOptFlush (dopt); /* rotate about y axis */ for(i = 0; i <= 50; i++) { vgl_DrawFunClear (dfGL); vgl_XfmRotate (xfm,(Vfloat)(3.14159/25.*i),XFM_YAXIS); vgl_XfmGetMatrix (xfm,tm4); vgl_DrawFunXfmLoad (dfGL,tm4); vgl_DListCall (dlist); vgl_DrawFunSwap (dfGL); } vgl_DrawFunDelay (dfGL,1.); /* close window */ vgl_DrawFunCloseWindow (dfGL); /* free ogldev and dfGL AFTER freeing dlist. dlist needs these objects to free VBO memory if DListErase has not been previously called */ vgl_DListEnd (dlist); vgl_DrawFunEnd (dfGL); vgl_OpenGLDevEnd (ogldev); vgl_DrawFunEnd (dfDL); vgl_DrawFunEnd (dfDO); vgl_QuadricEnd (qu); vgl_XfmEnd (xfm); vgl_DOptEnd (dopt); /* disconnect from X */ vgl_OpenGLDevDisconnect (); /* close X display */ #ifdef VKI_WIND_X11 XCloseDisplay (display); #endif return 0; } /*---------------------------------------------------------------------- draw cone ----------------------------------------------------------------------*/ static void draw_cone(vgl_DrawFun *df, vgl_Quadric *qu, Vfloat r, Vfloat h, Vint n) { Vfloat c[3]; c[0] = .5; c[1] = .5; c[2] = .5; vgl_DrawFunColor (df,c); vgl_DrawFunSpecularity (df,.5,10.); vgl_QuadricSetObject (qu,VGL_DRAWFUN,df); vgl_QuadricSetParami (qu,QUADRIC_SLICES,n); vgl_QuadricSetParami (qu,QUADRIC_STACKS,n); vgl_QuadricSetParami (qu,QUADRIC_SHADE,VGL_VERTEXSHADE); vgl_QuadricSetParami (qu,QUADRIC_FILL,SYS_ON); vgl_QuadricCylinder (qu,r,.5*r,h); }
The function vgl_DrawFunSetMode is used to enable and disable various modes which must be set in order for rubber band drawing to give the desired result. Initially, in addition to enabling XOR mode, front buffer mode should be enabled and z-buffering disabled.
This example illustrates using XOR with OpenGLDev with the associated window system 2D driver, in this case X11Dev on X Windows and GDIDev on Microsoft Windows. There are various advantages to using the window system drivers for immediate mode, front buffer drawing with respect to performance during desktop sharing, etc.
#include "base/base.h" #include "vgl/vgl.h" static Vfloat xpol[4][3] = { {-.4,-.4,0.}, {.4,-.4,0.}, {.4,.4,0.}, {-.4,.4,0.} }; static void draw_rubberband(vgl_DrawFun *df, vgl_DrawFun *dfxor, Vint iws); /*---------------------------------------------------------------------- Rubber banding ----------------------------------------------------------------------*/ int main(int argc, char **argv) { Vint xsize, ysize; #ifdef VKI_WIND_X11 Display *display; int screen; vgl_X11Dev *x11dev; #else vgl_GDIDev *gdidev; #endif vgl_OpenGLDev *ogldev; vgl_DrawFun *df, *dfws; Vword window; Vint dev; Vchar devname[256]; /* dev=1 OpenGL */ dev = 1; if(argc > 1) { sscanf(argv[1],"%d",&dev); } /* open X display */ #ifdef VKI_WIND_X11 display = XOpenDisplay (0); screen = DefaultScreen (display); vgl_OpenGLDevConnectX (display,screen); #else if(dev == 1) { vgl_OpenGLDevConnectWIN (); } #endif /* create drawing functions */ df = vgl_DrawFunBegin(); /* create device objects and load drawing functions */ if(dev == 1) { ogldev = vgl_OpenGLDevBegin(); vgl_OpenGLDevDrawFun (ogldev,df); strcpy(devname,"OpenGL"); } /* open window */ xsize = 400; ysize = 300; vgl_DrawFunPositionWindow (df,400,400,xsize,ysize); vgl_DrawFunOpenWindow (df,devname); vgl_DrawFunQueryWindow (df,&window); /* rubber band using 3D driver */ draw_rubberband (df,df,0); /* rubber band using window system driver */ dfws = vgl_DrawFunBegin(); #ifdef VKI_WIND_X11 vgl_X11DevConnectX (display,screen); x11dev = vgl_X11DevBegin(); vgl_X11DevDrawFun (x11dev,dfws); #else vgl_GDIDevConnectWIN (); gdidev = vgl_GDIDevBegin(); vgl_GDIDevDrawFun (gdidev,dfws); #endif vgl_DrawFunConnectWindow (dfws,window); draw_rubberband (df,dfws,1); vgl_DrawFunDisconnectWindow (dfws); /* close window */ vgl_DrawFunCloseWindow (df); /* free objects */ vgl_DrawFunEnd (df); #ifdef VKI_WIND_X11 vgl_X11DevEnd (x11dev); vgl_X11DevDisconnect (); if(dev == 1) { vgl_OpenGLDevEnd (ogldev); vgl_OpenGLDevDisconnect (); } #else vgl_GDIDevEnd (gdidev); if(dev == 1) { vgl_OpenGLDevEnd (ogldev); vgl_OpenGLDevDisconnect (); } #endif vgl_DrawFunEnd (dfws); /* close X display */ #ifdef VKI_WIND_X11 XCloseDisplay (display); #endif return 0; } static void draw_rubberband(vgl_DrawFun *df, vgl_DrawFun *dfxor, Vint iws) { Vint i; Vfloat x[3], c[3], xr[2][3]; Vint ix, iy; Vint iold; Vint ipar[2], xsize, ysize; /* get window size */ vgl_DrawFunGetInteger (df,VGL_WINDOWSIZE,ipar); xsize = ipar[0]; ysize = ipar[1]; /* clear and draw a magenta polygon and text */ vgl_DrawFunClear (df); c[0] = 1.; c[1] = 0.; c[2] = 1.; vgl_DrawFunColor (df,c); vgl_DrawFunPolygon (df,VGL_POLYGON,4,xpol,VGL_NOSHADE,NULL); c[0] = 1.; c[1] = 1.; c[2] = 1.; vgl_DrawFunColor (df,c); x[0] = -.9; x[1] = .9; x[2] = 0.; if(iws == 0) { vgl_DrawFunText (df,x,"XOR drawing, 3D driver"); } else { vgl_DrawFunText (df,x,"XOR drawing, Window system driver"); } vgl_DrawFunSwap (df); /* now draw rubber band */ /* set drawing mode to front buffer */ vgl_DrawFunSetMode (dfxor,VGL_FRONTBUFFERDRAWMODE,VGL_ON); /* set z buffering off */ vgl_DrawFunSetMode (dfxor,VGL_ZBUFFERMODE,VGL_OFF); /* set projection matrix to match screen pixel size */ vgl_DrawFunProjOrtho (dfxor,0.,(Vfloat)(xsize-1), 0.,(Vfloat)(ysize-1), -1.,1.); /* set color of rubber banding line to white */ c[0] = 1.; c[1] = 1.; c[2] = 1.; vgl_DrawFunColor (dfxor,c); /* turn on xor mode */ vgl_DrawFunSetMode (dfxor,VGL_XORMODE,VGL_ON); /* line anchor in lower left of window */ ix = 20; iy = 20; xr[0][0] = ix; xr[0][1] = iy; xr[0][2] = 0.; /* draw rubber band starting in upper right */ ix = xsize-20; iy = ysize-20; iold = 0; for(i = 0; i < ysize-40; i+=4) { iy -= 4; if(iold) { vgl_DrawFunPolyLine (dfxor,VGL_LINESTRIP,2,xr); vgl_DrawFunFlush (dfxor); } iold = 1; xr[1][0] = ix; xr[1][1] = iy; xr[1][2] = 0.; vgl_DrawFunPolyLine (dfxor,VGL_LINESTRIP,2,xr); vgl_DrawFunFlush (dfxor); vgl_DrawFunDelay (dfxor,.1); } /* return modes and projection to defaults */ vgl_DrawFunSetMode (dfxor,VGL_XORMODE,VGL_OFF); vgl_DrawFunProjOrtho (dfxor,-1.,1.,-1.,1.,-1.,1.); vgl_DrawFunSetMode (dfxor,VGL_ZBUFFERMODE,VGL_ON); vgl_DrawFunSetMode (dfxor,VGL_FRONTBUFFERDRAWMODE,VGL_OFF); /* clear and draw a blue polygon */ vgl_DrawFunClear (df); c[0] = 0.; c[1] = 0.; c[2] = 1.; vgl_DrawFunColor (df,c); vgl_DrawFunPolygon (df,VGL_POLYGON,4,xpol,VGL_NOSHADE,NULL); vgl_DrawFunSwap (df); /* wait */ vgl_DrawFunDelay (df,1.); }
This example illustrates using the update mode to implement a pixel magnification tool under the cursor. This feature would be useful for picking operations which need precise selection. A scene of 4 quadrilaterals is drawn and then saved when the update mode is enabled. Only the frame (color) buffer is saved. The FBuffer object is then used to capture a 21x21 pixel square of the frame buffer using the FBufferRead drawing function and then magnify it by a factor of 4 using vgl_FBufferScale. A 2 pixel wide white border is added to the square using vgl_FBufferBorder. The scaled frame buffer is then drawn using the FBufferWrite drawing function. The CNTL key will toggle the magnification between 4 and 8.
#include "base/base.h" #include "vgl/vgl.h" #include "vgldev.h" static Vfloat xquads[4][4][3] = { {{2.,-1.,2.}, {2.,-1.,-2.}, {2.,1.,-2.}, {2.,1.,2.}}, {{2.,-1.,-2.}, {-2.,-1.,-2.}, {-2.,1.,-2.}, {2.,1.,-2.}}, {{-2.,-1.,-2.}, {-2.,-1.,2.}, {-2.,1.,2.}, {-2.,1.,-2.}}, {{-2.,-1.,2.}, {2.,-1.,2.}, {2.,1.,2.}, {-2.,1.,2.}} }; static Vfloat rquad[4][3] = { {0.,0.,0.}, {1.,0.,0.}, {1.,1.,0.}, {0.,1.,0.} }; static Vfloat cquads[4][3] = { {1.,0.,0.}, {0.,1.,0.}, {0.,0.,1.}, {.5,.5,.5} }; static Vfloat cwhite[3] = { 1.,1.,1. }; static Vfloat xprompt[4][3] = { {-4.5, -3.5, 0.}, {-4.5, -3.9, 0.}, {-4.5, -4.3, 0.}, {-4.5, -4.7, 0.} }; /*---------------------------------------------------------------------- Using Update Mode for a Cursor Magnifier ----------------------------------------------------------------------*/ int main() { vgl_DrawFun *df; vgl_Xfm *xfm; vgl_FBuffer *fb, *fbm; Vint i; Vint xsize, ysize; Vint ix, iy, but1, but2, but3, cntl, shft; Vfloat c[3], x[3], tm[4][4]; Vchar title[65]; Vint test; Vint s, wx, sm; /* create drawing function object */ df = vgl_DrawFunBegin(); strcpy(title,"Example 7a, "); VglDevCreate (df,VGLDEV_OPENGL,title,&test); /* open window and set lighting, etc. */ xsize = 400; ysize = 400; vgl_DrawFunPositionWindow (df,200,200,xsize,ysize); vgl_DrawFunOpenWindow (df,title); vgl_DrawFunProjOrtho (df,-5.,5.,-5.,5.,-5.,5.); vgl_DrawFunSetMode (df,VGL_ZBUFFERMODE,VGL_ON); vgl_DrawFunSetMode (df,VGL_LIGHTMODE,VGL_ON); c[0] = .3; c[1] = .3; c[2] = .3; x[0] = 0.; x[1] = 0.; x[2] = 0.; vgl_DrawFunLight (df,0,VGL_LIGHT_AMBIENT,c,x); c[0] = .7; c[1] = .7; c[2] = .7; x[0] = 1.; x[1] = 1.; x[2] = 1.; vgl_DrawFunLight (df,1,VGL_LIGHT_DISTANT,c,x); x[0] = -1.; x[1] = -1.; x[2] = -1.; vgl_DrawFunLight (df,2,VGL_LIGHT_DISTANT,c,x); /* create transformation object */ xfm = vgl_XfmBegin (); /* draw basic scene */ vgl_DrawFunClear (df); /* draw prompt message */ vgl_DrawFunColor (df,cwhite); vgl_DrawFunText (df,xprompt[0],"Left button: Magnifier"); vgl_DrawFunText (df,xprompt[1],"Middle button: quit"); vgl_DrawFunText (df,xprompt[2],"Right button: quit"); vgl_DrawFunText (df,xprompt[3],"Control button: double magnification"); /* draw rectangles */ vgl_XfmRotateVector (xfm,48.*.017453,.75,1.,0.); vgl_XfmGetMatrix (xfm,tm); vgl_DrawFunXfmLoad (df,tm); for(i = 0; i < 4; i++) { vgl_DrawFunColor (df,cquads[i]); /* draw gray rectangle with 50% transparency */ if(i == 3) { vgl_DrawFunTrans (df,.5); } else { vgl_DrawFunTrans (df,0.); } vgl_DrawFunPolygon (df,VGL_POLYGON,4,xquads[i],VGL_NOSHADE,NULL); vgl_DrawFunPolygonData (df,VGL_POLYGON,4,xquads[i], 3,(Vfloat*)rquad,VGL_NOSHADE,NULL); } vgl_DrawFunSwap (df); vgl_DrawFunTrans (df,0.); vgl_DrawFunSetMode (df,VGL_UPDATEMODE,VGL_ON); vgl_DrawFunSetMode (df,VGL_FRONTBUFFERREADMODE,VGL_OFF); fb = vgl_FBufferBegin (); fbm = vgl_FBufferBegin (); /* sample dimension is 2*wz + 1 */ wx = 10; /* magnification factor */ s = 4; /* cursor magnifier loop */ while (1) { vgl_DrawFunPollMouse (df,&ix,&iy,&but1,&but2,&but3); vgl_DrawFunPollModifiers (df,&cntl,&shft); vgl_DrawFunClear (df); /* toggle magnification factor */ if(cntl) { s = 8; } else { s = 4; } /* draw magnifier */ if(but1) { vgl_DrawFunFBufferRead (df, ix-wx,ix+wx, iy-wx,iy+wx, fb); vgl_FBufferScale (fb,s,fbm); vgl_FBufferColor (fbm,cwhite); vgl_FBufferBorder (fbm,2); sm = wx*s + s/2; vgl_DrawFunFBufferWrite (df, ix-sm,ix+sm, iy-sm,iy+sm, fbm); /* break out */ } else if(but2) { break; } else if(but3) { break; } vgl_DrawFunSwap (df); } vgl_FBufferEnd (fb); vgl_FBufferEnd (fbm); vgl_DrawFunSetMode (df,VGL_UPDATEMODE,VGL_OFF); /* close window */ vgl_DrawFunCloseWindow (df); /* free all objects */ vgl_DrawFunEnd (df); vgl_XfmEnd (xfm); VglDevDestroy (); return 0; }
#include "base/base.h" #include "vgl/vgl.h" #include "vgldev.h" static Vfloat xquads[4][4][3] = { {{2.,-1.,2.}, {2.,-1.,-2.}, {2.,1.,-2.}, {2.,1.,2.}}, {{2.,-1.,-2.}, {-2.,-1.,-2.}, {-2.,1.,-2.}, {2.,1.,-2.}}, {{-2.,-1.,-2.}, {-2.,-1.,2.}, {-2.,1.,2.}, {-2.,1.,-2.}}, {{-2.,-1.,2.}, {2.,-1.,2.}, {2.,1.,2.}, {-2.,1.,2.}} }; static Vfloat rquad[4][3] = { {0.,0.,0.}, {1.,0.,0.}, {1.,1.,0.}, {0.,1.,0.} }; static Vfloat cquads[4][3] = { {1.,0.,0.}, {0.,1.,0.}, {0.,0.,1.}, {.5,.5,.5} }; static Vfloat cwhite[3] = { 1.,1.,1. }; static Vfloat cyellow[3] = { 1.,1.,.5 }; static Vfloat xprompt[4][3] = { {-4.5, -3.5, 0.}, {-4.5, -3.9, 0.}, {-4.5, -4.3, 0.}, {-4.5, -4.7, 0.} }; static Vfloat xcursor[3][3] = { {-4.5, 4.3, 0.}, {-4.5, 3.9, 0.}, {-4.5, 3.5, 0.} }; static void xfmstack_init(vgl_DrawFun *df, vgl_Xfmstack *xfmstack); /*---------------------------------------------------------------------- Using Update Mode for a 3D Probe ----------------------------------------------------------------------*/ int main() { vgl_DrawFun *df; vgl_Xfm *xfm; vgl_Xfmstack *xfmstack; vgl_Quadric *qu; Vint i; Vint xsize, ysize; Vint ix, iy, but1, but2, but3, cntl, shft; Vfloat c[3], x[3], tm[4][4]; Vfloat xi[3], z; Vchar stg[33], title[65]; Vint test; Vint s, wx, sm; wx = 10; s = 4; sm = wx*s+s/2; /* create drawing function object */ df = vgl_DrawFunBegin(); strcpy(title,"Example 7a, "); VglDevCreate (df,VGLDEV_OPENGL,title,&test); /* open window and set lighting, etc. */ xsize = 400; ysize = 400; vgl_DrawFunPositionWindow (df,200,200,xsize,ysize); vgl_DrawFunOpenWindow (df,title); vgl_DrawFunProjOrtho (df,-5.,5.,-5.,5.,-5.,5.); vgl_DrawFunSetMode (df,VGL_ZBUFFERMODE,VGL_ON); vgl_DrawFunSetMode (df,VGL_LIGHTMODE,VGL_ON); c[0] = .4; c[1] = .4; c[2] = .4; x[0] = 0.; x[1] = 0.; x[2] = 0.; vgl_DrawFunLight (df,0,VGL_LIGHT_AMBIENT,c,x); c[0] = .6; c[1] = .6; c[2] = .6; x[0] = 1.; x[1] = 1.; x[2] = 1.; vgl_DrawFunLight (df,1,VGL_LIGHT_DISTANT,c,x); x[0] = -1.; x[1] = -1.; x[2] = -1.; vgl_DrawFunLight (df,2,VGL_LIGHT_DISTANT,c,x); /* create transformation object */ xfm = vgl_XfmBegin (); /* draw basic scene */ vgl_DrawFunClear (df); /* draw prompt message */ vgl_DrawFunColor (df,cwhite); vgl_DrawFunText (df,xprompt[0],"Left button: 3D Cursor"); vgl_DrawFunText (df,xprompt[1],"Middle/Right button: quit"); vgl_DrawFunText (df,xprompt[2],"Control button: z farer"); vgl_DrawFunText (df,xprompt[3],"Shift button: z nearer"); /* draw rectangles */ vgl_XfmRotateVector (xfm,48.*.017453,.75,1.,0.); vgl_XfmGetMatrix (xfm,tm); vgl_DrawFunXfmLoad (df,tm); for(i = 0; i < 4; i++) { vgl_DrawFunColor (df,cquads[i]); /* draw gray rectangle with 50% transparency */ if(i == 3) { vgl_DrawFunTrans (df,.5); } else { vgl_DrawFunTrans (df,0.); } vgl_DrawFunPolygon (df,VGL_POLYGON,4,xquads[i],VGL_NOSHADE,NULL); vgl_DrawFunPolygonData (df,VGL_POLYGON,4,xquads[i], 3,(Vfloat*)rquad,VGL_NOSHADE,NULL); } vgl_DrawFunSwap (df); vgl_DrawFunTrans (df,0.); vgl_DrawFunSetMode (df,VGL_UPDATEMODE,VGL_ON); vgl_DrawFunSetMode (df,VGL_FRONTBUFFERREADMODE,VGL_OFF); xfmstack = vgl_XfmstackBegin (); xfmstack_init (df,xfmstack); qu = vgl_QuadricBegin (); vgl_QuadricSetObject (qu,VGL_DRAWFUN,df); /* starting z screen coordinate in middle */ z = .5; /* cursor 3D sphere probe loop */ while (1) { vgl_DrawFunPollMouse (df,&ix,&iy,&but1,&but2,&but3); vgl_DrawFunPollModifiers (df,&cntl,&shft); vgl_DrawFunClear (df); if(cntl) { z += .001; if(z > 1.) z = 1.; } if(shft) { z -= .001; if(z < 0.) z = 0.; } /* sphere */ if(but1) { xi[0] = ix; xi[1] = iy; xi[2] = z; vgl_XfmstackUnproject (xfmstack,xi[0],xi[1],xi[2],&x[0],&x[1],&x[2]); vgl_DrawFunColor (df,cyellow); vgl_QuadricSetParamfv (qu,QUADRIC_ORIGIN,x); vgl_QuadricSphere (qu,.2); /* draw cursor location in screen coordinates */ vgl_DrawFunXfmPush (df); vgl_XfmIdentity (xfm); vgl_XfmGetMatrix (xfm,tm); vgl_DrawFunXfmLoad (df,tm); vgl_DrawFunColor (df,cwhite); sprintf(stg,"ix = %d",ix); vgl_DrawFunText (df,xcursor[0],stg); sprintf(stg,"iy = %d",iy); vgl_DrawFunText (df,xcursor[1],stg); sprintf(stg,"z = %f",z); vgl_DrawFunText (df,xcursor[2],stg); vgl_DrawFunXfmPop (df); /* break out */ } else if(but2) { break; } else if(but3) { break; } vgl_DrawFunSwap (df); } vgl_QuadricEnd (qu); vgl_XfmstackEnd (xfmstack); vgl_DrawFunSetMode (df,VGL_UPDATEMODE,VGL_OFF); /* close window */ vgl_DrawFunCloseWindow (df); /* free all objects */ vgl_DrawFunEnd (df); vgl_XfmEnd (xfm); VglDevDestroy (); return 0; } static void xfmstack_init(vgl_DrawFun *df, vgl_Xfmstack *xfmstack) { Vfloat tm[4][4]; Vint iparam[4]; vgl_Xfm *xfm; /* query and load complete viewing transformation into transformation stack object */ xfm = vgl_XfmBegin(); vgl_DrawFunGetFloat (df,VGL_MODELVIEWMATRIX,(Vfloat*)tm); vgl_XfmSetMatrix (xfm,tm); vgl_XfmstackLoad (xfmstack,xfm); vgl_DrawFunGetFloat (df,VGL_PROJECTIONMATRIX,(Vfloat*)tm); vgl_XfmSetMatrix (xfm,tm); vgl_XfmstackProj (xfmstack,xfm); vgl_DrawFunGetInteger (df,VGL_VIEWPORT,iparam); vgl_XfmstackSetViewport (xfmstack,iparam[0],iparam[1],iparam[2],iparam[3]); vgl_XfmEnd (xfm); }
#include <stdlib.h> #include <string.h> #include "base/base.h" #include "vgl/vgl.h" static void displayFBuffer(vgl_FBuffer *fbuffer, Vchar *inputfile); /*---------------------------------------------------------------------- FBuffer file interfaces ----------------------------------------------------------------------*/ int main(int argc, char **argv) { char inputfile[256], outputfile[256]; char infile[256], outfile[256]; vgl_FBuffer *fbuffer; /* check for proper number of arguments */ if(argc < 2) { fprintf(stderr,"Usage: %s inputfile [outputfile]\n",argv[0]); fprintf(stderr," inputfile is blank, 'earth.gif' is assumed\n"); strcpy(inputfile,"earth.gif"); } else { strcpy(inputfile,argv[1]); } strcpy(infile,inputfile); /* create FBuffer object */ fbuffer = vgl_FBufferBegin(); /* decode input display file format and file name */ if(strstr(infile,".tga")) { vgl_FBufferReadTarga (fbuffer,infile); } else if(strstr(infile,".gif")) { vgl_FBufferReadGIF (fbuffer,infile); } else if(strstr(infile,".rgb")) { vgl_FBufferReadSGI (fbuffer,infile); } else if(strstr(infile,".bmp")) { vgl_FBufferReadBMP (fbuffer,infile); } else if(strstr(infile,".png")) { vgl_FBufferReadPNG (fbuffer,infile); } else if(strstr(infile,".tif")) { vgl_FBufferReadTIFF (fbuffer,infile); } else if(strstr(infile,".jpg")) { vgl_FBufferReadJPEG (fbuffer,infile); } else { fprintf(stderr,"Error: Unsupported input file format %s\n",infile); exit(1); } if(vgl_FBufferError(fbuffer)) { fprintf(stderr,"Error: Can not read image file %s\n",infile); exit(1); } /* display input image */ displayFBuffer (fbuffer, infile); /* write output file if requested */ if(argc == 3) { strcpy(outputfile,argv[2]); strcpy(outfile,outputfile); /* write to proper output file format */ if(strstr(outfile,".tga")) { vgl_FBufferWriteTarga (fbuffer,outfile); } else if(strstr(outfile,".gif")) { vgl_FBufferSetParami (fbuffer,FBUFFER_GIFCOMPTYPE, FBUFFER_GIFCOMP_RLE); vgl_FBufferWriteGIF (fbuffer,outfile); } else if(strstr(outfile,".rgb")) { vgl_FBufferWriteSGI (fbuffer,outfile); } else if(strstr(outfile,".bmp")) { vgl_FBufferWriteBMP (fbuffer,outfile); } else if(strstr(outfile,".png")) { vgl_FBufferWritePNG (fbuffer,outfile); } else if(strstr(outfile,".tif")) { vgl_FBufferWriteTIFF (fbuffer,outfile); } else if(strstr(outfile,".jpg")) { vgl_FBufferWriteJPEG (fbuffer,outfile); } else if(strstr(outfile,".svg")) { vgl_FBufferWriteSVG (fbuffer,outfile); } else { fprintf(stderr,"Error: Unsupported output file format %s\n",outfile); exit(1); } if(vgl_FBufferError(fbuffer)) { fprintf(stderr,"Error: Can not write image file %s\n",outfile); exit(1); } } /* free objects */ vgl_FBufferEnd (fbuffer); return 0; } /*---------------------------------------------------------------------- display contents of FBuffer object ----------------------------------------------------------------------*/ static void displayFBuffer(vgl_FBuffer *fbuffer, Vchar *inputfile) { Vint params[2]; #ifdef VKI_WIND_X11 Display *display; int screen; #endif vgl_OpenGLDev *ogldev; vgl_DrawFun *df; /* open X display */ #ifdef VKI_WIND_X11 display = XOpenDisplay (0); screen = DefaultScreen (display); vgl_OpenGLDevConnectX (display,screen); #else vgl_OpenGLDevConnectWIN (); #endif /* create drawing functions */ df = vgl_DrawFunBegin(); /* create device objects and load drawing functions */ ogldev = vgl_OpenGLDevBegin(); vgl_OpenGLDevDrawFun (ogldev,df); /* open window to size of FBuffer */ vgl_FBufferInq (fbuffer,¶ms[0],¶ms[1]); vgl_DrawFunConfigureWindow (df,VGL_WINDOWSIZE,params); /* Write FBuffer */ vgl_DrawFunOpenWindow (df,inputfile); vgl_DrawFunFBufferWrite (df,0,0,0,0,fbuffer); vgl_DrawFunSwap (df); /* wait */ vgl_DrawFunDelay (df,20.); /* close windows */ vgl_DrawFunCloseWindow (df); /* free objects */ vgl_OpenGLDevEnd (ogldev); vgl_DrawFunEnd (df); /* disconnect from X */ vgl_OpenGLDevDisconnect (); /* close X display */ #ifdef VKI_WIND_X11 XCloseDisplay (display); #endif }
#include <stdlib.h> #include <string.h> #include "base/base.h" #include "vgl/vgl.h" #include <vfw.h> static void displayFBuffer(vgl_FBuffer *fbuffer, Vchar *inputfile); /*---------------------------------------------------------------------- FBuffer write AVI file ----------------------------------------------------------------------*/ int main(int argc, char **argv) { int i; char inputfile[256], outputfile[256]; char infile[256], outfile[256]; char *inputext, *outputext; char *token; vgl_FBuffer *fbuffer; PAVIFILE avifile; Vfloat c[3]; Vint compressFlag; Vint compressFactor; /* check for proper number of arguments */ if(argc < 2) { fprintf(stderr,"Usage: %s inputfile [outputfile [compressionFlag [compressionFactor] ] ]\n",argv[0]); fprintf(stderr," inputfile is blank, 'earth.gif' is assumed\n"); strcpy(inputfile,"earth.gif"); } else { strcpy(inputfile,argv[1]); } strcpy(infile,inputfile); token = strtok(inputfile,"."); if(!token) { fprintf(stderr,"Error: Bad input file %s\n",infile); exit(1); } inputext = strtok(NULL," "); if(!inputext) { fprintf(stderr,"Error: Bad input file %s\n",infile); exit(1); } if(argc > 2) { strcpy(outfile,argv[2]); } else { strcpy(outfile,"exam8a.avi"); } if(argc > 3) { if(!strcmp(argv[3],"NONE")) { compressFlag = FBUFFER_AVICOMP_NONE; } else if (!strcmp(argv[3],"INTELINDEO")) { compressFlag = FBUFFER_AVICOMP_INTELINDEO; } else if (!strcmp(argv[3],"CINEPAK")) { compressFlag = FBUFFER_AVICOMP_CINEPAK; } else if (!strcmp(argv[3],"MSVIDEO")) { compressFlag = FBUFFER_AVICOMP_MSVIDEO; } else { fprintf(stderr,"Error: Unidentifiable compression type (%s)\n" " Will create uncompressed AVI file.\n",argv[3]); compressFlag = FBUFFER_AVICOMP_NONE; } } else { compressFlag = FBUFFER_AVICOMP_NONE; } if(argc > 4) { compressFactor = atoi(argv[4]); if(compressFactor <= 0) { fprintf(stderr,"Error: Bad compression factor %s\n" " Setting compression factor to 80\n",argv[4]); compressFactor = 80; } } else { compressFactor = 80; } /* create FBuffer object */ fbuffer = vgl_FBufferBegin(); /* decode input display file format and file name */ if(!strncmp(inputext,"tga",3)) { vgl_FBufferReadTarga (fbuffer,infile); } else if(!strncmp(inputext,"gif",3)) { vgl_FBufferReadGIF (fbuffer,infile); } else if(!strncmp(inputext,"rgb",3)) { vgl_FBufferReadSGI (fbuffer,infile); } else if(!strncmp(inputext,"bmp",3)) { vgl_FBufferReadBMP (fbuffer,infile); } else { fprintf(stderr,"Error: Unsupported input file format %s\n",infile); exit(1); } if(vgl_FBufferError(fbuffer)) { fprintf(stderr,"Error: Can not read image file %s\n",infile); exit(1); } /* display input image */ displayFBuffer (fbuffer, infile); AVIFileInit (); AVIFileOpen (&avifile,outfile,OF_CREATE|OF_WRITE,NULL); /* set compression information */ vgl_FBufferSetParami (fbuffer,FBUFFER_AVICOMPTYPE,compressFlag); vgl_FBufferSetParami (fbuffer,FBUFFER_AVICOMPFACT,compressFactor); /* set border color */ c[0] = 0.; c[1] = .5; c[2] = .75; vgl_FBufferColor (fbuffer,c); /* write 30 images animating the border size */ for(i = 1; i <= 30; i++) { vgl_FBufferBorder (fbuffer,2*i); vgl_FBufferWriteWINAVI (fbuffer,&avifile); } /* close AVI */ vgl_FBufferCloseWINAVI (fbuffer); AVIFileRelease (avifile); AVIFileExit (); /* free objects */ vgl_FBufferEnd (fbuffer); return 0; } /*---------------------------------------------------------------------- display contents of FBuffer object ----------------------------------------------------------------------*/ static void displayFBuffer(vgl_FBuffer *fbuffer, Vchar *inputfile) { Vint params[2]; #ifdef VKI_WIND_X11 Display *display; int screen; #endif vgl_OpenGLDev *ogldev; vgl_DrawFun *df; /* open X display */ #ifdef VKI_WIND_X11 display = XOpenDisplay (0); screen = DefaultScreen (display); vgl_OpenGLDevConnectX (display,screen); #else vgl_OpenGLDevConnectWIN (); #endif /* create drawing functions */ df = vgl_DrawFunBegin(); /* create device objects and load drawing functions */ ogldev = vgl_OpenGLDevBegin(); vgl_OpenGLDevDrawFun (ogldev,df); /* open window to size of FBuffer */ vgl_FBufferInq (fbuffer,¶ms[0],¶ms[1]); vgl_DrawFunConfigureWindow (df,VGL_WINDOWSIZE,params); /* Write FBuffer */ vgl_DrawFunOpenWindow (df,inputfile); vgl_DrawFunFBufferWrite (df,0,0,0,0,fbuffer); vgl_DrawFunSwap (df); /* wait */ vgl_DrawFunDelay (df,5.); /* close windows */ vgl_DrawFunCloseWindow (df); /* free objects */ vgl_OpenGLDevEnd (ogldev); vgl_DrawFunEnd (df); /* disconnect from X */ vgl_OpenGLDevDisconnect (); /* close X display */ #ifdef VKI_WIND_X11 XCloseDisplay (display); #endif }
#include <stdlib.h> #include <string.h> #include "base/base.h" #include "vgl/vgl.h" static void displayFBuffer(vgl_FBuffer *fbuffer, Vchar *text); /*---------------------------------------------------------------------- FBuffer Image Operations ----------------------------------------------------------------------*/ int main(int argc, char **argv) { char infile[256]; vgl_FBuffer *fbuffer; vgl_FBuffer *fbufferi; Vint xsize, ysize; Vfloat cb[3]; /* check for proper number of arguments */ if(argc < 2) { fprintf(stderr,"Usage: %s inputfile\n",argv[0]); fprintf(stderr," inputfile is blank, 'earth.gif' is assumed\n"); strcpy(infile,"earth.gif"); } else { strcpy(infile,argv[1]); } /* create FBuffer object */ fbuffer = vgl_FBufferBegin(); /* decode input display file format and file name */ if(strstr(infile,".tga")) { vgl_FBufferReadTarga (fbuffer,infile); } else if(strstr(infile,".gif")) { vgl_FBufferReadGIF (fbuffer,infile); } else if(strstr(infile,".rgb")) { vgl_FBufferReadSGI (fbuffer,infile); } else if(strstr(infile,".bmp")) { vgl_FBufferReadBMP (fbuffer,infile); } else if(strstr(infile,".png")) { vgl_FBufferReadPNG (fbuffer,infile); } else if(strstr(infile,".tif")) { vgl_FBufferReadTIFF (fbuffer,infile); } else if(strstr(infile,".jpg")) { vgl_FBufferReadJPEG (fbuffer,infile); } else { fprintf(stderr,"Error: Unsupported input file format %s\n",infile); exit(1); } if(vgl_FBufferError(fbuffer)) { fprintf(stderr,"Error: Can not read image file %s\n",infile); exit(1); } vgl_FBufferInq (fbuffer,&xsize,&ysize); /* display original image */ displayFBuffer (fbuffer,infile); /* gamma warp */ vgl_FBufferGammaWarp (fbuffer,1.2); displayFBuffer (fbuffer,"Gamma Warp"); /* add red border */ cb[0] = 1.; cb[1] = 0.; cb[2] = 0.; vgl_FBufferColor (fbuffer,cb); vgl_FBufferBorder (fbuffer,4); displayFBuffer (fbuffer,"Border"); /* change image size */ fbufferi = vgl_FBufferBegin(); vgl_FBufferDef (fbufferi,.6*xsize,.6*ysize); vgl_FBufferZoom (fbufferi,fbuffer); /* display processed image */ displayFBuffer (fbufferi,"Zoom"); /* free objects */ vgl_FBufferEnd (fbufferi); vgl_FBufferEnd (fbuffer); return 0; } /*---------------------------------------------------------------------- display contents of FBuffer object ----------------------------------------------------------------------*/ static void displayFBuffer(vgl_FBuffer *fbuffer, Vchar *text) { Vint params[2]; #ifdef VKI_WIND_X11 Display *display; int screen; #endif vgl_OpenGLDev *ogldev; vgl_DrawFun *df; /* open X display */ #ifdef VKI_WIND_X11 display = XOpenDisplay (0); screen = DefaultScreen (display); vgl_OpenGLDevConnectX (display,screen); #else vgl_OpenGLDevConnectWIN (); #endif /* create drawing functions */ df = vgl_DrawFunBegin(); /* create device objects and load drawing functions */ ogldev = vgl_OpenGLDevBegin(); vgl_OpenGLDevDrawFun (ogldev,df); /* open window to size of FBuffer */ vgl_FBufferInq (fbuffer,¶ms[0],¶ms[1]); vgl_DrawFunConfigureWindow (df,VGL_WINDOWSIZE,params); /* Write FBuffer */ vgl_DrawFunOpenWindow (df,text); vgl_DrawFunClear (df); vgl_DrawFunFBufferWrite (df,0,0,0,0,fbuffer); vgl_DrawFunSwap (df); /* wait */ vgl_DrawFunDelay (df,2.); /* close windows */ vgl_DrawFunCloseWindow (df); /* free objects */ vgl_OpenGLDevEnd (ogldev); vgl_DrawFunEnd (df); /* disconnect from X */ vgl_OpenGLDevDisconnect (); }
#include <stdlib.h> #include <string.h> #include "base/base.h" #include "vgl/vgl.h" static void displayFBuffer(vgl_FBuffer *fbuffer, Vchar *inputfile); /*---------------------------------------------------------------------- FBuffer Write MP4 or H264 File ----------------------------------------------------------------------*/ int main(int argc, char **argv) { int i, h264flag, mp4flag; char inputfile[256], outputfile[256]; vgl_FBuffer *fbuffer; Vfloat c[3]; /* check for proper number of arguments */ if(argc < 2) { fprintf(stderr,"Usage: %s [inputfile] [outputfile]\n",argv[0]); fprintf(stderr," inputfile is blank, 'earth.gif' is assumed\n"); fprintf(stderr," output is blank, 'earth_mpeg4.mp4' is assumed\n"); strcpy(inputfile,"earth.gif"); strcpy(outputfile,"earth_mpeg4.mp4"); } else if(argc < 3) { fprintf(stderr,"Usage: %s [inputfile] [outputfile]\n",argv[0]); fprintf(stderr," output is blank, 'earth_mpeg4.mp4' is assumed\n"); strcpy(inputfile,argv[1]); strcpy(outputfile,"earth_mpeg4.mp4"); } else { strcpy(inputfile,argv[1]); strcpy(outputfile,argv[2]); } /* create FBuffer object */ fbuffer = vgl_FBufferBegin(); /* decode input display file format and file name */ if(strstr(inputfile,".tga")) { vgl_FBufferReadTarga (fbuffer,inputfile); } else if(strstr(inputfile,".gif")) { vgl_FBufferReadGIF (fbuffer,inputfile); } else if(strstr(inputfile,".rgb")) { vgl_FBufferReadSGI (fbuffer,inputfile); } else if(strstr(inputfile,".bmp")) { vgl_FBufferReadBMP (fbuffer,inputfile); } else { fprintf(stderr,"Error: Unsupported input file format %s\n",inputfile); exit(1); } if(vgl_FBufferError(fbuffer)) { fprintf(stderr,"Error: Can not read image file %s\n",inputfile); exit(1); } /* decode output display file format and file name */ h264flag = 0; if(strstr(outputfile,"h264")) { h264flag = 1; } else if(strstr(outputfile,"mpeg4")) { mp4flag = 1; } else { fprintf(stderr,"Error: Unsupported output file format %s\n",outputfile); exit(1); } /* display input image */ displayFBuffer (fbuffer, inputfile); vgl_FBufferSetParamf (fbuffer,FBUFFER_FRAMERATE,10.); if(h264flag) { vgl_FBufferOpenFFMPEG (fbuffer,FBUFFER_FFMPEG_H264,outputfile); } else if(mp4flag) { vgl_FBufferOpenFFMPEG (fbuffer,FBUFFER_FFMPEG_MPEG4,outputfile); } /* set border color */ c[0] = 0.; c[1] = .5; c[2] = .75; vgl_FBufferColor (fbuffer,c); /* write 30 images animating the border size */ for(i = 1; i <= 30; i++) { vgl_FBufferBorder (fbuffer,2*i); vgl_FBufferWriteFFMPEG (fbuffer); } /* close file */ vgl_FBufferCloseFFMPEG (fbuffer); /* free objects */ vgl_FBufferEnd (fbuffer); return 0; } /*---------------------------------------------------------------------- display contents of FBuffer object ----------------------------------------------------------------------*/ static void displayFBuffer(vgl_FBuffer *fbuffer, Vchar *inputfile) { Vint params[2]; #ifdef VKI_WIND_X11 Display *display; int screen; #endif vgl_OpenGLDev *ogldev; vgl_DrawFun *df; /* open X display */ #ifdef VKI_WIND_X11 display = XOpenDisplay (0); screen = DefaultScreen (display); vgl_OpenGLDevConnectX (display,screen); #else vgl_OpenGLDevConnectWIN (); #endif /* create drawing functions */ df = vgl_DrawFunBegin(); /* create device objects and load drawing functions */ ogldev = vgl_OpenGLDevBegin(); vgl_OpenGLDevDrawFun (ogldev,df); /* open window to size of FBuffer */ vgl_FBufferInq (fbuffer,¶ms[0],¶ms[1]); vgl_DrawFunConfigureWindow (df,VGL_WINDOWSIZE,params); /* Write FBuffer */ vgl_DrawFunOpenWindow (df,inputfile); vgl_DrawFunFBufferWrite (df,0,0,0,0,fbuffer); vgl_DrawFunSwap (df); /* wait */ vgl_DrawFunDelay (df,5.); /* close windows */ vgl_DrawFunCloseWindow (df); /* free objects */ vgl_OpenGLDevEnd (ogldev); vgl_DrawFunEnd (df); /* disconnect from X */ vgl_OpenGLDevDisconnect (); /* close X display */ #ifdef VKI_WIND_X11 XCloseDisplay (display); #endif }
The example uses a DTee object to split the drawing functions to a DataBuf object and to a device interface object for rendering the surfaces in color in a graphics window. A Pixelmap object is used to capture the frame buffer after the initial drawing. During the data navigation query loop, the Pixelmap object is written repeatedly to the frame buffer and queried information is drawn on it.
The index and parametric coordinates can be used within an application to retrieve any information concerning the entity associated with the index. The parametric coordinates may be used to interpolate application data associated with the entity to the precise parametric coordinate location at the pixel. Note that in this example only two parametric coordinates were used, three coordinates could be used, for example if the entity were a 3D solid finite element.
#include "base/base.h" #include "vgl/vgl.h" #include "vgldev.h" static Vfloat xquads[4][4][3] = { {{2.,-1.,2.}, {2.,-1.,-2.}, {2.,1.,-2.}, {2.,1.,2.}}, {{2.,-1.,-2.}, {-2.,-1.,-2.}, {-2.,1.,-2.}, {2.,1.,-2.}}, {{-2.,-1.,-2.}, {-2.,-1.,2.}, {-2.,1.,2.}, {-2.,1.,-2.}}, {{-2.,-1.,2.}, {2.,-1.,2.}, {2.,1.,2.}, {-2.,1.,2.}} }; static Vfloat rquad[4][3] = { {0.,0.,0.}, {1.,0.,0.}, {1.,1.,0.}, {0.,1.,0.} }; static Vfloat cquads[4][3] = { {1.,0.,0.}, {0.,1.,0.}, {0.,0.,1.}, {.5,.5,.5} }; static Vfloat cwhite[3] = { 1.,1.,1. }; static Vfloat xprompt[3][3] = { {-4.5, -3.5, 0.}, {-4.5, -3.9, 0.}, {-4.5, -4.3, 0.} }; /*---------------------------------------------------------------------- Data Navigator Drawing to a Graphics Window and a Data Buffer ----------------------------------------------------------------------*/ int main() { vgl_DataBuf *databuf; vgl_DTee *dtee; vgl_DrawFun *df, *dfDB, *dfGD; vgl_Xfm *xfm; vgl_Pixelmap *pixelmap; Vint i; Vint xsize, ysize; Vint ix, iy, but1, but2, but3; Vfloat c[3], x[3], tm[4][4]; Vint index, nrws; Vfloat d[3]; Vfloat xi[3]; Vint dc[3]; Vchar stg[33], title[65]; Vint test; /* create drawing function object */ dfGD = vgl_DrawFunBegin(); strcpy(title,"DataBuf Example, "); VglDevCreate (dfGD,VGLDEV_OPENGL,title,&test); /* create databuf */ databuf = vgl_DataBufBegin(); dfDB = vgl_DrawFunBegin (); vgl_DataBufDrawFun (databuf,dfDB); vgl_DataBufSetRender (databuf,VGL_OFF,VGL_OFF,VGL_OFF); vgl_DataBufSetBuffers (databuf,1,3); /* create DTee object */ dtee = vgl_DTeeBegin (); df = vgl_DrawFunBegin (); vgl_DTeeDrawFun (dtee,df); /* link graphics device and data buffer to DTee */ vgl_DTeeSetObject (dtee,VGL_DRAWFUN,dfGD); vgl_DTeeSetObject (dtee,VGL_DRAWFUN_TEE,dfDB); /* open window and set lighting, etc. */ xsize = 400; ysize = 400; vgl_DrawFunPositionWindow (df,200,200,xsize,ysize); vgl_DrawFunOpenWindow (df,title); vgl_DrawFunProjOrtho (df,-5.,5.,-5.,5.,-5.,5.); vgl_DrawFunSetMode (df,VGL_ZBUFFERMODE,VGL_ON); vgl_DrawFunSetMode (df,VGL_LIGHTMODE,VGL_ON); c[0] = .3; c[1] = .3; c[2] = .3; x[0] = 0.; x[1] = 0.; x[2] = 0.; vgl_DrawFunLight (df,0,VGL_LIGHT_AMBIENT,c,x); c[0] = .7; c[1] = .7; c[2] = .7; x[0] = 1.; x[1] = 1.; x[2] = 1.; vgl_DrawFunLight (df,1,VGL_LIGHT_DISTANT,c,x); x[0] = -1.; x[1] = -1.; x[2] = -1.; vgl_DrawFunLight (df,2,VGL_LIGHT_DISTANT,c,x); /* create transformation object */ xfm = vgl_XfmBegin (); /* create pixelmap */ pixelmap = vgl_PixelmapBegin (); /* draw basic scene */ vgl_DrawFunClear (df); /* draw prompt message */ vgl_DrawFunColor (dfGD,cwhite); vgl_DrawFunText (dfGD,xprompt[0],"Left button: index"); vgl_DrawFunText (dfGD,xprompt[1],"Middle button: data"); vgl_DrawFunText (dfGD,xprompt[2],"Right button: quit"); /* draw rectangles */ vgl_DrawFunXfmPush (df); vgl_XfmRotateVector (xfm,48.*.017453,.75,1.,0.); vgl_XfmGetMatrix (xfm,tm); vgl_DrawFunXfmLoad (df,tm); for(i = 0; i < 4; i++) { index = i+1; vgl_DrawFunDataIndex (df,1,1,&index); vgl_DrawFunColor (df,cquads[i]); /* draw gray rectangle with 50% transparency */ if(i == 3) { vgl_DrawFunTrans (df,.5); } else { vgl_DrawFunTrans (df,0.); } vgl_DrawFunPolygon (df,VGL_POLYGON,4,xquads[i],VGL_NOSHADE,NULL); vgl_DrawFunPolygonData (df,VGL_POLYGON,4,xquads[i], 3,(Vfloat*)rquad,VGL_NOSHADE,NULL); } vgl_DrawFunXfmPop (df); vgl_DrawFunSwap (df); /* read pixelmap */ vgl_DrawFunPixelmapCreate (df,pixelmap); vgl_DrawFunPixelmapRead (df,pixelmap); /* prepare graphics device for data navigation */ /* set projection matrix to match screen pixel size */ vgl_DrawFunProjOrtho (dfGD, 0.,(Vfloat)(xsize-1), 0.,(Vfloat)(ysize-1), -1.,1.); /* set modelview matrix identity */ vgl_DrawFunXfmPush (dfGD); vgl_XfmIdentity (xfm); vgl_XfmGetMatrix (xfm,tm); vgl_DrawFunXfmLoad (dfGD,tm); /* data navigation loop */ while (1) { vgl_DrawFunPollMouse (dfGD,&ix,&iy,&but1,&but2,&but3); vgl_DrawFunClear (dfGD); vgl_DrawFunPixelmapWrite (dfGD,pixelmap); vgl_DrawFunColor (dfGD,cwhite); if(but1) { vgl_DataBufGetDataIndex (databuf,ix,iy,&index); xi[0] = ix; xi[1] = iy; xi[2] = 0.; sprintf(stg,"index = %d\n",index); vgl_DrawFunText (dfGD,xi,stg); } else if(but2) { vgl_DataBufGetDataIndex (databuf,ix,iy,&index); xi[0] = ix; xi[1] = iy; xi[2] = 0.; if(index) { vgl_DataBufGetData (databuf,ix,iy,&nrws,d); sprintf(stg,"data = %f",d[0]); vgl_DrawFunText (dfGD,xi,stg); sprintf(stg," %f",d[1]); dc[0] = 0; dc[1] = -15; dc[2] = 0; vgl_DrawFunTextDC (dfGD,xi,dc,stg); sprintf(stg," %f",d[2]); dc[0] = 0; dc[1] = -30; dc[2] = 0; vgl_DrawFunTextDC (dfGD,xi,dc,stg); } else { sprintf(stg,"data = NONE"); vgl_DrawFunText (dfGD,xi,stg); } } else if(but3) { break; } vgl_DrawFunSwap (dfGD); } vgl_DrawFunXfmPop (dfGD); vgl_DrawFunPixelmapDestroy (dfGD,pixelmap); /* close window */ vgl_DrawFunCloseWindow (df); /* free all objects */ vgl_DrawFunEnd (df); vgl_DrawFunEnd (dfGD); vgl_DrawFunEnd (dfDB); vgl_DTeeEnd (dtee); vgl_DataBufEnd (databuf); vgl_XfmEnd (xfm); vgl_PixelmapEnd (pixelmap); VglDevDestroy (); return 0; }
Rendering of data indices is enabled using vgl_DrawFunSetMode with mode VGL_DATAINDEXMAXROWS set to maximum number of data indices to be rendered at any pixel. By default this mode is set to zero which disables data index rendering. Then the data indices are rendered to an off-screen frame buffer. The frame buffer containing the data indices are then read to a FBuffer object using an OpenGLDev specific function vgl_OpenGLDevFBufferDataIndex. The data index at any pixel can now be accessed very quickly from the FBuffer object using vgl_FBufferGetPixel.
Finally the data navigation loop in entered. This loop uses the VGL_UPDATEMODE to quickly refresh the scene while each pass of the navigation loop annotates or highlights the entities picked from the screen.
#include "base/base.h" #include "vgl/vgl.h" #include "vgldev.h" static Vfloat xquads[4][4][3] = { {{2.,-1.,2.}, {2.,-1.,-2.}, {2.,1.,-2.}, {2.,1.,2.}}, {{2.,-1.,-2.}, {-2.,-1.,-2.}, {-2.,1.,-2.}, {2.,1.,-2.}}, {{-2.,-1.,-2.}, {-2.,-1.,2.}, {-2.,1.,2.}, {-2.,1.,-2.}}, {{-2.,-1.,2.}, {2.,-1.,2.}, {2.,1.,2.}, {-2.,1.,2.}} }; /* red, green, blue, gray */ static Vfloat cquads[4][3] = { {1.,0.,0.}, {0.,1.,0.}, {0.,0.,1.}, {.5,.5,.5} }; static Vfloat cwhite[3] = { 1.,1.,1. }; static Vfloat xprompt[3][3] = { {-4.5, -3.5, 0.}, {-4.5, -3.9, 0.}, {-4.5, -4.3, 0.} }; static Vint useoit = 1; static Vint multisample = 0; /*---------------------------------------------------------------------- Data Navigator Framework for a Data Navigator Using OpenGLDev ----------------------------------------------------------------------*/ int main() { vgl_DrawFun *df; vgl_Xfm *xfm; vgl_OpenGLDev *ogldev; vgl_FBuffer *fbuffer; #ifdef VKI_WIND_X11 Display *display; int screen; #endif Vint i; Vint ix, iy, but1, but2, but3; Vfloat c[3], x[3], tm[4][4]; Vint index; Vfloat xi[3]; Vchar stg[33]; Vint xsize, ysize; /* create drawing function object */ #ifdef VKI_WIND_X11 display = XOpenDisplay (0); screen = DefaultScreen (display); vgl_OpenGLDevConnectX (display,screen); #else vgl_OpenGLDevConnectWIN (); #endif /* create GL device and drawing functions */ ogldev = vgl_OpenGLDevBegin(); df = vgl_DrawFunBegin(); vgl_OpenGLDevDrawFun (ogldev,df); if(multisample) { vgl_DrawFunVisualWindow (df,VGL_VISUAL_MULTISAMPLE); } /* open window */ xsize = 400; ysize = 400; vgl_DrawFunPositionWindow (df,200,200,xsize,ysize); vgl_DrawFunOpenWindow (df,"OpenGL window"); if(multisample) { vgl_DrawFunSetMode (df,VGL_MULTISAMPLEMODE,VGL_ON); } /* enable data index */ vgl_DrawFunSetMode (df,VGL_DATAINDEXMAXROWS,1); vgl_DrawFunSetMode (df,VGL_SHADERMODE,1); if(useoit) { vgl_DrawFunSetMode (df,VGL_OITMODE,1); } vgl_DrawFunProjOrtho (df,-5.,5.,-5.,5.,-5.,5.); vgl_DrawFunSetMode (df,VGL_ZBUFFERMODE,VGL_ON); vgl_DrawFunSetMode (df,VGL_LIGHTMODE,VGL_ON); c[0] = .3; c[1] = .3; c[2] = .3; x[0] = 0.; x[1] = 0.; x[2] = 0.; vgl_DrawFunLight (df,0,VGL_LIGHT_AMBIENT,c,x); c[0] = .7; c[1] = .7; c[2] = .7; x[0] = 1.; x[1] = 1.; x[2] = 1.; vgl_DrawFunLight (df,1,VGL_LIGHT_DISTANT,c,x); x[0] = -1.; x[1] = -1.; x[2] = -1.; vgl_DrawFunLight (df,2,VGL_LIGHT_DISTANT,c,x); /* create transformation object */ xfm = vgl_XfmBegin (); /* draw basic scene */ /* draw rectangles */ vgl_XfmRotateVector (xfm,48.*.017453,.75,1.,0.); vgl_XfmGetMatrix (xfm,tm); vgl_DrawFunClear (df); /* draw prompt message */ vgl_DrawFunColor (df,cwhite); vgl_DrawFunText (df,xprompt[0],"Left button: index"); vgl_DrawFunText (df,xprompt[1],"Middle button: currently inactive"); vgl_DrawFunText (df,xprompt[2],"Right button: quit"); vgl_DrawFunXfmPush (df); vgl_DrawFunXfmLoad (df,tm); /* draw rectangles and data indices */ for(i = 0; i < 4; i++) { index = i-101; vgl_DrawFunDataIndex (df,1,1,&index); vgl_DrawFunColor (df,cquads[i]); /* draw gray rectangle with 50% transparency */ if(i == 3) { vgl_DrawFunTrans (df,.5); } else { vgl_DrawFunTrans (df,0.); } vgl_DrawFunPolygon (df,VGL_POLYGON,4,xquads[i],VGL_NOSHADE,NULL); } vgl_DrawFunXfmPop (df); vgl_DrawFunSwap (df); /* retrieve indices at all pixels */ fbuffer = vgl_FBufferBegin (); /* need to use OpenGLDev specific function */ vgl_OpenGLDevFBufferDataIndex (ogldev,1,fbuffer); vgl_DrawFunSetMode (df,VGL_DATAINDEXMAXROWS,0); vgl_DrawFunSetMode (df,VGL_SHADERMODE,0); if(useoit) { vgl_DrawFunSetMode (df,VGL_OITMODE,0); } /* prepare graphics device for data navigation */ /* grab current frame buffer and zbuffer */ vgl_DrawFunSetMode (df,VGL_UPDATEMODE,VGL_ON); /* turn zbuffer off so text always visible */ vgl_DrawFunSetMode (df,VGL_ZBUFFERMODE,VGL_OFF); /* set projection matrix to match screen pixel size */ vgl_DrawFunProjOrtho (df,0.,(Vfloat)(xsize-1), 0.,(Vfloat)(ysize-1),-1.,1.); /* set modelview matrix identity */ vgl_DrawFunXfmPush (df); vgl_XfmIdentity (xfm); vgl_XfmGetMatrix (xfm,tm); vgl_DrawFunXfmLoad (df,tm); /* data navigation loop */ while (1) { vgl_DrawFunPollMouse (df,&ix,&iy,&but1,&but2,&but3); vgl_DrawFunClear (df); vgl_DrawFunColor (df,cwhite); if(but1) { vgl_FBufferGetPixeli (fbuffer,ix,iy,&index); xi[0] = ix; xi[1] = iy; xi[2] = 0.; sprintf(stg,"index = %d\n",index); vgl_DrawFunText (df,xi,stg); } else if(but3) { break; } vgl_DrawFunSwap (df); } /* close window */ vgl_DrawFunCloseWindow (df); /* free all objects */ vgl_FBufferEnd (fbuffer); vgl_DrawFunEnd (df); vgl_XfmEnd (xfm); vgl_OpenGLDevEnd (ogldev); return 0; }
When performing object picking using selection mode, it is useful to be able to regenerate the 3D scene for rendering, selection and extent box calculation. The four rectangles of Example 9 are initially drawn to a display list object using the DList module for this purpose. During the polling loop, the scene is first drawn to the screen in normal render mode, then depending upon which mouse button is depressed, the device is placed into selection or extent mode using the function vgl_DrawFunRender.
If selection mode is specified, the selection region and hit buffers are defined and the scene is redrawn. The frame buffer is unchanged - instead hit detection in the selection region is performed. The number of DataIndex hits in the selection region under the cursor is queried using vgl_DrawFunSelectQuery. The actual DataIndex values and depth information are retrieved from the selection buffers and displayed.
If extent calculation is specified, the device is placed in extent mode and the scene is redrawn. As in selection mode, the frame buffer is unchanged. The extent box is queried using vgl_DrawFunExtentQuery and displayed.
#include "base/base.h" #include "vgl/vgl.h" #include "vgldev.h" static void draw_scene(vgl_DrawFun *df, vgl_DList *dlist, vgl_Xfm *xfm); static void draw_select(vgl_DrawFun *df, Vint ix, Vint iy, Vint numhits, Vint indexlist[], Vfloat mindepth[]); static void draw_extent(vgl_DrawFun *df, Vfloat lft, Vfloat rgt, Vfloat btm, Vfloat top); static Vfloat xquads[4][4][3] = { {{2.,-1.,2.}, {2.,-1.,-2.}, {2.,1.,-2.}, {2.,1.,2.}}, {{2.,-1.,-2.}, {-2.,-1.,-2.}, {-2.,1.,-2.}, {2.,1.,-2.}}, {{-2.,-1.,-2.}, {-2.,-1.,2.}, {-2.,1.,2.}, {-2.,1.,-2.}}, {{-2.,-1.,2.}, {2.,-1.,2.}, {2.,1.,2.}, {-2.,1.,2.}} }; static Vfloat rquad[4][3] = { {0.,0.,0.}, {1.,0.,0.}, {1.,1.,0.}, {0.,1.,0.} }; static Vfloat cquads[4][3] = { {1.,0.,0.}, {0.,1.,0.}, {0.,0.,1.}, {.5,.5,.5} }; static Vfloat cwhite[3] = { 1.,1.,1. }; static Vfloat xprompt[3][3] = { {-4.5, -3.5, 0.}, {-4.5, -3.9, 0.}, {-4.5, -4.3, 0.} }; /*---------------------------------------------------------------------- Select and Extent Example ----------------------------------------------------------------------*/ int main() { vgl_DList *dlist; vgl_DrawFun *dfGD, *dfDL; vgl_Xfm *xfm; Vint i; Vint xsize, ysize; Vint ix, iy, but1, but2, but3; Vfloat c[3], x[3]; Vint index; Vfloat lft, rgt, btm, top; Vfloat znear, zfar; Vint indexlist[2]; Vfloat mindepth[2], maxdepth[2]; Vint numhits; Vint iparam[4]; Vchar title[65]; Vint test; /* create drawing function object */ dfGD = vgl_DrawFunBegin(); strcpy(title,"Selection Example, "); VglDevCreate (dfGD,VGLDEV_OPENGL,title,&test); /* create DList device */ dlist = vgl_DListBegin (); dfDL = vgl_DrawFunBegin (); vgl_DListDrawFun (dlist,dfDL); vgl_DListSetObject (dlist,VGL_DRAWFUN,dfGD); /* place quadrilaterals in display list */ for(i = 0; i < 4; i++) { index = i+1; vgl_DrawFunDataIndex (dfDL,1,1,&index); vgl_DrawFunColor (dfDL,cquads[i]); vgl_DrawFunPolygon (dfDL,VGL_POLYGON,4,xquads[i],VGL_NOSHADE,NULL); vgl_DrawFunPolygonData (dfDL,VGL_POLYGON,4,xquads[i], 3,(Vfloat*)rquad,VGL_NOSHADE,NULL); } /* open window and set lighting, etc. */ xsize = 400; ysize = 400; vgl_DrawFunPositionWindow (dfGD,200,200,xsize,ysize); vgl_DrawFunOpenWindow (dfGD,title); vgl_DrawFunProjOrtho (dfGD,-5.,5.,-5.,5.,-5.,5.); vgl_DrawFunSetMode (dfGD,VGL_ZBUFFERMODE,VGL_ON); vgl_DrawFunSetMode (dfGD,VGL_LIGHTMODE,VGL_ON); c[0] = .3; c[1] = .3; c[2] = .3; x[0] = 0.; x[1] = 0.; x[2] = 0.; vgl_DrawFunLight (dfGD,0,VGL_LIGHT_AMBIENT,c,x); c[0] = .7; c[1] = .7; c[2] = .7; x[0] = 1.; x[1] = 1.; x[2] = 1.; vgl_DrawFunLight (dfGD,1,VGL_LIGHT_DISTANT,c,x); x[0] = -1.; x[1] = -1.; x[2] = -1.; vgl_DrawFunLight (dfGD,2,VGL_LIGHT_DISTANT,c,x); /* create transformation object */ xfm = vgl_XfmBegin (); /* draw loop */ while (1) { vgl_DrawFunClear (dfGD); /* draw prompt message */ vgl_DrawFunColor (dfGD,cwhite); vgl_DrawFunText (dfGD,xprompt[0],"Left button: select"); vgl_DrawFunText (dfGD,xprompt[1],"Middle button: extent"); vgl_DrawFunText (dfGD,xprompt[2],"Right button: quit"); /* draw quads */ draw_scene (dfGD,dlist,xfm); vgl_DrawFunSwap (dfGD); /* poll mouse */ vgl_DrawFunPollMouse (dfGD,&ix,&iy,&but1,&but2,&but3); /* select */ if(but1) { vgl_DrawFunSelectBuffer (dfGD,2,indexlist,mindepth,maxdepth); vgl_DrawFunRender (dfGD,VGL_SELECT); iparam[0] = ix; iparam[1] = ix; iparam[2] = iy; iparam[3] = iy; vgl_DrawFunSelectRegion (dfGD,VGL_REGION_RECTANGLE,iparam); draw_scene (dfGD,dlist,xfm); vgl_DrawFunRender (dfGD,VGL_RENDER); vgl_DrawFunSelectQuery (dfGD,&numhits); vgl_DrawFunProjOrtho (dfGD,0.,(Vfloat)(xsize-1), 0.,(Vfloat)(ysize-1), -1.,1.); draw_select (dfGD,ix,iy,numhits,indexlist,mindepth); vgl_DrawFunProjOrtho (dfGD,-5.,5.,-5.,5.,-5.,5.); /* extent */ } else if(but2) { vgl_DrawFunRender (dfGD,VGL_EXTENT); draw_scene (dfGD,dlist,xfm); vgl_DrawFunRender (dfGD,VGL_RENDER); vgl_DrawFunExtentQuery (dfGD,&lft,&rgt,&btm,&top,&znear,&zfar); vgl_DrawFunProjOrtho (dfGD,0.,(Vfloat)(xsize-1), 0.,(Vfloat)(ysize-1), -1.,1.); draw_extent (dfGD,lft,rgt,btm,top); vgl_DrawFunProjOrtho (dfGD,-5.,5.,-5.,5.,-5.,5.); /* quit */ } else if(but3) { break; } } /* close window */ vgl_DrawFunCloseWindow (dfGD); /* free all objects */ vgl_DrawFunEnd (dfGD); vgl_DrawFunEnd (dfDL); vgl_DListEnd (dlist); vgl_XfmEnd (xfm); VglDevDestroy (); return 0; } static void draw_scene(vgl_DrawFun *df, vgl_DList *dlist, vgl_Xfm *xfm) { Vfloat tm[4][4]; /* draw scene in display list */ vgl_DrawFunXfmPush (df); vgl_XfmRotateVector (xfm,48.*.017453,.75,1.,0.); vgl_XfmGetMatrix (xfm,tm); vgl_DrawFunXfmLoad (df,tm); vgl_DListCall (dlist); vgl_DrawFunXfmPop (df); } static void draw_select(vgl_DrawFun *df, Vint ix, Vint iy, Vint numhits, Vint indexlist[], Vfloat mindepth[]) { Vfloat xi[3]; Vchar stg[33]; vgl_DrawFunSetMode (df,VGL_FRONTBUFFERDRAWMODE,VGL_ON); vgl_DrawFunSetMode (df,VGL_ZBUFFERMODE,VGL_OFF); vgl_DrawFunColor (df,cwhite); xi[0] = ix; xi[1] = iy; xi[2] = 0.; if(numhits == 0) { sprintf(stg,"no hits\n"); } else if(numhits == 1) { sprintf(stg,"index = %d\n",indexlist[0]); } else if(numhits == 2) { if(mindepth[0] < mindepth[1]) { sprintf(stg,"index = %d,%d\n",indexlist[0],indexlist[1]); } else { sprintf(stg,"index = %d,%d\n",indexlist[1],indexlist[0]); } } vgl_DrawFunText (df,xi,stg); vgl_DrawFunSetMode (df,VGL_ZBUFFERMODE,VGL_ON); vgl_DrawFunSetMode (df,VGL_FRONTBUFFERDRAWMODE,VGL_OFF); vgl_DrawFunFlush (df); } static void draw_extent(vgl_DrawFun *df, Vfloat lft, Vfloat rgt, Vfloat btm, Vfloat top) { Vfloat xrect[4][3]; /* draw white extent rectangle */ vgl_DrawFunSetMode (df,VGL_FRONTBUFFERDRAWMODE,VGL_ON); vgl_DrawFunColor (df,cwhite); xrect[0][0] = lft; xrect[0][1] = btm; xrect[0][2] = 0.; xrect[1][0] = rgt; xrect[1][1] = btm; xrect[1][2] = 0.; xrect[2][0] = rgt; xrect[2][1] = top; xrect[2][2] = 0.; xrect[3][0] = lft; xrect[3][1] = top; xrect[3][2] = 0.; vgl_DrawFunPolyLine (df,VGL_LINELOOP,4,xrect); vgl_DrawFunFlush (df); vgl_DrawFunSetMode (df,VGL_FRONTBUFFERDRAWMODE,VGL_OFF); }
As opposed to picking with selection mode, it is not necessary to be able to regenerate the 3D scene explicitly for selection. Since the intersection of the line of sight with the appropriate 3D objects is performed by the application instead of the rendering software, the application can customize the intersection test to pick "hollow" objects or perform fast spatial searches to optimize the picking process.
The four rectangles of Example 9 are initially drawn to a display list object using the DList module. Note that the "index" does not need to be defined since selection mode will not used. During the polling loop, the scene is first drawn to the screen. A Xfmstack object is loaded with the current viewing transformation when the scene is drawn. A device coordinate (pixel) point is selected by the cursor in the plane of the window. Two points, dnear and dfar at depth device coordinates 0. and 1. respectively are then unprojected to world coordinates. The application must then intersect this line with the appropriate 3D geometric objects, in this example 4 rectangles, to determine which objects have been picked.
#include "base/base.h" #include "vgl/vgl.h" #include "vgldev.h" static void draw_scene(vgl_DrawFun *df, vgl_DList *dlist, vgl_Xfm *xfm, vgl_Xfmstack *xfmstack); static void intersect_elem(Vint nelem, Vfloat xquads[][4][3], Vfloat wnear[3], Vfloat wfar[3], Vint *numints, Vint indexlist[]); static void draw_pick(vgl_DrawFun *df, Vint ix, Vint iy, Vint numints, Vint indexlist[]); static Vfloat xquads[4][4][3] = { {{2.,-1.,2.}, {2.,-1.,-2.}, {2.,1.,-2.}, {2.,1.,2.}}, {{2.,-1.,-2.}, {-2.,-1.,-2.}, {-2.,1.,-2.}, {2.,1.,-2.}}, {{-2.,-1.,-2.}, {-2.,-1.,2.}, {-2.,1.,2.}, {-2.,1.,-2.}}, {{-2.,-1.,2.}, {2.,-1.,2.}, {2.,1.,2.}, {-2.,1.,2.}} }; static Vfloat rquad[4][3] = { {0.,0.,0.}, {1.,0.,0.}, {1.,1.,0.}, {0.,1.,0.} }; static Vfloat cquads[4][3] = { {1.,0.,0.}, {0.,1.,0.}, {0.,0.,1.}, {.5,.5,.5} }; static Vfloat cwhite[3] = { 1.,1.,1. }; static Vfloat xprompt[3][3] = { {-4.5, -3.5, 0.}, {-4.5, -3.9, 0.}, {-4.5, -4.3, 0.} }; /*---------------------------------------------------------------------- Project/Unproject Example ----------------------------------------------------------------------*/ int main() { vgl_DList *dlist; vgl_DrawFun *dfGD, *dfDL; vgl_Xfm *xfm; vgl_Xfmstack *xfmstack; Vint i; Vint xsize, ysize; Vint ix, iy, but1, but2, but3; Vfloat c[3], x[3]; Vfloat dnear[3], dfar[3]; Vfloat wnear[3], wfar[3]; Vchar title[65]; Vint test; Vint numints, indexlist[4]; /* create drawing function object */ dfGD = vgl_DrawFunBegin(); strcpy(title,"Project/Unproject Example, "); VglDevCreate (dfGD,VGLDEV_OPENGL,title,&test); /* create DList device */ dlist = vgl_DListBegin (); dfDL = vgl_DrawFunBegin (); vgl_DListDrawFun (dlist,dfDL); vgl_DListSetObject (dlist,VGL_DRAWFUN,dfGD); /* place quadrilaterals in display list */ for(i = 0; i < 4; i++) { vgl_DrawFunColor (dfDL,cquads[i]); vgl_DrawFunPolygon (dfDL,VGL_POLYGON,4,xquads[i],VGL_NOSHADE,NULL); vgl_DrawFunPolygonData (dfDL,VGL_POLYGON,4,xquads[i], 3,(Vfloat*)rquad,VGL_NOSHADE,NULL); } /* open window and set lighting, etc. */ xsize = 400; ysize = 400; vgl_DrawFunPositionWindow (dfGD,200,200,xsize,ysize); vgl_DrawFunOpenWindow (dfGD,title); vgl_DrawFunProjOrtho (dfGD,-5.,5.,-5.,5.,-5.,5.); vgl_DrawFunSetMode (dfGD,VGL_ZBUFFERMODE,VGL_ON); vgl_DrawFunSetMode (dfGD,VGL_LIGHTMODE,VGL_ON); c[0] = .3; c[1] = .3; c[2] = .3; x[0] = 0.; x[1] = 0.; x[2] = 0.; vgl_DrawFunLight (dfGD,0,VGL_LIGHT_AMBIENT,c,x); c[0] = .7; c[1] = .7; c[2] = .7; x[0] = 1.; x[1] = 1.; x[2] = 1.; vgl_DrawFunLight (dfGD,1,VGL_LIGHT_DISTANT,c,x); x[0] = -1.; x[1] = -1.; x[2] = -1.; vgl_DrawFunLight (dfGD,2,VGL_LIGHT_DISTANT,c,x); /* create transformation object */ xfm = vgl_XfmBegin (); /* create transformation stack object */ xfmstack = vgl_XfmstackBegin (); /* draw loop */ while (1) { vgl_DrawFunClear (dfGD); /* draw prompt message */ vgl_DrawFunColor (dfGD,cwhite); vgl_DrawFunText (dfGD,xprompt[0],"Left button: pick"); vgl_DrawFunText (dfGD,xprompt[1],"Middle button: refresh"); vgl_DrawFunText (dfGD,xprompt[2],"Right button: quit"); /* draw quads */ draw_scene (dfGD,dlist,xfm,xfmstack); vgl_DrawFunSwap (dfGD); /* poll mouse */ vgl_DrawFunPollMouse (dfGD,&ix,&iy,&but1,&but2,&but3); /* pick */ if(but1) { dnear[0] = ix; dnear[1] = iy; dnear[2] = 0.; dfar[0] = ix; dfar[1] = iy; dfar[2] = 1.; /* unproject near and far points */ vgl_XfmstackUnproject (xfmstack,dnear[0],dnear[1],dnear[2], &wnear[0],&wnear[1],&wnear[2]); vgl_XfmstackUnproject (xfmstack,dfar[0],dfar[1],dfar[2], &wfar[0],&wfar[1],&wfar[2]); /* intersect line with elements */ intersect_elem (4,xquads,wnear,wfar,&numints,indexlist); vgl_DrawFunProjOrtho (dfGD,0.,(Vfloat)(xsize-1), 0.,(Vfloat)(ysize-1), -1.,1.); draw_pick (dfGD,ix,iy,numints,indexlist); vgl_DrawFunProjOrtho (dfGD,-5.,5.,-5.,5.,-5.,5.); /* refresh */ } else if(but2) { draw_scene (dfGD,dlist,xfm,xfmstack); /* quit */ } else if(but3) { break; } } /* close window */ vgl_DrawFunCloseWindow (dfGD); /* free all objects */ vgl_DrawFunEnd (dfGD); vgl_DrawFunEnd (dfDL); vgl_DListEnd (dlist); vgl_XfmEnd (xfm); vgl_XfmstackEnd (xfmstack); VglDevDestroy (); return 0; } static void draw_scene(vgl_DrawFun *df, vgl_DList *dlist, vgl_Xfm *xfm, vgl_Xfmstack *xfmstack) { Vfloat tm[4][4]; Vint iparam[4]; /* draw scene in display list */ vgl_DrawFunXfmPush (df); vgl_XfmRotateVector (xfm,48.*.017453,.75,1.,0.); vgl_XfmGetMatrix (xfm,tm); vgl_DrawFunXfmLoad (df,tm); /* query and load complete viewing transformation into transformation stack object */ vgl_DrawFunGetFloat (df,VGL_MODELVIEWMATRIX,(Vfloat*)tm); vgl_XfmSetMatrix (xfm,tm); vgl_XfmstackLoad (xfmstack,xfm); vgl_DrawFunGetFloat (df,VGL_PROJECTIONMATRIX,(Vfloat*)tm); vgl_XfmSetMatrix (xfm,tm); vgl_XfmstackProj (xfmstack,xfm); vgl_DrawFunGetInteger (df,VGL_VIEWPORT,iparam); vgl_XfmstackSetViewport (xfmstack,iparam[0],iparam[1],iparam[2],iparam[3]); vgl_DListCall (dlist); vgl_DrawFunXfmPop (df); } static void intersect_elem(Vint nelem, Vfloat xquads[][4][3], Vfloat wnear[3], Vfloat wfar[3], Vint *numints, Vint indexlist[]) { Vint j, k; Vfloat v1[3], v2[3], nv[3]; Vfloat wd[3], vp[3]; Vfloat d, t; Vfloat a, b; *numints = 0; /* loop through elements */ for(j = 0; j < nelem; j++) { for(k = 0; k < 3; k++) { v1[k] = xquads[j][1][k] - xquads[j][0][k]; v2[k] = xquads[j][3][k] - xquads[j][0][k]; wd[k] = wnear[k] - wfar[k]; } nv[0] = v1[1]*v2[2]-v1[2]*v2[1]; nv[1] = v1[2]*v2[0]-v1[0]*v2[2]; nv[2] = v1[0]*v2[1]-v1[1]*v2[0]; d = -(xquads[j][0][0] * nv[0] + xquads[j][0][1] * nv[1] + xquads[j][0][2] * nv[2]); t = - (d + (nv[0]*wfar[0] + nv[1]*wfar[1] + nv[2]*wfar[2])) / (nv[0]*wd[0] + nv[1]*wd[1] + nv[2]*wd[2]); for(k = 0; k < 3; k++) { vp[k] = (wfar[k] + t*wd[k]) - xquads[j][0][k]; } /* project onto 4 by 2 rectangle squared base and height */ a = (v1[0]*vp[0] + v1[1]*vp[1] + v1[2]*vp[2]) / 16.; b = (v2[0]*vp[0] + v2[1]*vp[1] + v2[2]*vp[2]) / 4.; /* check for within rectangle limits */ if(a >= 0. && a <= 1. && b >= 0. && b <= 1.) { indexlist[*numints] = j+1; *numints += 1; } } } static void draw_pick(vgl_DrawFun *df, Vint ix, Vint iy, Vint numints, Vint indexlist[]) { Vfloat xi[3]; Vchar stg[33]; vgl_DrawFunSetMode (df,VGL_FRONTBUFFERDRAWMODE,VGL_ON); vgl_DrawFunSetMode (df,VGL_ZBUFFERMODE,VGL_OFF); vgl_DrawFunColor (df,cwhite); xi[0] = ix; xi[1] = iy; xi[2] = 0.; if(numints == 0) { sprintf(stg,"no intersections\n"); } else if(numints == 1) { sprintf(stg,"index = %d\n",indexlist[0]); } else if(numints == 2) { sprintf(stg,"index = %d,%d\n",indexlist[0],indexlist[1]); } vgl_DrawFunText (df,xi,stg); vgl_DrawFunSetMode (df,VGL_ZBUFFERMODE,VGL_ON); vgl_DrawFunSetMode (df,VGL_FRONTBUFFERDRAWMODE,VGL_OFF); vgl_DrawFunFlush (df); }
A triangle and quadrilateral polygon are drawn with each texture. A texture is enabled by calling vgl_DrawFunTextureSelect. Finally the same polygons are drawn with texture mapping disabled. In this case, the base color of white is unaltered by a texture map.
#include "base/base.h" #include "vgl/vgl.h" #include "vgldev.h" static void draw_tri_and_quad(vgl_DrawFun *df, Vint index); static Vfloat xtri[4][3] = { {0.,.5,0.}, {.5,-.5,0.}, {-.5,-.5,0.}, {-1.,.5,0.} }; static Vfloat ttri[4] = { 0.,0.,1.,1. }; /*---------------------------------------------------------------------- Draw Textured Polygons ----------------------------------------------------------------------*/ int main() { vgl_DrawFun *df; vgl_Texture *texture; int i; Vchar title[65]; Vint test; Vfloat cgray[64][4]; Vfloat gray; /* create drawing functions */ df = vgl_DrawFunBegin(); strcpy(title,"Texture Example, "); VglDevCreate (df,VGLDEV_OPENGL,title,&test); /* open windows and file */ vgl_DrawFunPositionWindow (df,400,400,400,300); vgl_DrawFunOpenWindow (df,title); /* define textures */ texture = vgl_TextureBegin (); /* built-in is index 1 */ vgl_TextureLoad (texture,TEXTURE_HUE_BANDED); vgl_DrawFunTextureDefine (df,1,texture); /* gray banded is index 2 */ for(i = 0; i < 64; i++) { gray = i / 64.; gray = ((int)(gray*10)) / 10.; cgray[i][0] = gray; cgray[i][1] = gray; cgray[i][2] = gray; cgray[i][3] = 1.; } vgl_TextureDef (texture,4,64,1); vgl_TextureSetColors (texture,(Vfloat*)cgray); vgl_DrawFunTextureDefine (df,2,texture); /* free texture object */ vgl_TextureEnd (texture); /* draw with texture 1 */ draw_tri_and_quad (df,1); /* draw with texture 2 */ draw_tri_and_quad (df,2); /* draw with no texturing */ draw_tri_and_quad (df,0); /* close windows */ vgl_DrawFunCloseWindow (df); /* free objects */ vgl_DrawFunEnd (df); VglDevDestroy (); return 0; } /*---------------------------------------------------------------------- utility ----------------------------------------------------------------------*/ static void draw_tri_and_quad(vgl_DrawFun *df, Vint index) { Vfloat c[3]; /* draw triangle */ vgl_DrawFunClear (df); /* set white base color */ c[0] = 1.; c[1] = 1.; c[2] = 1.; vgl_DrawFunColor (df,c); vgl_DrawFunTextureSelect (df,index); /* draw triangle outlined in yellow */ vgl_DrawFunPolygon (df,VGL_POLYGON,3,xtri,VGL_1DTEXTURE,(Vfloat*)ttri); /* set outline color and turn off texturing */ c[0] = 1.; c[1] = 1.; c[2] = 0.; vgl_DrawFunColor (df,c); vgl_DrawFunTextureSelect (df,0); vgl_DrawFunLineWidth (df,4); /* draw outline */ vgl_DrawFunPolyLine (df,VGL_LINELOOP,3,xtri); /* set texturing back on */ vgl_DrawFunTextureSelect (df,index); vgl_DrawFunSwap (df); vgl_DrawFunDelay (df,2.); /* draw quadrilateral */ vgl_DrawFunClear (df); c[0] = 1.; c[1] = 1.; c[2] = 1.; vgl_DrawFunColor (df,c); vgl_DrawFunPolygon (df,VGL_POLYGON,4,xtri,VGL_1DTEXTURE,(Vfloat*)ttri); vgl_DrawFunSwap (df); vgl_DrawFunDelay (df,2.); }
#include "base/base.h" #include "vgl/vgl.h" #include "vgldev.h" static void draw_quad(vgl_DrawFun *df, Vchar *text); static Vfloat xquad[4][3] = { {.5,-.5,0.}, {.5,.5,0.}, {-.5,.5,0.}, {-.5,-.5,0.} }; /* list of built-in bitmaps to display */ static Vint lbitmap[32] = { BITMAP_XES5, BITMAP_XES7, BITMAP_CIRCLES5, BITMAP_CIRCLES7, BITMAP_DIAMONDS5, BITMAP_DIAMONDS7, BITMAP_BOXES5, BITMAP_BOXES7, BITMAP_SQUARE4, BITMAP_SQUARE8, BITMAP_SQUARE8B, BITMAP_SQUARE16B, BITMAP_CROSS8, BITMAP_CROSS8B, BITMAP_CROSS16, BITMAP_CROSS16B, BITMAP_BDIAGONAL8, BITMAP_BDIAGONAL8B, BITMAP_BDIAGONAL16, BITMAP_BDIAGONAL16B, BITMAP_FDIAGONAL8, BITMAP_FDIAGONAL8B, BITMAP_FDIAGONAL16, BITMAP_FDIAGONAL16B, BITMAP_HORIZONTAL4, BITMAP_HORIZONTAL8, BITMAP_HORIZONTAL8B, BITMAP_HORIZONTAL16B, BITMAP_VERTICAL4, BITMAP_VERTICAL8, BITMAP_VERTICAL8B, BITMAP_VERTICAL16B }; /* character string name of built-in bitmaps */ static Vchar *cbitmap[32] = { "BITMAP_XES5", "BITMAP_XES7", "BITMAP_CIRCLES5", "BITMAP_CIRCLES7", "BITMAP_DIAMONDS5", "BITMAP_DIAMONDS7", "BITMAP_BOXES5", "BITMAP_BOXES7", "BITMAP_SQUARE4", "BITMAP_SQUARE8", "BITMAP_SQUARE8B", "BITMAP_SQUARE16B", "BITMAP_CROSS8", "BITMAP_CROSS8B", "BITMAP_CROSS16", "BITMAP_CROSS16B", "BITMAP_BDIAGONAL8", "BITMAP_BDIAGONAL8B", "BITMAP_BDIAGONAL16", "BITMAP_BDIAGONAL16B", "BITMAP_FDIAGONAL8", "BITMAP_FDIAGONAL8B", "BITMAP_FDIAGONAL16", "BITMAP_FDIAGONAL16B", "BITMAP_HORIZONTAL4", "BITMAP_HORIZONTAL8", "BITMAP_HORIZONTAL8B", "BITMAP_HORIZONTAL16B", "BITMAP_VERTICAL4", "BITMAP_VERTICAL8", "BITMAP_VERTICAL8B", "BITMAP_VERTICAL16B" }; /* user defined bitmap */ static unsigned char userpat[8] = { 0x01, 0x01, 0x11, 0x39, 0x11, 0x01, 0x01, 0xff }; /* the user defined bitmap looks like this 0000000x 0000000x 000x000x 00xxx00x 000x000x 0000000x 0000000x xxxxxxxx */ /*---------------------------------------------------------------------- Drawing Stippled Polygons Using Bitmap ----------------------------------------------------------------------*/ int main() { vgl_DrawFun *df; vgl_Bitmap *bitmap; int i; Vchar title[65]; Vint test; /* create drawing functions */ df = vgl_DrawFunBegin(); strcpy(title,"Bitmap Example, "); VglDevCreate (df,VGLDEV_OPENGL,title,&test); /* open windows and file */ vgl_DrawFunPositionWindow (df,400,400,400,300); vgl_DrawFunOpenWindow (df,title); /* define bitmap */ bitmap = vgl_BitmapBegin (); /* loop through built-in bitmaps */ for(i = 0; i < 32; i++) { /* load and define */ vgl_BitmapLoad (bitmap,lbitmap[i]); vgl_DrawFunBitmapDefine (df,1,bitmap); /* now draw */ vgl_DrawFunBitmapSelect (df,1); draw_quad (df,cbitmap[i]); } /* draw user defined bitmap */ vgl_BitmapDef (bitmap,8,8); vgl_BitmapSetRast (bitmap,userpat); vgl_DrawFunBitmapDefine (df,1,bitmap); vgl_DrawFunBitmapSelect (df,1); draw_quad (df,"User Bitmap"); /* free bitmap object */ vgl_BitmapEnd (bitmap); /* draw with no bitmap */ vgl_DrawFunBitmapSelect (df,0); draw_quad (df,"No Bitmap"); /* close windows */ vgl_DrawFunCloseWindow (df); /* free objects */ vgl_DrawFunEnd (df); VglDevDestroy (); return 0; } /*---------------------------------------------------------------------- utility ----------------------------------------------------------------------*/ static void draw_quad(vgl_DrawFun *df, Vchar *text) { Vfloat c[3]; Vfloat xtext[3]; /* draw quad */ vgl_DrawFunClear (df); /* set white color */ c[0] = 1.; c[1] = 1.; c[2] = 1.; vgl_DrawFunColor (df,c); /* draw text */ xtext[0] = -.5; xtext[1] = .8; xtext[2] = 0.; vgl_DrawFunText (df,xtext,text); /* draw quadrilateral outlined in red */ vgl_DrawFunPolygon (df,VGL_POLYGON,4,xquad,VGL_NOSHADE,NULL); /* set outline color */ c[0] = 1.; c[1] = 0.; c[2] = 0.; vgl_DrawFunColor (df,c); vgl_DrawFunLineWidth (df,1); /* draw outline */ vgl_DrawFunPolyLine (df,VGL_LINELOOP,4,xquad); vgl_DrawFunSwap (df); vgl_DrawFunDelay (df,2.); }
#include "base/base.h" #include "vgl/vgl.h" #include "vgldev.h" static void draw_quad(vgl_DrawFun *df, Vint index, Vint tdim); /* coordinates of quadrilateral */ static Vfloat xquad[4][3] = { {-.5,-.5,0.}, { .5,-.5,0.}, { .5, .5,0.}, {-.5, .5,0.} }; /* 2D texture coordinates */ static Vfloat tquad2[4][2] = { {0.,0.}, {1.,0.}, {1.,1.}, {0.,1.} }; /* 1D texture coordinates */ static Vfloat tquad1[4] = { 0.,1.,1.,0. }; /*---------------------------------------------------------------------- Draw Image as 1D or 2D Textured Polygon ----------------------------------------------------------------------*/ int main(int argc, char **argv) { char infile[256]; vgl_FBuffer *fbuffer, *fbuffert; vgl_Texture *texture; vgl_DrawFun *df; Vchar title[65]; Vint test; Vint xsize, ysize, tdim, tsx, tsy; /* read image file source for texture */ /* check for proper number of arguments */ if(argc < 2) { fprintf(stderr,"Usage: %s inputfile\n",argv[0]); fprintf(stderr," inputfile is blank, 'earth.gif' is assumed\n"); strcpy(infile,"earth.gif"); } else { strcpy(infile,argv[1]); } /* create FBuffer object */ fbuffer = vgl_FBufferBegin(); /* decode input display file format and file name */ if(strstr(infile,"gif")) { vgl_FBufferReadGIF (fbuffer,infile); } else if(strstr(infile,"bmp")) { vgl_FBufferReadBMP (fbuffer,infile); } else if(strstr(infile,"jpg")) { vgl_FBufferReadJPEG (fbuffer,infile); } else { fprintf(stderr,"Error: Unsupported input file format %s\n",infile); exit(1); } vgl_FBufferInq (fbuffer,&xsize,&ysize); printf("xsize= %d, ysize= %d, file= %s\n",xsize,ysize,infile); /* determine texture dimension */ if(ysize == 1) { tdim = 1; } else { tdim = 2; } /* find largest sizes which are a power of two */ for(tsx = 1; tsx < 1024; tsx *= 2) { if(2*tsx > xsize) break; } for(tsy = 1; tsy < 1024; tsy *= 2) { if(2*tsy > ysize) break; } /* scale image to texture friendly size */ printf("texture dimension= %d\n",tdim); printf("texture scaled tsx= %d, tsy= %d\n",tsx,tsy); fbuffert = vgl_FBufferBegin(); vgl_FBufferDef (fbuffert,tsx,tsy); vgl_FBufferZoom (fbuffert,fbuffer); vgl_FBufferAlpha (fbuffert,1.); /* create drawing functions */ df = vgl_DrawFunBegin(); strcpy(title,"1D or 2D Texture Example, "); VglDevCreate (df,VGLDEV_OPENGL,title,&test); /* open windows and file */ vgl_DrawFunPositionWindow (df,400,400,400,300); vgl_DrawFunOpenWindow (df,title); /* create texture from fbuffer */ texture = vgl_TextureBegin (); vgl_TextureFBuffer (texture,fbuffert); /* free fbuffer */ vgl_FBufferEnd (fbuffer); vgl_FBufferEnd (fbuffert); vgl_TextureSetEnv (texture,TEXTURE_DECAL); vgl_DrawFunTextureDefine (df,1,texture); vgl_TextureEnd (texture); /* draw with texture 1 */ draw_quad (df,1,tdim); /* close windows */ vgl_DrawFunCloseWindow (df); /* free objects */ vgl_DrawFunEnd (df); VglDevDestroy (); return 0; } /*---------------------------------------------------------------------- utility ----------------------------------------------------------------------*/ static void draw_quad(vgl_DrawFun *df, Vint index, Vint tdim) { Vfloat c[3]; vgl_DrawFunTextureSelect (df,index); /* draw quadrilateral */ vgl_DrawFunClear (df); /* set white base color */ c[0] = 1.; c[1] = 1.; c[2] = 1.; vgl_DrawFunColor (df,c); /* 1D texture */ if(tdim == 1) { vgl_DrawFunPolygon (df,VGL_POLYGON,4,xquad,VGL_1DTEXTURE,(Vfloat*)tquad1); /* 2D texture */ } else { vgl_DrawFunPolygon (df,VGL_POLYGON,4,xquad,VGL_2DTEXTURE,(Vfloat*)tquad2); } vgl_DrawFunSwap (df); vgl_DrawFunDelay (df,5.); }
For the 3D object animation a List object is used to hold a set of DList objects, each DList object holds a complete set of 3D graphics primitives for each frame in the animation. The animation in this case is the warping of a simple cone. In the case of 3D object animation the geometry is created for each frame without rendering it to the screen. In an actual application it is recommended to render each display list as it is generated as a visual cue to the user that the animation is being properly created. Once the DList objects are created, the animation is "played back" by rendering each DList object in turn.
The 2D image animation is generated by drawing each frame of the warping cone directly to the display device in "immediate mode". A Pixelmap object is instanced to hold the frame buffer contents for each frame. Pixelmap objects are device dependent and are designed for playback speed. A single "FBuffer object is instanced to hold a device independent image of each frame and write the data to an animated .gif file, exam12.gif.
Note the use of the vsy_ListForEach function to delete the DList and Pixelmap objects.
#include "base/base.h" #include "vgl/vgl.h" static void draw_cone(vgl_DrawFun *df, vgl_Quadric *qu, Vfloat r1, Vfloat r2, Vfloat h); /* light properties */ static Vfloat camb[3] = { .5,.5,.5 }; static Vfloat cdis[3] = { .5,.5,.5 }; static Vfloat xdis[3] = { 1.,0.,0. }; static Vfloat xtex[3] = { -1.2,.8,0. }; /*---------------------------------------------------------------------- 3D Object and 2D Image Animation ----------------------------------------------------------------------*/ int main() { int i, j; Vfloat tm4[4][4]; Vfloat c[3]; #ifdef VKI_WIND_X11 Display *display; int screen; #endif vsy_List *list; vgl_DList *dlist; vgl_Pixelmap *pixelmap; vgl_Quadric *qu; vgl_DrawFun *dfGL, *dfDL; vgl_Xfm *xfm; vgl_FBuffer *fbuffer; vgl_OpenGLDev *ogldev; /* open X display */ #ifdef VKI_WIND_X11 display = XOpenDisplay (0); screen = DefaultScreen (display); vgl_OpenGLDevConnectX (display,screen); #else vgl_OpenGLDevConnectWIN (); #endif /* create GL device and drawing functions */ ogldev = vgl_OpenGLDevBegin(); dfGL = vgl_DrawFunBegin(); vgl_OpenGLDevDrawFun (ogldev,dfGL); list = vsy_ListBegin(); /* open window */ vgl_DrawFunPositionWindow (dfGL,400,400,400,300); vgl_DrawFunOpenWindow (dfGL,"OpenGL window"); /* set viewing volume to match window aspect ratio */ vgl_DrawFunProjOrtho (dfGL,-1.3333,1.3333,-1.,1.,-2.,2.); vgl_DrawFunDepthRange (dfGL,0.,1.); /* turn on zbuffering */ vgl_DrawFunSetMode (dfGL,VGL_ZBUFFERMODE,VGL_ON); /* set lights */ vgl_DrawFunLight (dfGL,0,VGL_LIGHT_AMBIENT,camb,NULL); vgl_DrawFunLight (dfGL,1,VGL_LIGHT_DISTANT,cdis,xdis); vgl_DrawFunSetMode (dfGL,VGL_LIGHTMODE,VGL_ON); /* generate quadric for drawing cone */ qu = vgl_QuadricBegin (); /* create transform object */ xfm = vgl_XfmBegin(); vgl_XfmRotate (xfm,-3.14159/4.,XFM_YAXIS); vgl_XfmGetMatrix (xfm,tm4); /* create drawing functions */ dfDL = vgl_DrawFunBegin(); /* 3D object animation using DList objects */ /* create 10 frames in the animation, warping the cone */ for(i = 1; i <= 10; i++) { dlist = vgl_DListBegin(); vgl_DListDrawFun (dlist,dfDL); vgl_DListSetObject (dlist,VGL_DRAWFUN,dfGL); vsy_ListInsert (list,i,(Vobject*)dlist); c[0] = 1.; c[1] = 1.; c[2] = 1.; vgl_DrawFunColor (dfDL,c); vgl_DrawFunText (dfDL,xtex,"3D object DList"); draw_cone (dfDL,qu,.4+.04*i,.8-.04*i,1.); } /* animate 3D display lists 5 times */ vgl_DrawFunXfmLoad (dfGL,tm4); for(j = 0; j < 5; j++) { for(i = 1; i <= 10; i++) { vgl_DrawFunClear (dfGL); vsy_ListRef (list,i,(Vobject**)&dlist); vgl_DListCall (dlist); vgl_DrawFunSwap (dfGL); vgl_DrawFunDelay (dfGL,.05); } for(i = 9; i >= 2; i--) { vgl_DrawFunClear (dfGL); vsy_ListRef (list,i,(Vobject**)&dlist); vgl_DListCall (dlist); vgl_DrawFunSwap (dfGL); vgl_DrawFunDelay (dfGL,.05); } } /* delete display lists */ vsy_ListForEach (list,(void(*)(Vobject*))vgl_DListEnd); vsy_ListClear (list); fbuffer = vgl_FBufferBegin (); /* 2D image animation using Pixelmap objects */ /* create 10 frames in the animation, warping the cone */ /* create an animated .gif file */ for(i = 1; i <= 10; i++) { vgl_DrawFunClear (dfGL); c[0] = 1.; c[1] = 1.; c[2] = 1.; vgl_DrawFunColor (dfGL,c); vgl_DrawFunText (dfGL,xtex,"2D image Pixelmap"); draw_cone (dfGL,qu,.4+.04*i,.8-.04*i,1.); vgl_DrawFunSwap (dfGL); pixelmap = vgl_PixelmapBegin(); vgl_DrawFunPixelmapCreate (dfGL,pixelmap); vgl_DrawFunPixelmapRead (dfGL,pixelmap); vsy_ListInsert (list,i,(Vobject*)pixelmap); vgl_DrawFunFBufferRead (dfGL,0,0,0,0,fbuffer); if(i == 1) { vgl_FBufferWriteGIF (fbuffer,"exam12.gif"); } else { vgl_FBufferAppendGIF (fbuffer,"exam12.gif"); } } /* animate 2D pixelmaps 5 times */ /* 20 frames per second maximum */ for(j = 0; j < 5; j++) { for(i = 1; i <= 10; i++) { vgl_DrawFunClear (dfGL); vsy_ListRef (list,i,(Vobject**)&pixelmap); vgl_DrawFunPixelmapWrite (dfGL,pixelmap); vgl_DrawFunSwap (dfGL); vgl_DrawFunDelay (dfGL,.05); } for(i = 9; i >= 2; i--) { vgl_DrawFunClear (dfGL); vsy_ListRef (list,i,(Vobject**)&pixelmap); vgl_DrawFunPixelmapWrite (dfGL,pixelmap); vgl_DrawFunSwap (dfGL); vgl_DrawFunDelay (dfGL,.05); } } /* destory contents of pixelmaps */ for(i = 1; i <= 10; i++) { vsy_ListRef (list,i,(Vobject**)&pixelmap); vgl_DrawFunPixelmapDestroy (dfGL,pixelmap); } /* delete pixelmaps */ vsy_ListForEach (list,(void(*)(Vobject*))vgl_PixelmapEnd); vsy_ListClear (list); /* free objects */ vgl_OpenGLDevEnd (ogldev); vgl_DrawFunEnd (dfGL); vgl_DrawFunEnd (dfDL); vgl_QuadricEnd (qu); vgl_XfmEnd (xfm); vgl_FBufferEnd (fbuffer); vsy_ListEnd (list); /* disconnect from X */ vgl_OpenGLDevDisconnect (); /* close X display */ #ifdef VKI_WIND_X11 XCloseDisplay (display); #endif return 0; } /*---------------------------------------------------------------------- draw cone ----------------------------------------------------------------------*/ static void draw_cone(vgl_DrawFun *df, vgl_Quadric *qu, Vfloat r1, Vfloat r2, Vfloat h) { Vfloat c[3]; c[0] = .5; c[1] = .5; c[2] = .5; vgl_DrawFunColor (df,c); vgl_DrawFunSpecularity (df,.5,10.); vgl_QuadricSetObject (qu,VGL_DRAWFUN,df); vgl_QuadricSetParami (qu,QUADRIC_SLICES,21); vgl_QuadricSetParami (qu,QUADRIC_STACKS,21); vgl_QuadricCylinder (qu,r1,r2,h); }
The background is cleared to white and a variety of line, polygon and text primitives are drawn in constant color and interpolated color. The internal frame buffer, FBuffer, object is retrieved from the RendBuf object using vgl_RendBufGetFBuffer and a GIF file of the frame buffer contents are written using vgl_FBufferWriteGIF.
#include "base/base.h" #include "vgl/vgl.h" #include <math.h> static void draw_triangle(vgl_DrawFun *df); static void draw_circle(vgl_DrawFun *df, Vfloat x[3], Vfloat radius, Vint nedge); static void draw_ring(vgl_DrawFun *df, Vfloat x[3], Vfloat inner, Vfloat outer, Vint nedge); static double twopi = 6.2831853; /*---------------------------------------------------------------------- Software Rendered Image File of a 2D Diagram ----------------------------------------------------------------------*/ int main() { vgl_RendBuf *rendbuf; vgl_DrawFun *df; vgl_FBuffer *fbuffer; Vfloat x[3], c[3]; Vfloat xl[2][3]; vgl_RasFont *rasfont; Vfloat path[3], plane[3]; /* create drawing function */ df = vgl_DrawFunBegin(); /* create software renderer object, load drawing functions */ rendbuf = vgl_RendBufBegin(); vgl_RendBufDrawFun (rendbuf,df); /* open "software" window (400 x 300 pixels) */ vgl_DrawFunPositionWindow (df,0,0,400,300); vgl_DrawFunOpenWindow (df,"Example 13"); /* set orthographic projection */ /* aspect ratio matches window dimensions */ vgl_DrawFunProjOrtho (df,-1.,1.,-.75,.75,-1.,1.); vgl_DrawFunSetMode (df,VGL_ZBUFFERMODE,VGL_OFF); /* clear to white background color */ c[0] = 1.; c[1] = 1.; c[2] = 1.; vgl_DrawFunBackColor (df,c); vgl_DrawFunClear (df); /* draw a color interpolated triangle */ draw_triangle (df); /* draw a red circle */ x[0] = .5; x[1] = 0.; x[2] = 0.; c[0] = 1.; c[1] = 0.; c[2] = 0.; vgl_DrawFunColor (df,c); draw_circle (df,x,0.15,16); /* draw a semi-transparent blue circle */ x[0] = .7; x[1] = .2; x[2] = 0.1; c[0] = 0.; c[1] = 0.; c[2] = 1.; vgl_DrawFunColor (df,c); vgl_DrawFunTrans (df,.5); vgl_DrawFunSetMode (df,VGL_BLENDTRANSMODE,VGL_ON); draw_circle (df,x,0.25,16); vgl_DrawFunTrans (df,.0); vgl_DrawFunSetMode (df,VGL_BLENDTRANSMODE,VGL_OFF); /* draw a ring color interpolated from blue to green */ x[0] = -.25; x[1] = .1; x[2] = 0.; draw_ring (df,x,0.3,0.5,64); /* draw a double width black line */ vgl_DrawFunLineWidth (df,2); xl[0][0] = -.6; xl[0][1] = -.5; xl[0][2] = 0.; xl[1][0] = 0.; xl[1][1] = .6; xl[1][2] = 0.; c[0] = 0.; c[1] = 0.; c[2] = 0.; vgl_DrawFunColor (df,c); vgl_DrawFunPolyLine (df,VGL_LINESTRIP,2,xl); /* draw a multisampled (anti-aliased) line */ vgl_DrawFunSetMode (df,VGL_MULTISAMPLEMODE,VGL_ON); xl[0][0] = -.7; xl[0][1] = -.5; xl[0][2] = 0.; xl[1][0] = -.1; xl[1][1] = .6; xl[1][2] = 0.; vgl_DrawFunPolyLine (df,VGL_LINESTRIP,2,xl); vgl_DrawFunSetMode (df,VGL_MULTISAMPLEMODE,VGL_OFF); /* draw text in default font in upper left corner */ c[0] = 1.; c[1] = 0.; c[2] = 0.; vgl_DrawFunColor (df,c); x[0] = -.9; x[1] = .65; x[2] = 0.; vgl_DrawFunText (df,x,"Hello World"); /* draw text plane text */ rasfont = vgl_RasFontBegin(); vgl_RasFontLoad (rasfont,RASFONT_QUALITY9X13); vgl_RasFontSetParami (rasfont,RASFONT_TEXTPLANE,SYS_ON); vgl_RasFontSetParami (rasfont,RASFONT_DEVICESIZE,SYS_OFF); vgl_RasFontSetPixelSize (rasfont,.01); vgl_DrawFunRasFontDefine (df,1,rasfont); vgl_RasFontEnd (rasfont); vgl_DrawFunRasFontSelect (df,1); path[0] = 2.; path[1] = 1.; path[2] = 0.; plane[0] = -1.; plane[1] = 0.; plane[2] = 0.; vgl_DrawFunTextPlane (df,path,plane); x[0] = -.9; x[1] = -.65; x[2] = 0.; vgl_DrawFunText (df,x,"Hello World"); /* get image buffer */ vgl_RendBufGetFBuffer (rendbuf,&fbuffer); /* write image in gif format to file */ vgl_FBufferWriteGIF (fbuffer,"exam13.gif"); /* write image in bmp format to file */ vgl_FBufferWriteBMP (fbuffer,"exam13.bmp"); /* close software window */ vgl_DrawFunCloseWindow (df); /* free objects */ vgl_RendBufEnd (rendbuf); vgl_DrawFunEnd (df); return 0; } static void draw_triangle(vgl_DrawFun *df) { Vfloat xt[3][3] = { {0.,.5,0.}, {.5,-.5,0.}, {-.5,-.5,0.} }; Vfloat ct[3][3] = { {1.,0.,0.}, {0.,1.,0.}, {0.,0.,1.} }; Vfloat c[3]; Vuint ixtri[3] = {0,1,2}; /* draw triangle */ vgl_DrawFunPolyElemArray (df,VGL_POLYGON,3,ixtri,xt, VGL_COLOR_3F,ct,0,NULL,0,NULL,0,NULL); /* draw blue outline */ c[0] = 0.; c[1] = 0.; c[2] = 1.; vgl_DrawFunColor (df,c); vgl_DrawFunPolyElemArray (df,VGL_LINELOOP,3,ixtri,xt, 0,NULL,0,NULL,0,NULL,0,NULL); } static void draw_circle(vgl_DrawFun *df, Vfloat x[3], Vfloat radius, Vint nedge) { Vint i; Vfloat xl[200][3]; Vdouble angle,ainc; /* this check for hard-coded parameter can be removed for efficiency */ if(nedge > 200) { printf("Internal error: max edges = 20\n"); return; } ainc = twopi/nedge; for(i = 0; i < nedge; i++) { angle = ainc*i; xl[i][0] = radius*cos(angle) + x[0]; xl[i][1] = radius*sin(angle) + x[1]; xl[i][2] = x[2]; } vgl_DrawFunPolygon (df,VGL_POLYGON,nedge,xl,VGL_NOSHADE,NULL); } static void draw_ring(vgl_DrawFun *df, Vfloat x[3], Vfloat inner, Vfloat outer, Vint nedge) { Vint i; Vfloat xt[3][3]; static Vfloat c1[3][3] = { {0.,1.,0.}, {0.,1.,1.}, {0.,1.,1.} }; static Vfloat c2[3][3] = { {0.,1.,0.}, {0.,1.,1.}, {0.,1.,0.} }; Vdouble angle, ainc; xt[0][2] = x[2]; xt[1][2] = x[2]; xt[2][2] = x[2]; ainc = twopi/nedge; for(i = 0; i < nedge; i++) { angle = ainc*i; xt[0][0] = inner*cos(angle) + x[0]; xt[0][1] = inner*sin(angle) + x[1]; xt[1][0] = outer*cos(angle) + x[0]; xt[1][1] = outer*sin(angle) + x[1]; xt[2][0] = outer*cos(angle+ainc) + x[0]; xt[2][1] = outer*sin(angle+ainc) + x[1]; vgl_DrawFunPolygonColor (df,VGL_POLYGON,3,xt,c1,VGL_NOSHADE,NULL); xt[1][0] = xt[2][0]; xt[1][1] = xt[2][1]; xt[2][0] = inner*cos(angle+ainc) + x[0]; xt[2][1] = inner*sin(angle+ainc) + x[1]; vgl_DrawFunPolygonColor (df,VGL_POLYGON,3,xt,c2,VGL_NOSHADE,NULL); } }
In the first section a clipping plane, index=0, at x = -.5 is defined using vgl_DrawFunClipPlane. Up to 6 clipping planes may be defined, each given an index from 0 to 5. The position of the clipping plane is fixed when it is defined by the call to vgl_DrawFunClipPlane. After the object is drawn then selection is enabled using the clipping planes. The region type, VGL_REGION_CLIPPLANE specifies that any vertex of a given graphics primitive must be within all the active clipping planes for a hit to be recorded. This means that any vertex of the cone must be within the clipping plane for a hit on it to be recorded. The object is rotated through 180 degrees and the recorded hits are printed.
In the second section, the clipping plane is rotated by the same set of modelview matrices as the object in the first section. Note the use of vgl_DrawFunXfmPush and vgl_DrawFunXfmPop to isolate the modelview matrix to affect the clipping plane position and not the graphics object position.
#include "base/base.h" #include "vgl/vgl.h" static void draw_scene(vgl_DrawFun *df, vgl_Quadric *qu, Vfloat r, Vfloat h, Vint n); /* light properties */ static Vfloat camb[3] = { .5,.5,.5 }; static Vfloat cdis[3] = { .5,.5,.5 }; static Vfloat xdis[3] = { 1.,0.,0. }; /* points */ static Vfloat xpts[7][3] = { {0.,0.,0.}, {1.,0.,0.}, {0.,1.,0.}, {0.,0.,1.}, {-1.,0.,0.}, {0.,-1.,0.}, {0.,0.,-1.} }; /*---------------------------------------------------------------------- Using Clipping Planes ----------------------------------------------------------------------*/ int main() { int i, j; Vfloat tm4[4][4]; Vfloat eqn[4]; Vint numhits; Vint indexlist[8]; Vfloat mindepth[8], maxdepth[8]; Vint dev; Vchar devname[256]; #ifdef VKI_WIND_X11 Display *display; int screen; #endif vgl_OpenGLDev *ogldev; #ifdef VKI_WIND_X11 vgl_X11Dev *x11dev; #else vgl_GDIDev *gdidev; #endif vgl_Quadric *qu; vgl_DrawFun *df; vgl_Xfm *xfm; /* 1 = OpenGLDev, 2 = GDIDev or X11Dev */ dev = 1; /* connect to X or Windows */ #ifdef VKI_WIND_X11 display = XOpenDisplay (0); screen = DefaultScreen (display); if(dev == 1) { vgl_OpenGLDevConnectX (display,screen); } else if(dev == 2) { vgl_X11DevConnectX (display,screen); } #else if(dev == 1) { vgl_OpenGLDevConnectWIN (); } else if(dev == 2) { vgl_GDIDevConnectWIN (); } #endif /* create drawing functions */ df = vgl_DrawFunBegin(); /* create device objects and load drawing functions */ if(dev == 1) { ogldev = vgl_OpenGLDevBegin(); vgl_OpenGLDevDrawFun (ogldev,df); strcpy(devname,"OpenGL"); } else if(dev == 2) { #ifdef VKI_WIND_X11 x11dev = vgl_X11DevBegin(); vgl_X11DevDrawFun (x11dev,df); strcpy(devname,"X11"); #else gdidev = vgl_GDIDevBegin(); vgl_GDIDevDrawFun (gdidev,df); strcpy(devname,"GDI"); #endif } /* open window */ vgl_DrawFunPositionWindow (df,400,400,400,300); vgl_DrawFunOpenWindow (df,devname); /* set viewing volume to match window aspect ratio */ vgl_DrawFunProjOrtho (df,-2.6667,2.6667,-2.,2.,-2.,2.); /* turn on zbuffering */ vgl_DrawFunSetMode (df,VGL_ZBUFFERMODE,VGL_ON); /* generate quadric for drawing cone */ qu = vgl_QuadricBegin (); vgl_QuadricSetObject (qu,VGL_DRAWFUN,df); /* create transform object */ xfm = vgl_XfmBegin(); /* set lights */ vgl_DrawFunLight (df,0,VGL_LIGHT_AMBIENT,camb,NULL); vgl_DrawFunLight (df,1,VGL_LIGHT_DISTANT,cdis,xdis); vgl_DrawFunSetMode (df,VGL_LIGHTMODE,VGL_ON); /* define clipping plane at x = -.5 */ eqn[0] = 1.; eqn[1] = 0.; eqn[2] = 0.; eqn[3] = .5; vgl_DrawFunClipPlane (df,0,eqn); vgl_DrawFunSetSwitch (df,VGL_CLIPPLANE,0,VGL_ON); vgl_DrawFunXfmPush (df); /* rotate model about y axis */ for(i = 0; i <= 25; i++) { vgl_DrawFunClear (df); vgl_XfmRotate (xfm,(Vfloat)(3.14159/25.*i),XFM_YAXIS); vgl_XfmGetMatrix (xfm,tm4); vgl_DrawFunXfmLoad (df,tm4); /* render */ draw_scene (df,qu,.6,.8,17); vgl_DrawFunSwap (df); /* set select */ vgl_DrawFunSelectBuffer (df,8,indexlist,mindepth,maxdepth); vgl_DrawFunRender (df,VGL_SELECT); vgl_DrawFunSelectRegion (df,VGL_REGION_CLIPPLANE,NULL); draw_scene (df,qu,.6,.8,17); /* reset render */ vgl_DrawFunRender (df,VGL_RENDER); vgl_DrawFunSelectQuery (df,&numhits); /* print hits */ printf("rotate model: hits="); for(j = 0; j < numhits; j++) { printf(" %d",indexlist[j]); } printf("\n"); vgl_DrawFunDelay (df,1.); } vgl_DrawFunXfmPop (df); vgl_DrawFunDelay (df,5.); /* rotate clipping plane about y axis */ for(i = 0; i <= 25; i++) { vgl_DrawFunClear (df); vgl_DrawFunXfmPush (df); vgl_XfmRotate (xfm,(Vfloat)(3.14159/25.*i),XFM_YAXIS); vgl_XfmGetMatrix (xfm,tm4); vgl_DrawFunXfmLoad (df,tm4); vgl_DrawFunClipPlane (df,0,eqn); vgl_DrawFunXfmPop (df); /* render */ draw_scene (df,qu,.6,.8,17); vgl_DrawFunSwap (df); /* set select */ vgl_DrawFunSelectBuffer (df,8,indexlist,mindepth,maxdepth); vgl_DrawFunRender (df,VGL_SELECT); vgl_DrawFunSelectRegion (df,VGL_REGION_CLIPPLANE,NULL); draw_scene (df,qu,.6,.8,17); /* reset render */ vgl_DrawFunRender (df,VGL_RENDER); vgl_DrawFunSelectQuery (df,&numhits); /* print hits */ printf("rotate plane: hits="); for(j = 0; j < numhits; j++) { printf(" %d",indexlist[j]); } printf("\n"); vgl_DrawFunDelay (df,1.); } vgl_DrawFunDelay (df,5.); /* free transform object */ vgl_XfmEnd (xfm); /* close window */ vgl_DrawFunCloseWindow (df); /* free objects */ if(dev == 1) { vgl_OpenGLDevEnd (ogldev); } else if(dev == 2) { #ifdef VKI_WIND_X11 vgl_X11DevEnd (x11dev); #else vgl_GDIDevEnd (gdidev); #endif } vgl_DrawFunEnd (df); vgl_QuadricEnd (qu); /* disconnect */ if(dev == 1) { vgl_OpenGLDevDisconnect (); } else if(dev == 2) { #ifdef VKI_WIND_X11 vgl_X11DevDisconnect (); #else vgl_GDIDevDisconnect (); #endif } /* close X display */ #ifdef VKI_WIND_X11 XCloseDisplay (display); #endif return 0; } /*---------------------------------------------------------------------- draw cone and points ----------------------------------------------------------------------*/ static void draw_scene(vgl_DrawFun *df, vgl_Quadric *qu, Vfloat r, Vfloat h, Vint n) { Vint i; Vfloat c[3]; Vint index; Vchar stg[9]; /* draw gray cone, index 0 */ c[0] = .5; c[1] = .5; c[2] = .5; vgl_DrawFunColor (df,c); vgl_DrawFunSpecularity (df,.5,10.); vgl_DrawFunDataIndex (df,0,0,NULL); vgl_QuadricSetParami (qu,QUADRIC_SLICES,n); vgl_QuadricSetParami (qu,QUADRIC_STACKS,2); vgl_QuadricCylinder (qu,r,0.,h); /* draw 7 red points, indices 1 to 7 */ c[0] = 1.0; c[1] = 0.; c[2] = 0.; vgl_DrawFunColor (df,c); vgl_DrawFunPointSize (df,2); for(i = 0; i < 7; i++) { index = i+1; vgl_DrawFunDataIndex (df,1,1,&index); vgl_DrawFunPolyPoint (df,1,(Vfloat(*)[3])xpts[i]); sprintf(stg,"%d",index); vgl_DrawFunText (df,xpts[i],stg); } }
#include <stdio.h> #include <stdlib.h> #include "vgl/vgl.h" /* face connectivity of unit cube */ static Vint faces[6][4] = { {3,2,1,0},{4,5,6,7},{0,1,5,4},{2,3,7,6},{3,0,4,7},{1,2,6,5} }; /* vertices coordinates of unit cube */ static Vfloat coords[8][3] = { {0.,0.,0.},{1.,0.,0.},{1.,1.,0.},{0.,1.,0.}, {0.,0.,1.},{1.,0.,1.},{1.,1.,1.},{0.,1.,1.} }; /* face colors */ static Vfloat frgb[6][3] = { {1.,0.,0.},{0.,1.,0.},{0.,0.,1.},{1.,1.,0.},{1.,0.,1.},{0.,1.,1.} }; /* edge connectivity */ static Vint edges[12][2] = { {0,1},{1,2},{2,3},{3,0}, {4,5},{5,6},{6,7},{7,4}, {0,4},{1,5},{2,6},{3,7} }; /* vertex colors for edge drawing */ static Vfloat vrgb[8][3] = { {1.,0.,0.},{0.,1.,0.},{0.,0.,1.},{1.,1.,0.}, {1.,0.,1.},{0.,1.,1.},{.5,.5,.5},{1.,1.,1.} }; /* face normals */ static Vfloat normals[6][3] = { {0.,0.,-1.},{0.,0.,1.},{0.,-1.,0.},{0.,1.,0.},{-1.,0.,0.},{1.,0.,0.} }; /*---------------------------------------------------------------------- Write External JT Open File Using DFile ----------------------------------------------------------------------*/ int main(int argc, char** argv) { Vint i, j, n; vgl_DFile *dfile; vgl_DrawFun *df; Vfloat xp[4][3], cp[2][3], c[3]; Vchar outputroot[256]; /* specify assembly name */ if(argc < 2) { fprintf(stderr,"Usage: %s outputroot\n",argv[0]); fprintf(stderr," outputroot is blank, 'Assembly' is assumed\n"); strcpy(outputroot,"Assembly"); } else { strcpy(outputroot,argv[1]); } /* instance vgl objects */ dfile = vgl_DFileBegin (); df = vgl_DrawFunBegin (); vgl_DFileDrawFun (dfile,df); /* specify jt file format, name, path */ vgl_DFileSetFileType (dfile,DFILE_JT); if(vgl_DFileError(dfile)) { fprintf(stderr,"JT file format not supported\n"); return 0; } vgl_DFileSetJTAssemblyName (dfile,outputroot); vgl_DFileSetFileName (dfile,"./"); /* open JT */ vgl_DFileOpen (dfile); /* draw faces of a hex into internal part, Part_1 */ vgl_DFileOpenJTPart (dfile,NULL); for(n = 0; n < 6; n++) { vgl_DrawFunColor (df,frgb[n]); for(i = 0; i < 4; ++i) { for(j = 0; j < 3; ++j) { xp[i][j] = coords[faces[n][i]][j]; } } vgl_DrawFunPolygon(df,VGL_POLYGON,4,xp,VGL_FLATSHADE,(Vfloat*)normals[n]); } vgl_DFileCloseJTPart (dfile); /* draw vertices and face edges into internal part, Part_2 */ vgl_DFileOpenJTPart (dfile,NULL); /* draw vertices of a hex in white */ c[0] = 1.; c[1] = 1.; c[2] = 1.; vgl_DrawFunColor (df,c); vgl_DrawFunPolyPoint (df,8,coords); /* draw face edges of a hex */ for(n = 0; n < 12; n++) { for(i = 0; i < 2; ++i) { for(j = 0; j < 3; ++j) { xp[i][j] = coords[edges[n][i]][j]; cp[i][j] = vrgb[edges[n][i]][j]; } } vgl_DrawFunPolyLineColor (df,VGL_LINESTRIP,2,xp,cp); } vgl_DFileCloseJTPart (dfile); /* this is actually when JT file is written */ vgl_DFileClose (dfile); /* delete objects */ vgl_DrawFunEnd (df); vgl_DFileEnd (dfile); return 0; }
#include <stdio.h> #include <stdlib.h> #include <JtTk/JtkEntityFactory.h> #include <JtTk/JtkHierarchy.h> #include <JtTk/JtkAttrib.h> #include <JtTk/JtkCADExporter.h> #include "vgl/vgl.h" /* face connectivity of unit cube */ static Vint faces[6][4] = { {3,2,1,0},{4,5,6,7},{0,1,5,4},{2,3,7,6},{1,2,6,5},{3,0,4,7} }; /* vertices coordinates of unit cube */ static Vfloat coords[8][3] = { {0.,0.,0.},{1.,0.,0.},{1.,1.,0.},{0.,1.,0.}, {0.,0.,1.},{1.,0.,1.},{1.,1.,1.},{0.,1.,1.} }; /* face colors */ static Vfloat frgb[6][3] = { {1.,0.,0.},{0.,1.,0.},{0.,0.,1.},{1.,1.,0.},{1.,0.,1.},{0.,1.,1.} }; /* edge connectivity */ static Vint edges[12][2] = { {0,1},{1,2},{2,3},{3,0}, {4,5},{5,6},{6,7},{7,4}, {0,4},{1,5},{2,6},{3,7} }; /* vertex colors for edge drawing */ static Vfloat vrgb[8][3] = { {1.,0.,0.},{0.,1.,0.},{0.,0.,1.},{1.,1.,0.}, {1.,0.,1.},{0.,1.,1.},{.5,.5,.5},{1.,1.,1.} }; /* face normals */ static Vfloat normals[6][3] = { {0.,0.,-1.},{0.,0.,1.},{0.,-1.,0.},{0.,1.,0.},{-1.,0.,0.},{1.,0.,0.} }; /*---------------------------------------------------------------------- Fill JT Open Part Using DFile ----------------------------------------------------------------------*/ int main(int argc, char** argv) { JtkAssembly *assembly; JtkPart *part; JtkCADExporter *cadexporter; Vint i, j, n; vgl_DFile *dfile; vgl_DrawFun *df; Vfloat xp[4][3], cp[2][3], c[3]; Vchar outputroot[256]; /* Initialize Jtk */ JtkEntityFactory::init(); /* Create an assembly */ if(argc < 2) { fprintf(stderr,"Usage: %s outputroot\n",argv[0]); fprintf(stderr," outputroot is blank, 'Assembly' is assumed\n"); strcpy(outputroot,"Assembly"); } else { strcpy(outputroot,argv[1]); } assembly = JtkEntityFactory::createAssembly(outputroot); if(assembly == NULL) { printf("Unable to create JtkAssembly node\n"); return 0; } assembly->ref(); /* instance vgl objects */ dfile = vgl_DFileBegin (); df = vgl_DrawFunBegin (); vgl_DFileDrawFun (dfile,df); /* specify jt part only */ vgl_DFileSetFileType (dfile,DFILE_JTPART); /* Create a part for face polygons */ part = JtkEntityFactory::createPart("Part1"); if(part == NULL) { printf("Unable to create JtkPart node\n"); return 0; } assembly->addChild(part); /* open JtkPart */ vgl_DFileOpenJTPart (dfile,(Vobject*)part); /* draw faces of a hex */ for(n = 0; n < 6; n++) { vgl_DrawFunColor (df,frgb[n]); for(i = 0; i < 4; ++i) { for(j = 0; j < 3; ++j) { xp[i][j] = coords[faces[n][i]][j]; } } vgl_DrawFunPolygon (df,VGL_POLYGON,4,xp,VGL_FLATSHADE,(Vfloat*)normals); } /* close JtkPart */ vgl_DFileCloseJTPart (dfile); /* Create a part for vertices and face edges */ part = JtkEntityFactory::createPart("Part2"); if(part == NULL) { printf("Unable to create JtkPart node\n"); return 0; } assembly->addChild(part); /* open JtkPart */ vgl_DFileOpenJTPart (dfile,(Vobject*)part); /* draw vertices of a hex in white */ c[0] = 1.; c[1] = 1.; c[2] = 1.; vgl_DrawFunColor (df,c); vgl_DrawFunPolyPoint (df,8,coords); /* draw face edges of a hex */ for(n = 0; n < 12; n++) { for(i = 0; i < 2; ++i) { for(j = 0; j < 3; ++j) { xp[i][j] = coords[edges[n][i]][j]; cp[i][j] = vrgb[edges[n][i]][j]; } } vgl_DrawFunPolyLineColor (df,VGL_LINESTRIP,2,xp,cp); } /* close JtkPart */ vgl_DFileCloseJTPart (dfile); /* export data */ cadexporter = JtkEntityFactory::createCADExporter(); if(cadexporter == NULL) { printf("Unable to create JtkCADExporter\n"); return 0; } cadexporter->ref(); cadexporter->setExportPath("./"); /* recommended by JT Open personnel to disable tristripping and LOD generation */ cadexporter->setFileFormat(JtkCADExporter::JtkMONOLITHIC); cadexporter->setExportOption(JtkCADExporter::JtkAUTO_LOW_LODS_OFF); cadexporter->setExportOption(JtkCADExporter::JtkSMART_LODS_OFF); cadexporter->setExportOption(JtkCADExporter::JtkPART_SIMPLIFY_OFF); cadexporter->setExportOption(JtkCADExporter::JtkRETRISTRIP_OFF); cadexporter->setExportOption(JtkCADExporter::JtkJT_VERSION_80); cadexporter->export(assembly); /* clean up */ assembly->unref(); cadexporter->unref(); vgl_DrawFunEnd (df); vgl_DFileEnd (dfile); JtkEntityFactory::fini(); return 0; }
#include <stdio.h> #include <stdlib.h> #include "vgl/vgl.h" /*---------------------------------------------------------------------- Read External JT Open File Using DFile ----------------------------------------------------------------------*/ int main(int argc, char** argv) { vgl_DFile *dfiler, *dfilew; vgl_DrawFun *dfr, *dfw; Vchar outputroot[256]; /* specify assembly name */ if(argc < 2) { fprintf(stderr,"Usage: %s outputroot\n",argv[0]); fprintf(stderr," outputroot is blank, 'Assembly' is assumed\n"); strcpy(outputroot,"Assembly"); } else { strcpy(outputroot,argv[1]); } /* instance JT reader objects */ dfiler = vgl_DFileBegin (); dfr = vgl_DrawFunBegin (); vgl_DFileDrawFun (dfiler,dfr); /* specify JT file format, name, path */ vgl_DFileSetFileType (dfiler,DFILE_JT); vgl_DFileSetJTAssemblyName (dfiler,outputroot); vgl_DFileSetFileName (dfiler,"./"); /* instance STL writer objects */ dfilew = vgl_DFileBegin (); dfw = vgl_DrawFunBegin (); vgl_DFileDrawFun (dfilew,dfw); vgl_DFileSetFileType (dfilew,DFILE_STL_ASCII); vgl_DFileSetFileName (dfilew,"examjt.stl"); /* Output STL file must be opened first */ vgl_DFileOpen (dfilew); /* Read JT file and output to STL file */ vgl_DFileSetObject (dfiler,VGL_DRAWFUN,dfw); vgl_DFileOpen (dfiler); vgl_DFileRead (dfiler); vgl_DFileClose (dfiler); /* Output STL file must be closed last */ vgl_DFileClose (dfilew); /* clean up */ vgl_DFileEnd (dfiler); vgl_DFileEnd (dfilew); vgl_DrawFunEnd (dfr); vgl_DrawFunEnd (dfw); return 0; }
#include <stdio.h> #include <stdlib.h> #include "vgl/vgl.h" /* face connectivity of unit cube */ static Vint faces[6][4] = { {3,2,1,0},{4,5,6,7},{0,1,5,4},{2,3,7,6},{3,0,4,7},{1,2,6,5} }; /* vertices coordinates of unit cube */ static Vfloat coords[8][3] = { {0.,0.,0.},{1.,0.,0.},{1.,1.,0.},{0.,1.,0.}, {0.,0.,1.},{1.,0.,1.},{1.,1.,1.},{0.,1.,1.} }; /* face colors */ static Vfloat frgb[6][3] = { {1.,0.,0.},{0.,1.,0.},{0.,0.,1.},{1.,1.,0.},{1.,0.,1.},{0.,1.,1.} }; /* edge connectivity */ static Vint edges[12][2] = { {0,1},{1,2},{2,3},{3,0}, {4,5},{5,6},{6,7},{7,4}, {0,4},{1,5},{2,6},{3,7} }; /* vertex colors for edge drawing */ static Vfloat vrgb[8][3] = { {1.,0.,0.},{0.,1.,0.},{0.,0.,1.},{1.,1.,0.}, {1.,0.,1.},{0.,1.,1.},{.5,.5,.5},{1.,1.,1.} }; /* face normals */ static Vfloat normals[6][3] = { {0.,0.,-1.},{0.,0.,1.},{0.,-1.,0.},{0.,1.,0.},{-1.,0.,0.},{1.,0.,0.} }; /*---------------------------------------------------------------------- Write VglTools Native ASCII File Using DFile ----------------------------------------------------------------------*/ int main(int argc, char** argv) { Vint i, j, n; vgl_DFile *dfile; vgl_DrawFun *df; Vfloat xp[4][3], cp[2][3], c[3]; Vchar filename[256]; long pos; /* specify file name */ if(argc < 2) { fprintf(stderr,"Usage: %s filename\n",argv[0]); fprintf(stderr," filename is blank, 'exam16d.asc' is assumed\n"); strcpy(filename,"exam16d.asc"); } else { strcpy(filename,argv[1]); } /* instance vgl objects */ dfile = vgl_DFileBegin (); df = vgl_DrawFunBegin (); vgl_DFileDrawFun (dfile,df); /* specify file format, name, path */ vgl_DFileSetFileType (dfile,DFILE_ASCII); vgl_DFileSetFileName (dfile,filename); /* open to draw 1st frame */ vgl_DFileOpen (dfile); /* draw text */ vgl_DrawFunText (df,coords[0],"Frame 1"); /* draw faces of a hex */ for(n = 0; n < 6; n++) { vgl_DrawFunColor (df,frgb[n]); for(i = 0; i < 4; ++i) { for(j = 0; j < 3; ++j) { xp[i][j] = coords[faces[n][i]][j]; } } vgl_DrawFunPolygon(df,VGL_POLYGON,4,xp,VGL_FLATSHADE,(Vfloat*)normals[n]); } /* draw vertices and face edges */ /* draw vertices of a hex in white */ c[0] = 1.; c[1] = 1.; c[2] = 1.; vgl_DrawFunColor (df,c); vgl_DrawFunPolyPoint (df,8,coords); /* draw face edges of a hex */ for(n = 0; n < 12; n++) { for(i = 0; i < 2; ++i) { for(j = 0; j < 3; ++j) { xp[i][j] = coords[edges[n][i]][j]; cp[i][j] = vrgb[edges[n][i]][j]; } } vgl_DrawFunPolyLineColor (df,VGL_LINESTRIP,2,xp,cp); } vgl_DFileClose (dfile); /* query position to start writing 2nd frame */ vgl_DFileCurPosition (dfile,&pos); /* set position to start writing 2nd frame */ vgl_DFileSetPosition (dfile,pos); /* open to draw 2nd frame */ vgl_DFileOpen (dfile); vgl_DrawFunColor (df,c); vgl_DrawFunText (df,coords[0],"Frame 2"); vgl_DFileClose (dfile); /* delete objects */ vgl_DrawFunEnd (df); vgl_DFileEnd (dfile); return 0; }
The function vgl_DFileRead begins reading from the beginning of the file until it reads the token terminating the first frame. This token is written in the previous example by the vgl_DFileClose function. All graphics primitives read are issued to the drawing function object which has been registered with the DFile object using vgl_DFileSetObject.
The second frame is read by querying for the current file position using vgl_DFileCurPosition and setting it using vgl_DFileSetPosition prior to calling vgl_DFileRead.
#include <stdio.h> #include <stdlib.h> #include "vgl/vgl.h" /*---------------------------------------------------------------------- Read Native DFile and Print ----------------------------------------------------------------------*/ int main(int argc, char** argv) { vgl_DFile *dfile; vgl_DrawFun *df; Vchar filename[256]; Vint filetype; long pos; /* specify filename */ if(argc < 2) { fprintf(stderr,"Usage: %s filename\n",argv[0]); fprintf(stderr," filename is blank, 'exam16d.asc' is assumed\n"); strcpy(filename,"exam16d.asc"); } else { strcpy(filename,argv[1]); } /* instance reader objects */ dfile = vgl_DFileBegin (); df = vgl_DrawFunBegin (); vgl_DFileSetObject (dfile,VGL_DRAWFUN,df); vgl_DrawFunAPI (df,DRAWFUN_APIPRINT); /* set file name */ vgl_DFileSetFileName (dfile,filename); /* query and set file format */ vgl_DFileReadFileType (dfile,&filetype); vgl_DFileSetFileType (dfile,filetype); /* Read and print 1st frame */ vgl_DFileRead (dfile); /* Query position to start reading 2nd frame */ vgl_DFileCurPosition (dfile,&pos); /* Set position to start reading 2nd frame */ vgl_DFileSetPosition (dfile,pos); /* Read and print 2nd frame */ vgl_DFileRead (dfile); /* clean up */ vgl_DFileEnd (dfile); vgl_DrawFunEnd (df); return 0; }
#include <stdio.h> #include <stdlib.h> #include "vgl/vgl.h" /* face connectivity of unit cube */ static Vint faces[6][4] = { {3,2,1,0},{4,5,6,7},{0,1,5,4},{2,3,7,6},{3,0,4,7},{1,2,6,5} }; /* vertices coordinates of unit cube */ static Vfloat coords[8][3] = { {0.,0.,0.},{1.,0.,0.},{1.,1.,0.},{0.,1.,0.}, {0.,0.,1.},{1.,0.,1.},{1.,1.,1.},{0.,1.,1.} }; /* face colors */ static Vfloat frgb[6][3] = { {1.,0.,0.},{0.,1.,0.},{0.,0.,1.},{1.,1.,0.},{1.,0.,1.},{0.,1.,1.} }; /* edge connectivity */ static Vint edges[12][2] = { {0,1},{1,2},{2,3},{3,0}, {4,5},{5,6},{6,7},{7,4}, {0,4},{1,5},{2,6},{3,7} }; /* vertex colors for edge drawing */ static Vfloat vrgb[8][3] = { {1.,0.,0.},{0.,1.,0.},{0.,0.,1.},{1.,1.,0.}, {1.,0.,1.},{0.,1.,1.},{.5,.5,.5},{1.,1.,1.} }; /* face normals */ static Vfloat normals[6][3] = { {0.,0.,-1.},{0.,0.,1.},{0.,-1.,0.},{0.,1.,0.},{-1.,0.,0.},{1.,0.,0.} }; /*---------------------------------------------------------------------- Write All ASCII File Types Using DFile ----------------------------------------------------------------------*/ int main(int argc, char** argv) { Vint i, j, n; vgl_DList *dlist; vgl_DFile *dfile; vgl_DrawFun *dl, *df; Vfloat xp[4][3], cp[2][3], c[3]; /* instance vgl objects */ dfile = vgl_DFileBegin (); df = vgl_DrawFunBegin (); vgl_DFileDrawFun (dfile,df); dlist = vgl_DListBegin (); dl = vgl_DrawFunBegin (); vgl_DListDrawFun (dlist,dl); /* set DFile as output of DList */ vgl_DListSetObject (dlist,VGL_DRAWFUN,df); /* fill display list */ /* draw text */ vgl_DrawFunText (dl,coords[0],"Frame 1"); /* draw faces of a hex */ for(n = 0; n < 6; n++) { vgl_DrawFunColor (dl,frgb[n]); for(i = 0; i < 4; ++i) { for(j = 0; j < 3; ++j) { xp[i][j] = coords[faces[n][i]][j]; } } vgl_DrawFunPolygon(dl,VGL_POLYGON,4,xp,VGL_FLATSHADE,(Vfloat*)normals[n]); } /* draw vertices and face edges */ /* draw vertices of a hex in white */ c[0] = 1.; c[1] = 1.; c[2] = 1.; vgl_DrawFunColor (dl,c); vgl_DrawFunPolyPoint (dl,8,coords); /* draw face edges of a hex */ for(n = 0; n < 12; n++) { for(i = 0; i < 2; ++i) { for(j = 0; j < 3; ++j) { xp[i][j] = coords[edges[n][i]][j]; cp[i][j] = vrgb[edges[n][i]][j]; } } vgl_DrawFunPolyLineColor (dl,VGL_LINESTRIP,2,xp,cp); } /* specify Native ascii file type */ vgl_DFileSetFileType (dfile,DFILE_ASCII); vgl_DFileSetFileName (dfile,"exam16f.asc"); /* draw DList to DFile */ vgl_DFileOpen (dfile); vgl_DListCall (dlist); vgl_DFileClose (dfile); /* X3D file type */ vgl_DFileSetFileType (dfile,DFILE_X3D); vgl_DFileSetFileName (dfile,"exam16f.x3d"); vgl_DFileOpen (dfile); vgl_DListCall (dlist); vgl_DFileClose (dfile); /* DAE file type */ vgl_DFileSetFileType (dfile,DFILE_DAE); vgl_DFileSetFileName (dfile,"exam16f.dae"); vgl_DFileOpen (dfile); vgl_DListCall (dlist); vgl_DFileClose (dfile); /* VRML file type */ vgl_DFileSetFileType (dfile,DFILE_VRML); vgl_DFileSetFileName (dfile,"exam16f.wrl"); vgl_DFileOpen (dfile); vgl_DListCall (dlist); vgl_DFileClose (dfile); /* OBJ file type */ vgl_DFileSetFileType (dfile,DFILE_OBJ); vgl_DFileSetFileName (dfile,"exam16f.obj"); vgl_DFileOpen (dfile); vgl_DListCall (dlist); vgl_DFileClose (dfile); /* delete objects */ vgl_DrawFunEnd (df); vgl_DrawFunEnd (dl); vgl_DListEnd (dlist); vgl_DFileEnd (dfile); return 0; }
#include "base/base.h" #include "vgl/vgl.h" static Vfloat xq[4][3] = { {-.75,-.75,0.}, { .75,-.75,0.}, { .75, .75,0.}, {-.75, .75,0.} }; static Vfloat xt[3][3] = { {0.,0.,0.}, {.5,0.,0.}, {.5,.5,0.} }; /*---------------------------------------------------------------------- Draw Polygon with Hole using Stencil Buffer ----------------------------------------------------------------------*/ int main() { Vfloat c[3]; Vint dev; Vchar devname[256]; #ifdef VKI_WIND_X11 Display *display; int screen; #else HFONT hfont; #endif vgl_OpenGLDev *ogldev; vgl_RendBuf *rendbuf; vgl_FBuffer *fbuffer; #ifdef VKI_WIND_X11 vgl_X11Dev *x11dev; #else vgl_GDIDev *gdidev; #endif vgl_DrawFun *df; /* 0 = RendBuf, 1 = OpenGLDev, 2 = GDIDev or X11Dev */ dev = 1; /* connect to X or Windows */ #ifdef VKI_WIND_X11 display = XOpenDisplay (0); screen = DefaultScreen (display); if(dev == 1) { vgl_OpenGLDevConnectX (display,screen); } else if(dev == 2) { vgl_X11DevConnectX (display,screen); } #else if(dev == 1) { vgl_OpenGLDevConnectWIN (); } else if(dev == 2) { vgl_GDIDevConnectWIN (); } #endif /* create drawing functions */ df = vgl_DrawFunBegin(); /* create device objects and load drawing functions */ if(dev == 0) { rendbuf = vgl_RendBufBegin(); vgl_RendBufDrawFun (rendbuf,df); strcpy(devname,"RendBuf"); } else if(dev == 1) { ogldev = vgl_OpenGLDevBegin(); vgl_OpenGLDevDrawFun (ogldev,df); strcpy(devname,"OpenGL"); } else if(dev == 2) { #ifdef VKI_WIND_X11 x11dev = vgl_X11DevBegin(); vgl_X11DevDrawFun (x11dev,df); strcpy(devname,"X11"); #else gdidev = vgl_GDIDevBegin(); vgl_GDIDevDrawFun (gdidev,df); strcpy(devname,"GDI"); #endif } /* request a stencil buffer */ vgl_DrawFunVisualWindow (df,VGL_VISUAL_STENCIL); /* open windows */ vgl_DrawFunPositionWindow (df,200,300,300,225); vgl_DrawFunOpenWindow (df,devname); vgl_DrawFunProjOrtho (df,-1.3333,1.3333,-1.,1.,-1.,1.); vgl_DrawFunSetMode (df,VGL_STENCILMODE,VGL_ON); /* draw white square with triangular hole */ /* stencil cleared to 0 */ vgl_DrawFunClear (df); c[0] = 1.; c[1] = 1.; c[2] = 1.; vgl_DrawFunColor (df,c); /* draw triangular hole, setting stencil to 1 */ vgl_DrawFunSetMode (df,VGL_STENCILFUNCMODE,VGL_NEVER); vgl_DrawFunSetMode (df,VGL_STENCILFUNCREF,1); vgl_DrawFunSetMode (df,VGL_STENCILOPFAIL,VGL_OP_REPLACE); vgl_DrawFunPolygon (df,VGL_POLYGON,3,xt,VGL_NOSHADE,NULL); /* draw enclosing quad, stencil value is not equal to 1 */ vgl_DrawFunSetMode (df,VGL_STENCILFUNCMODE,VGL_NOTEQUAL); vgl_DrawFunSetMode (df,VGL_STENCILFUNCREF,1); vgl_DrawFunSetMode (df,VGL_STENCILOPFAIL,VGL_OP_KEEP); vgl_DrawFunPolygon (df,VGL_POLYGON,4,xq,VGL_NOSHADE,NULL); vgl_DrawFunSwap (df); /* write out image if RendBuf used */ if(dev == 0) { fbuffer = vgl_FBufferBegin (); vgl_DrawFunFBufferRead (df,0,0,0,0,fbuffer); vgl_FBufferWriteGIF (fbuffer,"exam17.gif"); vgl_FBufferEnd (fbuffer); } /* wait */ vgl_DrawFunDelay (df,10.); /* close windows */ vgl_DrawFunCloseWindow (df); /* free objects */ if(dev == 0) { vgl_RendBufEnd (rendbuf); } else if(dev == 1) { vgl_OpenGLDevEnd (ogldev); } else if(dev == 2) { #ifdef VKI_WIND_X11 vgl_X11DevEnd (x11dev); #else vgl_GDIDevEnd (gdidev); #endif } vgl_DrawFunEnd (df); /* disconnect */ if(dev == 1) { vgl_OpenGLDevDisconnect (); } else if(dev == 2) { #ifdef VKI_WIND_X11 vgl_X11DevDisconnect (); #else vgl_GDIDevDisconnect (); #endif } /* clean up */ #ifdef VKI_WIND_X11 XCloseDisplay (display); #else DeleteObject (hfont); #endif return 0; }
#include "base/base.h" #include "vgl/vgl.h" /* triangle data */ static Vfloat xtris1[3][3] = { {-.5, -.6, 0.5}, { .3,-.6,0.5}, {-.1, .4, 0.5} }; static Vfloat ttris1[3] = { 0.,0.,1. }; static Vfloat xtris2[3][3] = { {-.3, -.7, 0.}, { .5,-.7,0.}, { .1, .3, 0.} }; static Vfloat xtris3[3][3] = { {-.1, -.5, 1.}, { .7,-.5,1.}, { .3, .6, 1.} }; static Vfloat xtris[3][3] = { {-.1, -.3, .75}, { .1,-.3,.75}, { .0, -.1, .75} }; /* text location */ static Vfloat xtext[3] = {-.9,.9,0.}; static void draw_scene(vgl_DrawFun *df) { Vfloat c[3]; vgl_DrawFunTrans (df,.5); /* white base color textured middle */ c[0] = 1.; c[1] = 1.; c[2] = 1.; vgl_DrawFunColor (df,c); vgl_DrawFunTextureSelect (df,1); vgl_DrawFunPolygon (df,VGL_TRIANGLES,3,xtris1,VGL_1DTEXTURE,(Vfloat*)ttris1); vgl_DrawFunTextureSelect (df,0); /* blue farthest */ c[0] = 0.; c[1] = 0.; c[2] = 1.; vgl_DrawFunColor (df,c); vgl_DrawFunPolygon (df,VGL_TRIANGLES,3,xtris2,VGL_NOSHADE,NULL); /* red nearest */ c[0] = 1.; c[1] = 0.; c[2] = 0.; vgl_DrawFunColor (df,c); vgl_DrawFunPolygon (df,VGL_TRIANGLES,3,xtris3,VGL_NOSHADE,NULL); return; } /*---------------------------------------------------------------------- Transparency with Depth Peeling ----------------------------------------------------------------------*/ int main() { Vfloat c[3]; Vint flag, peelpass, peelpix, peeltol; vgl_Texture *texture; #ifdef VKI_WIND_X11 Display *display; int screen; #endif vgl_OpenGLDev *opengldev; vgl_DrawFun *df; /* connect to X or Windows */ #ifdef VKI_WIND_X11 display = XOpenDisplay (0); screen = DefaultScreen (display); vgl_OpenGLDevConnectX (display,screen); #else vgl_OpenGLDevConnectWIN (); #endif /* create drawing functions */ df = vgl_DrawFunBegin(); /* create device objects and load drawing functions */ opengldev = vgl_OpenGLDevBegin(); vgl_OpenGLDevDrawFun (opengldev,df); /* open window */ vgl_DrawFunPositionWindow (df,200,200,400,400); #ifdef VKI_WIND_X11 vgl_DrawFunOpenWindow (df,"X Windows"); #else vgl_DrawFunOpenWindow (df,"Microsoft Windows"); #endif vgl_DrawFunSetMode (df,VGL_ZBUFFERMODE,VGL_ON); /* default projection limits are bi-unit cube */ /* test for shader support */ vgl_DrawFunGetInteger (df,VGL_SHADER_SUPPORTED,&flag); if(flag == 0) goto labelcleanup; /* define texture */ texture = vgl_TextureBegin (); /* built-in is index 1 */ vgl_TextureLoad (texture,TEXTURE_HUE_BANDED); vgl_TextureSetEnv (texture,TEXTURE_MODULATE); vgl_DrawFunTextureDefine (df,1,texture); /* free texture object */ vgl_TextureEnd (texture); /* turn on shader mode */ vgl_DrawFunSetMode (df,VGL_SHADERMODE,VGL_ON); /* turn on blending */ vgl_DrawFunSetMode (df,VGL_BLENDTRANSMODE,VGL_ON); /* white background */ c[0] = 1.; c[1] = 1.; c[2] = 1.; vgl_DrawFunBackColor (df,c); vgl_DrawFunClear (df); /* draw opaque objects first for optimization, not necessary for correct rendering however */ /* opaque yellow just behiind red */ vgl_DrawFunTrans (df,0.); c[0] = 1.; c[1] = 1.; c[2] = 0.; vgl_DrawFunColor (df,c); vgl_DrawFunPolygon (df,VGL_TRIANGLES,3,xtris,VGL_NOSHADE,NULL); /* set pixel threshold */ peeltol = 20000; peeltol = 0; /* depth peel loop */ for(peelpass = 1; peelpass < 10; peelpass++) { vgl_DrawFunSetMode (df,VGL_DEPTHPEELMODE,peelpass); draw_scene (df); vgl_DrawFunGetInteger (df,VGL_DEPTHPEEL_PIXELS,&peelpix); printf("peelpass= %d, peelpix= %d\n",peelpass,peelpix); if(peelpix <= peeltol) break; } /* last pass */ if(peelpix != 0) { vgl_DrawFunSetMode (df,VGL_DEPTHPEELMODE,VGL_DEPTHPEELLAST); draw_scene (df); } /* turn depth peel off to write any annotation */ vgl_DrawFunSetMode (df,VGL_DEPTHPEELMODE,0); c[0] = 0.; c[1] = 0.; c[2] = 0.; vgl_DrawFunSetMode (df,VGL_BLENDTRANSMODE,VGL_OFF); vgl_DrawFunTrans (df,0.); vgl_DrawFunColor (df,c); vgl_DrawFunText (df,xtext,"Depth Peeling"); /* swap buffers */ vgl_DrawFunSwap (df); /* wait 10 seconds */ vgl_DrawFunDelay (df,10.); /* cleanup */ labelcleanup:; /* close windows */ vgl_DrawFunCloseWindow (df); /* free objects */ vgl_OpenGLDevEnd (opengldev); vgl_DrawFunEnd (df); /* disconnect from X or Windows */ vgl_OpenGLDevDisconnect (); /* close X display */ #ifdef VKI_WIND_X11 XCloseDisplay (display); #endif return 0; }
#include "base/base.h" #include "vgl/vgl.h" /* point data */ static Vfloat xpoint[4][3] = { {-.5, .5, 0.}, {.5, .5, 0.}, {-.5,-.5, 0.}, {-.4,-.4, 0.} }; /* colors */ static Vfloat cpoint[4][3] = { {1., 0., 0.}, {0., 0., 1.}, {0., 1., 0.}, {1., 0., 1.} }; /* device size */ static Vfloat dpoint[4] = { 1., 2., 3., 4.}; /* world size */ static Vfloat wpoint[4] = { .1, .2, .3, .4}; /* numbers */ static Vuint idpoint[4] = { 101, 123456, 1234567890, 7091946}; static Vfloat xtext[3] = {-.7,.78,0.}; static Vfloat ctext[3] = {1.,1.,1.}; /* light properties */ static Vfloat camb[3] = { .3,.3,.3 }; static Vfloat cdis[3] = { .7,.7,.7 }; static Vfloat xdis[3] = { 1.,0.,0. }; /*---------------------------------------------------------------------- Drawing Scalar Icons at Points ----------------------------------------------------------------------*/ int main() { #ifdef VKI_WIND_X11 Display *display; int screen; #endif vgl_OpenGLDev *opengldev; vgl_DrawFun *df; Vfloat fac; /* connect to X or Windows */ #ifdef VKI_WIND_X11 display = XOpenDisplay (0); screen = DefaultScreen (display); vgl_OpenGLDevConnectX (display,screen); #else vgl_OpenGLDevConnectWIN (); #endif /* create drawing functions */ df = vgl_DrawFunBegin(); /* create device objects and load drawing functions */ opengldev = vgl_OpenGLDevBegin(); vgl_OpenGLDevDrawFun (opengldev,df); /* open window */ vgl_DrawFunPositionWindow (df,200,200,400,400); #ifdef VKI_WIND_X11 vgl_DrawFunOpenWindow (df,"X Windows"); #else vgl_DrawFunOpenWindow (df,"Microsoft Windows"); #endif /* set lights */ vgl_DrawFunLight (df,0,VGL_LIGHT_AMBIENT,camb,NULL); vgl_DrawFunLight (df,1,VGL_LIGHT_DISTANT,cdis,xdis); vgl_DrawFunSetMode (df,VGL_LIGHTMODE,VGL_ON); /* default projection limits are bi-unit cube */ /* turn on zbuffer mode */ vgl_DrawFunSetMode (df,VGL_ZBUFFERMODE,VGL_ON); /* turn on shader mode */ vgl_DrawFunSetMode (df,VGL_SHADERMODE,VGL_ON); /* draw four points as dot (pixel) icons, point size of 8 */ /* data size is ignored */ vgl_DrawFunClear (df); vgl_DrawFunColor (df,ctext); vgl_DrawFunText (df,xtext,"DOT, size 8"); vgl_DrawFunPointSize (df,8); vgl_DrawFunPointStyle (df,VGL_POINTSTYLE_DOT); vgl_DrawFunPolyPointArray (df,4,xpoint,VGL_COLOR_3F,cpoint, 0,NULL,0,NULL,1,dpoint); vgl_DrawFunSwap (df); vgl_DrawFunDelay (df,2.); /* draw four points as sphere icons */ /* data size is ignored */ vgl_DrawFunClear (df); vgl_DrawFunColor (df,ctext); vgl_DrawFunText (df,xtext,"SPHERE, size 16"); vgl_DrawFunPointSize (df,16); vgl_DrawFunPointStyle (df,VGL_POINTSTYLE_SPHERE); vgl_DrawFunPolyPointArray (df,4,xpoint,VGL_COLOR_3F,cpoint, 0,NULL,0,NULL,1,dpoint); vgl_DrawFunSwap (df); vgl_DrawFunDelay (df,2.); /* draw four points as sphere icons */ /* data size enabled */ vgl_DrawFunSetMode (df,VGL_DATASIZEMODE,VGL_ON); vgl_DrawFunClear (df); vgl_DrawFunColor (df,ctext); vgl_DrawFunText (df,xtext,"SPHERE, data sized"); vgl_DrawFunPolyPointArray (df,4,xpoint,VGL_COLOR_3F,cpoint, 0,NULL,0,NULL,1,dpoint); vgl_DrawFunSwap (df); vgl_DrawFunDelay (df,2.); /* draw four points as sphere world icons */ /* data size enabled */ vgl_DrawFunClear (df); vgl_DrawFunColor (df,ctext); vgl_DrawFunText (df,xtext,"SPHEREWORLD, data sized"); vgl_DrawFunPointStyle (df,VGL_POINTSTYLE_SPHEREWORLD); vgl_DrawFunPolyPointArray (df,4,xpoint,VGL_COLOR_3F,cpoint, 0,NULL,0,NULL,1,wpoint); vgl_DrawFunSwap (df); vgl_DrawFunDelay (df,2.); /* double their size */ vgl_DrawFunClear (df); vgl_DrawFunColor (df,ctext); vgl_DrawFunText (df,xtext,"SPHEREWORLD, doubled data sized"); fac = 2.; vgl_DrawFunSetFactors (df,VGL_WORLDSIZE,&fac); vgl_DrawFunPointStyle (df,VGL_POINTSTYLE_SPHEREWORLD); vgl_DrawFunPolyPointArray (df,4,xpoint,VGL_COLOR_3F,cpoint, 0,NULL,0,NULL,1,wpoint); fac = 1.; vgl_DrawFunSetFactors (df,VGL_WORLDSIZE,&fac); vgl_DrawFunSwap (df); vgl_DrawFunDelay (df,2.); /* data size disabled */ vgl_DrawFunSetMode (df,VGL_DATASIZEMODE,VGL_OFF); /* draw four points as bitmaps */ vgl_DrawFunClear (df); vgl_DrawFunColor (df,ctext); vgl_DrawFunText (df,xtext,"Bitmaps, constant 9x9"); vgl_DrawFunPointStyle (df,VGL_POINTSTYLE_PLUS9); vgl_DrawFunPolyPointArray (df,4,xpoint,VGL_COLOR_3F,cpoint, 0,NULL,0,NULL,0,NULL); vgl_DrawFunSwap (df); vgl_DrawFunDelay (df,2.); vgl_DrawFunPointSize (df,2); /* draw four numbers */ vgl_DrawFunClear (df); vgl_DrawFunColor (df,ctext); vgl_DrawFunText (df,xtext,"UINT, center"); vgl_DrawFunPointStyle (df,VGL_POINTSTYLE_DOT); vgl_DrawFunPolyPointArray (df,4,xpoint,0,NULL,0,NULL,0,NULL,0,NULL); vgl_DrawFunPointStyle (df,VGL_POINTSTYLE_UINT); vgl_DrawFunPolyPointArray (df,4,xpoint,VGL_COLOR_3F,cpoint, 0,NULL,0,NULL,1,(Vfloat*)idpoint); vgl_DrawFunSwap (df); vgl_DrawFunDelay (df,4.); vgl_DrawFunClear (df); vgl_DrawFunColor (df,ctext); vgl_DrawFunText (df,xtext,"UINT, lower left"); vgl_DrawFunPointStyle (df,VGL_POINTSTYLE_DOT); vgl_DrawFunPolyPointArray (df,4,xpoint,0,NULL,0,NULL,0,NULL,0,NULL); vgl_DrawFunPointStyle (df,VGL_POINTSTYLE_UINTLL); vgl_DrawFunPolyPointArray (df,4,xpoint,VGL_COLOR_3F,cpoint, 0,NULL,0,NULL,1,(Vfloat*)idpoint); vgl_DrawFunSwap (df); vgl_DrawFunDelay (df,4.); /* close windows */ vgl_DrawFunCloseWindow (df); /* free objects */ vgl_OpenGLDevEnd (opengldev); vgl_DrawFunEnd (df); /* disconnect from X or Windows */ vgl_OpenGLDevDisconnect (); /* close X display */ #ifdef VKI_WIND_X11 XCloseDisplay (display); #endif return 0; }
The OIT algorithm requires caching all generated transparent fragments in graphics memory and then compositing them with opaque pixels when vgl_DrawFunSwap is called. This memory is a limited resource and may not be sufficient for complex, multi-layered models on a large screen. The memory required in bytes is approximately 12 times the average transparent layer complexity per pixel times the number of screen pixels. This memory data structure is preallocated before rendering occurs. The average number of layers used for allocation is a value set using vgl_DrawFunSetMode with parameter VGL_OITAVERAGELAYERS. The user can query this value using vgl_DrawFunGetMode. The OIT rendering may fail if sufficient memory is not available. It may be incomplete if the number of fragments generated exceeds the allocated fragment memory. The user may query for these conditions before swap so that a problem rendering may be detected before swapping. Use vgl_DrawFunGetInteger with parameter VGL_OIT_MEMORYFAIL to query for memory failure. The user can also query for the fragment counters using vgl_DrawFunGetInteger with parameter VGL_OIT_COUNTERS. Two values are returned, the maximum number of fragments that can currently be stored and the number of fragments generated by the current rendering. If the number of fragments generated exceeds the maximum, the rendering will be incomplete. The user at this point can compute a new proportionately larger average layer value, set it using vgl_DrawFunSetMode and retry the rendering.
#include "base/base.h" #include "vgl/vgl.h" /* triangle data */ static Vfloat xtris1[3][3] = { {-.5, -.6, 0.5}, { .3,-.6,0.5}, {-.1, .4, 0.5} }; static Vfloat ttris1[3] = { 0.,0.,1. }; static Vfloat xtris2[3][3] = { {-.3, -.7, 0.}, { .5,-.7,0.}, { .1, .3, 0.} }; static Vfloat xtris3[3][3] = { {-.1, -.5, 1.}, { .7,-.5,1.}, { .3, .6, 1.} }; static Vfloat xtris[3][3] = { {-.1, -.3, .75}, { .1,-.3,.75}, { .0, -.1, .75} }; /* text location */ static Vfloat xfore[3] = {0.,0.1,0.}; static Vfloat xback[3] = {0.,-.15,0.}; static Vfloat xplan[3] = {-.6,-.6,0.}; /* title box location */ static Vfloat xtbox[4][3] = { {-.75, .7, 0.}, { .75,.7,0.}, { .75, .9, 0.}, {-.75,.9,0.}}; static Vfloat xtext[3] = {-.7,.78,0.}; static void draw_scene(vgl_DrawFun *df) { Vfloat c[3]; Vfloat path[3], plane[3]; /* 50 percent transparent */ vgl_DrawFunTrans (df,.5); /* red nearest */ c[0] = 1.; c[1] = 0.; c[2] = 0.; vgl_DrawFunColor (df,c); vgl_DrawFunPolygon (df,VGL_TRIANGLES,3,xtris3,VGL_NOSHADE,NULL); /* white base color textured middle */ c[0] = 1.; c[1] = 1.; c[2] = 1.; vgl_DrawFunColor (df,c); vgl_DrawFunTextureSelect (df,1); vgl_DrawFunPolygon (df,VGL_TRIANGLES,3,xtris1,VGL_1DTEXTURE,(Vfloat*)ttris1); vgl_DrawFunTextureSelect (df,0); /* blue farthest */ c[0] = 0.; c[1] = 0.; c[2] = 1.; vgl_DrawFunColor (df,c); vgl_DrawFunPolygon (df,VGL_TRIANGLES,3,xtris2,VGL_NOSHADE,NULL); /* opaque text parallel to triangle edge */ vgl_DrawFunTrans (df,0.); c[0] = 0.; c[1] = 0.; c[2] = 0.; vgl_DrawFunColor (df,c); vgl_DrawFunRasFontSelect (df,1); path[0] = .4; path[1] = 1.; path[2] = 0.; plane[0] = -1.; plane[1] = 0.; plane[2] = 0.; vgl_DrawFunTextPlane (df,path,plane); vgl_DrawFunText (df,xplan,"Parallel to Triangle Edge"); vgl_DrawFunRasFontSelect (df,0); return; } /*---------------------------------------------------------------------- Order Independent Transparency ----------------------------------------------------------------------*/ int main() { Vfloat c[3]; Vint dc[3]; Vint flag, oitcounters[2]; vgl_Texture *texture; vgl_RasFont *rasfont; #ifdef VKI_WIND_X11 Display *display; int screen; #endif vgl_OpenGLDev *opengldev; vgl_DrawFun *df; /* connect to X or Windows */ #ifdef VKI_WIND_X11 display = XOpenDisplay (0); screen = DefaultScreen (display); vgl_OpenGLDevConnectX (display,screen); #else vgl_OpenGLDevConnectWIN (); #endif /* create drawing functions */ df = vgl_DrawFunBegin(); /* create device objects and load drawing functions */ opengldev = vgl_OpenGLDevBegin(); vgl_OpenGLDevDrawFun (opengldev,df); /* open window */ vgl_DrawFunPositionWindow (df,200,200,400,400); #ifdef VKI_WIND_X11 vgl_DrawFunOpenWindow (df,"X Windows"); #else vgl_DrawFunOpenWindow (df,"Microsoft Windows"); #endif vgl_DrawFunSetMode (df,VGL_ZBUFFERMODE,VGL_ON); /* default projection limits are bi-unit cube */ /* test for OIT support */ vgl_DrawFunGetInteger (df,VGL_OIT_SUPPORTED,&flag); if(flag == 0) { printf("OIT not supported\n"); goto labelcleanup; } /* define texture, built-in is index 1 */ texture = vgl_TextureBegin (); vgl_TextureLoad (texture,TEXTURE_HUE_BANDED); vgl_TextureSetEnv (texture,TEXTURE_MODULATE); vgl_DrawFunTextureDefine (df,1,texture); vgl_TextureEnd (texture); /* define rasfont, textplane is index 1 */ rasfont = vgl_RasFontBegin(); vgl_RasFontLoad (rasfont,RASFONT_QUALITY9X13); vgl_RasFontSetParami (rasfont,RASFONT_TEXTPLANE,SYS_ON); vgl_RasFontSetParami (rasfont,RASFONT_DEVICESIZE,SYS_ON); vgl_DrawFunRasFontDefine (df,1,rasfont); vgl_RasFontEnd (rasfont); /* turn on shader and OIT mode */ vgl_DrawFunSetMode (df,VGL_SHADERMODE,VGL_ON); vgl_DrawFunSetMode (df,VGL_OITMODE,VGL_ON); /* white background */ c[0] = 1.; c[1] = 1.; c[2] = 1.; vgl_DrawFunBackColor (df,c); vgl_DrawFunClear (df); /* draw background text string */ vgl_DrawFunSetMode (df,VGL_ZBUFFERMODE,VGL_OFF); vgl_DrawFunTrans (df,0.); c[0] = 0.; c[1] = 0.; c[2] = 0.; vgl_DrawFunColor (df,c); vgl_DrawFunText (df,xback,"Background Text"); vgl_DrawFunSetMode (df,VGL_ZBUFFERMODE,VGL_ON); /* draw opaque objects first for potential optimization, not necessary for correct rendering however */ /* opaque yellow just behiind red */ vgl_DrawFunTrans (df,0.); c[0] = 1.; c[1] = 1.; c[2] = 0.; vgl_DrawFunColor (df,c); vgl_DrawFunPolygon (df,VGL_TRIANGLES,3,xtris,VGL_NOSHADE,NULL); /* draw transparent triangles and textplane text */ draw_scene (df); vgl_DrawFunSetMode (df,VGL_ZBUFFERMODE,VGL_OFF); /* draw opaque title */ vgl_DrawFunTrans (df,0.); c[0] = 0.5; c[1] = 0.5; c[2] = 0.5; vgl_DrawFunColor (df,c); vgl_DrawFunPolygon (df,VGL_QUADS,4,xtbox,VGL_NOSHADE,NULL); c[0] = 0.; c[1] = 0.; c[2] = 0.; vgl_DrawFunColor (df,c); vgl_DrawFunPolyLine (df,VGL_LINELOOP,4,xtbox); c[0] = 0.; c[1] = 0.; c[2] = 0.; vgl_DrawFunColor (df,c); dc[0] = 1; dc[1] = 1; dc[2] = 0; vgl_DrawFunTextDC (df,xtext,dc,"Order Independent Transparency"); c[0] = 1.; c[1] = 1.; c[2] = 1.; vgl_DrawFunColor (df,c); vgl_DrawFunText (df,xtext,"Order Independent Transparency"); /* draw foreground text string */ c[0] = 0.; c[1] = 0.; c[2] = 0.; vgl_DrawFunColor (df,c); vgl_DrawFunText (df,xfore,"Foreground Text"); vgl_DrawFunSetMode (df,VGL_ZBUFFERMODE,VGL_ON); /* check for various failures */ vgl_DrawFunGetInteger (df,VGL_OIT_COUNTERS,oitcounters); printf("maxnode= %d\n",oitcounters[0]); printf("numnode= %d\n",oitcounters[1]); if(oitcounters[1] > oitcounters[0]) { printf("counter overflow\n"); } vgl_DrawFunGetInteger (df,VGL_OIT_MEMORYFAIL,&flag); if(flag) { printf("GPU memory allocation failure\n"); } /* swap buffers */ vgl_DrawFunSwap (df); vgl_DrawFunGetInteger (df,VGL_DEV_ERROR,&flag); if(flag) { printf("Device error= %d\n",flag); } vgl_DrawFunSetMode (df,VGL_OITMODE,VGL_OFF); /* wait 5 seconds */ vgl_DrawFunDelay (df,5.); /* cleanup */ labelcleanup:; /* close windows */ vgl_DrawFunCloseWindow (df); /* free objects */ vgl_OpenGLDevEnd (opengldev); vgl_DrawFunEnd (df); /* disconnect from X or Windows */ vgl_OpenGLDevDisconnect (); /* close X display */ #ifdef VKI_WIND_X11 XCloseDisplay (display); #endif return 0; }