ToolTech
05-01-2004, 12:19 PM
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 (http://www.gizmosdk.se) for win32, Irix,Mac OS X and linux.
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 (http://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.
ToolTech
05-03-2004, 04:56 AM
Here is a program that uses either OpenGL Shaders or ARB fp/vp in parallell.
// ************************************************** ***************************
// 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,FAL SE)
{
// 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(),TRU E);
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_COL LECT_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)keysta te,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,(gzR eal)(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 &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.
Powered by vBulletin® Version 4.2.0 Copyright © 2013 vBulletin Solutions, Inc. All rights reserved.