(C++) New Magic Library - need testers

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
Post Reply
Emil_halim
Posts: 518
Joined: Tue Mar 29, 2005 9:02 pm
Location: Alex,Egypt
Contact:

(C++) New Magic Library - need testers

Post by Emil_halim »

Hi All

first i want to thanks SUDI for his great help.

this is a beta version of my new Magic Library that rely on Shader language , so you could
use it under directX9 or opengl drivers.

it has two new materials EMT_AlphaBlend & EMT_LightBlend and IShaderProgram interface for
simplfing impelement shader program under directx9 & opengl.

irrlicht uses the shder program under Materials , so if you supply a variable to shader program , it will be applied for all nodes those has that material type.

IShaderProgram interface could be used with a node instead of material ,you cuold create only one shader program and attache it for many nodes and with each node you could supply it own variable.

IShaderProgram interface is not completed yet,need some one to do low level shader class for directx9 driver.

here is the code test it , waiting for your opinion.

CMagicMaterials.h file

Code: Select all

/******************************************************
          New Materials classes

          part of Magic Library
          By Emil Halim

*******************************************************/

#ifndef __I_Magic_Materials_H_INCLUDED__
#define __I_Magic_Materials_H_INCLUDED__


//==================================================================================

class CAlphaBlendMaterial : public video::IMaterialRenderer
{
    IDirect3DDevice9*  _D3D_Device;

   public:

	CAlphaBlendMaterial()
	 {
          _D3D_Device=0;
	 }

  virtual void OnSetMaterial( video::SMaterial& material, const video::SMaterial& lastMaterial,
                              bool resetAllRenderstates, video::IMaterialRendererServices* services )
    {
        if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
		{
		    if(services->getVideoDriver()->getDriverType() == video::EDT_DIRECT3D9)
		    {
		        video::SExposedVideoData  Dat =services->getVideoDriver()->getExposedVideoData();
                _D3D_Device = Dat.D3D9.D3DDev9;
                _D3D_Device->SetRenderState(D3DRS_LIGHTING, false);
                _D3D_Device->SetRenderState( D3DRS_ALPHABLENDENABLE, true );
                _D3D_Device->SetRenderState( D3DRS_SRCBLEND,   D3DBLEND_SRCALPHA );
                _D3D_Device->SetRenderState( D3DRS_DESTBLEND,  D3DBLEND_INVSRCALPHA);
                _D3D_Device->SetTextureStageState(0,D3DTSS_ALPHAOP, D3DTOP_MODULATE);
                _D3D_Device->SetRenderState( D3DRS_ALPHATESTENABLE , false );
		    }
		    if(services->getVideoDriver()->getDriverType() == video::EDT_OPENGL)
		    {
                glDisable(GL_LIGHTING);
		        glEnable(GL_BLEND);
                glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
                glDisable(GL_ALPHA_TEST);
		    }
		}

		material.ZWriteEnable =  false;
		services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
    }

  virtual void OnUnsetMaterial( )
    {
        if(_D3D_Device!=0)
		 {
           _D3D_Device->SetRenderState( D3DRS_ALPHABLENDENABLE, false );
           _D3D_Device->SetRenderState( D3DRS_ALPHATESTENABLE , false );
		 }
		if(_D3D_Device==0)
		 {
		     glDisable(GL_BLEND);
             glDisable(GL_ALPHA_TEST);
		 }
    }

	virtual bool isTransparent()
	{
		return true;
	}

};

class CLightBlendMaterial : public video::IMaterialRenderer
{
    IDirect3DDevice9*  _D3D_Device;

   public:

	CLightBlendMaterial()
	 {
         _D3D_Device=0;
	 }

  virtual void OnSetMaterial( video::SMaterial& material, const video::SMaterial& lastMaterial,
                              bool resetAllRenderstates, video::IMaterialRendererServices* services )
    {
        if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
		{
		    if(services->getVideoDriver()->getDriverType() == video::EDT_DIRECT3D9)
		    {
		     video::SExposedVideoData  Dat =services->getVideoDriver()->getExposedVideoData();
             _D3D_Device = Dat.D3D9.D3DDev9;
             _D3D_Device->SetRenderState(D3DRS_LIGHTING, false);
             _D3D_Device->SetRenderState( D3DRS_ALPHABLENDENABLE, true );
             _D3D_Device->SetRenderState( D3DRS_SRCBLEND,   D3DBLEND_SRCALPHA );
             _D3D_Device->SetRenderState( D3DRS_DESTBLEND,  D3DBLEND_ONE);
             _D3D_Device->SetRenderState( D3DRS_ALPHATESTENABLE , false );
             _D3D_Device->SetTextureStageState(0,D3DTSS_ALPHAOP, D3DTOP_MODULATE);
		    }
		    if(services->getVideoDriver()->getDriverType() == video::EDT_OPENGL)
		    {
		        glDisable(GL_LIGHTING);
		        glEnable(GL_BLEND);
                glBlendFunc(GL_SRC_ALPHA,GL_ONE);
                glDisable(GL_ALPHA_TEST);
		    }
		}

		material.ZWriteEnable =  false;
		services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
    }

  virtual void OnUnsetMaterial( )
    {
        if(_D3D_Device!=0)
		 {
        _D3D_Device->SetRenderState( D3DRS_ALPHABLENDENABLE, false );
        _D3D_Device->SetRenderState( D3DRS_ALPHATESTENABLE , false );
		 }
		if(_D3D_Device==0)
		 {
		     glDisable(GL_BLEND);
             glDisable(GL_ALPHA_TEST);
		 }
    }

	virtual bool isTransparent()
	{
		return true;
	}

};


video::E_MATERIAL_TYPE EMT_AlphaBlend;
video::E_MATERIAL_TYPE EMT_LightBlend;

void CreateMagicMaterials(IrrlichtDevice* dev)
 {
    video::IMaterialRenderer* Mat = new CAlphaBlendMaterial();
	EMT_AlphaBlend = (video::E_MATERIAL_TYPE)dev->getVideoDriver()->addMaterialRenderer( Mat );
    Mat = new CLightBlendMaterial();
	EMT_LightBlend = (video::E_MATERIAL_TYPE)dev->getVideoDriver()->addMaterialRenderer( Mat );
    Mat->drop();
 }
//======================================================================================

#endif
Cshaderprogram.h file

Code: Select all

/******************************************************

          Shader program class

          part of Magic Library
          By Emil Halim


******************************************************/


#ifndef __I_Shader_program_H_INCLUDED__
#define __I_Shader_program_H_INCLUDED__

//======================================================================================


class IShaderProgram
 {
           bool GLSL;
           bool HLSL;
     public:
           virtual void AddToVertexProgram(char* s) = 0;
           virtual void CompileVertexProgram(char* fun) = 0;
           virtual void AddToPixelProgram(char* s) = 0;
           virtual void CompilePixelProgram(char* fun) = 0;
           virtual void LinkProgram() = 0;
           virtual void setPixelVariable(float* data, int startRegister, int constantAmount) = 0;
           virtual void setPixelVariable(const c8* name, float* data, int constantAmount) = 0;
           virtual void setVertexVariable(float* data, int startRegister, int constantAmount) = 0;
           virtual void setVertexVariable(const c8* name, float* data, int constantAmount) = 0;
           virtual void StartShaderProgram() = 0;
           virtual void StopShaderProgram() = 0;
           bool IsGLSLsupported() { return GLSL;}
           bool IsHLSLsupported() { return HLSL;}
           friend IShaderProgram* CreateShaderProgram(IrrlichtDevice* dev,bool usingHighLevel=true);
 };


//!*******************************************************
//!    THLSLShader class
//!*******************************************************

class THLSLShader : public IShaderProgram
  {
        IDirect3DDevice9*  pID3DDevice;
        IDirect3DVertexShader9* VertexShader;
	    IDirect3DPixelShader9*  PixelShader;

        LPD3DXCONSTANTTABLE VSConstantsTable;
	    LPD3DXCONSTANTTABLE PSConstantsTable;

        core::stringc VertixProgram;
        core::stringc PixelProgram;

      public:
           THLSLShader(IrrlichtDevice* dev);
           ~THLSLShader();
           void AddToVertexProgram(char* s);
           void CompileVertexProgram(char* fun);
           void AddToPixelProgram(char* s);
           void CompilePixelProgram(char* fun);
           void LinkProgram();
           void setPixelVariable(float* data, int startRegister, int constantAmount);
           void setPixelVariable(const c8* name, float* data, int constantAmount);
           void setVertexVariable(float* data, int startRegister, int constantAmount);
           void setVertexVariable(const c8* name, float* data, int constantAmount);
           void StartShaderProgram();
           void StopShaderProgram();
  };

