Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 3 of 3

Thread: OpenGL Shaders in a scene graph

  1. #1
    Super Moderator Regular Contributor
    Join Date
    Jul 2001
    Posts
    401

    OpenGL Shaders in a scene graph

    We have just released a new version of the scene graph Gizmo3D with full support for GLSL combined with ARB vp/fp. Would like some feedback of our hierarchical model of state changes that uses the shaders. Feel free to download and try at www.gizmosdk.se for win32, Irix,Mac OS X and linux.

  2. #2
    Junior Member Regular Contributor
    Join Date
    Jan 2001
    Location
    Lafayette, LA
    Posts
    129

    Re: OpenGL Shaders in a scene graph

    Originally posted by ToolTech:
    We have just released a new version of the scene graph Gizmo3D with full support for GLSL combined with ARB vp/fp. Would like some feedback of our hierarchical model of state changes that uses the shaders. Feel free to download and try at www.gizmosdk.se for win32, Irix,Mac OS X and linux.
    It sounds interesting, but I couldn't find much info about that, and it wasn't obvious from the headers. Can you give us a quick overview of how you integrated shaders in your system?

    Thanks

    Dirk

    P.S.: It is a cross-over topic, but I think it would be more appropriate for the Scenegraphs Forum.

  3. #3
    Super Moderator Regular Contributor
    Join Date
    Jul 2001
    Posts
    401

    Re: OpenGL Shaders in a scene graph

    Here is a program that uses either OpenGL Shaders or ARB fp/vp in parallell.

    Code :
     
    // *****************************************************************************
    // File			: shaders.cpp
    // Module		: 
    // Description	: Test app to show shader usage
    // Author		: Anders Modén          
    // Product		: Gizmo3D 1.2 RC 5
    //              
    // Copyright © 2003- Saab Training Systems AB, Sweden	
    //                      
    // NOTE:	Gizmo3D is a high performance 3D Scene Graph and effect visualisation 
    //			C++ toolkit for Linux, Mac OS X, Windows (Win32) and IRIX® for  
    //			usage in Game or VisSim development.
    //
    //
    // Revision History...                                                  
    //                                                                      
    // Who  Date    Description                                             
    //                                                                      
    // AMO  030707  Created file    
    //
    // ******************************************************************************
     
    // The general include
    #include "gzGizmo3DLibrary.h"
     
    #define USE_GLSL
     
     
    #ifdef USE_GLSL		// Test if we shall try a low level or high level shader
     
    const gzString vertexProgram	="glsl_PFLight.vsh";
    const gzString fragmentProgram	="glsl_PFLight.fsh";
     
    #else
     
    const gzString vertexProgram	="PFLight.vsh";
    const gzString fragmentProgram	="PFLight.fsh";
     
    #endif
     
    // And here comes the Java look alike app. It is a matter of taste.
     
    class MyWindow : public gzWindow
    {
    public:
    	MyWindow(gzApplication *app , gzGraphicsFormat *format , gzString filename ):gzWindow(gzString("Gizmo3D : ")+gzTime::now(TRUE).asString(),NULL,app,format,FALSE)
    	{
    			// Create a scene to render -------------------------------------
    			// We must have a scene that the camera can "look at"
    			m_scene=new gzScene("Database Loader Example Scene");
     
    			// Create some light environment group. This way we get lighting into the model
    			// All stuff under this is lit with material s etc.
    			gzEnvironment *group=new gzEnvironment;
     
    			// Create a backface culling state
    			// We don't want to render backfaces. this way we can "force" the geoms to be rendered without 
    			// backfaces. It also enable the use of the shaders
     
    			m_state=new gzState;
     
    			m_state->setMode(GZ_STATE_POLYGON_MODE,GZ_STATE_ON);
    			m_state->setBackPolygonMode(GZ_POLYGON_MODE_CULL);
    			m_state->setFrontPolygonMode(GZ_POLYGON_MODE_FILL);
    			m_state->disableAllNonEnabledModes();	// We need this for the top global state
     
    			gzState::setGlobalState(getContext(),m_state);
     
     
    			// ---------------------- DB loading ------------------------------
     
    			// Create a object node from a generic db file
     
    			model=gzDbManager::loadDB(filename);
     
    			if(model)	// We got a model
    			{
     
    					gzState *state;
     
    					state=model->getState();
     
    					if(!state)
    						state=new gzState;
     
     
    					// Set the vertex program
     
    					gzGFXProgram *program_vp=new gzGFXProgram;
     
    					program_vp->loadProgramScript(vertexProgram);
     
    					state->setGFXProgram(GZ_GFX_VERTEX_PROGRAM,program_vp);
     
     
    					// Set the fragment program
     
    					gzGFXProgram *program_fp=new gzGFXProgram;
     
    					program_fp->loadProgramScript(fragmentProgram);
     
    					state->setGFXProgram(GZ_GFX_FRAGMENT_PROGRAM,program_fp);
     
    					program_fp->setLocalParameter("color",gzVec4(1,0.5,0.3,1));
     
    					//gzGFXProgram::setGlobalParameter("color",gzVec4(1,0.5,0.3,1));
     
    					// Enable GFX programs
     
    					state->setMode(GZ_STATE_GFX_PROGRAM,GZ_STATE_ON);
     
    					model->setState(state);
     
     
    			}
     
    			gzNodeOptimizer opt;		// We let the optimizer take away redundant geometry etc.
     
    			opt.setMaxRecursionDepth(0);
     
    			model=opt.optimize(model,(gzNodeOptimizeLevel)(GZ_NODE_OPTIMIZE_DONT_COMBINE_NAME_ENCODED/*|GZ_NODE_OPTIMIZE_DONT_CONCAT_GEOMETRY*/));
     
    			// -------------------- lights --------------------------------
     
    			// Add some dynamic light
    			m_spin=new gzLight;						// This is the lamp that we move around
    			m_spin->setSpecularColor(0.2f,0.2f,0.2f);
    			m_spin->setDiffuseColor(0.5f,0.5f,0.5f);
    			m_spin->setAmbientColor(0.3f,0.3f,0.3f);
    			m_spin->setPosition(26,10,90);
     
    			group->addLight(m_spin);
     
    			// ------------------------ some global settings --------------
     
    			gzEnvironment::setTwoSideLighting(getContext(),TRUE);
     
    			gzEnvironment::setLocalViewer(getContext(),TRUE);
     
    			// Translate the model and scale it
     
    			gzTransform *trans=new gzTransform;
     
    			trans->addNode(model);
     
    			trans->unitScale();
     
    			trans->scale(30.0f,30.0f,30.0f);
     
    			group->addNode(trans);
     
    			// Add a geometry alike lamp to show position of light
     
    			m_lamp=new gzTransform;
     
    			gzGeometry *sphere=new gzGeometrySphere(1 , 20 ,gzVec4(1.0,1.0,1.0,1.0) );
     
    			m_lamp->addNode( sphere );
     
    			// Set mouse press state
    			m_inMousePress=FALSE;
     
     
     
    			// And add the group to the scene as well
    			m_scene->addNode(group);
     
    			// And add the lamp
    			m_scene->addNode(m_lamp);
     
     
    			// Now we want to look at the scene. Grab the default perspective camera from the window and set the scen as the
    			// active one.
    			getCamera()->setScene(m_scene);
    			getCamera()->setNearClipPlane(1);
    			getCamera()->setFarClipPlane(2000);
     
    			// Lets add some movement to the scene
     
    			m_input=new gzSimpleMouseViewControl(getCamera());
     
    			addInputInterface(m_input);
     
    			// Hmm. trivial
    			setBackground(0.0f,0.0f,1.0f,1.0f);
     
    			// and show us ...
    			show();
     
    			// hm. wonder why I put this one here ?
    			angle=2.22f;
     
    	};
     
     
    	/*
    		The following code snippet is a virtual function to catch the window messages
    		for pressed, repeated and released keys
    	*/
     
    	gzBool onKey(gzKeyValue key , gzKeyState keystate , gzLong mouse_x , gzLong mouse_y)
    	{
    		switch(key)
    		{
    			case ' ':	// Space pressed // default to non shader view
     
    				if(keystate == GZ_KEY_STATE_PRESSED)
    				{
    					gzState *state=new gzState;
     
    					state->setOverride(GZ_STATE_GFX_PROGRAM,GZ_STATE_ON);
     
    					state->setMode(GZ_STATE_GENERATE_DEBUG_INFO,GZ_STATE_ON);
    					state->setDebugMode((gzStateDebugMode)(GZ_STATE_DEBUG_COLLECT_STATS));
     
    					state->disableAllNonEnabledModes();
     
    					gzState::setGlobalState(getContext(),state);
    				}
    				if(keystate == GZ_KEY_STATE_RELEASED)
    				{
    					gzState::setGlobalState(getContext(),m_state);
    				}
    				break;
     
    			case GZ_KEY_LBUTTON :
     
    				if((keystate == GZ_KEY_STATE_PRESSED) && !m_inMousePress)
    				{
    					setCaptureMouse(TRUE);
    					setHideMouse(TRUE);
    					m_inMousePress=TRUE;
    				}
    				else if((keystate == GZ_KEY_STATE_RELEASED) && m_inMousePress)
    				{
    					setHideMouse(FALSE);
    					setCaptureMouse(FALSE);
    					m_inMousePress=FALSE;
    				}
    				break;
     
    		}
     
    		return gzWindow::onKey((gzKeyValue)key,(gzKeyState)keystate,mouse_x,mouse_y);
    	}
     
     
    	gzVoid onIdle()
    	{
    		// Hmm. Now i remember. The spinning lamp..
     
    		angle+=0.003f;
     
    		if(angle>2*GZ_PI)
    			angle-=(gzReal)(2*GZ_PI);
     
    		m_spin->setPosition((gzReal)(50*cos(5*angle)),5.0f,(gzReal)(50*sin(angle/2)+20));
     
    		m_lamp->setTranslation((gzReal)(50*cos(5*angle)),5.0f,(gzReal)(50*sin(angle/2)+20));
     
    	}
     
    	virtual ~MyWindow()
    	{
    		if(m_input)
    			delete m_input;
     
    	}
     
    	gzRefPointer<gzState>		m_state;
     
    	gzLight *					m_spin;
     
    	gzReal						angle;
     
    	gzTransform	*				m_lamp;
     
    	gzBool						m_inMousePress;
     
    	gzNode						*model;
     
    	gzScene						*m_scene;
     
    	gzSimpleMouseViewControl	*m_input;
     
    };
     
    // Definition of a sample application
    // The application provides an initialisation and an onIdle loop manager
    // to do the refresh of the window
     
    class WindowApp : public gzApplication
    {
    public:
     
    	WindowApp():m_win(NULL),m_format(NULL)
    	{
    	}
     
        ~WindowApp()
    	{
    		if(m_win)
    		{
    			delete m_win;
    		}
     
    	}
     
        void Create(gzString filename)
    	{
    		m_format = new gzGraphicsFormat;
     
    		m_format->useStencil(TRUE);
     
    		m_win = new MyWindow(this,m_format,filename);
     
    		gzPerspCamera *camera=gzDynamic_Cast<gzPerspCamera>(m_win->getCamera());
     
    		camera->setPosition(30,30,150);
    		camera->lookAt(0,0,0);
    		camera->useInfiniteFarPlane(TRUE);
     
    	}
     
    	void onIdle()
    	{
    		if(m_win)
    		{
    			m_win->onIdle();
     
    			m_win->triggerKeyEvaluation();
     
    			if(!m_win->refreshWindow())	// Yield some time if no rendering
    				gzSleep(30);
     
    		}
     
    	}
     
    private:
     
    	friend class MyWindow;
     
    	MyWindow                *m_win;
    	gzGraphicsFormat        *m_format;
    };
     
     
    int main(int argc, char *argv[])
    {
     
    	gzMessage::setMessageLevel(GZ_MESSAGE_MEM_DEBUG);
     
    	gzCheckLibraryVersion();
     
     
    	try
    	{ 
    		gzString	filename="script.3ds";
     
    		gzLicense::notifyDefaultLicense();
     
    		gzGraphicsEngine::useEngine(GZ_ENGINE_OPENGL);
     
    		gzInitializeDbManagers();
     
    		if(argc > 1)
    		{
    			argv++;
    			argc--;
    			while(argc > 0)
    			{
    				if(argv[0][0] == '-')
    				{
    					switch(toupper(argv[0][1]))
    					{
     
    						case 'M' :
    							filename=gzString(*(++argv));
    							argc--;
    							break;
     
    					}
     
    				}
    				argv++;
    				argc--;
    			}
    		}
     
    		// Make the application
    		WindowApp app;
     
    		// Create the scene and the window
    		app.Create(	filename);
     
    		// run the application
    		app.run();
     
    	}
    	catch(gzBaseError &amp;error)       // In case of exceptions thrown we want to print the message
    	{
    		error.reportError();
    	}
     
    	gzShutDownGizmo();
     
    	return 0;
    }
    As we use the state hierarchy mechanism, we can add a top state where defualt shaders are defined and then later in the hierarchy replace a sibling child with a new fragment shader etc.

    The combination of textures and other resourses still works and the system can fallback on other shaders or fixed pipe.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •