C interface as core feature

What it says on the tin: a place to discuss proposed new features.
Post Reply
User avatar
so0os
Bugbear
Posts: 833
Joined: Thu Apr 15, 2010 7:42 am
Location: Poznan, Poland
x 33

Re: C interface as core feature

Post by so0os »

Let me try!

Seriously, make a repo, i'll try to negotiate with VS.
Sos Sosowski :)
http://www.sos.gd
User avatar
jacmoe
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 20570
Joined: Thu Jan 22, 2004 10:13 am
Location: Denmark
x 179
Contact:

Re: C interface as core feature

Post by jacmoe »

I am probably doing something really stupid. :)
Funny thing is, that the CREATE_HANDLE does exactly the same thing, and it's defined in WinDef.h ...

Alright, here's the repo:
http://code.google.com/p/llcoi/
/* Less noise. More signal. */
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.
User avatar
jacmoe
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 20570
Joined: Thu Jan 22, 2004 10:13 am
Location: Denmark
x 179
Contact:

Re: C interface as core feature

Post by jacmoe »

But, it would be better if we could come up with something more clever, as interchanging the handle name merely triggers a warning in GCC.
/* Less noise. More signal. */
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.
User avatar
Chris Jones
Lich
Posts: 1742
Joined: Tue Apr 05, 2005 1:11 pm
Location: Gosport, South England
x 1

Re: C interface as core feature

Post by Chris Jones »

What Jacmoe is doing is correct in that you create a Camera, cast it to a void* then cast the same pointer back to Camera again. It would be dangerous to cast it to any of its base classes though (directly from the void*) as they could have different address offsets.
User avatar
so0os
Bugbear
Posts: 833
Joined: Thu Apr 15, 2010 7:42 am
Location: Poznan, Poland
x 33

Re: C interface as core feature

Post by so0os »

Looks nice! I'll take a closer look as soon as I get back from work. But I guess that reinterpreting handles is overdoing it a bit.

I mean this:

Code: Select all

DLLEXP coiCameraHandle get_camera(const char* camera_name)
{
    Ogre::Camera* camera =  Ogre::Root::getSingletonPtr()->getSceneManager("scene-manager")->getCamera(camera_name);
    return (coiCameraHandle)reinterpret_cast<void*>(camera);
}

DLLEXP void camera_set_near_clip_distance(coiCameraHandle camera_handle, coiReal d)
{
    Ogre::Camera* camera = reinterpret_cast<Ogre::Camera*>(camera_handle);
    camera->setNearClipDistance( d );
}
can be this:

Code: Select all

void* get_camera(const char* camera_name)
{
	return Ogre::Root::getSingletonPtr()->getSceneManager("scene-manager")->getCamera(camera_name);
}

 void camera_set_near_clip_distance(void* camera_handle, float d)
{
	((Ogre::Camera*)camera_handle)->setNearClipDistance( d );
}
Both compile well and do the same thing.
I would go defining each handle as void* and getting rid of the fake struct.
Sos Sosowski :)
http://www.sos.gd
User avatar
Chris Jones
Lich
Posts: 1742
Joined: Tue Apr 05, 2005 1:11 pm
Location: Gosport, South England
x 1

Re: C interface as core feature

Post by Chris Jones »

We should probably be using static_cast rather than reinterpret_cast or c style casts. (Stackoverflow post). There's probably not a lot of difference but its probably more inline with the C++ standard.
User avatar
so0os
Bugbear
Posts: 833
Joined: Thu Apr 15, 2010 7:42 am
Location: Poznan, Poland
x 33

Re: C interface as core feature

Post by so0os »

I guess you're right about the static_cast, but I'd go with one that produces less output code (if there's any difference in that at all). For a void*, cast operators will all work the same (I'm not sure about the dynamic_cast, but I never trusted this construct).