//========================================================================

      THLSLShader::THLSLShader(IrrlichtDevice* dev)
         {
                 VertexShader=0;
                 PixelShader=0;
                 video::SExposedVideoData  Dat = dev->getVideoDriver()->getExposedVideoData();
                 pID3DDevice = Dat.D3D9.D3DDev9;
         }

      THLSLShader::~THLSLShader()
         {
             if(PixelShader)pID3DDevice->SetPixelShader(0);
             if(VertexShader)pID3DDevice->SetVertexShader(0);
             PixelShader->Release();
             VertexShader->Release();
         }

      void THLSLShader::AddToVertexProgram(char* s)
         {
              VertixProgram.append(s);
              VertixProgram.append("\n");
         }

      void THLSLShader::CompileVertexProgram(char* fun)
         {
            LPD3DXBUFFER code = 0;
	        LPD3DXBUFFER errors = 0;

            //D3DXAssembleShader(VertixProgram.c_str(),VertixProgram.size(), 0, 0, 0, &code, &errors);
            D3DXCompileShader(VertixProgram.c_str(),VertixProgram.size(),0,0,fun,"vs_2_0",0, &code, &errors,&VSConstantsTable);
            if(errors)
             {
                  printf("%s \n",errors->GetBufferPointer());
                  printf("%s",VertixProgram.c_str());
                  errors->Release();
             }
            if(code!=0)
            {
              if (FAILED(pID3DDevice->CreateVertexShader((DWORD*)code->GetBufferPointer(), &VertexShader)))
	           {
		          printf("Could not create Vertex shader.");
	           }
	           code->Release();
            }

      	 }

      void THLSLShader::AddToPixelProgram(char* s)
         {
               PixelProgram.append(s);
         }

      void THLSLShader::CompilePixelProgram(char* fun)
         {
            LPD3DXBUFFER code = 0;
	        LPD3DXBUFFER errors = 0;

          //  D3DXAssembleShader(PixelProgram.c_str(),PixelProgram.size(), 0, 0, 0, &code, &errors);
            D3DXCompileShader(VertixProgram.c_str(),VertixProgram.size(),0,0,fun,"vs_2_0",0, &code, &errors,&PSConstantsTable);

	        if(errors)
             {
                  printf("%s \n",errors->GetBufferPointer());
                  printf("%s",VertixProgram.c_str());
                  errors->Release();
             }
            if(code!=0)
            {
              if (FAILED(pID3DDevice->CreatePixelShader((DWORD*)code->GetBufferPointer(), &PixelShader)))
	           {
		           printf("Could not create pixel shader.");
	           }
	           code->Release();
            }
         }

       void THLSLShader::LinkProgram()
         {

         }

       void THLSLShader::setPixelVariable(const c8* name, float* data, int constantAmount)
            {
                  D3DXHANDLE hndl = PSConstantsTable->GetConstantByName(NULL, name);
                  if(!hndl)
                        printf("HLSL Variable to set not found: '");
                  HRESULT hr = PSConstantsTable->SetFloatArray(pID3DDevice, hndl, data, constantAmount);
            }

        void THLSLShader::setPixelVariable(float* data, int startRegister, int constantAmount)
            {
            }

        void THLSLShader::setVertexVariable( const c8* name, float* data, int constantAmount)
            {
                  D3DXHANDLE hndl = VSConstantsTable->GetConstantByName(NULL, name);
                  if(!hndl)
                      printf("HLSL Variable to set not found: '");
                  HRESULT hr = VSConstantsTable->SetFloatArray(pID3DDevice, hndl, data, constantAmount);
            }

        void THLSLShader::setVertexVariable(float* data, int startRegister, int constantAmount)
           {
           }

        void THLSLShader::StartShaderProgram()
            {
               if(VertexShader)
                {
                     pID3DDevice->SetVertexShader(VertexShader);
                }
               if(PixelShader)
                {
                     pID3DDevice->SetPixelShader(PixelShader);
                }
            }

        void THLSLShader::StopShaderProgram()
            {
                    pID3DDevice->SetVertexShader(0);
                    pID3DDevice->SetPixelShader(0);
            }

//!*******************************************************
//!    TGlSlShader class
//!*******************************************************

class TGlSlShader : public IShaderProgram
 {
        GLhandleARB p;

        core::stringc VertixProgram;
        core::stringc PixelProgram;

        PFNGLCREATESHADEROBJECTARBPROC pGlCreateShaderObjectARB;
	    PFNGLSHADERSOURCEARBPROC pGlShaderSourceARB;
        PFNGLCOMPILESHADERARBPROC pGlCompileShaderARB;
        PFNGLCREATEPROGRAMOBJECTARBPROC pGlCreateProgramObjectARB;
        PFNGLATTACHOBJECTARBPROC pGlAttachObjectARB;
        PFNGLLINKPROGRAMARBPROC pGlLinkProgramARB;
		PFNGLUSEPROGRAMOBJECTARBPROC pGlUseProgramObjectARB;
		PFNGLDELETEOBJECTARBPROC pGlDeleteObjectARB;
 		PFNGLGETOBJECTPARAMETERIVARBPROC pGlGetObjectParameterivARB;
		PFNGLGETUNIFORMLOCATIONARBPROC pGlGetUniformLocationARB;
		PFNGLUNIFORM4FVARBPROC pGlUniform4fvARB;
		PFNGLUNIFORM1FVARBPROC pGlUniform1fvARB;
		PFNGLUNIFORM2FVARBPROC pGlUniform2fvARB;
		PFNGLUNIFORM3FVARBPROC pGlUniform3fvARB;
		PFNGLUNIFORMMATRIX2FVARBPROC pGlUniformMatrix2fvARB;
		PFNGLUNIFORMMATRIX3FVARBPROC pGlUniformMatrix3fvARB;
		PFNGLUNIFORMMATRIX4FVARBPROC pGlUniformMatrix4fvARB;
		PFNGLGETACTIVEUNIFORMARBPROC pGlGetActiveUniformARB;
		PFNGLGETINFOLOGARBPROC pGlGetInfoLogARB;

      public:
           TGlSlShader();
           ~TGlSlShader();
           void AddToVertexProgram(char* s);
           void CompileVertexProgram(char* fun);
           void AddToPixelProgram(char* s);
           void CompilePixelProgram(char* fun);
           void LinkProgram();
           void setPixelVariable(float* data, int startRegister, int constantAmount);
           void setPixelVariable(const c8* name, float* data, int constantAmount);
           void setVertexVariable(float* data, int startRegister, int constantAmount);
           void setVertexVariable(const c8* name, float* data, int constantAmount);
           void StartShaderProgram();
           void StopShaderProgram();
  };

