Flexible Vertex Format - special SVN branch is ready!!!

Discuss about anything related to the Irrlicht Engine, or read announcements about any significant features or usage changes.
zerochen
Posts: 273
Joined: Wed Jan 07, 2009 1:17 am
Location: Germany

Re: Flexible Vertex Format - special SVN branch is ready!!!

Post by zerochen »

are you using the example from the instanced patch that you wrote sometimes ago?
if so 2 little errors are there:

Code: Select all

 
bBuffer->setHardwareMappingHint(scene::EHM_STATIC);  // has to be after the last line
IMesh* bMesh = mgr->getMeshManipulator()->createMeshWith2TCoords(aMesh);
[b]IMeshBuffer*[/b] bBuffer = bMesh->getMeshBuffer(0); // bBuffer is a member of the class
 
Granyte
Posts: 850
Joined: Tue Jan 25, 2011 11:07 pm
Contact:

Re: Flexible Vertex Format - special SVN branch is ready!!!

Post by Granyte »

it's derived from it but ya I fixed this already

Code: Select all

 
#ifdef _MSC_VER
// We'll also define this to stop MSVC complaining about sprintf().
#define _CRT_SECURE_NO_WARNINGS
#pragma comment(lib, "Irrlicht.lib")
#endif
 
 
 
 
 
 
 
 
 
 
#include <irrlicht.h>
#include <driverChoice.h>
struct StarInst
{
    irr::core::matrix4 Transformation;
    irr::f32 Temperature;
    irr::f32 Temperature1;
    irr::f32 Temperature2;
    irr::f32 Temperature3;
    bool operator==(const StarInst &other) const
    {
        if((this->Transformation == other.Transformation)&&(this->Temperature == other.Temperature))
            return true;
 
 
        return false;
    }
};
using namespace irr;
 
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
 
 
 
 
 
 
 
struct ShaderCB : public video::IShaderConstantSetCallBack
{
    
    ShaderCB(irr::video::E_DRIVER_TYPE currentdriver);
   void OnSetConstants(video::IMaterialRendererServices* services,
      s32 userData);
    irr::video::E_DRIVER_TYPE Currentdriver;
};
 
void ShaderCB::OnSetConstants(video::IMaterialRendererServices* services,
      s32 userData)
   {
       
       core::matrix4 viewProjection;
       viewProjection = services->getVideoDriver()->getTransform(video::ETS_PROJECTION);
       viewProjection *= services->getVideoDriver()->getTransform(video::ETS_VIEW);
         services->setVertexShaderConstant("viewProjection", viewProjection.pointer(), 16);
 
    
 
//setPixelShaderConstant
  
}
ShaderCB::ShaderCB(irr::video::E_DRIVER_TYPE currentdriver)
    {
        Currentdriver=currentdriver;
    
    }
class InstanceManager : public scene::ISceneNode
{
 
    /*
    First, we declare some member variables:
    The Node array,  the mesh buffer, the mesh and the material instanced scenenode 
    we also need to keep track of the shader callback.
    */
    video::SMaterial Material;
    IMeshBuffer* bBuffer;
    IMesh* aMesh;
    ShaderCB* callback;
    /*Variable to handle shader instancing*/
    IMesh* bMesh;
    bool fakeinstancing;
    //CMeshBuffer dupBuffer;
    /*
        We treat the instance manager as a scene node so we don't really have to care about it in the future
    */
    core::aabbox3d<f32> mbb;
    public:
 
