[2.1] btOgre

Discussion area about developing with Ogre-Next (2.1, 2.2 and beyond)


User avatar
Thyrion
Goblin
Posts: 224
Joined: Wed Jul 31, 2013 1:58 pm
Location: germany
x 8

[2.1] btOgre

Post by Thyrion »

Hi,

someone got btOgre running under Ogre 2.1?
btOgre is using a simplerenderable.

why is the manualobject port not merged? is it wrong?
https://bitbucket.org/sinbad/ogre/pull- ... re-21/diff
xrgo
OGRE Expert User
OGRE Expert User
Posts: 1148
Joined: Sat Jul 06, 2013 10:59 pm
Location: Chile
x 168

Re: [2.1] btOgre

Post by xrgo »

I have made my own integration of bullet on 2.1, and I really need manualObject too, Its really hard to debug physics without 3D lines. this 3D lines stuffs was asked before here http://www.ogre3d.org/forums/viewtopic.php?f=25&t=82871
I hope that pull request works =D
User avatar
Crystal Hammer
Gnome
Posts: 318
Joined: Sat Jun 23, 2007 5:16 pm
x 77
Contact:

Re: [2.1] btOgre

Post by Crystal Hammer »

I'm also very interested in both ManualObjects and btOgre.
(hmm and terrain :roll: )
al2950
OGRE Expert User
OGRE Expert User
Posts: 1227
Joined: Thu Dec 11, 2008 7:56 pm
Location: Bristol, UK
x 157

Re: [2.1] btOgre

Post by al2950 »

The pull request has not been assigned a reviewer. If the author was to assign it to dark_sylinc it might be reviewed and merged quicker.
xrgo
OGRE Expert User
OGRE Expert User
Posts: 1148
Joined: Sat Jul 06, 2013 10:59 pm
Location: Chile
x 168

Re: [2.1] btOgre

Post by xrgo »

It seems that dark_sylinc it's already looking at it =D
Gdlk
Halfling
Posts: 53
Joined: Mon Dec 05, 2011 9:43 pm
x 1

Re: [2.1] btOgre

Post by Gdlk »

Some news about manual object??
rassweiler
Gnoblar
Posts: 13
Joined: Mon Aug 04, 2014 10:28 pm
Location: Ottawa

Re: [2.1] btOgre

Post by rassweiler »

xrgo wrote:I have made my own integration of bullet on 2.1, and I really need manualObject too, Its really hard to debug physics without 3D lines. this 3D lines stuffs was asked before here http://www.ogre3d.org/forums/viewtopic.php?f=25&t=82871
I hope that pull request works =D
Is it your own from scratch or a modification to btOgre? Just asking since I've been trying to fix btOgre for 2.1.
xrgo
OGRE Expert User
OGRE Expert User
Posts: 1148
Joined: Sat Jul 06, 2013 10:59 pm
Location: Chile
x 168

Re: [2.1] btOgre

Post by xrgo »

rassweiler wrote:Is it your own from scratch or a modification to btOgre? Just asking since I've been trying to fix btOgre for 2.1.
It's from scratch I haven't even look btOgre's code. But the important part, construct collision shapes from the mesh, it's not directly compatible with ogre since I am using data readed from a blender file. Anyways I can still share my code if you need something =)
rassweiler
Gnoblar
Posts: 13
Joined: Mon Aug 04, 2014 10:28 pm
Location: Ottawa

Re: [2.1] btOgre

Post by rassweiler »

That would be great if you don't mind!
xrgo
OGRE Expert User
OGRE Expert User
Posts: 1148
Joined: Sat Jul 06, 2013 10:59 pm
Location: Chile
x 168

Re: [2.1] btOgre

Post by xrgo »

Thing is... I don't have an "bulletOgre" class, its not modular :P, its integrated with my gameObjects and engine, so you going to have to tell me in which part are you stuck
rassweiler
Gnoblar
Posts: 13
Joined: Mon Aug 04, 2014 10:28 pm
Location: Ottawa

Re: [2.1] btOgre

Post by rassweiler »

Oh ok, I have a system-entity-component type setup. I was wondering how you handled the ogre mesh mostly (is it easier to use the blender file?).

Does that mean that your project will have both the blender and mesh files?
xrgo
OGRE Expert User
OGRE Expert User
Posts: 1148
Joined: Sat Jul 06, 2013 10:59 pm
Location: Chile
x 168

Re: [2.1] btOgre

Post by xrgo »

rassweiler wrote:Does that mean that your project will have both the blender and mesh files?
Yes, mostly blender files, I used the blender file serializer used in gamekit: https://code.google.com/p/gamekit/source/browse/
but I implemented my own bullet shape construction, for instance, this is my method to construct a convex hull shape using the blender's object data:

Code: Select all

            if( bObject->collision_boundtype == OB_BOUND_CONVEX_HULL ){
                //Create a temp ConvexHullShape to fill in with vertex info
                btConvexHullShape *tempHull = new btConvexHullShape();

                //Add the vertexs from the blender mesh
                Blender::MVert * mvert = bMesh->mvert;
                for (int n = 0; n < bMesh->totvert; n++){
                    Ogre::Vector3 vertexPos = convertToYup(Ogre::Vector3(mvert[n].co[0],mvert[n].co[1],mvert[n].co[2]));
                    tempHull->addPoint(btVector3(vertexPos.x,vertexPos.y,vertexPos.z));
                }

                //Optimize the shape
                btShapeHull shapeHull(tempHull);
                shapeHull.buildHull(0.01);
                delete tempHull;
                //Create te final Collision Shape
                colShape = new btConvexHullShape(reinterpret_cast<const btScalar*>(shapeHull.getVertexPointer()), shapeHull.numVertices());
            }
that's why I was saying that "it's not directly compatible with ogre"
Anyways you can see how btOgre constructs the shapes here https://github.com/nikki93/btogre/blob/ ... BtOgre.cpp seems pretty simple if you have the vertex information.
rassweiler wrote:(is it easier to use the blender file?).
oh no... that was (and still is) the hardest part of my engine, its easier to use just .mesh... but once its done its really nice to work with, just make a change in the blender file and load the engine and its there! no export/convert process. Same functionality offered by GameKit
User avatar
Thyrion
Goblin
Posts: 224
Joined: Wed Jul 31, 2013 1:58 pm
Location: germany
x 8

Re: [2.1] btOgre

Post by Thyrion »

One month later, still no merge and no answer from the "ogre team".
Someone made progress and want to share it? :)
User avatar
Crystal Hammer
Gnome
Posts: 318
Joined: Sat Jun 23, 2007 5:16 pm
x 77
Contact:

Re: [2.1] btOgre

Post by Crystal Hammer »

