[SOLVED] A simple shader program?

Problems building or running the engine, queries about how to use features etc.
Nav
Halfling
Posts: 91
Joined: Fri Sep 30, 2011 11:22 am
x 2

[SOLVED] A simple shader program?

Post by Nav »

I've been through the wiki, the cookbook, ogre-source and the tutorials, but yet me and my colleague can't understand how to get a simple shader program (GLSL or HLSL) working in Ogre. Yup, we're newbies to this, and the problem is that although there's a lot of sample shader code and material scripts, there's no tutorial that explains it in steps like:
1. Create a cpp file with your program
2. Place the script in a file in this folder
3. Invoke that script with this code in the cpp file.

We're just not able to visualise what goes where and how to invoke the code in the script files. The ogre-source isn't helping coz I'm not able to debug using Visual Studio's attach to process because the sample demo goes full-screen.
Any help with the steps or a new tutorial would be very much appreciated.
Last edited by Nav on Tue Feb 07, 2012 11:07 am, edited 1 time in total.
zootlewurdle
Halfling
Posts: 91
Joined: Sat Aug 06, 2011 8:38 am
Location: United Kingdom
x 2

Re: A simple shader program?

Post by zootlewurdle »

I know this won't answer all your issues in detail, or even anything, but I'll say this. You don't really invoke shader code directly, the render system does that as required. Shaders are used by materials, so it is in the material script where the reference to the shader is made, telling it what file the shader is in, what the entry point is (for vertex and fragment), and what the function parameters are.
User avatar
Jabberwocky
OGRE Moderator
OGRE Moderator
Posts: 2819
Joined: Mon Mar 05, 2007 11:17 pm
Location: Canada
x 218

Re: A simple shader program?

Post by Jabberwocky »

zootlewurdle is right.

Here's the basic flow for including a shader:

1. You create your shader in a .cg/.glsl/.hlsl file, and put it in one of the resource directories your program reads. Your resource directories may be specified in a resources.cfg file or if not then directly in code.

2. You need to declare your shader before your material can use it.
This looks something like this:

Code: Select all

// This says you are declaring a cg vertex program named "example_vp"
vertex_program example_vp cg
{
	// the name of the file containing your shader
	source example.cg

	// the name of your shader's function name inside example.cg
	// this is often the same as the name you've declared for this shader above
	entry_point example_vp

	// what shader model you're using - see ogre manual for more details
	profiles vs_2_x arbvp1 

	default_params
	{
	   // If you had any parameters you wanted to pass to every instance/use of this shader, you'd put them here.
           // See the ogre manual and the ogre examples about how to pass parameters
        }
}

// This says you are declaring a cg fragment program (aka "pixel shader") named "example_fp"
fragment_program example_fp cg
{
	source example.cg
	entry_point example_fp
	profiles ps_2_x arbfp1
}
These can be placed in .program files, or inside your material file at the top, before you use your shader.
As always, your .program or .material files need to be in one of your resource directories loaded by your game.

3. Your material has to reference this shader.
Example:

Code: Select all

material ExampleMaterial
{
	technique
	{
		pass
		{
			// This tells this material to use the shader you defined above
			vertex_program_ref example_vp
			{
			   // (advanced) You can provide any custom parameters to your shader here
			}
			fragment_program_ref example_fp
			{
			   // (advanced) You can provide any custom parameters to your shader here
			}
 
			texture_unit 
			{
				texture example_texture.png
			}
		}
	}
}
If your shader doesn't work, open your ogre.log file, and search for "error".
It usually spits out some helpful info.
Image
Nav
Halfling
Posts: 91
Joined: Fri Sep 30, 2011 11:22 am
x 2

Re: A simple shader program?

Post by Nav »

Thanks Jabberwocky. I've just found the JajDoo tutorials too, and was trying it out: http://www.ogre3d.org/tikiwiki/JaJDoo+S ... e=Cookbook

...but it doesn't work.

This is my shader code [filename: simple_shader.hlsl]. Placed this file in C:\Ogre\ogre_src_v1-7-3\bin\bin\debug. This is where my Debug > Working Directory points to.

