J'essaie de créer un moteur de jeu 2D en utilisant OpenGL ES 2.0 (iOS pour l'instant). J'ai écrit la couche Application dans Objective C et un RendererGLES20 autonome séparé en C ++. Aucun appel spécifique à GL n'est effectué en dehors du moteur de rendu. Cela fonctionne parfaitement.
Mais j'ai des problèmes de conception lors de l'utilisation de shaders. Chaque shader a ses propres attributs et uniformes uniques qui doivent être définis juste avant l'appel de dessin principal (glDrawArrays dans ce cas). Par exemple, pour dessiner une géométrie, je ferais:
void RendererGLES20::render(Model * model)
{
// Set a bunch of uniforms
glUniformMatrix4fv(.......);
// Enable specific attributes, can be many
glEnableVertexAttribArray(......);
// Set a bunch of vertex attribute pointers:
glVertexAttribPointer(positionSlot, 2, GL_FLOAT, GL_FALSE, stride, m->pCoords);
// Now actually Draw the geometry
glDrawArrays(GL_TRIANGLES, 0, m->vertexCount);
// After drawing, disable any vertex attributes:
glDisableVertexAttribArray(.......);
}
Comme vous pouvez le voir, ce code est extrêmement rigide. Si je devais utiliser un autre shader, disons effet d'entraînement, j'aurais besoin de passer des uniformes supplémentaires, des attributs de vertex, etc. En d'autres termes, je devrais changer le code source du rendu RendererGLES20 juste pour incorporer le nouveau shader.
Existe-t-il un moyen de rendre l'objet shader totalement générique? Comme si je voulais juste changer l'objet shader et ne pas m'inquiéter de la recompilation de la source du jeu? N'importe quel moyen de rendre le rendu indépendant des uniformes et des attributs, etc.? Même si nous devons transmettre des données aux uniformes, quel est le meilleur endroit pour le faire? Classe de modèle? La classe de modèle connaît-elle les uniformes et les attributs spécifiques au shader?
Spectacles suivants: Classe d'acteur:
class Actor : public ISceneNode
{
ModelController * model;
AIController * AI;
};
Classe de contrôleur de modèle: classe ModelController {class IShader * shader; int textureId; teinte vec4; float alpha; struct Vertex * vertexArray; };
La classe Shader contient simplement l'objet Shader, compilant et liant des sous-routines, etc.
Dans la classe Game Logic, je rend en fait l'objet:
void GameLogic::update(float dt)
{
IRenderer * renderer = g_application->GetRenderer();
Actor * a = GetActor(id);
renderer->render(a->model);
}
Veuillez noter que même si Actor étend ISceneNode, je n'ai pas encore commencé à implémenter SceneGraph. Je le ferai dès que je résoudrai ce problème.
Des idées pour améliorer cela? Modèles de conception associés, etc.?
Merci d'avoir lu la question.