I was on IRC and asked dark_sylinc what's the deal with ManualObjects. Here is what he replied:
Nothing in particular. I haven't gotten the time to review the pull request, and it's not a priority as the functionality ManualObjects is not unique.
ManualObject just wraps around a buffer and exposes a glBegin-glEnd approach to specifying vertices.
any idea when you will - nope
You can create meshes from code.
The code from Mesh::importV1 creates a vertex buffer, an index buffer (if present); fills them with the data of the v1 mesh, and creates a Vao that binds those two.
The same code can be used to create a buffer with arbitrary data and update it every frame. Just keep the pointer to the VertexBuffer so you can fill it every frame.
You can use the code from importV1 mesh to create v2 meshes directly, without intermediates. You just need to create a SubMesh, grab SubMesh::mVao (it's a public variable), and you can do whatever you want with it.
Since Items use the SubMesh::mVao pointer, changes made to it will be visible to the items.
I didn't get much done, that code isn't short and easy.
Since that day there is a TODO item: Write a sample that shows how to dynamically create & update a mesh from code.
But it is low priority.
I tried merging ManualObject's pull request but didn't get far. There is a demo sample in it, showing that it works. So far I looked at its code, seems to me like every mesh update just creates VAO always, I'm guessing it's not the fastest way, but whatever at least seems working and its the same code as in 1.9 and such.
IMO it would be cool to merge it (if it works) since every postponed merge just makes it more difficult to merge after new changes on repo.
N0vember
Gremlin
Posts: 196
Joined: Tue Jan 27, 2009 12:27 am
x 24

Re: [2.1] btOgre

Post by N0vember »

I don't really agree with dark_sylinc on this one...
No functionality in programming is ever "unique".
The important measure is how concise it allows to write any solution to any problem you want to implement.
By that measure ManualObject is VERY useful, to a lot of Ogre users, and it has proven so since a long time ago.
So yeah, I think the merge should happen, but if dark_sylinc doesn't have time to review it I don't know who could ?
User avatar
Thyrion
Goblin
Posts: 224
Joined: Wed Jul 31, 2013 1:58 pm
Location: germany
x 8

Re: [2.1] btOgre

Post by Thyrion »

Crystal Hammer wrote:So far I looked at its code, seems to me like every mesh update just creates VAO always, I'm guessing it's not the fastest way,
what's the alternative, instead of destroying and creating the VAO and buffers (if the size changed)?

In the old hardwarebuffer was this flag:

Code: Select all

 /** Discards the <em>entire</em> buffer while locking; this allows optimisation to be 
                performed because synchronisation issues are relaxed. Only allowed on buffers 
                created with the HBU_DYNAMIC flag. 
                */
                HBL_DISCARD,
User avatar
Crystal Hammer
Gnome
Posts: 318
Joined: Sat Jun 23, 2007 5:16 pm
x 77
Contact:

Re: [2.1] btOgre

Post by Crystal Hammer »

There are new samples on master 2.1 now: DynamicGeometry and CustomRenderable.
I think DynamicGeometry could be better for btOgre but IDK if it can handle varying vertices count or unknown each frame for lines.
Those are probably much better and meant to replace the ManualObject.
I did update few road segments geometry in real time by just destroying them and recreating mesh, it works fast. But is definitely too slow for whole road.
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5299
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1279
Contact:

Re: [2.1] btOgre

Post by dark_sylinc »

I had this question via PM, which can benefit others, so I'm going to paste the answer here. Question was:
how do we update the buffers if the size is changing?

do we always have to destroy and create the buffers?
destroyVertexBuffer
destroyIndexBuffer
destroyVertexArrayObject
Yes, that's one way to do it. For non-immutable buffers it should be relatively fast (compared to v1 objects which almost always meant a full stall depending on the driver); but can consume a lot more memory if done frequently (3x or even up to 9x as much memory depending on a lot of variables)

One simple way to avoid this higher memory consumption, and is even faster, is to create oversized buffers, and use VertexArrayObject::setPrimitiveRange to dynamically control how much of these buffers is actually used and shrink it.
If you need bigger buffers than what you've allocated (e.g. you don't know how much memory you will need upfront, and you suddenly have a spike in the amount required), then yes, you're going to destroy and create the buffers again.
xrgo
OGRE Expert User
OGRE Expert User
Posts: 1148
Joined: Sat Jul 06, 2013 10:59 pm
Location: Chile
x 168

Re: [2.1] btOgre

Post by xrgo »

Hello! I just made a simple debugDrawer (just lines) with the new manual Object implementation for my engine

Disclaimer: its not been tested much, and maybe is not the correct/efficient way to do it, but its something =)

cpp:

Code: Select all

#include "yDebugDrawer.h"
#include "yEngine.h"

yDebugDrawer& yDebugDrawer::getSingleton()
{
    static yDebugDrawer instance;
    return instance;
}
yDebugDrawer::yDebugDrawer()
{
}

void yDebugDrawer::init()
{
    sceneManager = Ogre::Root::getSingletonPtr()->getSceneManager("SceneManager");
    isDebuggingPhysics = false;
    previousLineCount = 0;

    Ogre::String datablockName = "DebugLineMat";
    yEngine::getSingleton().getHlmsUnlit()->createDatablock( datablockName,
                                          datablockName,
                                          Ogre::HlmsMacroblock(),
                                          Ogre::HlmsBlendblock(),
                                          Ogre::HlmsParamVec() );

    manualObjectLines = sceneManager->createManualObject();
    manualObjectLines->setStatic( false );
    manualObjectLines->setCastShadows( false );
    sceneManager->getRootSceneNode()->attachObject( manualObjectLines );

    manualObjectLines->begin( "DebugLineMat", Ogre::v1::RenderOperation::OT_LINE_LIST );
    manualObjectLines->position( Ogre::Vector3::ZERO );
    manualObjectLines->position( Ogre::Vector3::ZERO );
    manualObjectLines->line(0, 1);
    manualObjectLines->end();

    debugModes = (DebugDrawModes) DBG_DrawWireframe;
}

yDebugDrawer::~yDebugDrawer()
{
    Ogre::Root::getSingleton().removeFrameListener( this );
    delete manualObjectLines;
}