//========================================================================

       TGlSlShader::TGlSlShader()
         {
                 pGlCreateShaderObjectARB = (PFNGLCREATESHADEROBJECTARBPROC) wglGetProcAddress("glCreateShaderObjectARB");
	         	 pGlShaderSourceARB = (PFNGLSHADERSOURCEARBPROC) wglGetProcAddress("glShaderSourceARB");
                 pGlCompileShaderARB = (PFNGLCOMPILESHADERARBPROC) wglGetProcAddress("glCompileShaderARB");
                 pGlCreateProgramObjectARB = (PFNGLCREATEPROGRAMOBJECTARBPROC) wglGetProcAddress("glCreateProgramObjectARB");
                 pGlAttachObjectARB = (PFNGLATTACHOBJECTARBPROC) wglGetProcAddress("glAttachObjectARB");
                 pGlLinkProgramARB = (PFNGLLINKPROGRAMARBPROC) wglGetProcAddress("glLinkProgramARB");
		         pGlUseProgramObjectARB = (PFNGLUSEPROGRAMOBJECTARBPROC) wglGetProcAddress("glUseProgramObjectARB");
		         pGlDeleteObjectARB = (PFNGLDELETEOBJECTARBPROC) wglGetProcAddress("glDeleteObjectARB");
 		         pGlGetObjectParameterivARB = (PFNGLGETOBJECTPARAMETERIVARBPROC)	wglGetProcAddress("glGetObjectParameterivARB");
		         pGlGetUniformLocationARB = (PFNGLGETUNIFORMLOCATIONARBPROC)  wglGetProcAddress("glGetUniformLocationARB");
		         pGlUniform4fvARB = (PFNGLUNIFORM4FVARBPROC) wglGetProcAddress("glUniform4fvARB");
		         pGlUniform1fvARB = (PFNGLUNIFORM1FVARBPROC)	wglGetProcAddress("glUniform1fvARB");
		         pGlUniform2fvARB = (PFNGLUNIFORM2FVARBPROC)	wglGetProcAddress("glUniform2fvARB");
		         pGlUniform3fvARB = (PFNGLUNIFORM3FVARBPROC)	wglGetProcAddress("glUniform3fvARB");
		         pGlUniformMatrix2fvARB = (PFNGLUNIFORMMATRIX2FVARBPROC)	wglGetProcAddress("glUniformMatrix2fvARB");
		         pGlUniformMatrix3fvARB = (PFNGLUNIFORMMATRIX3FVARBPROC)	wglGetProcAddress("glUniformMatrix3fvARB");
		         pGlUniformMatrix4fvARB = (PFNGLUNIFORMMATRIX4FVARBPROC)	wglGetProcAddress("glUniformMatrix4fvARB");
		         pGlGetActiveUniformARB = (PFNGLGETACTIVEUNIFORMARBPROC)	wglGetProcAddress("glGetActiveUniformARB");
		        // pGlGetInfoLogARB = (PFNGLGETINFOLOGARBPROC)  wglGetProcAddress("glGetInfoLogARB");
                 p = pGlCreateProgramObjectARB();
         }

       TGlSlShader::~TGlSlShader()
         {
              pGlDeleteObjectARB(p);
         }


        void TGlSlShader::AddToVertexProgram(char* s)
            {
                VertixProgram.append(s);
            }

        void TGlSlShader::CompileVertexProgram(char* fun)
             {
                const char *vs =(char*) VertixProgram.c_str();
                GLhandleARB v = pGlCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
                pGlShaderSourceARB(v, 1, &vs,NULL);
                pGlCompileShaderARB(v);
                pGlAttachObjectARB(p,v);

                GLenum g = glGetError();
	            if (g != GL_NO_ERROR)
	             {
	               printf("Error in Vert Program \n");
	               GLint errPos;
		           glGetIntegerv( GL_PROGRAM_ERROR_POSITION_ARB, &errPos );
		           const GLubyte* errString = glGetString(GL_PROGRAM_ERROR_STRING_ARB);
         		   printf("Pixel shader compilation failed at position %d:\n%s", errPos, errString);
	             }

             }

        void TGlSlShader::AddToPixelProgram(char* s)
            {
                PixelProgram.append(s);
            }

        void TGlSlShader::CompilePixelProgram(char* fun)
            {
                const char *ps =(char*)PixelProgram.c_str();
                GLhandleARB f = pGlCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
                pGlShaderSourceARB(f,1,&ps,NULL);
                pGlCompileShaderARB(f);
                pGlAttachObjectARB(p,f);

                GLenum g = glGetError();
	            if (g != GL_NO_ERROR)
	             {
	               printf("Error in Fragment Program \n");
	               GLint errPos;
		           glGetIntegerv( GL_PROGRAM_ERROR_POSITION_ARB, &errPos );
		           const GLubyte* errString = glGetString(GL_PROGRAM_ERROR_STRING_ARB);
         		   printf("Pixel shader compilation failed at position %d:\n%s", errPos, errString);
	             }
            }

        void TGlSlShader::LinkProgram()
          {
            //  char str[2048];
            //  s32 len;
            //  str[0]=0;
              pGlLinkProgramARB(p);
            //  pGlGetInfoLogARB(p,2048,&len,str);
            //  if(str[0]!=0)printf(str);
          }

        void TGlSlShader::setPixelVariable(float* data, int startRegister, int constantAmount)
            {

            }

        void TGlSlShader::setPixelVariable(const c8* name, float* data, int constantAmount)
           {
              setVertexVariable(name,data,constantAmount);
           }

        void TGlSlShader::setVertexVariable(float* data, int startRegister, int constantAmount)
            {

            }

        void TGlSlShader::setVertexVariable(const c8* name, float* data, int constantAmount)
           {
                 s32 loc = pGlGetUniformLocationARB(p,name);
                 pGlUniform4fvARB(loc,constantAmount,data);
           }

        void TGlSlShader::StartShaderProgram()
            {
               pGlUseProgramObjectARB(p);
            }

        void TGlSlShader::StopShaderProgram()
            {
               pGlUseProgramObjectARB(0);
            }

