Sto cercando di creare un motore di gioco 2D usando OpenGL ES 2.0 (iOS per ora). Ho scritto il livello Applicazione in Obiettivo C e un RendererGLES20 autonomo separato in C ++. Non viene effettuata alcuna chiamata specifica GL al di fuori del renderer. Funziona perfettamente.
Ma ho alcuni problemi di progettazione quando uso gli shader. Ogni shader ha i suoi attributi e uniformi unici che devono essere impostati appena prima della chiamata principale (in questo caso glDrawArrays). Ad esempio, per disegnare una geometria farei:
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(.......);
}
Come puoi vedere questo codice è estremamente rigido. Se dovessi usare un altro shader, per esempio l'effetto a catena, avrei bisogno di passare uniformi extra, attributi di vertice ecc. In altre parole, dovrei cambiare il codice sorgente di rendering di RendererGLES20 solo per incorporare il nuovo shader.
C'è un modo per rendere l'oggetto shader totalmente generico? Mi piace Cosa succede se voglio solo cambiare l'oggetto shader e non preoccuparmi della ricompilazione della fonte di gioco? Qualche modo per rendere agnostico il renderer di uniformi e attributi ecc.? Anche se dobbiamo trasferire i dati alle uniformi, qual è il posto migliore per farlo? Classe di modello? La classe del modello è a conoscenza delle uniformi e degli attributi specifici dello shader?
Spettacoli seguenti: Classe attori:
class Actor : public ISceneNode
{
ModelController * model;
AIController * AI;
};
Classe controller modello: class ModelController {class IShader * shader; int textureId; tinta vec4; float alpha; struct Vertex * vertexArray; };
La classe Shader contiene solo l'oggetto shader, compilando e collegando le sub-routine ecc.
Nella classe Game Logic sto realizzando il rendering dell'oggetto:
void GameLogic::update(float dt)
{
IRenderer * renderer = g_application->GetRenderer();
Actor * a = GetActor(id);
renderer->render(a->model);
}
Si noti che anche se Actor estende ISceneNode, non ho ancora iniziato a implementare SceneGraph. Lo farò non appena risolverò questo problema.
Qualche idea su come migliorare questo? Modelli di progettazione correlati ecc.?
Grazie per aver letto la domanda.