void yDebugDrawer::drawLine( const btVector3 &from, const btVector3 &to, const btVector3 &color )
{
    if(!isDebuggingPhysics) return;
    yDebugLine line;
    line.from = Ogre::Vector3(from.x(), from.y(), from.z());
    line.to = Ogre::Vector3(to.x(), to.y(), to.z());
    line.color = Ogre::ColourValue( color.getX(), color.getY(), color.getZ() );
    line.color.saturate();
    lines.push_back( line );
}

bool yDebugDrawer::frameRenderingQueued( const Ogre::FrameEvent& evt )
{
    if( previousLineCount != lines.size() ){
        manualObjectLines->clear();
        manualObjectLines->begin( "DebugLineMat", Ogre::v1::RenderOperation::OT_LINE_LIST );
    }
    else manualObjectLines->beginUpdate(0);

    for(int i=0; i<lines.size(); i++){
        manualObjectLines->position( lines.at(i).from );
        manualObjectLines->colour( lines.at(i).color );
        manualObjectLines->position( lines.at(i).to );
        manualObjectLines->colour( lines.at(i).color );
        manualObjectLines->line(i*2, i*2+1);
    }
    manualObjectLines->end();

    previousLineCount = lines.size();
    lines.clear();

    return true;
}

void yDebugDrawer::debugPhysics(bool enable){
    isDebuggingPhysics = enable;
    if( isDebuggingPhysics ){
        manualObjectLines->setVisible(true);
        Ogre::Root::getSingleton().addFrameListener( this );
    }
    else{
        lines.clear();
        manualObjectLines->setVisible(false);
        Ogre::Root::getSingleton().removeFrameListener( this );
    }
}

void yDebugDrawer::setDebugMode( int debugMode )
{
    debugModes = (DebugDrawModes) debugMode;
}

int yDebugDrawer::getDebugMode() const
{
    return debugModes;
}
h:

Code: Select all

#ifndef DebugDrawer_h__
#define DebugDrawer_h__

#include "Ogre.h"
#include "OgreRoot.h"
#include "OgreFrameListener.h"
#include "OgreTimer.h"
#include "LinearMath/btIDebugDraw.h"


class yDebugDrawer: public btIDebugDraw, public Ogre::FrameListener{
public:
    static yDebugDrawer &getSingleton();
    yDebugDrawer();
    void init();
    void debugPhysics(bool enable);
    virtual void     drawLine (const btVector3 &from, const btVector3 &to, const btVector3 &color);
    virtual void     drawTriangle (const btVector3 &v0, const btVector3 &v1, const btVector3 &v2, const btVector3 &color, btScalar){};
    virtual void     drawContactPoint (const btVector3 &PointOnB, const btVector3 &normalOnB, btScalar distance, int lifeTime, const btVector3 &color){};
    virtual void     reportErrorWarning (const char *warningString){};
    virtual void     draw3dText (const btVector3 &location, const char *textString){};
    virtual void     setDebugMode (int debugMode);
    virtual int     getDebugMode () const;

protected:
    bool frameRenderingQueued( const Ogre::FrameEvent& evt );

private:
    yDebugDrawer(yDebugDrawer const&); //don't implement!
    void operator=(yDebugDrawer const&); //don't implement!
    ~yDebugDrawer ();

    struct yDebugLine{
        Ogre::Vector3 from;
        Ogre::Vector3 to;
        Ogre::ColourValue color;
    };

    Ogre::SceneManager* sceneManager;
    DebugDrawModes               debugModes;
    Ogre::ManualObject          *manualObjectLines;

    bool isDebuggingPhysics;
    bool isAfterBegin;
    int previousLineCount;

    std::vector<yDebugLine> lines;
};
 
#endif // DebugDrawer_h__
nyxkn
Gnoblar
Posts: 6
Joined: Fri Mar 05, 2010 1:16 am
Contact:

Re: [2.1] btOgre

Post by nyxkn »

Hi! I forked btogre to make it compile with ogre 2.1, since I'm using it for my project.
Everything should work, except for the debug drawer which I haven't figured out yet.

https://github.com/nyxkn/btogre21

Maybe it will be helpful to some of you!
xrgo
OGRE Expert User
OGRE Expert User
Posts: 1148
Joined: Sat Jul 06, 2013 10:59 pm
Location: Chile
x 168

Re: [2.1] btOgre

Post by xrgo »

Awesome!
check my debugDrawer above, its working for me, but seems very expensive, should be a better way to do that but might be a good start
nyxkn
Gnoblar
Posts: 6
Joined: Fri Mar 05, 2010 1:16 am
Contact:

Re: [2.1] btOgre