EDIT:
HAHA, I'm stupid, casts produce no code, it's just a compiler construct. i guess we should take one that just looks better, then
Sos Sosowski :)
http://www.sos.gd
User avatar
jacmoe
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 20570
Joined: Thu Jan 22, 2004 10:13 am
Location: Denmark
x 179
Contact:

Re: C interface as core feature

Post by jacmoe »

Alright. It's static_cast, and reinterpret_cast when the first one fails. :wink:

The nice thing about void pointers is that it's fast, but it's extremely error prone as the user can pass anything to it.
Look up is slower, but safe.
I guess it's a matter of preference.
The fake type is only an extra hint - I have two versions:

Code: Select all

#define COI_DECLARE_HANDLE(name) typedef struct name##__ { int unused; } *name
#define COI_DECLARE_HANDLE(name) typedef void* name
The first one (which doesn't work with VC yet) actually produces a warning in GCC if you pass the wrong type.
The second one doesn't lift an eyebrow as it's plain void pointers.
I know that void pointers are the most common way to deal with this, but maybe there's another option:
http://yosefk.com/c++fqa/mixing.html#fqa-32.8
/* Less noise. More signal. */
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.
User avatar
so0os
Bugbear
Posts: 833
Joined: Thu Apr 15, 2010 7:42 am
Location: Poznan, Poland
x 33

Re: C interface as core feature

Post by so0os »

Pointers are pointers, user can pass anything (another pointer or int) since it's C, also, I guess we shouldn't babysit C programmers and complicate stuff just to do that.

EDIT: fake struct would screw Autocomplete
Sos Sosowski :)
http://www.sos.gd
User avatar
jacmoe
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 20570
Joined: Thu Jan 22, 2004 10:13 am
Location: Denmark
x 179
Contact:

Re: C interface as core feature

Post by jacmoe »

I finally figured out the VC problem:
It's C89/C90, so you need to declare all variables at the top of the function.
Bleh :wink:
It probably means that the handle macro actually works..
/* Less noise. More signal. */
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.
User avatar
jacmoe
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 20570
Joined: Thu Jan 22, 2004 10:13 am
Location: Denmark
x 179
Contact:

Re: C interface as core feature

Post by jacmoe »

Code: Select all

2>ClCompile:
2>  main.c
2>..\..\llcoi\test\main.c(56): error C2220: warning treated as error - no 'object' file generated
2>..\..\llcoi\test\main.c(56): warning C4133: '=' : incompatible types - from 'LightHandle' to 'LightHandleWrong'
2>..\..\llcoi\test\main.c(58): warning C4133: 'function' : incompatible types - from 'LightHandleWrong' to 'LightHandle'
2>
2>Build FAILED.
YES!! :)
Well - if warnings are set to be treated as errors.
So the handle macro now works in VC.
I think it's slightly better than just a bare void pointer.
It does require reinterpret_cast, though. :wink:
/* Less noise. More signal. */
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.
User avatar
so0os
Bugbear
Posts: 833
Joined: Thu Apr 15, 2010 7:42 am
Location: Poznan, Poland
x 33

Re: C interface as core feature

Post by so0os »

It's making straight things artificially complex IMO. I'm glad C doesn't babble about pointer types, and that's why I still use it, let's not force the compiler to do this. Also, it kind of undermine the 'low-level' part of project name ;)

I think WinAPI is the best example of such an interface, and following its ways is a good thing IMO.
Sos Sosowski :)
http://www.sos.gd
User avatar
jacmoe
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 20570
Joined: Thu Jan 22, 2004 10:13 am
Location: Denmark
x 179
Contact:

Re: C interface as core feature

Post by jacmoe »

Indeed. :wink:
Straight from winnt.h :

Code: Select all

DECLARE_HANDLE(name) struct name##__ { int unused; }; typedef struct name##__ *name
In my eyes, this is better:

Code: Select all

DLL RenderWindowHandle root_initialise(int auto_create_window, const char* render_window_title);
than this:

Code: Select all

