VertexBufferObject.cpp

Demonstration of a 3D render object that uses vertex buffer objects to cache its result.

Start e.g.:

../../../bin/vish VertexBufferObject.vis

See also:
Required tutorials: - Simple3DObject.cpp - DisplayListObject.cpp

Further tutorials: - VBOShader.cpp

00001 
00002 #include <stdio.h>
00003 
00004 #include <ocean/GLvish/VRenderObject.hpp>
00005 #include <ocean/plankton/VCreator.hpp>
00006 #include <ocean/plankton/VTime.hpp>
00007 #include <ocean/GLvish/BoundingBox.hpp>
00008 #include <ocean/GLvish/ArrayTypes.hpp>
00009 
00010 #include <stdio.h>
00011 
00012 using namespace Wizt;
00013 
00014 
00032 /*
00033  Render some object using vertex buffers.
00034  */
00035 class   VertexBufferObject : public VRenderObject
00036 {
00037         struct  MyState : State
00038         {
00039                 double  complexity;
00040 
00041                 MyState()
00042                 : complexity(0.5)
00043                 {}
00044         };
00045 
00046         override RefPtr<State> newState() const
00047         {
00048                 return new MyState();
00049         }
00050 
00051         virtual void render(VRenderContext&Context) const;
00052 
00053 public:
00054         TypedSlot<double>       Complexity;
00055 
00056         VertexBufferObject(const string&name, int p, const RefPtr<VCreationPreferences>&VP)
00057         : VRenderObject(name, p, VP)
00058         , Complexity(this, "complexity", 0.5)
00059         {}
00060 
00061         ~VertexBufferObject()
00062         {}
00063 };
00064 
00065 void VertexBufferObject::render(VRenderContext&Context) const
00066 {
00067 static  GLfloat Red[4]   = {0.9, 0.1, 0.1, 1.0 }; 
00068 
00069 int     N = 300;
00070 double  r = 1.0;
00071 
00072 double  complexity = 0.5; 
00073         Complexity << Context >> complexity; 
00074 
00075 double  dphi = 3.1415/ 10,
00076         zs   = 0.1 * complexity;
00077 
00078 
00079         glEnable( GL_COLOR_MATERIAL );
00080         glColorMaterial( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE );
00081         SubObjectBegin(Context);
00082         vglColor4fv(Context, Red, 0.4); 
00083 
00084         glEnable(GL_DEPTH_TEST);
00085 
00086 RefPtr<MyState> state = myState(Context);
00087 
00088         //
00089         // Define a parameter space for which VBO's need to be stored.
00090         // For each value of the parameters in this value set, there will
00091         // be one VBO, until we run out of memory.
00092         // In this example, the parameter space is empty.
00093         //
00094 RefPtr<ValueSet> RenderParameterSpace = new ValueSet();
00095 
00096         //
00097         // Retrieve a Vertex Buffer Object relative to the Context
00098         // and call it if exists.
00099         //
00100 RefPtr<VBO> myVBO;
00101         try
00102         {
00103                 myVBO = Context(*state)(this)( RenderParameterSpace )( VERTEXBUFFER() );
00104         }
00105         catch(...){}
00106         if (myVBO && !myVBO->empty() && state->complexity == complexity)
00107         {
00108                 if (myVBO->call() )
00109                         return;
00110         }
00111 
00112         //
00113         // We don't have a valid VBO, so need to create one.
00114         //
00115         myVBO = Context[*state][this][ RenderParameterSpace ]( VERTEXBUFFER() ); 
00116         // 
00117         // In case we had one, but need to re-create it, clear the one found. 
00118         //
00119         myVBO->clear(); 
00120 
00121         // 
00122         // Store the complexity value in the state object for further 
00123         // comparision. 
00124         //
00125         state->complexity = complexity; 
00126 
00127         //
00128         // Create a vertex array and a normal array
00129         //
00130         RefPtr<VertexArray> Points = new TypedVertexArray<point>();
00131         RefPtr<NormalArray> Normals = new TypedNormalArray<bivector>(); 
00132 
00133         // 
00134         // Compute the geometry and store them in the vertex and normal arrays. 
00135         //
00136         resetBBox(Context);
00137         {
00138         std::vector<point>    PointData;
00139         std::vector<bivector> NormalData; 
00140                 PointData.resize(2*N); 
00141                 NormalData.resize(2*N); 
00142 
00143                 // 
00144                 // The actual compution. Note that it is completely 
00145                 // independent from OpenGL and could be done elsewhere, 
00146                 // for instance in the object's update() function or 
00147                 // within a thread. However, we need to take care to 
00148                 // employ the caching system right, since this computation 
00149                 // does not need to be performed if a valid VBO object 
00150                 // already exists. The existence of a VBO object however 
00151                 // requires an OpenGL context.
00152                 //
00153                 for (int i=0;i<N;i++) 
00154                 {
00155                 double  phi0 = i*dphi,
00156                         phi1 = (i+1/complexity)*dphi;
00157 
00158                 point   A, B; 
00159                         A = r*cos(phi0), r*sin(phi0), phi0*zs; 
00160                         B = r*cos(phi0), r*sin(phi0), phi1*zs; 
00161 
00162                 bivector N; 
00163                         N = cos(phi0), sin(phi0), 0; 
00164 
00165                         embrace( Context, A );
00166                         embrace( Context, B );
00167 
00168                         PointData[2*i  ] = A;
00169                         PointData[2*i+1] = B; 
00170 
00171                         NormalData[2*i  ] = N;
00172                         NormalData[2*i+1] = N;
00173                 } 
00174 
00175                 // 
00176                 // Now load the data from RAM to the GPU.
00177                 //
00178                 Points ->load( PointData );
00179                 Normals->load( NormalData );
00180         }
00181         closeBBox(Context); 
00182 
00183         // 
00184         // Tell the VBO to use these arrays 
00185         //
00186         myVBO->append(Points);
00187         myVBO->append(Normals);
00188 
00189         /*
00190           Define a Renderer object, as it will be used in the VBO.
00191           Here, the standard renderer will do, otherwise we could
00192           well derive from the DrawArrays class.
00193          */ 
00194         myVBO->setRenderer( new DrawArrays(GL::QUAD_STRIP, 2*N) ); 
00195         myVBO->call();
00196 }
00197 
00198 static Ref<VCreator<VertexBufferObject> > MyCreator("Tutorial/VertexBufferObject", 0);
00199 
00200 /*
00201  This line needs to be contained in ONE source file of each
00202  VISH plugin module. It's not important which one.
00203  */
00204 VISH_DEFAULT_INIT
00205 
00206 

Generated on Thu Apr 2 18:58:49 2009 for VISHTutorial by  doxygen 1.4.7