Masz interfejs, załóżmy IRenderer. Jak wiadomo, ma on same metody czysto wirtualne. Masz klasę odpowiedzialną za logikę gui - CGUI. Dodajesz do swojego GUI nowe przyciski (CButtons), ikonki (CIcon) itp (pGui->addObject(pButton)). Na końcu przekazujesz do klasy renderującej (wydziedziczonej po IRenderer) obiekt klasy CGUI, który zawiera wszystkie informacje o położeniu przycisków, ich stanie itp. Renderujesz (pOpenGLGuiRenderer->render(pGui) lub pDXRenderer->render(pGui)).
Ja sobie wyobrażam to tak. Nie pisałem jeszcze wlasnego GUI, więc możliwe, że projekt jest zły :)
Wadą tego są wszędobylskie funkcje wirtualne i dziedziczenie, jednak na dobrą sprawę, nie jest to duży narzut.