DLL void* root_initialise(int auto_create_window, const char* render_window_title);
/* Less noise. More signal. */
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.
User avatar
Kojack
OGRE Moderator
OGRE Moderator
Posts: 7157
Joined: Sun Jan 25, 2004 7:35 am
Location: Brisbane, Australia
x 534

Re: C interface as core feature

Post by Kojack »

sfml might be a good project to take a look at for ideas. It's a c++ based graphics library, but it comes with an optional C api (built as a separate lib but is an official part of the project) which has been used to expose all of sfml to .Net, Ruby, Python and D.
(I'm not saying laurent did it the best way, I've only spent 30 seconds looking at the c api code. Maybe it rocks, maybe it doesn't. Could be worth a quick look)
User avatar
so0os
Bugbear
Posts: 833
Joined: Thu Apr 15, 2010 7:42 am
Location: Poznan, Poland
x 33

Re: C interface as core feature

Post by so0os »

Ok, I give up :P Anyways, I guess it's what matters the least. I have another concern, tho.

Should we wrap up OIS as well, or use something that's already C?

Also, I will get to work as soon as i find some spare time, and I can take care of some basic Listeners for a start.

EDIT: And let's remove the coi~ prefix from types, it looks kind of annoying. It would make sense if someone was to use this along with Ogre. I suppose keeping Ogre naming for handles is a good idea (e.g. a SceneNode handle is named SceneNode, or SCENENODE)
Sos Sosowski :)
http://www.sos.gd
User avatar
jacmoe
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 20570
Joined: Thu Jan 22, 2004 10:13 am
Location: Denmark
x 179
Contact:

Re: C interface as core feature

Post by jacmoe »

@So0os:
I am on the brink of integrating OIS, but - as it's C - it would be nice to integrate SDL and/or OpenInput (which is C) as well. :)
I briefly looked into Listeners, but I am happy to leave that to you.
It would be a matter of having a background class which registers itself as a Listener to Ogre/OIS and with the option of registering a callback functions from C.

About the handles: we can make it a switch so that you can get your void pointers back, So0os. :wink:
I just think the it's good to at least hint about the types.
Like root_initialise:
void* root_initialise(args) - does it return a Root or a RenderWindow?
If using void*, we need to look at a comment to see what the void pointer points to.
Using an opaque pointer, you can see what it's supposed to be (even if C allows you to mix the types up).

Thanks for the tip, Kojack - I'll check out SFML. :)
/* Less noise. More signal. */
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.
User avatar
jacmoe
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 20570
Joined: Thu Jan 22, 2004 10:13 am
Location: Denmark
x 179
Contact:

Re: C interface as core feature

Post by jacmoe »

so0os wrote:And let's remove the coi~ prefix from types, it looks kind of annoying.
Already done. :)
It's SceneNodeHandle, RenderWindowHandle, etc. now.
I am a bit allergic to all caps handles.
/* Less noise. More signal. */
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.
User avatar
so0os
Bugbear
Posts: 833
Joined: Thu Apr 15, 2010 7:42 am
Location: Poznan, Poland
x 33

Re: C interface as core feature

Post by so0os »

Cool ;) I'll get to work as soon as I come back from work (~6h from now) and get the listeners working.
Sos Sosowski :)
http://www.sos.gd
User avatar
jacmoe
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 20570
Joined: Thu Jan 22, 2004 10:13 am
Location: Denmark
x 179
Contact:

Re: C interface as core feature

Post by jacmoe »

As for input, maybe Allegro? :)
It was my first game library back in my 16 bit days.

GLFW and SFML are also worth a look.

<edit>
Found glfw-lite which might be a good candidate.
Horde3D (again) uses it for the demos.
/* Less noise. More signal. */
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.
User avatar
so0os
Bugbear
Posts: 833
Joined: Thu Apr 15, 2010 7:42 am
Location: Poznan, Poland
x 33

Re: C interface as core feature

Post by so0os »

Haha, great Idea. It's easy to hook up, and it can become a nice RTT extension later on.

EDIT: I meant allegro :P

