Comece identificando o que você realmente precisa da parte "wrapper" da API. Geralmente, é muito, muito simples: você precisa dos recursos básicos (buffers, shaders, texturas, estado do pipeline) e uma maneira de usar esses recursos para construir um quadro enviando algumas chamadas de empate.
Tente manter qualquer lógica de alto nível fora da parte do invólucro da API. Se você implementar uma técnica inteligente de seleção de cenas nesta parte da API, agora você está pronto para duplicar essa lógica em todas as implementações de back-end. Isso exige muito esforço, portanto, mantenha-o simples. O gerenciamento de cenas deve fazer parte de uma parte de nível superior da API que usa o wrapper, em vez de fazer parte do próprio wrapper.
Escolha os alvos que você apoiará e entenda. É difícil escrever wrappers decentes para "tudo" e você provavelmente não precisa (provavelmente também não precisa escrever um único wrapper, como observado na resposta de Philipp ). É quase impossível escrever um invólucro decente se você ainda não conhece as APIs que irá embrulhar.
Avalie o estado da sua API regularmente. Em geral, ele deve ter uma área de superfície menor que as APIs agrupadas subjacentes; se você criar tipos de invólucros individuais para cada estrutura do D3D ou para cada chamada de função do OpenGL, provavelmente está saindo do curso.
Veja o que foi feito antes. Sokol e BGFX são APIs que fornecem níveis de agnosticismo que podem ser úteis para você e são relativamente fáceis de entender (especialmente o primeiro).