//!*******************************************************
//!    TGlSlShader class
//!*******************************************************

class TglShader : public IShaderProgram
 {
        u32   Vid;
        u32   Fid;

        core::stringc VertixProgram;
        core::stringc PixelProgram;

        PFNGLGENPROGRAMSARBPROC pGlGenProgramsARB;
        PFNGLBINDPROGRAMARBPROC pGlBindProgramARB;
        PFNGLPROGRAMSTRINGARBPROC pGlProgramStringARB;
        PFNGLDELETEPROGRAMSNVPROC pGlDeleteProgramsARB;
        PFNGLPROGRAMLOCALPARAMETER4FVARBPROC pGlProgramLocalParameter4fvARB;

      public:
           TglShader();
           ~TglShader();
           void AddToVertexProgram(char* s);
           void CompileVertexProgram(char* fun);
           void AddToPixelProgram(char* s);
           void CompilePixelProgram(char* fun);
           void LinkProgram();
           void setPixelVariable(float* data, int startRegister, int constantAmount);
           void setPixelVariable(const c8* name, float* data, int constantAmount);
           void setVertexVariable(float* data, int startRegister, int constantAmount);
           void setVertexVariable(const c8* name, float* data, int constantAmount);
           void StartShaderProgram();
           void StopShaderProgram();
  };