EDIT2: I was starting with allegro too :D I still enjoy using it sometimes.
Sos Sosowski :)
http://www.sos.gd
User avatar
jacmoe
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 20570
Joined: Thu Jan 22, 2004 10:13 am
Location: Denmark
x 179
Contact:

Re: C interface as core feature

Post by jacmoe »

See what I found in Allegro 5.x:

Code: Select all

/*
 *    Example program for the Allegro library, by Peter Wang.
 *
 *    This is a test program to see if Allegro can be used alongside the OGRE
 *    graphics library.  It currently only works on Linux/GLX.  To run, you
 *    will need to have OGRE plugins.cfg and resources.cfg files in the
 *    current directory.
 *
 *    Inputs: W A S D, mouse
 *
 *    This code is based on the samples in the OGRE distribution.
 */

#include <Ogre.h>
#include <allegro5/allegro.h>
#include <allegro5/allegro_opengl.h>

/*
 * Ogre 1.7 (and, optionally, earlier versions) uses the FreeImage library to
 * handle image loading.  FreeImage bundles its own copies of common libraries
 * like libjpeg and libpng, which can conflict with the system copies of those
 * libraries that allegro_image uses.  That means we can't use allegro_image
 * safely, nor any of the addons which depend on it.
 *
 * One solution would be to write a codec for Ogre that avoids FreeImage, or
 * write allegro_image handlers using FreeImage.  The latter would probably be
 * easier and useful for other reasons.
 */

using namespace Ogre;

const int WIDTH = 640;
const int HEIGHT = 480;
const float MOVE_SPEED = 1500.0;

class Application
{
protected:
   Root *mRoot;
   RenderWindow *mWindow;
   SceneManager *mSceneMgr;
   Camera *mCamera;

public:
   void setup(int w, int h)
   {
      createRoot();
      defineResources();
      setupRenderSystem();
      createRenderWindow(w, h);
      initializeResourceGroups();
      chooseSceneManager();
      createCamera();
      createViewports();
      createScene();
   }

   ~Application()
   {
      delete mRoot;
   }

private:
   void createRoot()
   {
      mRoot = new Root();
   }

   void defineResources()
   {
      String secName, typeName, archName;
      ConfigFile cf;
      cf.load("resources.cfg");
      ConfigFile::SectionIterator seci = cf.getSectionIterator();
      while (seci.hasMoreElements()) {
         secName = seci.peekNextKey();
         ConfigFile::SettingsMultiMap *settings = seci.getNext();
         ConfigFile::SettingsMultiMap::iterator i;
         for (i = settings->begin(); i != settings->end(); ++i) {
            typeName = i->first;
            archName = i->second;
            ResourceGroupManager::getSingleton().addResourceLocation(archName,
               typeName, secName);
         }
      }
   }

   void setupRenderSystem()
   {
      if (!mRoot->restoreConfig() && !mRoot->showConfigDialog()) {
         throw Exception(52, "User canceled the config dialog!",
            "Application::setupRenderSystem()");
      }
   }

   void createRenderWindow(int w, int h)
   {
      // Initialise Ogre without creating a window.
      mRoot->initialise(false);

      Ogre::NameValuePairList misc;
      // Tell Ogre to use the current GL context.  This works on Linux/GLX but
      // you *will* need something different on Windows or Mac.
      misc["currentGLContext"] = String("True");

      mWindow = mRoot->createRenderWindow("MainRenderWindow", w, h, false,
         &misc);
      mWindow->setVisible(true);
   }

   void initializeResourceGroups()
   {
      TextureManager::getSingleton().setDefaultNumMipmaps(5);
      ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
   }

   virtual void chooseSceneManager()
   {
      mSceneMgr = mRoot->createSceneManager(ST_GENERIC, "Default SceneManager");
   }

   virtual void createCamera()
   {
      mCamera = mSceneMgr->createCamera("PlayerCam");
      mCamera->setPosition(Vector3(-300, 300, -300));
      mCamera->lookAt(Vector3(0, 0, 0));
      mCamera->setNearClipDistance(5);
   }

