Multiple Objects (and an API)

Moving forward. Made a little more progress on Equinox. One of the things that I disliked the most about renderran was the fact that it was kind of hard to create new scenes. specially for those not familiar with the code. The way the code was written you could only create objects by making instances of them, knowing where to place them in the code and how to access their parameters. I talked with some more experienced programmers about how I could make scene creation easier. I was thinking about creating file format that I could parse. My friends recommended that I first create an API, and since I was writing the code in C, I could then create some Python bindings with ctypes. I thought these where great ideas since I have never written a rendering API and never written python bindings for C. Even more learning to do!

I have seen on several rendering APIs that there is usually a “begin” statement. For RenderMan it is RiBegin(), Arnold has AiBegin so naturally I wanted Equinox to use EiBegin(). This placed me in a spot that I had not been before. I new that EiBegin would do a lot of initialization of the necessary defaults for a scene to be rendered. Things such as default resolution and image output. I also knew that I needed a “world” structure. A structure that would hold the data of my rendering world, such as an array of lights, materials, textures, cameras and objects. I gave other APIs a look and I saw that none of them passed a world structure around to every function. This being the case, I realized that I needed the world to be global variable.

I am sure that at some point I will need other global variables so I needed to figure out a way to create global variables when someone used the Equinox api. The goal was to be able to do this:

[C]
#include "equinox.h"

int main() {
    // Initialize the Equinox rendering environment
    EiBegin();
    ....
}
[/C]

Getting the global variables to work was a bit tricky. I wanted the global variables to be created automatically so I created a Globals.h file. This created som issues mainly because I would get redefined symbols if I placed the global file in any of the source files that would end up in my equinox library. I did some reading and consulting and I figured that I needed to make sure that Globals.h was only included once and only in the main file. Everywhere else all references to my global variables would just need to use the “extern” keyword. The commit for these changes can be found on github. Here is an image generated with the very early API.

and here is the code that generated the image

[C]
#include "equinox.h"

int main() {

  EiBegin();
  // Create the camera
  EtNode cam = EiNode("ortho_camera");

  int i;
  for (i = -250; i <= 250; i+=50) {
    EtNode sph = EiNode("sphere");
    EiNodeSetFlt(&sph,"radius",25.f);
    EiNodeSetFlt(&sph,"zmin",-25.f);
    EiNodeSetFlt(&sph,"zmax",25.f);
    EiNodeSetPnt(&sph,"center",i,0,0);
  }
  // start the renderer
  EiRender();
  return 0;
}
[/C]