//!*******************************************************

       TglShader::TglShader()
         {
                 pGlGenProgramsARB = (PFNGLGENPROGRAMSARBPROC) wglGetProcAddress("glGenProgramsARB");
		         pGlBindProgramARB = (PFNGLBINDPROGRAMARBPROC) wglGetProcAddress("glBindProgramARB");
		         pGlProgramStringARB = (PFNGLPROGRAMSTRINGARBPROC) wglGetProcAddress("glProgramStringARB");
		         pGlDeleteProgramsARB = (PFNGLDELETEPROGRAMSNVPROC) wglGetProcAddress("glDeleteProgramsARB");
                 pGlProgramLocalParameter4fvARB = (PFNGLPROGRAMLOCALPARAMETER4FVARBPROC) wglGetProcAddress("glProgramLocalParameter4fvARB");
                 Vid=Fid=0;
         }

       TglShader::~TglShader()
         {
             if(Vid)pGlDeleteProgramsARB(1,&Vid);
             if(Fid)pGlDeleteProgramsARB(1,&Fid);
         }


        void TglShader::AddToVertexProgram(char* s)
            {
                VertixProgram.append(s);
            }

        void TglShader::CompileVertexProgram(char* fun)
             {
                pGlGenProgramsARB(1, &Vid);
                pGlBindProgramARB(GL_VERTEX_PROGRAM_ARB, Vid);
                pGlProgramStringARB(GL_VERTEX_PROGRAM_ARB,GL_PROGRAM_FORMAT_ASCII_ARB,VertixProgram.size(),VertixProgram.c_str());
                GLenum g = glGetError();
	            if (g != GL_NO_ERROR)
	             {
	               printf("Error in Vert Program \n");
	               GLint errPos;
		           glGetIntegerv( GL_PROGRAM_ERROR_POSITION_ARB, &errPos );
		           const GLubyte* errString = glGetString(GL_PROGRAM_ERROR_STRING_ARB);
         		   printf("Pixel shader compilation failed at position %d:\n%s", errPos, errString);
         		   Sleep(5000);
	             }
             }

        void TglShader::AddToPixelProgram(char* s)
            {
                PixelProgram.append(s);
            }

        void TglShader::CompilePixelProgram(char* fun)
            {
                pGlGenProgramsARB(1, &Fid);
                pGlBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, Fid);
                pGlProgramStringARB(GL_FRAGMENT_PROGRAM_ARB,GL_PROGRAM_FORMAT_ASCII_ARB,PixelProgram.size(),PixelProgram.c_str());
                GLenum g = glGetError();
	            if (g != GL_NO_ERROR)
	             {
	               printf("Error in Fragment Program \n");
	               GLint errPos;
		           glGetIntegerv( GL_PROGRAM_ERROR_POSITION_ARB, &errPos );
		           const GLubyte* errString = glGetString(GL_PROGRAM_ERROR_STRING_ARB);
         		   printf("Pixel shader compilation failed at position %d:\n%s", errPos, errString);

	             }
            }

        void TglShader::LinkProgram()
          {

          }

        void TglShader::setPixelVariable(float* data, int startRegister, int constantAmount)
            {
                for (int i=0; i<constantAmount; ++i)
		        pGlProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, startRegister+i, &data[i*4]);
            }

        void TglShader::setPixelVariable(const c8* name, float* data, int constantAmount)
           {

           }

        void TglShader::setVertexVariable(float* data, int startRegister, int constantAmount)
            {
	            for (int i=0; i<constantAmount; ++i)
		        pGlProgramLocalParameter4fvARB(GL_VERTEX_PROGRAM_ARB, startRegister+i, &data[i*4]);
            }

        void TglShader::setVertexVariable(const c8* name, float* data, int constantAmount)
           {
           }

        void TglShader::StartShaderProgram()
            {
               if(Vid)
                {
                    pGlBindProgramARB(GL_VERTEX_PROGRAM_ARB, Vid);
                    glEnable(GL_VERTEX_PROGRAM_ARB);
                }
               if(Fid)
                {
                    pGlBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, Fid);
                    glEnable(GL_FRAGMENT_PROGRAM_ARB);
                }
            }

        void TglShader::StopShaderProgram()
            {
               glDisable(GL_VERTEX_PROGRAM_ARB);
               glDisable(GL_FRAGMENT_PROGRAM_ARB);
            }


//!*******************************************************
//!    CreateShaderProgram Function
//!*******************************************************

 IShaderProgram* CreateShaderProgram(IrrlichtDevice* dev,bool usingHighLevel)
  {
     video::E_DRIVER_TYPE type = dev->getVideoDriver()->getDriverType();
     IShaderProgram*  sp;

     if(type == video::EDT_DIRECT3D9)
      {
          if(usingHighLevel)
           {
              if(dev->getVideoDriver()->queryFeature(video::EVDF_HLSL ))
               {
                  sp = new THLSLShader(dev);
                  sp->HLSL = true;
                  return sp;
               }
              printf("WARNING: Your hardware does not support HLSL .");
		      Sleep(5000);
		      return 0;
	       }
	      else
	       {
	           // TOdo creating Low level shader
               sp->HLSL = false;
	       }
      }

      if(type == video::EDT_OPENGL)
       {
           if(usingHighLevel)
           {
               if(dev->getVideoDriver()->queryFeature(video::EVDF_ARB_GLSL ))
                {
                    sp = new TGlSlShader;
                    sp->GLSL = true;
                    return sp;
                }
		       printf("WARNING: Your hardware does not support GLSL .");
		       Sleep(5000);
		       return 0;
           }
          else
           {
		       sp = new TglShader;
		       sp->GLSL = false;
               return sp;
	       }
        }

       return 0;
  }


#endif
main.cpp file

Code: Select all

/******************************************************

             test program

          part of Magic Library
          By Emil Halim


******************************************************/

#include <irrlicht.h>
#include <iostream>

#include "windows.h"

#include "d3dx9.h"
#include "d3dx9anim.h"

#include "gl/gl.h"
#include "gl/glu.h"
#include "gl/glaux.h"
#include "gl/glext.h"