   virtual void createViewports()
   {
      // Create one viewport, entire window.
      Viewport *vp = mWindow->addViewport(mCamera);
      vp->setBackgroundColour(ColourValue(0, 0.25, 0.5));

      // Alter the camera aspect ratio to match the viewport.
      mCamera->setAspectRatio(
         Real(vp->getActualWidth()) / Real(vp->getActualHeight()));
   }

   virtual void createScene() = 0;

public:

   void render()
   {
      const bool swap_buffers = false;
      mWindow->update(swap_buffers);
      mRoot->renderOneFrame();
      al_flip_display();
   }
};

class Example : public Application
{
private:
   ALLEGRO_DISPLAY *display;
   ALLEGRO_EVENT_QUEUE *queue;
   ALLEGRO_TIMER *timer;

   double startTime;
   double lastRenderTime;
   double lastMoveTime;
   bool lmb;
   bool rmb;
   bool forward;
   bool back;
   bool left;
   bool right;
   float current_speed;
   Vector3 last_translate;

public:
   Example(ALLEGRO_DISPLAY *display);
   ~Example();
   void setup();
   void mainLoop();

private:
   void createScene();
   void moveCamera(double timestamp, Radian rot_x, Radian rot_y,
         Vector3 & translate);
   void animate(double now);
   void nextFrame();
};

Example::Example(ALLEGRO_DISPLAY *display) :
   display(display),
   queue(NULL),
   timer(NULL),
   startTime(0.0),
   lastRenderTime(0.0),
   lastMoveTime(0.0),
   lmb(false),
   rmb(false),
   forward(false),
   back(false),
   left(false),
   right(false),
   current_speed(0),
   last_translate(Vector3::ZERO)
{
}

Example::~Example()
{
   al_destroy_timer(timer);
   al_destroy_event_queue(queue);
}

void Example::createScene()
{
   // Enable shadows.
   mSceneMgr->setAmbientLight(ColourValue(0.5, 0.25, 0.0));
   //mSceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_ADDITIVE);  // slower
   mSceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_MODULATIVE);  // faster

   // Create the character.
   Entity *ent1 = mSceneMgr->createEntity("Ninja", "ninja.mesh");
   ent1->setCastShadows(true);
   mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ent1);

   AnimationState *anim1 = ent1->getAnimationState("Walk");
   anim1->setLoop(true);
   anim1->setEnabled(true);

   // Create the ground.
   Plane plane(Vector3::UNIT_Y, 0);
   MeshManager::getSingleton().createPlane("ground",
      ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane,
      1500, 1500, 20, 20, true, 1, 5, 5, Vector3::UNIT_Z);

   Entity *ent2 = mSceneMgr->createEntity("GroundEntity", "ground");
   ent2->setMaterialName("Examples/Rockwall");
   ent2->setCastShadows(false);
   mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ent2);

   // Create a light.
   Light *light = mSceneMgr->createLight("Light1");
   light->setType(Light::LT_POINT);
   light->setPosition(Vector3(0, 150, 250));
   light->setDiffuseColour(1.0, 1.0, 1.0);
   light->setSpecularColour(1.0, 0.0, 0.0);
}

void Example::setup()
{
   int w = al_get_display_width(display);
   int h = al_get_display_height(display);
   Application::setup(w, h);

   const double BPS = 60.0;
   timer = al_create_timer(1.0 / BPS);

   queue = al_create_event_queue();
   al_register_event_source(queue, al_get_keyboard_event_source());
   al_register_event_source(queue, al_get_mouse_event_source());
   al_register_event_source(queue, al_get_timer_event_source(timer));
   al_register_event_source(queue, al_get_display_event_source(display));
}

