Start e.g.:
../../../bin/vish VertexBufferObject.vis
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