Code: Select all

float4 mainVS(		float4 		pos : POSITION,
		uniform float4x4 	worldViewProj_m
		) : POSITION
{
	return mul(pos,worldViewProj_m);
}
 
float4 mainPS() : COLOR 
{
	return float4(1, 0, 0, 1);
}
This is my material script [filename: myMaterial.material]. Placed this in C:\Ogre\ogre_src_v1-7-3\Samples\Media\materials\scripts

Code: Select all

vertex_program myVertexProgram hlsl
{
	source simple_shader.hlsl
	entry_point mainVS
	target vs_1_1
	default_params
	{
		param_named_auto worldViewProj_m worldviewproj_matrix
	}
}
fragment_program myFragmentProgram hlsl
{
	source simple_shader.hlsl
	entry_point mainPS
	target ps_2_0
}
 
material myMaterial
{
	technique 
	{
		pass
		{
			vertex_program_ref myVertexProgram
			{
			}
			fragment_program_ref myFragmentProgram
			{
			}
		}
	}
}
This is my program:

Code: Select all

#include <OgreRoot.h>
#include <OgreCamera.h>
#include <OgreSceneManager.h>
#include <OgreRenderWindow.h>

#include <OISEvents.h>
#include <OISInputManager.h>
#include <OISKeyboard.h>
#include <OISMouse.h>

#include <OgreManualObject.h>
#include <OgrePrerequisites.h>
#include <OgreRenderQueueListener.h>

#include <OgreConfigFile.h>
#include <OgreMaterialManager.h>


class LowLevelOgre
{
public:
    LowLevelOgre(void);
    virtual ~LowLevelOgre(void);
    bool go(void);
protected:
    Ogre::Root *mRoot;
    Ogre::Camera* mCamera;
    Ogre::SceneManager* mSceneMgr;
    Ogre::RenderWindow* mWindow;

    //OIS Input devices
    OIS::InputManager* mInputManager;
    OIS::Mouse*    mMouse;
    OIS::Keyboard* mKeyboard;
};

#include <OgreLogManager.h>
#include <OgreViewport.h>
#include <OgreEntity.h>
#include <OgreWindowEventUtilities.h>
#include <OgrePlugin.h>

//-------------------------------------------------------------------------------------
LowLevelOgre::LowLevelOgre(void)   : mRoot(0), mCamera(0), mSceneMgr(0), mWindow(0), mInputManager(0), mMouse(0), mKeyboard(0) {}
LowLevelOgre::~LowLevelOgre(void) {delete mRoot;}
//-------------------------------------------------------------------------------------
 