Post by nyxkn »

Thanks xrgo! I'll look into it and see if I can get it working.
xrgo
OGRE Expert User
OGRE Expert User
Posts: 1148
Joined: Sat Jul 06, 2013 10:59 pm
Location: Chile
x 168

Re: [2.1] btOgre

Post by xrgo »

Hello! I just revamped my debugDrawer, as recommended... not using manualObject this time =), it seems to be faster (have to test on another pc, my notebook its too old)... but I still have a question!
is it possible to create a vertexbuffer without knowing the vertexCount? I set the vertexCount to a very high value, so it will fit most cases but I am guessing there's a better option.

yDebugDrawer.cpp

Code: Select all

#include "yDebugDrawer.h"
#include "yGraphicsSystem.h"
#include "OgreMesh2.h"
#include "OgreMeshManager2.h"
#include "OgreSubMesh2.h"

yDebugDrawer& yDebugDrawer::getSingleton()
{
    static yDebugDrawer instance;
    return instance;
}
yDebugDrawer::yDebugDrawer()
{
}

void yDebugDrawer::init()
{
    sceneManager = Ogre::Root::getSingletonPtr()->getSceneManager("SceneManager");
    isDebuggingPhysics = false;

    Ogre::String datablockName = "DebugLineMat";
    Ogre::HlmsUnlitDatablock *datablock = static_cast<Ogre::HlmsUnlitDatablock*>(yGraphicsSystem::getSingleton().getHlmsUnlit()->createDatablock( datablockName,
                                          datablockName,
                                          Ogre::HlmsMacroblock(),
                                          Ogre::HlmsBlendblock(),
                                          Ogre::HlmsParamVec() ) );

    vertexCount = 1000000;


    Ogre::Root *root = Ogre::Root::getSingletonPtr();
    Ogre::RenderSystem *renderSystem = root->getRenderSystem();
    Ogre::VaoManager *vaoManager = renderSystem->getVaoManager();

    Ogre::MeshPtr mesh = Ogre::MeshManager::getSingleton().createManual( "PhysicsDebuggingMesh", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME );

    Ogre::SubMesh *subMesh = mesh->createSubMesh();

    Ogre::VertexElement2Vec vertexElements;
    vertexElements.push_back( Ogre::VertexElement2( Ogre::VET_FLOAT3, Ogre::VES_POSITION ) );
    vertexElements.push_back( Ogre::VertexElement2( Ogre::VET_FLOAT3, Ogre::VES_DIFFUSE) );

    size_t vertexSize = vaoManager->calculateVertexSize(vertexElements);

    Ogre::Real* vertexData = static_cast<Ogre::Real*>( OGRE_MALLOC_SIMD( vertexSize * vertexCount, Ogre::MEMCATEGORY_GEOMETRY ) );

    Ogre::VertexBufferPackedVec vertexBuffers;

    pVertexBuffer = vaoManager->createVertexBuffer( vertexElements, vertexCount, Ogre::BT_DYNAMIC_PERSISTENT, vertexData, false );
    vertexBuffers.push_back(pVertexBuffer);


    Ogre::VertexArrayObject *vao = vaoManager->createVertexArrayObject(
                vertexBuffers, 0, Ogre::OperationType::OT_LINE_LIST );

    subMesh->mVao[0].push_back( vao );
    subMesh->mVao[1].push_back( vao );

    mesh->_setBounds( Ogre::Aabb::BOX_INFINITE );


    item = sceneManager->createItem( mesh, Ogre::SCENE_DYNAMIC );
    item->setDatablock( datablock );
    item->setCastShadows( false );
    Ogre::SceneNode *sceneNode = sceneManager->getRootSceneNode( Ogre::SCENE_DYNAMIC )->createChildSceneNode( Ogre::SCENE_DYNAMIC );
    sceneNode->attachObject( item );


    debugModes = (DebugDrawModes) DBG_DrawWireframe;

}

yDebugDrawer::~yDebugDrawer()
{
}

void yDebugDrawer::deinit() {
    if( isDebuggingPhysics ) debugPhysics(false);
}