    InstanceManager(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id, bool Fakeinstancing)
        : scene::ISceneNode(parent, mgr, id)//, dupBuffer( irr::video::E_INDEX_TYPE::EIT_16BIT)
    {
        fakeinstancing = false;
 
        //lodused =0;
 
 
        //scene::ISceneNode* bg= mgr->addCubeSceneNode(50000,0,ID_IsNotPickable);
        //bg->setMaterialFlag(irr::video::E_MATERIAL_FLAG::EMF_LIGHTING,false);
        //bg->setMaterialFlag(irr::video::E_MATERIAL_FLAG::EMF_BACK_FACE_CULLING,false);
 
         //shader
    s32 mtrlShader,mtrlShader2;
   callback = new ShaderCB(mgr->getVideoDriver()->getDriverType());
   if (mgr->getVideoDriver()->getDriverType() == EDT_OPENGL)
       mtrlShader = SceneManager->getVideoDriver()->getGPUProgrammingServices()->addHighLevelShaderMaterialFromFiles("media/shaders/instancing.vert", "", video::EVST_VS_2_0,
                            "media/shaders/instancing.frag", "", video::EPST_PS_2_0,callback, video::EMT_SOLID);
   else if (mgr->getVideoDriver()->getDriverType() == EDT_DIRECT3D9)
        mtrlShader = SceneManager->getVideoDriver()->getGPUProgrammingServices()->addHighLevelShaderMaterialFromFiles("../../media/InstancingFVF.hlsl", "vsmain", video::EVST_VS_3_0,
                            "../../media/InstancingFVF.hlsl", "psmain", video::EPST_PS_3_0,callback, video::EMT_SOLID);
   else if (mgr->getVideoDriver()->getDriverType() == EDT_DIRECT3D11)
        mtrlShader = SceneManager->getVideoDriver()->getGPUProgrammingServices()->addHighLevelShaderMaterialFromFiles("media/shaders/InstancingFVF.hlsl", "vsmain", video::EVST_VS_4_0,
                            "media/shaders/InstancingFVF.hlsl", "psmain", video::EPST_PS_4_0,callback, video::EMT_SOLID);
 
 
 
 
 
  
   
   callback->drop();
   
   mbb.addInternalPoint(5000*2,5000*2,5000*2);
   mbb.addInternalPoint(-5000*2,-5000*2,-5000*2);
 
   aMesh = SceneManager->getGeometryCreator()->createSphereMesh(0.5,8,8);
        Material.Lighting = false;
        Material.setTexture(0, SceneManager->getVideoDriver()->getTexture("../../media/wall.jpg"));
        Material.MaterialType = (video::E_MATERIAL_TYPE)mtrlShader;
        //Material.BackfaceCulling = false;
  
    
 
 
      
 
        
    
        IVertexDescriptor* index =              mgr->getVideoDriver()->getVertexDescriptor("BaseInstanceIndex");
 
    if(!index)
    {
        IVertexDescriptor* stdv = mgr->getVideoDriver()->getVertexDescriptor(0);
                                                mgr->getVideoDriver()->addVertexDescriptor("BaseInstanceIndex");
        index =             mgr->getVideoDriver()->getVertexDescriptor("BaseInstanceIndex");
        for (int i = 0; i < stdv->getAttributeCount(); i++)
        {
            index->addAttribute(stdv->getAttribute(i)->getName(), stdv->getAttribute(i)->getElementCount(), stdv->getAttribute(i)->getSemantic(), stdv->getAttribute(i)->getType(), 0);
        }
        index->addAttribute("InstancingIndex1",4,EVAS_TEXCOORD1,EVAT_FLOAT,1);
        index->addAttribute("InstancingIndex2",4,EVAS_TEXCOORD2,EVAT_FLOAT,1);
        index->addAttribute("InstancingIndex3",4,EVAS_TEXCOORD3,EVAT_FLOAT,1);
        index->addAttribute("InstancingIndex4",4,EVAS_TEXCOORD4,EVAT_FLOAT,1);
        index->addAttribute("InstancingIndex5",4,EVAS_TEXCOORD5,EVAT_FLOAT,1);
    }
        //dupBuffer.SetvertexDescriptor(Instanced2tcoords);
            IVertexBuffer* InscanceIndex = new CVertexBuffer<StarInst>(index);
 
 
   bBuffer = aMesh->getMeshBuffer(0);
   
    bBuffer->getVertexBuffer(0)->setVertexDescriptor(index);
   mgr->getVideoDriver()->setMinHardwareBufferVertexCount(bBuffer->getVertexBuffer()->getVertexCount()-1);
   bBuffer->setHardwareMappingHint(scene::EHM_STATIC);
   InscanceIndex->setHardwareMappingHint(scene::EHM_DYNAMIC);
    bBuffer->setHardwareMappingHint(EHM_STATIC);
    bBuffer->addVertexBuffer(InscanceIndex);
    bBuffer->getVertexBuffer(0)->setHardwareMappingHint(EHM_STATIC);
    bBuffer->getVertexBuffer(1)->setDirty();
 
 
 
 
 
 
    
    /*
   IMesh* bMesh = mgr->getMeshManipulator()->createMeshWith2TCoords(aMesh);
   IMeshBuffer* cBuffer = bMesh->getMeshBuffer(0);
 
   //!create dupBuffer with bBuffer repeated NUM_BATCH_INSTANCES times
  /*
   if (mgr->getVideoDriver()->getDriverType() == EDT_OPENGL)
   for (int k=0;k<248;k++)
   {
      S3DVertex2TCoords* verts = (S3DVertex2TCoords*)cBuffer->getVertices();
      for (u32 i=0; i<bBuffer->getVertexCount(); i++)
      {
         verts[i].TCoords2.X = k;//assign the index of instance that each vertex belongs to
      }
      dupBuffer.append(verts,bBuffer->getVertexCount(),cBuffer->getIndices(),bBuffer->getIndexCount());
      dupBuffer.setHardwareMappingHint(scene::EHM_STATIC);
   }
   else if (mgr->getVideoDriver()->getDriverType() == EDT_DIRECT3D9)
   {
       for (int k=0;k<62;k++)
   {
      S3DVertex2TCoords* verts = (S3DVertex2TCoords*)cBuffer->getVertices();
      for (u32 i=0; i<bBuffer->getVertexCount(); i++)
      {
         verts[i].TCoords2.X = k;//assign the index of instance that each vertex belongs to
      }
      dupBuffer.append(verts,bBuffer->getVertexCount(),cBuffer->getIndices(),bBuffer->getIndexCount());
      dupBuffer.setHardwareMappingHint(scene::EHM_STATIC);
   }
   }
   else if(mgr->getVideoDriver()->getDriverType() == EDT_DIRECT3D11)
   {
       for (int k=0;k<62;k++)
   {
      S3DVertex2TCoords* verts = (S3DVertex2TCoords*)cBuffer->getVertices();
      for (u32 i=0; i<bBuffer->getVertexCount(); i++)
      {
         verts[i].TCoords2.X = k;//assign the index of instance that each vertex belongs to
      }
      dupBuffer.append(verts,bBuffer->getVertexCount(),cBuffer->getIndices(),bBuffer->getIndexCount());
      dupBuffer.setHardwareMappingHint(scene::EHM_STATIC);
   }
   }
   */
}
    /*The node array is put here to be public only for the purpose of the demo in the future a function coud take care of this without having it public*/
    