#pragma comment(lib,"gdi32.lib")
#pragma comment(lib,"advapi32.lib")
#pragma comment(lib,"d3d9.lib")
#pragma comment(lib,"d3dx9.lib")

#pragma comment(lib, "opengl32.lib")

#pragma comment(lib, "Irrlicht.lib")

using namespace irr;

#include "CMagicMaterials.h"
#include "CshaderProgram.h"


class CMagicSceneNode : public scene::ISceneNode
{
     scene::IMesh*       mesh;
     IShaderProgram*     Sprogram;
     f32                 col[4];
     u8                  red,green,blue;
     f32                 alpha;

   public:
     CMagicSceneNode(char* File, scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id) : ISceneNode(parent, mgr, id)
     {
           mesh = SceneManager->getMesh(File)->getMesh(0);
           Sprogram = 0;
           red   =255;
           green =255;
           blue  =255;
           alpha =1.0f;
     }
     ~CMagicSceneNode()
     {
     }

     void setShaderProgram(IShaderProgram* Sp)
      {
           Sprogram = Sp;
      }

     virtual void OnPreRender()
      {
         if (IsVisible)
         SceneManager->registerNodeForRendering(this);
         ISceneNode::OnPreRender();
      }

     virtual void render()
      {
         video::IVideoDriver* driver = SceneManager->getVideoDriver();

         if(Sprogram)
               {
                   Sprogram->StartShaderProgram();
                   col[0]=red/255.0;
                   col[1]=green/255.0;
                   col[2]=blue/255.0;
                   col[3]=alpha;

		           core::matrix4 worldViewProj;
		           worldViewProj  = driver->getTransform(video::ETS_PROJECTION);
		           worldViewProj *= driver->getTransform(video::ETS_VIEW);
		           worldViewProj *= AbsoluteTransformation;

                   if(driver->getDriverType() == video::EDT_DIRECT3D9 && Sprogram->IsHLSLsupported())
                    {
                        Sprogram->setVertexVariable("mColor", &col[0], 4);
                        Sprogram->setVertexVariable("mWorldViewProj", &worldViewProj.M[0], 16);
                    }

                   if(driver->getDriverType() == video::EDT_OPENGL && !Sprogram->IsGLSLsupported())
                    {
                        driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
                        Sprogram->setVertexVariable(&col[0], 0, 4);
                    }
               }
         else
               {
                   driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
               }

         for(int i=0;i<mesh->getMeshBufferCount();i++)
           {
                driver->setMaterial(mesh->getMeshBuffer(i)->getMaterial());
                driver->drawMeshBuffer(mesh->getMeshBuffer(i));
           }

         if(Sprogram)
               {
                   Sprogram->StopShaderProgram();
               }
      }

     virtual const core::aabbox3d<f32>& getBoundingBox() const
      {
           return mesh->getBoundingBox ();
      }

     virtual s32 getMaterialCount()
      {
           return mesh->getMeshBufferCount();
      }

     virtual video::SMaterial& getMaterial(s32 i)
       {
            return mesh->getMeshBuffer(i)->getMaterial();
       }

      void setColor(u8 r,u8 g, u8 b)
       {
           red   =r;
           green =g;
           blue  =b;
       }

      void setAlpha(f32 a)
       {
           alpha=a;
       }

};


CMagicSceneNode* node;

class MyEventReceiver : public IEventReceiver
{
public:
	virtual bool OnEvent(SEvent event)
	{
        static f32 alpha =1.0;
		if (event.EventType == irr::EET_KEY_INPUT_EVENT && !event.KeyInput.PressedDown)
		{
	  	  switch(event.KeyInput.Key)
		  {
			case KEY_KEY_W:
                {
                   alpha -= 0.05f;
                   if(alpha < 0.0)
                      alpha=0.0;
                   node->setAlpha(alpha);
		           break;
                }
			case KEY_KEY_S:
				{
                   alpha += 0.05f;
                   if(alpha > 1.0)
                       alpha=1.0;
                   node->setAlpha(alpha);
		           break;
				}
				return true;
			}
		}
		return false;
	}
};