void Example::mainLoop()
{
   bool redraw = true;

   startTime = lastMoveTime = al_get_time();
   al_start_timer(timer);

   for (;;) {
      ALLEGRO_EVENT event;

      if (al_is_event_queue_empty(queue) && redraw) {
         nextFrame();
         redraw = false;
      }

      al_wait_for_event(queue, &event);
      if (event.type == ALLEGRO_EVENT_KEY_DOWN &&
            event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) {
         break;
      }
      if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) {
         break;
      }

      Radian rot_x(0);
      Radian rot_y(0);
      Vector3 translate(Vector3::ZERO);

      switch (event.type) {
         case ALLEGRO_EVENT_TIMER:
            redraw = true;
            break;

         case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN:
            if (event.mouse.button == 1)
               lmb = true;
            if (event.mouse.button == 2)
               rmb = true;
            break;

         case ALLEGRO_EVENT_MOUSE_BUTTON_UP:
            if (event.mouse.button == 1)
               lmb = false;
            if (event.mouse.button == 2)
               rmb = false;
            if (!lmb && !rmb)
               al_show_mouse_cursor(display);
            break;

         case ALLEGRO_EVENT_MOUSE_AXES:
            if (lmb) {
               rot_x = Degree(-event.mouse.dx * 0.13);
               rot_y = Degree(-event.mouse.dy * 0.13);
            }
            if (rmb) {
               translate.x = event.mouse.dx * 0.5;
               translate.y = event.mouse.dy * -0.5;
            }
            if (lmb || rmb) {
               al_hide_mouse_cursor(display);
               al_set_mouse_xy(display,
                  al_get_display_width(display)/2,
                  al_get_display_height(display)/2);
            }
            break;

         case ALLEGRO_EVENT_KEY_DOWN:
         case ALLEGRO_EVENT_KEY_UP: {
            const bool is_down = (event.type == ALLEGRO_EVENT_KEY_DOWN);
            if (event.keyboard.keycode == ALLEGRO_KEY_W)
               forward = is_down;
            if (event.keyboard.keycode == ALLEGRO_KEY_S)
               back = is_down;
            if (event.keyboard.keycode == ALLEGRO_KEY_A)
               left = is_down;
            if (event.keyboard.keycode == ALLEGRO_KEY_D)
               right = is_down;
            break;
         }

         case ALLEGRO_EVENT_DISPLAY_RESIZE: {
            al_acknowledge_resize(event.display.source);
            int w = al_get_display_width(display);
            int h = al_get_display_height(display);
            mWindow->resize(w, h);
            mCamera->setAspectRatio(Real(w) / Real(h));
            redraw = true;
            break;
         }
      }

      moveCamera(event.any.timestamp, rot_x, rot_y, translate);
   }
}

void Example::moveCamera(double timestamp, Radian rot_x, Radian rot_y,
   Vector3 & translate)
{
   const double time_since_move = timestamp - lastMoveTime;
   const float move_scale = MOVE_SPEED * time_since_move;

   if (forward) {
      translate.z = -move_scale;
   }
   if (back) {
      translate.z = move_scale;
   }
   if (left) {
      translate.x = -move_scale;
   }
   if (right) {
      translate.x = move_scale;
   }

   if (translate == Vector3::ZERO) {
      // Continue previous motion but dampen.
      translate = last_translate;
      current_speed -= time_since_move * 0.3;
   }
   else {
      // Ramp up.
      current_speed += time_since_move;
   }
   if (current_speed > 1.0)
      current_speed = 1.0;
   if (current_speed < 0.0)
      current_speed = 0.0;

   translate *= current_speed;

   mCamera->yaw(rot_x);
   mCamera->pitch(rot_y);
   mCamera->moveRelative(translate);

   last_translate = translate;
   lastMoveTime = timestamp;
}

void Example::animate(double now)
{
   const double dt0 = now - startTime;
   const double dt = now - lastRenderTime;

   // Animate the character.
   Entity *ent = mSceneMgr->getEntity("Ninja");
   AnimationState *anim = ent->getAnimationState("Walk");
   anim->addTime(dt);

   // Move the light around.
   Light *light = mSceneMgr->getLight("Light1");
   light->setPosition(Vector3(300 * cos(dt0), 300, 300 * sin(dt0)));
}