    core::array<ISceneNode*> totalNodeArray;
 
 
    /*Create an empty scenenode and return the pointer to the user
    this empty scene node is used for irrlicht and the user to manage the instance
    Each instance can be manipulated individualy through thier own empty scenenode*/
    ISceneNode* AddInstance(vector3df pos, f32 scale,vector3df Rotation )
    {
        ISceneNode* empty = SceneManager->addEmptySceneNode();
      empty->setPosition(pos);
      empty->setScale(vector3df(scale));
      empty->setRotation(Rotation);
      totalNodeArray.push_back(empty);
      return empty;
    }
    /*
    we always register this for rendering since visibility is handeled in the sub node
    */
    virtual void OnRegisterSceneNode()
    {
        
        SceneManager->registerNodeForRendering(this);
 
        ISceneNode::OnRegisterSceneNode();
    }
 
    /*
    In the render() method most of the interesting stuff happens: The manager goes through the node array and upload thier matrices to the shader callback
    In OpenGL we render per batches of 248 and in dx per batches of 62 this is due to the amount of variable register availible being diferent in both drivers
    in the future if a vertex texture patch is accepted both could be made to render every node in a single draw call and fetch thier matrices from a texture
    */
    virtual void OnAnimate(u32 timeMs)
    {
        //ISceneNode::OnAnimate(timeMs);
        bBuffer->getVertexBuffer(1)->clear();
        const SViewFrustum* frust = SceneManager->getActiveCamera()->getViewFrustum();
        for (int i=0;i<totalNodeArray.size();  i++)
               {
                  
                   int cliped=0;
                   for (s32 e=0; e<scene::SViewFrustum::VF_PLANE_COUNT; ++e)
                       if((frust->planes[e].classifyPointRelation(totalNodeArray[i]->getAbsolutePosition())) == core::EIntersectionRelation3D::ISREL3D_FRONT)
                       {
                          // cliped =1;
                           break;
                       }
                       if(cliped ==false)
                       {
                           StarInst currinst;
                           currinst.Transformation= totalNodeArray[i]->getAbsoluteTransformation();
                           bBuffer->getVertexBuffer(1)->addVertex(&currinst);
                           mbb.addInternalPoint(totalNodeArray[i]->getAbsolutePosition());
                       }
               }
               bBuffer->getVertexBuffer(1)->setDirty();
               
              // std::cout<<bBuffer->getVertexBuffer(1)->getVertexCount()<<std::endl;
    }
    virtual void render()
    {
        SceneManager->getVideoDriver()->setMaterial(Material);
            int nRemainingBoxes = totalNodeArray.size();
        
               
              // if (fakeinstancing == false)
            SceneManager->getVideoDriver()->drawInstancedMeshBuffer(bBuffer);
              // else
                //   SceneManager->getVideoDriver()->drawMeshBuffer(&dupBuffer);
            
    }
 