void yDebugDrawer::drawLine( const btVector3 &from, const btVector3 &to, const btVector3 &color )
{
    if(!isDebuggingPhysics) return;

    if( pVertexBuffer->isCurrentlyMapped() ){
        meshVertices[vertIndex++] = from.x();
        meshVertices[vertIndex++] = from.y();
        meshVertices[vertIndex++] = from.z();

        meshVertices[vertIndex++] = color.getX();
        meshVertices[vertIndex++] = color.getY();
        meshVertices[vertIndex++] = color.getZ();

        meshVertices[vertIndex++] = to.x();
        meshVertices[vertIndex++] = to.y();
        meshVertices[vertIndex++] = to.z();

        meshVertices[vertIndex++] = color.getX();
        meshVertices[vertIndex++] = color.getY();
        meshVertices[vertIndex++] = color.getZ();
    }
}

bool yDebugDrawer::frameStarted( const Ogre::FrameEvent& evt ){
    vertIndex = 0;
    meshVertices = reinterpret_cast<Ogre::Real*>( pVertexBuffer->map( 0, pVertexBuffer->getNumElements() ) );

    return true;
}

bool yDebugDrawer::frameEnded( const Ogre::FrameEvent& evt ){
    if( pVertexBuffer->isCurrentlyMapped() ) pVertexBuffer->unmap( Ogre::UO_KEEP_PERSISTENT );

    return true;
}

void yDebugDrawer::debugPhysics(bool enable){
    isDebuggingPhysics = enable;
    if( isDebuggingPhysics ){
        item->setVisible(true);
        Ogre::Root::getSingleton().addFrameListener( this );
    }
    else{
        item->setVisible(false);
        Ogre::Root::getSingleton().removeFrameListener( this );
    }
}

void yDebugDrawer::setDebugMode( int debugMode )
{
    debugModes = (DebugDrawModes) debugMode;
}

int yDebugDrawer::getDebugMode() const
{
    return debugModes;
}
yDebugDrawer.h

Code: Select all

#ifndef DebugDrawer_h__
#define DebugDrawer_h__

#include "Ogre.h"
#include "OgreRoot.h"
#include "OgreFrameListener.h"
#include "LinearMath/btIDebugDraw.h"


class yDebugDrawer: public btIDebugDraw, public Ogre::FrameListener{
public:
    static yDebugDrawer &getSingleton();
    void init();
    void deinit();
    void debugPhysics(bool enable);
    virtual void     drawLine (const btVector3 &from, const btVector3 &to, const btVector3 &color);
    virtual void     drawTriangle (const btVector3 &v0, const btVector3 &v1, const btVector3 &v2, const btVector3 &color, btScalar){ (void)v0; (void)v1; (void)v2; (void)color; }
    virtual void     drawContactPoint (const btVector3 &PointOnB, const btVector3 &normalOnB, btScalar distance, int lifeTime, const btVector3 &color){ (void)PointOnB; (void)normalOnB; (void)distance; (void)lifeTime; (void)color; }
    virtual void     reportErrorWarning (const char *warningString){ (void)warningString; }
    virtual void     draw3dText (const btVector3 &location, const char *textString){ (void)location; (void)textString; }
    virtual void     setDebugMode (int debugMode);
    virtual int     getDebugMode () const;

protected:
    bool frameStarted( const Ogre::FrameEvent& evt );
    bool frameEnded( const Ogre::FrameEvent& evt );

private:
    yDebugDrawer();
    yDebugDrawer(yDebugDrawer const&); //don't implement!
    void operator=(yDebugDrawer const&); //don't implement!
    ~yDebugDrawer ();

    Ogre::SceneManager* sceneManager;
    DebugDrawModes               debugModes;

    bool isDebuggingPhysics;

    Ogre::VertexBufferPacked *pVertexBuffer;
    int vertexCount;
    Ogre::Item *item;
    Ogre::Real* meshVertices;
    int vertIndex;
};
 
#endif // DebugDrawer_h__
User avatar
Thyrion
Goblin
Posts: 224
Joined: Wed Jul 31, 2013 1:58 pm
Location: germany
x 8

Re: [2.1] btOgre

Post by Thyrion »

dark_sylinc wrote:
how do we update the buffers if the size is changing?

do we always have to destroy and create the buffers?
destroyVertexBuffer
destroyIndexBuffer
destroyVertexArrayObject
Yes, that's one way to do it. For non-immutable buffers it should be relatively fast (compared to v1 objects which almost always meant a full stall depending on the driver); but can consume a lot more memory if done frequently (3x or even up to 9x as much memory depending on a lot of variables)