void Example::nextFrame()
{
   const double now = al_get_time();
   animate(now);
   render();
   lastRenderTime = now;
}

int main(int argc, char *argv[])
{
   (void)argc;
   (void)argv;
   ALLEGRO_DISPLAY *display;

   if (!al_init()) {
      return 1;
   }
   al_install_keyboard();
   al_install_mouse();

   al_set_new_display_flags(ALLEGRO_OPENGL | ALLEGRO_RESIZABLE);
   display = al_create_display(WIDTH, HEIGHT);
   if (!display) {
      return 1;
   }
   al_set_window_title(display, "My window");

   {
      Example app(display);
      app.setup();
      app.mainLoop();
   }

   al_uninstall_system();

   return 0;
}

/* vim: set sts=3 sw=3 et: */
Nice? :)
/* Less noise. More signal. */
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.
User avatar
so0os
Bugbear
Posts: 833
Joined: Thu Apr 15, 2010 7:42 am
Location: Poznan, Poland
x 33

Re: C interface as core feature

Post by so0os »

Wow! I haven't looked at allegro 5 yet, but I guess that makes it the winner :D
Sos Sosowski :)
http://www.sos.gd
User avatar
jacmoe
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 20570
Joined: Thu Jan 22, 2004 10:13 am
Location: Denmark
x 179
Contact:

Re: C interface as core feature

Post by jacmoe »

I think I'll test it in Windows first. :)
  • Linux: You create the window using Allegro and then tell Ogre to use the current GL context.
  • Windows: Ogre creates the window, and Allegro is instructed to use it by means of win_set_window(hwnd).
Allegro looks like a winner - for input (and maybe other things)
It's much easier than wrapping yet another C++ library. :wink:
/* Less noise. More signal. */
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.
User avatar
Zonder
Ogre Magi
Posts: 1168
Joined: Mon Aug 04, 2008 7:51 pm
Location: Manchester - England
x 73

Re: C interface as core feature

Post by Zonder »

I did this a while back for VB6 unfortunatly I lost my work on this :( I actually created an OgreCAPI file that I included with the build of ogre

The approach I used was this

Code: Select all

[Class Name]_[Method_Name](OBJECT_HANDLE, ....) 
Class_Name and Method name retained the casing from the original method, OBJECT_HANDLE is the memory pointer for the actual live ogre class

so in the case of

Code: Select all

DLL void create_camera(const char* name);
this would be

Code: Select all

DLL OBJECT_HANDLE Camera_ctor(const char* name, <<OBJECT_HANDLE for a SceneManager>> );
and

Code: Select all

camera_set_near_clip_distance(const char* camera_name, double d);
this would be

Code: Select all

Camera_setNearClipDistance(OBJECT_HANDLE, double d);
You would have a Create / Destroy method on all classes as well

The acutual methods exposed are all public methods from all inherited classes I belive the setNearClip is part of somthing else can't remember off hand I also toyed with putting the namespace before the class name as well but never did that. I did it all by hand as well but a parser could be wrote which I belive the MOGRE system already has for the C++ side you would just need to omit C instead and probably just have a class list of classes to expose as all isn't reall needed.

Essentially you are doing the same as me though. I am sure I did somthings slightly different in places but I can't remember any off hand (it was ogre 0.4 I think I did this for)
There are 10 types of people in the world: Those who understand binary, and those who don't...
User avatar
so0os
Bugbear
Posts: 833
Joined: Thu Apr 15, 2010 7:42 am
Location: Poznan, Poland
x 33

Re: C interface as core feature

Post by so0os »

We don't want to use a tool to generate the stuff for us, but create an interface with a pleasant feel to it ;) The names you gave look like from a tool (especially the _ctor thingie), I suppose all_small_caps_and_lots_of_underscores_is_much_more_like_c
Sos Sosowski :)
http://www.sos.gd
Post Reply