    /*
    Here we return the bounding box for the whole instance batch to make sure the node does not get culled wen there is still even a single instance in the view fulstrum
    */
    
    virtual const core::aabbox3d<f32>& getBoundingBox() const
    {
        
 
        
        return mbb;
    }
 
    virtual u32 getMaterialCount() const
    {
        return 1;
    }
 
    virtual video::SMaterial& getMaterial(u32 i)
    {
        return Material;
    }   
};
 
 
 
bool initIrrlicht(s32 w, s32 h, bool opengl = true, s32 bpp=32, bool fullscreen=false, bool stentil = false);
 
 
 
 
int main()
{
 
    video::E_DRIVER_TYPE driverType=driverChoiceConsole();
    if (driverType==video::EDT_COUNT)
        return 1;
    bool usefakeinst = false;
    bool animate = false;
    char i;
        
            printf("Please press 'y' if you want to use Shader Instancing.\n");
            std::cin >> i;
            if (i == 'y')
            {
                usefakeinst = true;
            }
            printf("Please press 'y' if you want each instance to be animated.\n");
            std::cin >> i;
            if (i == 'y')
            {
                animate = true;
            }
    // create device and exit if creation failed
 
    IrrlichtDevice * device = createDevice(driverType, core::dimension2d<u32>(800, 600),32u,false);
 
    if (device == 0)
        return 1; // could not create selected driver.
 
    /* The creation was successful, now we set the event receiver and
        store pointers to the driver and to the gui environment. */
    
        
    device->setWindowCaption(L"Irrlicht Engine - Hardware Instancing Demo");
 
   video::IVideoDriver* driver = device->getVideoDriver();
    scene::ISceneManager* smgr = device->getSceneManager();
    IGUIEnvironment* env = device->getGUIEnvironment();
   InstanceManager* InstancingTest = new InstanceManager(smgr->getRootSceneNode(),smgr,-1,usefakeinst);
 
   //!save transformation in one EmptySceneNode which doesn't render itself
   f32 scale = 1.5f;
   for (u32 i=0;i<20;i++)
      for (u32 j=1;j<40;j++)
         for (u32 k=0;k<20;k++)
   {
     
       scene::ISceneNode* empty = InstancingTest->AddInstance(vector3df(i*scale,j*scale,k*scale),scale,vector3df(rand()%360,rand()%360,rand()%360));
       if (animate== true)
       {
      scene::ISceneNodeAnimator* anim =
            smgr->createFlyCircleAnimator(vector3df(i*scale,j*scale,k*scale),rand()/20,rand()*0.0000001);
        if (anim)
        {
            
            
            empty->addAnimator(anim);
            anim->drop();
        }
       }
       
   }
         smgr->addCubeSceneNode();
   scene::ICameraSceneNode* cam = smgr->addCameraSceneNodeFPS();
   cam->setFarValue(2000);
  
   device->getCursorControl()->setVisible(false);
 
   s32 lastFPS = -1;
   while(device->run())
   {
      if (device->isWindowActive())
      {
         driver->beginScene(true, true, SColor(255,122,122,122));
 
         smgr->drawAll();
 
         
         {
            
         }
         env->drawAll();
 
         driver->endScene();
 
         int fps = driver->getFPS();
 
         if (lastFPS != fps)
         {
            core::stringw str = L"fps: ";
            str += fps;
            str += ", poly: ";
            str += driver->getPrimitiveCountDrawn();
            str += ", Node count:";
            str += InstancingTest->totalNodeArray.size();
            device->setWindowCaption(str.c_str());
            lastFPS = fps;
         }
      }
   }
 
   device->drop();
 
   return 0;
}
 
 
 
 
here is the full code to the sample but here it's not working.