One simple way to avoid this higher memory consumption, and is even faster, is to create oversized buffers, and use VertexArrayObject::setPrimitiveRange to dynamically control how much of these buffers is actually used and shrink it.
If you need bigger buffers than what you've allocated (e.g. you don't know how much memory you will need upfront, and you suddenly have a spike in the amount required), then yes, you're going to destroy and create the buffers again.
class yDebugDrawer: public btIDebugDraw, public Ogre::FrameListener{
why do you use FrameListener and not the movableobject and Renderable?
xrgo
OGRE Expert User
OGRE Expert User
Posts: 1148
Joined: Sat Jul 06, 2013 10:59 pm
Location: Chile
x 168

Re: [2.1] btOgre

Post by xrgo »

Thyrion wrote:One simple way to avoid this higher memory consumption, and is even faster, is to create oversized buffers, and use VertexArrayObject::setPrimitiveRange
thanks! I did that... or I think i did, because I didn't get any improvement :P

cpp

Code: Select all

#include "yDebugDrawer.h"
#include "yGraphicsSystem.h"
#include "OgreMesh2.h"
#include "OgreMeshManager2.h"
#include "OgreSubMesh2.h"
#include "Vao/OgreVertexArrayObject.h"

yDebugDrawer& yDebugDrawer::getSingleton()
{
    static yDebugDrawer instance;
    return instance;
}
yDebugDrawer::yDebugDrawer()
{
}

void yDebugDrawer::init()
{
    sceneManager = Ogre::Root::getSingletonPtr()->getSceneManager("SceneManager");
    isDebuggingPhysics = false;

    Ogre::String datablockName = "DebugLineMat";
    Ogre::HlmsUnlitDatablock *datablock = static_cast<Ogre::HlmsUnlitDatablock*>(yGraphicsSystem::getSingleton().getHlmsUnlit()->createDatablock( datablockName,
                                          datablockName,
                                          Ogre::HlmsMacroblock(),
                                          Ogre::HlmsBlendblock(),
                                          Ogre::HlmsParamVec() ) );

    vertexCount = 0;
    int maxVertexCount = 10000000;


    Ogre::Root *root = Ogre::Root::getSingletonPtr();
    Ogre::RenderSystem *renderSystem = root->getRenderSystem();
    Ogre::VaoManager *vaoManager = renderSystem->getVaoManager();

    Ogre::MeshPtr mesh = Ogre::MeshManager::getSingleton().createManual( "PhysicsDebuggingMesh", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME );

    Ogre::SubMesh *subMesh = mesh->createSubMesh();

    Ogre::VertexElement2Vec vertexElements;
    vertexElements.push_back( Ogre::VertexElement2( Ogre::VET_FLOAT3, Ogre::VES_POSITION ) );
    vertexElements.push_back( Ogre::VertexElement2( Ogre::VET_FLOAT3, Ogre::VES_DIFFUSE) );

    size_t vertexSize = vaoManager->calculateVertexSize(vertexElements);

    Ogre::Real* vertexData = static_cast<Ogre::Real*>( OGRE_MALLOC_SIMD( vertexSize * maxVertexCount, Ogre::MEMCATEGORY_GEOMETRY ) );

    Ogre::VertexBufferPackedVec vertexBuffers;

    pVertexBuffer = vaoManager->createVertexBuffer( vertexElements, maxVertexCount, Ogre::BT_DYNAMIC_PERSISTENT, vertexData, false );
    vertexBuffers.push_back(pVertexBuffer);


    vao = vaoManager->createVertexArrayObject(
                vertexBuffers, 0, Ogre::OperationType::OT_LINE_LIST );

    subMesh->mVao[0].push_back( vao );
    subMesh->mVao[1].push_back( vao );


    mesh->_setBounds( Ogre::Aabb::BOX_INFINITE );


    item = sceneManager->createItem( mesh, Ogre::SCENE_DYNAMIC );
    item->setDatablock( datablock );
    item->setCastShadows( false );
    Ogre::SceneNode *sceneNode = sceneManager->getRootSceneNode( Ogre::SCENE_DYNAMIC )->createChildSceneNode( Ogre::SCENE_DYNAMIC );
    sceneNode->attachObject( item );


    debugModes = (DebugDrawModes) DBG_DrawWireframe;

}

yDebugDrawer::~yDebugDrawer()
{
}

void yDebugDrawer::deinit() {
    if( isDebuggingPhysics ) debugPhysics(false);
}

void yDebugDrawer::drawLine( const btVector3 &from, const btVector3 &to, const btVector3 &color )
{
    if(!isDebuggingPhysics) return;

    if( pVertexBuffer->isCurrentlyMapped() ){
        meshVertices[vertIndex++] = from.x();
        meshVertices[vertIndex++] = from.y();
        meshVertices[vertIndex++] = from.z();

        meshVertices[vertIndex++] = color.getX()*0.9;
        meshVertices[vertIndex++] = color.getY()*0.9;
        meshVertices[vertIndex++] = color.getZ()*0.9;

        meshVertices[vertIndex++] = to.x();
        meshVertices[vertIndex++] = to.y();
        meshVertices[vertIndex++] = to.z();

        meshVertices[vertIndex++] = color.getX()*0.9;
        meshVertices[vertIndex++] = color.getY()*0.9;
        meshVertices[vertIndex++] = color.getZ()*0.9;

        vertexCount += 2;

        vao->setPrimitiveRange(0,vertexCount);
    }
}

bool yDebugDrawer::frameStarted( const Ogre::FrameEvent& evt ){
    vertIndex = 0;
    vertexCount = 0;
    meshVertices = reinterpret_cast<Ogre::Real*>( pVertexBuffer->map( 0, pVertexBuffer->getNumElements() ) );

    return true;
}

bool yDebugDrawer::frameEnded( const Ogre::FrameEvent& evt ){
    if( pVertexBuffer->isCurrentlyMapped() ) pVertexBuffer->unmap( Ogre::UO_KEEP_PERSISTENT );

    return true;
}

void yDebugDrawer::debugPhysics(bool enable){
    isDebuggingPhysics = enable;
    if( isDebuggingPhysics ){
        item->setVisible(true);
        Ogre::Root::getSingleton().addFrameListener( this );
    }
    else{
        item->setVisible(false);
        Ogre::Root::getSingleton().removeFrameListener( this );
    }
}

void yDebugDrawer::setDebugMode( int debugMode )
{
    debugModes = (DebugDrawModes) debugMode;
}

int yDebugDrawer::getDebugMode() const
{
    return debugModes;
}
.h

Code: Select all

#ifndef DebugDrawer_h__
#define DebugDrawer_h__

#include "Ogre.h"
#include "OgreRoot.h"
#include "OgreFrameListener.h"
#include "LinearMath/btIDebugDraw.h"


class yDebugDrawer: public btIDebugDraw, public Ogre::FrameListener{
public:
    static yDebugDrawer &getSingleton();
    void init();
    void deinit();
    void debugPhysics(bool enable);
    virtual void     drawLine (const btVector3 &from, const btVector3 &to, const btVector3 &color);
    virtual void     drawTriangle (const btVector3 &v0, const btVector3 &v1, const btVector3 &v2, const btVector3 &color, btScalar){ (void)v0; (void)v1; (void)v2; (void)color; }
    virtual void     drawContactPoint (const btVector3 &PointOnB, const btVector3 &normalOnB, btScalar distance, int lifeTime, const btVector3 &color){ (void)PointOnB; (void)normalOnB; (void)distance; (void)lifeTime; (void)color; }
    virtual void     reportErrorWarning (const char *warningString){ (void)warningString; }
    virtual void     draw3dText (const btVector3 &location, const char *textString){ (void)location; (void)textString; }
    virtual void     setDebugMode (int debugMode);
    virtual int     getDebugMode () const;

protected:
    bool frameStarted( const Ogre::FrameEvent& evt );
    bool frameEnded( const Ogre::FrameEvent& evt );

private:
    yDebugDrawer();
    yDebugDrawer(yDebugDrawer const&); //don't implement!
    void operator=(yDebugDrawer const&); //don't implement!
    ~yDebugDrawer ();

    Ogre::SceneManager* sceneManager;
    DebugDrawModes               debugModes;

    bool isDebuggingPhysics;

    Ogre::VertexBufferPacked *pVertexBuffer;
    int vertexCount;
    Ogre::Item *item;
    Ogre::Real* meshVertices;
    int vertIndex;
    Ogre::VertexArrayObject *vao;
};
 
#endif // DebugDrawer_h__
Thyrion wrote:why do you use FrameListener and not the movableobject and Renderable?
Because I started with this one: http://www.ogre3d.org/tikiwiki/BulletDe ... e=Cookbook and to be honest I have never used movableobject and renderable, what would be the advantage of using those?
Post Reply