int main()
{
	// let user select driver type

	video::E_DRIVER_TYPE driverType;

	printf("Please select the driver you want for this example:\n"\
		" (a) Direct3D 9.0c\n (b) Direct3D 8.1\n (c) OpenGL 1.5\n"\
		" (d) Software Renderer\n (e) Apfelbaum Software Renderer\n"\
		" (f) NullDevice\n (otherKey) exit\n\n");

	char i;
	std::cin >> i;

	switch(i)
	{
		case 'a': driverType = video::EDT_DIRECT3D9;break;
		case 'b': driverType = video::EDT_DIRECT3D8;break;
		case 'c': driverType = video::EDT_OPENGL;   break;
		case 'd': driverType = video::EDT_SOFTWARE; break;
		case 'e': driverType = video::EDT_SOFTWARE2;break;
		case 'f': driverType = video::EDT_NULL;     break;
		default: return 0;
	}

	bool HighLevel;
	printf("type h for HighLevel Shader\n");
	std::cin >> i;
	if(i=='h')
	  HighLevel=true;
	else
	  HighLevel=false;

	// create device

	MyEventReceiver receiver;

	IrrlichtDevice *device =
		createDevice(driverType, core::dimension2d<s32>(640, 480), 32,false, false, false, &receiver);

	if (device == 0)
		return 1; // could not create selected driver.

	// create engine and camera
	device->setWindowCaption(L"Custom Scene Node - Irrlicht Engine Demo");
	video::IVideoDriver* driver = device->getVideoDriver();
	scene::ISceneManager* smgr = device->getSceneManager();

	scene::ICameraSceneNode* cam = smgr->addCameraSceneNodeFPS(0, 100.0f, 100.0f);
	cam->setPosition(core::vector3df(0,0,-5));
	cam->setTarget(core::vector3df(0,0,0));

	IShaderProgram* sp = CreateShaderProgram(device,HighLevel);

    if(driver->getDriverType() == video::EDT_DIRECT3D9 && sp->IsHLSLsupported())
     {
        sp->AddToVertexProgram("float4   mColor;");
        sp->AddToVertexProgram("float4x4 mWorldViewProj;");
        sp->AddToVertexProgram("struct VS_OUTPUT");
        sp->AddToVertexProgram("{");
        sp->AddToVertexProgram("   float4 Position   : POSITION;");
        sp->AddToVertexProgram("   float4 Diffuse    : COLOR0; ");
        sp->AddToVertexProgram("   float2 TexCoord   : TEXCOORD0;");
        sp->AddToVertexProgram("};");
        sp->AddToVertexProgram("VS_OUTPUT vertexMain( in float4 vPosition : POSITION,");
        sp->AddToVertexProgram("                      float2 texCoord     : TEXCOORD0 )");
        sp->AddToVertexProgram("{");
        sp->AddToVertexProgram("      VS_OUTPUT Output;");
        sp->AddToVertexProgram("      Output.Position = mul(vPosition, mWorldViewProj);");
        sp->AddToVertexProgram("      Output.Diffuse = mColor;");
        sp->AddToVertexProgram("      Output.TexCoord = texCoord;");
        sp->AddToVertexProgram("      return Output;");
        sp->AddToVertexProgram("}");
      }

     if(driver->getDriverType() == video::EDT_OPENGL && !sp->IsGLSLsupported())
      {
        sp->AddToVertexProgram("!!ARBvp1.0");
        sp->AddToVertexProgram("ATTRIB InPos    = vertex.position;");
        sp->AddToVertexProgram("ATTRIB InTexCoord = vertex.texcoord;");
        sp->AddToVertexProgram("OUTPUT OutPos   = result.position;");
        sp->AddToVertexProgram("OUTPUT OutColor = result.color;");
        sp->AddToVertexProgram("OUTPUT OutTexCoord = result.texcoord;");
        sp->AddToVertexProgram("PARAM  MVP[4]   = { state.matrix.mvp };");
        sp->AddToVertexProgram("PARAM  mColor = program.local[0];");
        sp->AddToVertexProgram("DP4 OutPos.x, InPos , MVP[0];");
        sp->AddToVertexProgram("DP4 OutPos.y, InPos , MVP[1];");
        sp->AddToVertexProgram("DP4 OutPos.z, InPos , MVP[2];");
        sp->AddToVertexProgram("DP4 OutPos.w, InPos , MVP[3];");
        sp->AddToVertexProgram("MOV OutColor, mColor;");
        sp->AddToVertexProgram("MOV OutTexCoord, InTexCoord;");
        sp->AddToVertexProgram("END");
      }

     sp->CompileVertexProgram("vertexMain");
     sp->LinkProgram();

     CreateMagicMaterials(device);


	node = new CMagicSceneNode("../../media/earth.x", smgr->getRootSceneNode(), smgr, -1);
    node->setMaterialTexture(0, driver->getTexture("../../media/wall.bmp"));
    node->setMaterialType(EMT_AlphaBlend);
    node->setShaderProgram(sp);

	node->drop();

	int lastFPS = -1;

	while(device->run())
	{
		driver->beginScene(true, true, video::SColor(0,100,100,100));

		smgr->drawAll();

		driver->endScene();

		int fps = driver->getFPS();

		if (lastFPS != fps)
		{
		  core::stringw str = L"Irrlicht Engine - Vertex and pixel shader example [";
		  str += driver->getName();
		  str += "] FPS:";
		  str += fps;

		  device->setWindowCaption(str.c_str());
		  lastFPS = fps;
		}
	}

	device->drop();

	return 0;
}

enjoy it.
Post Reply