bool LowLevelOgre::go(void)
{
    // construct Ogre::Root : no plugins filename, no config filename, using a custom log filename
    mRoot = new Ogre::Root("", "", "LowLevelOgre.log");
 
    // A list of required plugins
    Ogre::StringVector required_plugins;
    required_plugins.push_back("GL RenderSystem");
    required_plugins.push_back("Octree & Terrain Scene Manager");
 
    // List of plugins to load
    Ogre::StringVector plugins_toLoad;
    plugins_toLoad.push_back("RenderSystem_GL");
    plugins_toLoad.push_back("Plugin_OctreeSceneManager");
 
    // Load the OpenGL RenderSystem and the Octree SceneManager plugins
    for (Ogre::StringVector::iterator j = plugins_toLoad.begin(); j != plugins_toLoad.end(); j++)
    {
#ifdef _DEBUG
        mRoot->loadPlugin(*j + Ogre::String("_d"));
#else
        mRoot->loadPlugin(*j);
#endif;
    }
 
    // Check if the required plugins are installed and ready for use
    // If not: exit the application
    Ogre::Root::PluginInstanceList ip = mRoot->getInstalledPlugins();
    for (Ogre::StringVector::iterator j = required_plugins.begin(); j != required_plugins.end(); j++)
    {
        bool found = false;
        // try to find the required plugin in the current installed plugins
        for (Ogre::Root::PluginInstanceList::iterator k = ip.begin(); k != ip.end(); k++)
        {
            if ((*k)->getName() == *j) {found = true;break;}
        }//for
        if (!found) {return false;}  // return false because a required plugin is not available
    }//for
 
//-------------------------------------------------------------------------------------
    // setup resources. Only add the minimally required resource locations to load up the Ogre head mesh    
    Ogre::ResourceGroupManager::getSingleton().addResourceLocation("C:/Ogre/ogre_src_v1-7-3/Samples/Media/materials/programs", "FileSystem", "General");
    Ogre::ResourceGroupManager::getSingleton().addResourceLocation("C:/Ogre/ogre_src_v1-7-3/Samples/Media/materials/scripts", "FileSystem", "General");
    Ogre::ResourceGroupManager::getSingleton().addResourceLocation("C:/Ogre/ogre_src_v1-7-3/Samples/Media/materials/textures", "FileSystem", "General");
    Ogre::ResourceGroupManager::getSingleton().addResourceLocation("C:/Ogre/ogre_src_v1-7-3/Samples/Media/models", "FileSystem", "General");

    // configure 
    Ogre::RenderSystem* rs = mRoot->getRenderSystemByName("OpenGL Rendering Subsystem");
    if(!(rs->getName() == "OpenGL Rendering Subsystem")) {return false;}//No RenderSystem found

    // configure our RenderSystem
    rs->setConfigOption("Full Screen", "No");
    rs->setConfigOption("VSync", "No");
    rs->setConfigOption("Video Mode", "1024 x 760 @ 32-bit");
 
    mRoot->setRenderSystem(rs);
 
    mWindow = mRoot->initialise(true, "LowLevelOgre Render Window");
    // Get the SceneManager, in this case the OctreeSceneManager
    mSceneMgr = mRoot->createSceneManager("OctreeSceneManager", "DefaultSceneManager");
    mCamera = mSceneMgr->createCamera("PlayerCam");// create camera
    mCamera->setPosition(Ogre::Vector3(1,1,5));// Position it in Z direction
    mCamera->lookAt(Ogre::Vector3(0,0,0));// Look back along -Z
    mCamera->setNearClipDistance(5);
    // Create one viewport, entire window
    Ogre::Viewport* vp = mWindow->addViewport(mCamera);
    vp->setBackgroundColour(Ogre::ColourValue(0,0,0));
    mCamera->setAspectRatio( Ogre::Real(vp->getActualWidth()) / Ogre::Real(vp->getActualHeight()) );// Alter the camera aspect ratio to match the viewport
    Ogre::TextureManager::getSingleton().setDefaultNumMipmaps(5);// Set default mipmap level (NB some APIs ignore this)
    Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();// load resources
    Ogre::Entity* ogreHead = mSceneMgr->createEntity("Head", "ogrehead.mesh");// Create the scene
    Ogre::SceneNode* headNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
    //headNode->attachObject(ogreHead);
    mSceneMgr->setAmbientLight(Ogre::ColourValue(0.5, 0.5, 0.5));// Set ambient light
    Ogre::Light* l = mSceneMgr->createLight("MainLight");// Create a light
    l->setPosition(20,80,50);

//v shaders----------------------------------------------------------------------------------------------------------
    Ogre::ResourceManager::ResourceCreateOrRetrieveResult result = Ogre::MaterialManager::getSingleton().createOrRetrieve("myMaterial.material", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
    
    if ((bool)result.second) MessageBox( NULL, NULL, "Loaded", MB_OK | MB_ICONERROR | MB_TASKMODAL);
    else MessageBox( NULL, NULL, "Not Loaded", MB_OK | MB_ICONERROR | MB_TASKMODAL);
    
//^ shaders----------------------------------------------------------------------------------------------------------


	mRoot->clearEventTimes();

    while(true)
    {
        Ogre::WindowEventUtilities::messagePump(); // Pump window messages for nice behaviour
        mRoot->renderOneFrame();// Render a frame
        if(mWindow->isClosed()) {return false;}
    }
    // We should never be able to reach this corner but return true to calm down our compiler
    return true;
}//go
 
#include "windows.h"

extern "C" 
{ 
    INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
    {
        LowLevelOgre app;// Create application object
 
        try {app.go();} 
        catch( Ogre::Exception& e ) 
        {
            MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
        }
 
        return 0;
    }//main
}

It loads the material script, and the screen stays blank. How do I display the object that has to be displayed?
User avatar
madmarx
OGRE Expert User
OGRE Expert User
Posts: 1671
Joined: Mon Jan 21, 2008 10:26 pm
x 50

Re: A simple shader program?

Post by madmarx »

O_O

OK so you are newbies :D .
HLSL is direct3D only. You are using Opengl. Bad luck!

Did you read the Ogre log? I suspect it to tell that it can't compile the shader at least.

You read my tutorials about materials and loading elements first, and then you can try the "B_1_Cubes" (the shader code is more complicated but you can change it as you wish) example from my project. There are no external files, just a straight big cpp that is easy to catch.
Tutorials + Ogre searchable API + more for Ogre1.7 : http://sourceforge.net/projects/so3dtools/
Corresponding thread : http://www.ogre3d.org/forums/viewtopic. ... 93&start=0
Nav
Halfling
Posts: 91
Joined: Fri Sep 30, 2011 11:22 am
x 2

Re: A simple shader program?

Post by Nav »

Thanks madmarx. I've got to learn to look at the log files. Turned out that the material wasn't finding the hlsl file. Corrected it, and I still get a blank screen (I've changed the rendersystem to DirectX now).
This code is working. It's loading the resource.

Code: Select all

    Ogre::Entity* ogreHead = mSceneMgr->createEntity("Head", "ogrehead.mesh");// Create the scene
    Ogre::SceneNode* headNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
    headNode->attachObject(ogreHead);
    mSceneMgr->setAmbientLight(Ogre::ColourValue(0.5, 0.5, 0.5));// Set ambient light
    Ogre::Light* l = mSceneMgr->createLight("MainLight");// Create a light
    l->setPosition(20,80,50);

    Ogre::ResourceManager::ResourceCreateOrRetrieveResult result = Ogre::MaterialManager::getSingleton().createOrRetrieve("myMaterial.material", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
    ogreHead->setMaterialName("myMaterial");
    ogreHead->setMaterial(result.first);
But how do I make it display something on the screen? Shouldn't it at least display the ogre head with pixels shaded in red colour? (the usual green head is displayed when I don't set the material as myMaterial)

This is the log:
11:40:54: * Render to Vertex Buffer : no
11:40:54: * DirectX per stage constants: yes
11:40:54: ***************************************
11:40:54: *** D3D9 : Subsystem Initialised OK ***
11:40:54: ***************************************
...blah
11:40:56: Parsing script myMaterial.material
...blah
11:40:56: Mesh: Loading ogrehead.mesh.
11:40:56: Texture: GreenSkin.jpg: Loading 1 faces(PF_R8G8B8,256x256x1) with hardware generated mipmaps from Image. Internal format is PF_X8R8G8B8,256x256x1.
11:40:56: Texture: spheremap.png: Loading 1 faces(PF_R8G8B8,256x256x1) with hardware generated mipmaps from Image. Internal format is PF_X8R8G8B8,256x256x1.
11:40:56: Texture: tusk.jpg: Loading 1 faces(PF_R8G8B8,96x96x1) with 5 generated mipmaps from Image. Internal format is PF_X8R8G8B8,96x96x1.
11:42:15: DefaultWorkQueue('Root') shutting down on thread main.
11:42:15: *-*-* OGRE Shutdown
[I've been thru your tutorials. Couldn't find the "B_1_Cubes" though]
Nav
Halfling
Posts: 91
Joined: Fri Sep 30, 2011 11:22 am
x 2

Re: A simple shader program?

Post by Nav »

Phew! finally found the problem. The return value in mainVS should be

Code: Select all

return mul(worldViewProj_m,pos);
Earlier it was

Code: Select all

return mul(pos,worldViewProj_m);
The entire code is here for anyone who wants the simplest shader example.

Code: Select all

#include <OgreRoot.h>
#include <OgreCamera.h>
#include <OgreSceneManager.h>
#include <OgreRenderWindow.h>

#include <OISEvents.h>
#include <OISInputManager.h>
#include <OISKeyboard.h>
#include <OISMouse.h>

#include <OgreManualObject.h>
#include <OgrePrerequisites.h>
#include <OgreRenderQueueListener.h>

#include <OgreConfigFile.h>
#include <OgreMaterialManager.h>



class LowLevelOgre
{
public:
    LowLevelOgre(void);
    virtual ~LowLevelOgre(void);
    bool go(void);
protected:
    Ogre::Root *mRoot;
    Ogre::Camera* mCamera;
    Ogre::SceneManager* mSceneMgr;
    Ogre::RenderWindow* mWindow;

    //OIS Input devices
    OIS::InputManager* mInputManager;
    OIS::Mouse*    mMouse;
    OIS::Keyboard* mKeyboard;
};

#include <OgreLogManager.h>
#include <OgreViewport.h>
#include <OgreEntity.h>
#include <OgreWindowEventUtilities.h>
#include <OgrePlugin.h>

//-------------------------------------------------------------------------------------
LowLevelOgre::LowLevelOgre(void)   : mRoot(0), mCamera(0), mSceneMgr(0), mWindow(0), mInputManager(0), mMouse(0), mKeyboard(0) {}
LowLevelOgre::~LowLevelOgre(void) {delete mRoot;}
//-------------------------------------------------------------------------------------
 
bool LowLevelOgre::go(void)
{
    // construct Ogre::Root : no plugins filename, no config filename, using a custom log filename
    mRoot = new Ogre::Root("", "", "EntitiesMeshesAndShaders.log");
 
    // A list of required plugins
    Ogre::StringVector required_plugins;
    required_plugins.push_back("GL RenderSystem");
    required_plugins.push_back("D3D9 RenderSystem");
    required_plugins.push_back("Octree & Terrain Scene Manager");
 
    // List of plugins to load
    Ogre::StringVector plugins_toLoad;
    plugins_toLoad.push_back("RenderSystem_GL");
    plugins_toLoad.push_back("RenderSystem_Direct3D9");
    plugins_toLoad.push_back("Plugin_OctreeSceneManager");
 
    // Load the OpenGL RenderSystem and the Octree SceneManager plugins
    for (Ogre::StringVector::iterator j = plugins_toLoad.begin(); j != plugins_toLoad.end(); j++)
    {
#ifdef _DEBUG
        mRoot->loadPlugin(*j + Ogre::String("_d"));
#else
        mRoot->loadPlugin(*j);
#endif;
    }
 
    // Check if the required plugins are installed and ready for use
    // If not: exit the application
    Ogre::Root::PluginInstanceList ip = mRoot->getInstalledPlugins();
    for (Ogre::StringVector::iterator j = required_plugins.begin(); j != required_plugins.end(); j++)
    {
        bool found = false;
        // try to find the required plugin in the current installed plugins
        for (Ogre::Root::PluginInstanceList::iterator k = ip.begin(); k != ip.end(); k++)
        {
            if ((*k)->getName() == *j) {found = true;break;}
        }//for
        if (!found) {return false;}  // return false because a required plugin is not available
    }//for
 
//-------------------------------------------------------------------------------------
    // setup resources. Only add the minimally required resource locations to load up the Ogre head mesh    
    Ogre::ResourceGroupManager::getSingleton().addResourceLocation("C:/Ogre/ogre_src_v1-7-3/Samples/Media/materials/programs", "FileSystem", "General");
    Ogre::ResourceGroupManager::getSingleton().addResourceLocation("C:/Ogre/ogre_src_v1-7-3/Samples/Media/materials/scripts", "FileSystem", "General");
    Ogre::ResourceGroupManager::getSingleton().addResourceLocation("C:/Ogre/ogre_src_v1-7-3/Samples/Media/materials/textures", "FileSystem", "General");
    Ogre::ResourceGroupManager::getSingleton().addResourceLocation("C:/Ogre/ogre_src_v1-7-3/Samples/Media/models", "FileSystem", "General");
        /*
        Ogre::ConfigFile cf;// Load resource paths from config file
        cf.load("resources.cfg");//cf.load(mResourcePath + "resources_d.cfg");
        Ogre::ConfigFile::SectionIterator seci = cf.getSectionIterator();// Go through all sections & settings in the file

        Ogre::String secName, typeName, archName;
        while (seci.hasMoreElements())
        {
            secName = seci.peekNextKey();
            Ogre::ConfigFile::SettingsMultiMap *settings = seci.getNext();
            Ogre::ConfigFile::SettingsMultiMap::iterator i;
            for (i = settings->begin(); i != settings->end(); ++i)
            {
                typeName = i->first;
                archName = i->second;
                Ogre::ResourceGroupManager::getSingleton().addResourceLocation(archName, typeName, secName);
            }//for
        }//while*/

//-------------------------------------------------------------------------------------
    // configure 
    //Ogre::RenderSystem* rs = mRoot->getRenderSystemByName("OpenGL Rendering Subsystem");
    //if(!(rs->getName() == "OpenGL Rendering Subsystem")) {return false;}//No RenderSystem found
    //rs->setConfigOption("Full Screen", "No");
    //rs->setConfigOption("VSync", "No");
    //rs->setConfigOption("Video Mode", "1024 x 760 @ 32-bit"); 
    //mRoot->setRenderSystem(rs);
    //mWindow = mRoot->initialise(true, "LowLevelOgre Render Window");
    //mWindow = mRoot->initialise(false);


   Ogre::RenderSystem* rs = mRoot->getRenderSystemByName("Direct3D9 Rendering Subsystem");
   if(!(rs->getName() == "Direct3D9 Rendering Subsystem")) { return false; } //No RenderSystem found
   // configure our RenderSystem
   Ogre::ConfigOptionMap m; m = rs->getConfigOptions();
   rs->setConfigOption("Full Screen", "No");
   rs->setConfigOption("VSync", "No");
   rs->setConfigOption("Video Mode", "800 x 600 @ 32-bit colour");
   mRoot->setRenderSystem(rs);
   mWindow = mRoot->initialise(true, "LowLevelOgre Render Window");

    // Get the SceneManager, in this case the OctreeSceneManager
    mSceneMgr = mRoot->createSceneManager("OctreeSceneManager", "DefaultSceneManager");
//-------------------------------------------------------------------------------------
    mCamera = mSceneMgr->createCamera("PlayerCam");// create camera
    mCamera->setPosition(Ogre::Vector3(0,0,100));// Position it in Z direction
    mCamera->lookAt(Ogre::Vector3(0,0,0));// Look back along -Z
    mCamera->setNearClipDistance(5);
//-------------------------------------------------------------------------------------
    // Create one viewport, entire window
    Ogre::Viewport* vp = mWindow->addViewport(mCamera);
    vp->setBackgroundColour(Ogre::ColourValue(0,0,0));
    mCamera->setAspectRatio( Ogre::Real(vp->getActualWidth()) / Ogre::Real(vp->getActualHeight()) );// Alter the camera aspect ratio to match the viewport
//-------------------------------------------------------------------------------------
    Ogre::TextureManager::getSingleton().setDefaultNumMipmaps(5);// Set default mipmap level (NB some APIs ignore this)
//-------------------------------------------------------------------------------------
    // Create any resource listeners (for loading screens)
    //createResourceListener();
    Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();// load resources
    Ogre::Entity* ogreHead = mSceneMgr->createEntity("Head", "ogrehead.mesh");// Create the scene
    Ogre::SceneNode* headNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
    headNode->attachObject(ogreHead);
    mSceneMgr->setAmbientLight(Ogre::ColourValue(0.5, 0.5, 0.5));// Set ambient light
    Ogre::Light* l = mSceneMgr->createLight("MainLight");// Create a light
    l->setPosition(20,80,50);

//v shaders----------------------------------------------------------------------------------------------------------
    Ogre::ResourceManager::ResourceCreateOrRetrieveResult result = Ogre::MaterialManager::getSingleton().createOrRetrieve("myMaterial.material", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
    ogreHead->setMaterialName("shader/myMaterial");
    //if ((bool)result.second) MessageBox( NULL, NULL, "Loaded", MB_OK | MB_ICONERROR | MB_TASKMODAL); else MessageBox( NULL, NULL, "Not Loaded", MB_OK | MB_ICONERROR | MB_TASKMODAL);
//^ shaders----------------------------------------------------------------------------------------------------------


//----------------------------------------------------------------------------------------------------------

mRoot->clearEventTimes();//If you clicked 2000 times when the windows was being created, there are at least 2000 messages created by the OS to listen to. This is made to clean them.

    //mRoot->startRendering();
    while(true)
    {
        Ogre::WindowEventUtilities::messagePump(); // Pump window messages for nice behaviour
        mRoot->renderOneFrame();// Render a frame
        if(mWindow->isClosed()) {return false;}
    }
    // We should never be able to reach this corner but return true to calm down our compiler
    return true;
}//go
 
#include "windows.h"

extern "C" 
{ 
    INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
    {
        LowLevelOgre app;// Create application object
 
        try {app.go();} 
        catch( Ogre::Exception& e ) 
        {
            MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
        }
        return 0;
    }//main
}
and the material script (myMaterial.material) which I placed in the folder C:\Ogre\ogre_src_v1-7-3\Samples\Media\materials\scripts

Code: Select all

vertex_program myVertexProgram hlsl
{
	source simple_shader.hlsl
	entry_point mainVS
	target vs_1_1
	default_params
	{
		param_named_auto worldViewProj_m worldviewproj_matrix
	}
}

fragment_program myFragmentProgram hlsl
{
	source simple_shader.hlsl
	entry_point mainPS
	target ps_2_0
}
 
material shader/myMaterial
{
	technique 
	{
		pass
		{
			vertex_program_ref myVertexProgram
			{
			}
			fragment_program_ref myFragmentProgram
			{
			}
		}
	}
}

and the shader program (simple_shader.hlsl) which I placed in the folder C:\Ogre\ogre_src_v1-7-3\Samples\Media\materials\programs

Code: Select all

float4 mainVS(float4 pos : POSITION, uniform float4x4 worldViewProj_m) : POSITION
{
	return mul(worldViewProj_m,pos);
}
 
float4 mainPS() : COLOR 
{
	return float4(1, 0, 0, 1);
}
User avatar
madmarx
OGRE Expert User
OGRE Expert User
Posts: 1671
Joined: Mon Jan 21, 2008 10:26 pm
x 50

Re: [SOLVED] A simple shader program?

Post by madmarx »

Well done!
The tutorial is in my signature project, which contains more than the tutorials on Ogre3D wiki ^^.
Tutorials + Ogre searchable API + more for Ogre1.7 : http://sourceforge.net/projects/so3dtools/
Corresponding thread : http://www.ogre3d.org/forums/viewtopic. ... 93&start=0
Nav
Halfling
Posts: 91
Joined: Fri Sep 30, 2011 11:22 am
x 2

Re: [SOLVED] A simple shader program?

Post by Nav »

Thanks! :) What signature project do you mean? so3dtools? If not, then any link that can take me to where I can download it?

Some additional info for any newbie who ends up on this thread while searching for a simple shader example in ogre :
Similar to Jabberwocky's explanation above, there's Jajdoo's shader guide which can get you started on understanding shaders: http://www.ogre3d.org/tikiwiki/JaJDoo+Shader+Guide
That'll help you understand the code I've posted.
My code takes the usual Ogre head mesh, attaches it to a scene node and the pixel shader colours the ogre head red.

Some additional helpful stuff in my code is the commented out portion which shows you how to load resource paths from a config file, and also how to initialize the rendersystem in both OpenGL and DirectX.
User avatar
madmarx
OGRE Expert User
OGRE Expert User
Posts: 1671
Joined: Mon Jan 21, 2008 10:26 pm
x 50

Re: [SOLVED] A simple shader program?

Post by madmarx »

Yes it is.
Tutorials + Ogre searchable API + more for Ogre1.7 : http://sourceforge.net/projects/so3dtools/
Corresponding thread : http://www.ogre3d.org/forums/viewtopic. ... 93&start=0
mrmclovin
Gnome
Posts: 324
Joined: Sun May 11, 2008 9:27 pm
x 20

Re: [SOLVED] A simple shader program?

Post by mrmclovin »

Thank you! I added a worldview parameter in the shader function and multiplied it with the input position and returned it as the output position. It works successfully now!

Code: Select all

Test_Output main(float4 position : POSITION, uniform float4x4 worldview)

{

  Test_Output OUT;
	OUT.position = mul(worldview, position);
  OUT.color = float4(0, 1, 0, 1);


  return OUT;

};
I understood that I needed the "uniform" keyword. How would it work if I didnt put it there?
ryandeboer
Halfling
Posts: 85
Joined: Thu Oct 05, 2006 6:19 am
Location: Perth, Australia

Re: [SOLVED] A simple shader program?

Post by ryandeboer »

Thanks for the simple DX9 program! It let me have more luck with shaders than what I was having with opengl.
A tip: You can change the shaders to vs_5_0 and ps_5_0 and then it works in DX11! (Also have to change the render system dialog so you can choose DX11). (edit) I managed to get it to work in opengl 2 and 3+ too.

Here are the changes for OpenGL 2 and 3+:
myMaterialGL.material

Code: Select all

vertex_program myVertexProgramGL glsl
{
    source simple_shaderV.glsl
    profiles glsl330

default_params
{
    param_named_auto worldViewProj_m worldviewproj_matrix
}
}

fragment_program myFragmentProgramGL glsl
{
    source simple_shaderF.glsl
    profiles glsl330
}

material shader/myMaterialGL
{
    technique
    {
        pass
        {
            vertex_program_ref myVertexProgramGL
            {
            }
            fragment_program_ref myFragmentProgramGL
            {
            }
        }
    }
}

simple_shaderV.glsl

Code: Select all

#version 330 core

layout(location = 0) in vec3 position;  // Vertex position attribute
uniform mat4 worldViewProj_m;           // Transformation matrix

void main()
{
    gl_Position = worldViewProj_m * vec4(position, 1.0);
}

simple_shaderF.glsl

Code: Select all

#version 330 core

out vec4 fragColor;  // Output color

void main()
{
    fragColor = vec4(1.0, 0.0, 0.0, 1.0); // Solid red color
}

And this is some useful code to support DX9, DX11, GL2, GL3 in one codebase:

Code: Select all

  
Ogre::RenderSystem* renderSystem = Ogre::Root::getSingleton().getRenderSystem(); std::string renderSystemName = renderSystem->getName(); if (renderSystemName.find("Direct3D9") != std::string::npos) { Ogre::ResourceManager::ResourceCreateOrRetrieveResult result = Ogre::MaterialManager::getSingleton().createOrRetrieve("myMaterialDX9.material", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); ogreHead->setMaterialName("shader/myMaterialDX9"); } else if (renderSystemName.find("Direct3D11") != std::string::npos) { Ogre::ResourceManager::ResourceCreateOrRetrieveResult result = Ogre::MaterialManager::getSingleton().createOrRetrieve("myMaterial.material", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); ogreHead->setMaterialName("shader/myMaterial"); } else if (renderSystemName.find("OpenGL Rendering Subsystem") != std::string::npos) { Ogre::ResourceManager::ResourceCreateOrRetrieveResult result = Ogre::MaterialManager::getSingleton().createOrRetrieve("myMaterialGL.material", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); ogreHead->setMaterialName("shader/myMaterialGL"); } else if (renderSystemName.find("OpenGL 3+ Rendering Subsystem") != std::string::npos) { Ogre::ResourceManager::ResourceCreateOrRetrieveResult result = Ogre::MaterialManager::getSingleton().createOrRetrieve("myMaterialGL.material", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); ogreHead->setMaterialName("shader/myMaterialGL"); } else { //unsupported }