Start e.g.:
../../../bin/vish VBOShader.vis
Further tutorials: - VectorFieldLines.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 <ocean/GLvish/Shader.hpp> 00011 00012 #include <stdio.h> 00013 00014 using namespace Wizt; 00015 00016 00037 class MyRenderObject : public VRenderObject 00038 { 00039 struct MyState : State 00040 { 00041 double complexity; 00042 00043 MyState() 00044 : complexity(0.5) 00045 {} 00046 }; 00047 00048 override RefPtr<State> newState() const 00049 { 00050 return new MyState(); 00051 } 00052 00053 virtual void render(VRenderContext&Context) const; 00054 00055 public: 00056 TypedSlot<double> Complexity, 00057 ScaleFactor; 00058 00059 MyRenderObject(const string&name, int p, const RefPtr<VCreationPreferences>&VP) 00060 : VRenderObject(name, p, VP) 00061 , Complexity(this, "complexity", 0.5) 00062 , ScaleFactor(this, "ScaleFactor", 1.0) 00063 {} 00064 00065 ~MyRenderObject() 00066 {} 00067 }; 00068 00069 00070 /* 00071 http://www.opengl.org/sdk/libs/OpenSceneGraph/glsl_quickref.pdf 00072 */ 00073 00074 static const char vertexshader_src[] = 00075 "\n" 00076 "" 00077 "void main(void)\n" 00078 "{\n" 00079 " gl_Position = ftransform();\n" 00080 "" 00081 "\n" 00082 "}\n"; 00083 00084 00085 00086 static const char elevation_vertexshader_src[] = 00087 00088 #define SHADER_ELEVATION "elevation" 00089 00090 "attribute float "SHADER_ELEVATION";\n" 00091 "uniform float scaleFactor;\n" 00092 "\n" 00093 "" 00094 "void main(void)\n" 00095 "{\n" 00096 "vec4 Pos = gl_Vertex;\n" 00097 " Pos.x += 0.1*scaleFactor*"SHADER_ELEVATION";\n" 00098 " Pos.y += 0.1*scaleFactor*"SHADER_ELEVATION";\n" 00099 " Pos.z += 0.1*scaleFactor*"SHADER_ELEVATION";\n" 00100 "vec4 V = gl_ModelViewMatrix * Pos;\n" 00101 " gl_Position = gl_ProjectionMatrix * V;" 00102 "" 00103 "\n" 00104 "}\n"; 00105 00106 static const char fragmentshader_src[] = 00107 "\n" 00108 "void main (void)\n" 00109 "{\n" 00110 " gl_FragColor = gl_Color;\n" 00111 " gl_FragColor.g = 0.5+0.5*sin(gl_FragCoord.x*3.14/20);" // allows to modify pixel depending on pixel coordinates 00112 "}\n" 00113 ; 00114 00115 00116 void MyRenderObject::render(VRenderContext&Context) const 00117 { 00118 static GLfloat Red[4] = {0.9, 0.1, 0.1, 1.0 }; 00119 00120 int N = 3000; 00121 double r = 1.0; 00122 00123 double complexity = 0.5; 00124 Complexity << Context >> complexity; 00125 00126 double scalefactor = 1.0; 00127 ScaleFactor << Context >> scalefactor; 00128 00129 double dphi = 3.1415/ 80, 00130 zs = 0.3 * complexity; 00131 00132 glEnable( GL_COLOR_MATERIAL ); 00133 glColorMaterial( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE ); 00134 SubObjectBegin(Context); 00135 vglColor4fv(Context, Red, 0.4); 00136 00137 glEnable(GL_DEPTH_TEST); 00138 00139 RefPtr<MyState> state = myState(Context); 00140 00141 RefPtr<Program> MyProgram; 00142 MyProgram = new Program(); 00143 00144 RefPtr<VertexShader> VS = new VertexShader(); 00145 VS->compile( elevation_vertexshader_src); 00146 MyProgram->attach(*VS); 00147 00148 RefPtr<FragmentShader> FS = new FragmentShader(); 00149 FS->compile( fragmentshader_src ); 00150 MyProgram->attach(*FS); 00151 00152 MyProgram->link(); 00153 00154 if (!MyProgram->isValid() ) 00155 { 00156 printf("VertexView: Shader: %s\n", MyProgram->InfoLog().c_str() ); 00157 throw "Vertex Shader Compilation Error"; 00158 } 00159 else 00160 { 00161 MyProgram->use(); 00162 MyProgram->setUniformValuef( "scaleFactor", scalefactor); 00163 } 00164 00165 // 00166 // Define a parameter space for which VBO's need to be stored. 00167 // For each value of the parameters in this value set, there will 00168 // be one VBO, until we run out of memory. 00169 // In this example, the parameter space is empty. 00170 // 00171 RefPtr<ValueSet> RenderParameterSpace = new ValueSet(); 00172 00173 // 00174 // Retrieve a Vertex Buffer Object relative to the Context 00175 // and call it if exists. 00176 // 00177 RefPtr<VBO> myVBO; 00178 try 00179 { 00180 myVBO = Context(*state)(this)( RenderParameterSpace )( VERTEXBUFFER() ); 00181 } 00182 catch(...){} 00183 if (myVBO && !myVBO->empty() && state->complexity == complexity) 00184 { 00185 if (myVBO->call() ) 00186 return; 00187 } 00188 00189 // 00190 // We don't have a valid VBO, so need to create one. 00191 // 00192 myVBO = Context[*state][this][ RenderParameterSpace ]( VERTEXBUFFER() ); 00193 // 00194 // In case we had one, but need to re-create it, clear the one found. 00195 // 00196 myVBO->clear(); 00197 00198 // 00199 // Store the complexity value in the state object for further 00200 // comparision. 00201 // 00202 state->complexity = complexity; 00203 00204 // 00205 // Create a vertex array and a normal array 00206 // 00207 RefPtr<VertexArray> Points = new TypedVertexArray<point>(); 00208 RefPtr<NormalArray> Normals = new TypedNormalArray<bivector>(); 00209 00210 00211 RefPtr<VertexAttribArray> Attribs = new TypedVertexAttribArray<float>( MyProgram->getAttribID( SHADER_ELEVATION ) ); 00212 00213 // 00214 // Compute the geometry and store them in the vertex and normal arrays. 00215 // 00216 resetBBox(Context); 00217 { 00218 std::vector<point> PointData; 00219 std::vector<bivector> NormalData; 00220 std::vector<float> AttribData; 00221 PointData.resize(2*N); 00222 NormalData.resize(2*N); 00223 AttribData.resize(2*N); 00224 00225 // 00226 // The actual compution. Note that it is completely 00227 // independent from OpenGL and could be done elsewhere, 00228 // for instance in the object's update() function or 00229 // within a thread. However, we need to take care to 00230 // employ the caching system right, since this computation 00231 // does not need to be performed if a valid VBO object 00232 // already exists. The existence of a VBO object however 00233 // requires an OpenGL context. 00234 // 00235 for (int i=0;i<N;i++) 00236 { 00237 double phi0 = i*dphi, 00238 phi1 = (i+5/complexity)*dphi; 00239 00240 point A, B; 00241 A = r*cos(phi0), r*sin(phi0), phi0*zs; 00242 B = r*cos(phi0), r*sin(phi0), phi1*zs; 00243 00244 bivector N; 00245 N = cos(phi0), sin(phi0), 0; 00246 00247 embrace( Context, A ); 00248 embrace( Context, B ); 00249 00250 PointData[2*i ] = A; 00251 PointData[2*i+1] = B; 00252 00253 NormalData[2*i ] = N; 00254 NormalData[2*i+1] = N; 00255 00256 AttribData[2*i ] = 00257 AttribData[2*i+1] = sin(10*phi0); 00258 } 00259 00260 // 00261 // Now load the data from RAM to the GPU. 00262 // 00263 Points ->load( PointData ); 00264 Normals->load( NormalData ); 00265 Attribs->load( AttribData ); 00266 00267 } 00268 closeBBox(Context); 00269 00270 // 00271 // Tell the VBO ot use these arrays 00272 // 00273 myVBO->append(Points); 00274 myVBO->append(Normals); 00275 myVBO->append(Attribs); 00276 00277 /* 00278 Define a Renderer object, as it will be used in the VBO. 00279 Here, the standard renderer will do, otherwise we could 00280 well derive from the DrawArrays class. 00281 */ 00282 myVBO->setRenderer( new DrawArrays(GL::QUAD_STRIP, 2*N) ); 00283 myVBO->call(); 00284 } 00285 00286 static Ref<VCreator<MyRenderObject> > MyCreator("Tutorial/VertexShaderObject", 0); 00287 00288 /* 00289 This line needs to be contained in ONE source file of each 00290 VISH plugin module. It's not important which one. 00291 */ 00292 VISH_DEFAULT_INIT 00293 00294