Visualization Library v1.0.3A lightweight C++ OpenGL middleware for 2D/3D graphics |
[Download] [Tutorials] [All Classes] [Grouped Classes] |
This tutorial shows how simple it is to use the OpenGL Shading Language with Visualization Library.
The example below demostrates the use of vertex shaders, fragment shaders and geometry shaders.
[From App_GLSL.cpp
]
class App_GLSL: public BaseDemo { public: App_GLSL() { } void initEvent() { if (!Has_GLSL) { Log::error("OpenGL Shading Language not supported.\n"); Time::sleep(2000); exit(1); } trackball()->setPivot(vl::vec3(4.5f, 4.5f, 0.0f)); Log::notify(appletInfo()); ref<ResourceDatabase> res_db = loadResource("/models/3ds/monkey.3ds"); mModel = res_db->get<Geometry>(0); mModel->computeNormals(); AABB aabb = mModel->boundingBox(); mModel->transform( mat4::getTranslation(-aabb.center()) ); ref<Light> light = new Light; ref<GLSLProgram> glsl; ref<GLSLVertexShader> perpixellight_vs = new GLSLVertexShader("/glsl/perpixellight.vs"); //glsl = new GLSLProgram; //mGLSL.push_back(glsl); //glsl->attachShader( perpixellight_vs.get() ); //glsl->attachShader( new GLSLFragmentShader("/glsl/perpixellight.fs") ); glsl = new GLSLProgram; mGLSL.push_back(glsl); glsl->attachShader( new GLSLVertexShader("/glsl/examples/toyball.vs") ); glsl->attachShader( new GLSLFragmentShader("/glsl/examples/toyball.fs") ); glsl = new GLSLProgram; mGLSL.push_back(glsl); glsl->attachShader( perpixellight_vs.get() ); glsl->attachShader( new GLSLFragmentShader("/glsl/examples/perpixellight_toon.fs") ); glsl = new GLSLProgram; mGLSL.push_back(glsl); glsl->attachShader( perpixellight_vs.get() ); glsl->attachShader( new GLSLFragmentShader("/glsl/examples/heat.fs") ); glsl = new GLSLProgram; mGLSL.push_back(glsl); glsl->attachShader( perpixellight_vs.get() ); glsl->attachShader( new GLSLFragmentShader("/glsl/examples/perpixellight_interlaced.fs") ); ref<GLSLVertexShader> noise_vs = new GLSLVertexShader("/glsl/examples/noise.vs"); ref<GLSLFragmentShader> noise3D_fs = new GLSLFragmentShader("/glsl/noise3D.glsl"); glsl = new GLSLProgram; mGLSL.push_back(glsl); glsl->attachShader( noise_vs.get() ); glsl->attachShader( new GLSLFragmentShader("/glsl/examples/alien.fs") ); glsl->attachShader( noise3D_fs.get() ); glsl = new GLSLProgram; mGLSL.push_back(glsl); glsl->attachShader( noise_vs.get() ); glsl->attachShader( new GLSLFragmentShader("/glsl/examples/cloud.fs") ); glsl->attachShader( noise3D_fs.get() ); glsl = new GLSLProgram; mGLSL.push_back(glsl); glsl->attachShader( noise_vs.get() ); glsl->attachShader( new GLSLFragmentShader("/glsl/examples/granite.fs") ); glsl->attachShader( noise3D_fs.get() ); glsl = new GLSLProgram; mGLSL.push_back(glsl); glsl->attachShader( noise_vs.get() ); glsl->attachShader( new GLSLFragmentShader("/glsl/examples/marble.fs") ); glsl->attachShader( noise3D_fs.get() ); glsl = new GLSLProgram; mGLSL.push_back(glsl); glsl->attachShader( noise_vs.get() ); glsl->attachShader( new GLSLFragmentShader("/glsl/examples/marble2.fs") ); glsl->attachShader( noise3D_fs.get() ); glsl = new GLSLProgram; mGLSL.push_back(glsl); glsl->attachShader( noise_vs.get() ); glsl->attachShader( new GLSLFragmentShader("/glsl/examples/turbulence.fs") ); glsl->attachShader( noise3D_fs.get() ); glsl = new GLSLProgram; mGLSL.push_back(glsl); glsl->attachShader( noise_vs.get() ); glsl->attachShader( new GLSLFragmentShader("/glsl/examples/woody.fs") ); glsl->attachShader( noise3D_fs.get() ); glsl = new GLSLProgram; mGLSL.push_back(glsl); glsl->attachShader( noise_vs.get() ); glsl->attachShader( new GLSLFragmentShader("/glsl/examples/ribbon.fs") ); glsl->attachShader( noise3D_fs.get() ); glsl = new GLSLProgram; mGLSL.push_back(glsl); glsl->attachShader( new GLSLVertexShader("/glsl/examples/noisebump.vs") ); glsl->attachShader( new GLSLFragmentShader("/glsl/examples/noisebump.fs") ); glsl->attachShader( noise3D_fs.get() ); glsl = new GLSLProgram; mGLSL.push_back(glsl); glsl->attachShader( new GLSLVertexShader("/glsl/examples/hatching.vs") ); glsl->attachShader( new GLSLFragmentShader("/glsl/examples/hatching.fs") ); glsl = new GLSLProgram; mGLSL.push_back(glsl); glsl->attachShader( new GLSLVertexShader("/glsl/examples/stripes.vs") ); glsl->attachShader( new GLSLFragmentShader("/glsl/examples/stripes.fs") ); if (Has_Geometry_Shader) { glsl = new GLSLProgram; mGLSL.push_back(glsl); // a vertex shader is always needed when using geometry shaders glsl->attachShader( new GLSLVertexShader("/glsl/examples/diffuse.vs") ); glsl->attachShader( new GLSLGeometryShader("/glsl/examples/triangle_fur.gs") ); glsl->setGeometryInputType(GIT_TRIANGLES); glsl->setGeometryOutputType(GOT_TRIANGLE_STRIP); glsl->setGeometryVerticesOut( 3*6 ); } else { Log::print("Geomery shaders not supported.\n"); } mGLSL.resize(4*4); for(int y=0; y<4; ++y) { for(int x=0; x<4; ++x) { ref<Effect> fx = new Effect; fx->shader()->setRenderState( light.get(), 0 ); fx->shader()->enable(EN_LIGHTING); fx->shader()->enable(EN_DEPTH_TEST); // fx->shader()->enable(EN_CULL_FACE); GLSLProgram* glsl = mGLSL[x + y*4].get(); if (glsl) fx->shader()->setRenderState(glsl); ref<Transform> tr = new Transform; real grid= 3.0; tr->setLocalAndWorldMatrix( mat4::getTranslation(x*grid, y*grid, 0) ); sceneManager()->tree()->addActor( mModel.get(), fx.get(), tr.get() ); } } } void fileDroppedEvent(const std::vector<String>& files) { ref<ResourceDatabase> db = loadResource(files[0]); Geometry* geom = db->get<Geometry>(0); if (!geom) geom = db->get<Actor>(0)->lod(0)->as<Geometry>(); if (geom) { mModel->shallowCopyFrom( *geom ); mModel->computeBounds(); AABB aabb = mModel->boundingBox(); real norm = aabb.width() > aabb.height() ? aabb.width() : aabb.height(); norm = norm > aabb.depth() ? norm : aabb.depth(); real scale = 1.5; mModel->transform( vl::mat4::getTranslation( -aabb.center() ) ); mModel->transform( vl::mat4::getScaling( scale / norm, scale / norm, scale / norm ) ); } } void updateScene() { } protected: ref<Geometry> mModel; std::vector< ref<GLSLProgram> > mGLSL; }; // Have fun!