Upcoming Events
Unite 2010
11/10 - 11/12 @ Montréal, Canada

GDC China
12/5 - 12/7 @ Shanghai, China

Asia Game Show 2010
12/24 - 12/27  

GDC 2011
2/28 - 3/4 @ San Francisco, CA

More events...
Quick Stats
84 people currently visiting GDNet.
2406 articles in the reference section.

Help us fight cancer!
Join SETI Team GDNet!
Link to us Events 4 Gamers
Intel sponsors gamedev.net search:

"-almost there" "I can't shake him!"

So now that we've got our rendererInterface class defined, we can now just briefly cover how our rendererFactory object will work. To create and initialize a rendererInterface object, we'll need to follow a few steps that we can encapsulate within this factory object.

  1. decide which implementation the user wants (ie. OpenGL or Direct3D)
  2. use run-time linking to load up the proper DLL
  3. create and initialize the rendererInterface object
  4. return it for use to the programmer

Simple, eh? That's what usually happens when you break down your problem into smaller tasks.

//rendererFactory.cpp
HRESULT rendererFactory::initInterface(TCHAR *szType)
{
  if(strcmp(szType, "OpenGL") == 0)
  {
    //we're using OpenGL for our renderer
    m_hDLL = LoadLibraryEx("GameOGLRenderer.dll",NULL,0);
    if(!m_hDLL)
    {
      MessageBox(NULL,
             "Error loading up GameOGLRenderer.dll",
             "Fatal Error",
             MB_OK | MB_ICONERROR);

      return E_FAIL;
    }
  }
  else
  {
    //we're using Direct3D for our renderer
    m_hDLL = LoadLibraryEx("GameD3DRenderer.dll",NULL,0);
    if(!m_hDLL)
    {
      MessageBox(NULL,
             "Error loading up GameD3DRenderer.dll",
             "Fatal Error",
             MB_OK | MB_ICONERROR);

      return E_FAIL;
    }

  }

  //okay now that we've got our dll loaded, let's get a pointer
  //to our createInterface function
  CREATERENDERERINTERFACE CreateInterface = 0;
  HRESULT hr;

  CreateInterface = (CREATERENDERERINTERFACE)GetProcAddress(m_hDLL,
                                "createRendererInterface");

  hr = CreateInterface(&m_pRenderer);
  if(FAILED(hr)){
    MessageBox(NULL,
           "Error using our createInterface function",
           "FATAL Error", MB_OK | MB_ICONERROR);
    m_pRenderer = NULL;
    return E_FAIL;
  }

  return S_OK;
}

void rendererFactory::destroyInterface()
{
  DESTROYRENDERERINTERFACE DestroyInterface = 0;
  HRESULT hr;

  DestroyInterface = (DESTROYRENDERERINTERFACE)GetProcAddress(m_hDLL,
                            "destroyRendererInterface");

  hr = DestroyInterface(&m_pRenderer);
  if(FAILED(hr)){
    MessageBox(NULL,
               "Error using our destroyInterface function",
               "GameFramework Error", MB_OK);

    m_pRenderer = NULL;
  }
}

Well, this might look a little complicated, but again, reread the other GameDev.net article on using DLL's and you'll see that it's not so bad. We're just getting a function pointer into our DLL to the proper creating/destroying function. As a reminder, we need to do this in order to deal with the name mangling that accompanies DLL development.

What's Included?

With this article, I've provided all of the source code listed herein, as well as a TestFramework project, which demonstrates our rendering functionality in action. It's a project built with Visual Studio 6.0.

What we learned

Well I'm hoping that you had as much fun as I did! We covered quite a bit of material in this article, so hopefully I haven't glossed over things too much. If you have any corrections, or questions, please don't hesitate to email me.

References

  1. Gamma, Helm, Johnson & Vlissides. Design Patterns: Elements of reusable Object-Oriented Software, Addison Wesley, 1995.



Contents
  Introduction
  Static .lib and the DLL
  Conclusion

  Source code
  Printable version
  Discuss this article

The Series
  Part I
  Part II
  Part III
  Part IV