I have not yet found why but I have the very same code running inside my project and there it's working
zerochen
Posts: 273
Joined: Wed Jan 07, 2009 1:17 am
Location: Germany

Re: Flexible Vertex Format - special SVN branch is ready!!!

Post by zerochen »

can you provide InstancingFVF.hlsl please?
Granyte
Posts: 850
Joined: Tue Jan 25, 2011 11:07 pm
Contact:

Re: Flexible Vertex Format - special SVN branch is ready!!!

Post by Granyte »

Code: Select all

 
 
 
 
float4x4 viewProjection;
 
struct VS_INPUT
{
    float3 vPosition: POSITION;
    float3 vNormal  : NORMAL;
    float2 texCoord : TEXCOORD0;
    float4 color    : COLOR;
    float4 W0       : TEXCOORD1;    
    float4 W1       : TEXCOORD2;    
    float4 W2       : TEXCOORD3;    
    float4 W3       : TEXCOORD4;
    float4 Stemp    : TEXCOORD5;
};
 
 
struct VS_OUTPUT
{
    float4 Position   :POSITION;   // vertex position 
    float2 tcoord         : TEXCOORD1;
};
 
VS_OUTPUT vsmain(VS_INPUT Inputs)
{
 
    VS_OUTPUT tout;
    float4x4 transformation = {Inputs.W0, Inputs.W1, Inputs.W2, Inputs.W3};
    float4 pos = mul(Inputs.vPosition,transformation);
   tout.Position = mul(pos,viewProjection);
    tout.tcoord = Inputs.texCoord;
 
    return tout;
}
 
 
 
sampler2D tex0;
 
float4 psmain( VS_OUTPUT input ):COLOR0
{
//
   return tex2D(tex0,input.tcoord);
}
 
zerochen
Posts: 273
Joined: Wed Jan 07, 2009 1:17 am
Location: Germany

Re: Flexible Vertex Format - special SVN branch is ready!!!

Post by zerochen »

thx

should StarInst not inherit from S3DVertex?

like

Code: Select all

struct StarInst : public video::S3DVertex
Granyte
Posts: 850
Joined: Tue Jan 25, 2011 11:07 pm
Contact:

Re: Flexible Vertex Format - special SVN branch is ready!!!

Post by Granyte »

no because the s3dvertex is in the VB 0 and get combined on the gpu with the starinst.

making it inherit from S3DVertex would require you to double your description of it to deal with those from VB0 and from VB1
zerochen
Posts: 273
Joined: Wed Jan 07, 2009 1:17 am
Location: Germany

Re: Flexible Vertex Format - special SVN branch is ready!!!

Post by zerochen »

hi,

got it to work (at least for dx9, working on dx11 now)

here is the example code:
http://pastebin.com/678ha0mA

and here the shader:
http://pastebin.com/ujsqyeqs

i guess only the shader was wrong not sure anymore...

regards
zerochen
Granyte
Posts: 850
Joined: Tue Jan 25, 2011 11:07 pm
Contact:

Re: Flexible Vertex Format - special SVN branch is ready!!!

Post by Granyte »

I might have gotten it mixed with an old version when i rolled back to the trunk that would explain why it was working in my project but not in the sample


that shader is pretty much identical to mine at least the one i use on my project

by the way the stemp is there to allow passage of custom parameter per instance and it's a float 4 to keep a 16 byte padding with my custom version of the trunk that use sse for matrices math

by the way dx11 does not have instancing implemented in the driver yet neither does OGL
zerochen
Posts: 273
Joined: Wed Jan 07, 2009 1:17 am
Location: Germany

Re: Flexible Vertex Format - special SVN branch is ready!!!

Post by zerochen »

 
that shader is pretty much identical to mine at least the one i use on my project
vs_input was worng declared. the first parameter was not a float4 and tex and color were inverted. i think that was the error.

yes i deactivate stemp just for debug purpose

i implemented dx11 instancing already. with a little luck i find the error today :D
Granyte
Posts: 850
Joined: Tue Jan 25, 2011 11:07 pm
Contact:

Re: Flexible Vertex Format - special SVN branch is ready!!!

Post by Granyte »

nice I guess once this patch is applied the next step is more texture type (texture 2d array, 3d ,3d array)


and do you have a patch for what instancing on dx11 looks like?
Granyte
Posts: 850
Joined: Tue Jan 25, 2011 11:07 pm
Contact:

Re: Flexible Vertex Format - special SVN branch is ready!!!

Post by Granyte »

any one has a CFX setup I have an issue with instancing on DX9 on my current project and it seem to be CFX related so if any one else could perform test on multi-gpu it would be great


EDIT I think I fixed it any one knows why we were discarding the content of a buffer we were gonna over write anyway?
Squareys
Posts: 18
Joined: Tue Mar 11, 2014 8:09 pm
Location: Konstanz, Germany

Re: Flexible Vertex Format - special SVN branch is ready!!!

Post by Squareys »

Hello all!


What is the current state of the FVF branch and what is there left to be done for it to be merged into trunk/ogles?
Or will it remain a decision to the individual whether to use traditional irrlicht vertex types or the FVF?

I am guessing nobody had time to finish this, so maybe somebody could sum up some TODOs for others (potentially myself).


Sincerely,
Squareys
Squareys @ facebook > https://www.facebook.com/Squareys
Squareys @ twitter > https://twitter.com/squareys

VhiteRabbit @ facebook > https://facebook.com/vhiterabbit
VhiteRabbit @ twitter > https://twitter.com/vhiterabbitvr
Nadro
Posts: 1648
Joined: Sun Feb 19, 2006 9:08 am
Location: Warsaw, Poland

Re: Flexible Vertex Format - special SVN branch is ready!!!

Post by Nadro »

FVF stuff is available in shader-pipeline branch. It'll be merged with trunk since v2.0.
Library helping with network requests, tasks management, logger etc in desktop and mobile apps: https://github.com/GrupaPracuj/hermes
Squareys
Posts: 18
Joined: Tue Mar 11, 2014 8:09 pm
Location: Konstanz, Germany

Re: Flexible Vertex Format - special SVN branch is ready!!!

Post by Squareys »

Does this mean, the shader-pipeline branch is complete/finished?
Squareys @ facebook > https://www.facebook.com/Squareys
Squareys @ twitter > https://twitter.com/squareys

VhiteRabbit @ facebook > https://facebook.com/vhiterabbit
VhiteRabbit @ twitter > https://twitter.com/vhiterabbitvr
Nadro
Posts: 1648
Joined: Sun Feb 19, 2006 9:08 am
Location: Warsaw, Poland

Re: Flexible Vertex Format - special SVN branch is ready!!!

Post by Nadro »

No, only FVF stuff is finished, however some methods from IMeshManipulator still need some additional work/test. In shader-pipeline we have also other features eg. D3D11 etc.
Library helping with network requests, tasks management, logger etc in desktop and mobile apps: https://github.com/GrupaPracuj/hermes
Post Reply