2016-10-09 2 views
-1

Ich bin dabei, einige Teile einer Rendering-Engine zu refaktorieren, und frage mich, ob ein Shader wirklich wissen sollte, dass es OpenGL-Kontext ist. Gegenwärtig verfügt jeder Shader über eine bind() - und compileShader() -Methode, die nichts anderes tun, als den OpenGL-Kontext für die eigentliche Aufgabe aufzurufen.Software Architektur: OpenGL Shader erstellen und kompilieren

Es scheint üblich, diese Methoden im Shader implementiert zu haben - aber ist es wirklich eine gute Übung? Sollte es nicht besser sein, wenn der Kontext einen Shader erstellt, kompiliert und bindet? Und muss ein Shader unbedingt seinen Kontext kennen?

Einige Codefragmente unten. Hier sehen Sie, dass der Shader nur Kontextmethoden aufruft, und daher könnte die Kompilierung ein Anliegen des Kontextes sein und nicht der Shader selbst.

ShaderPtr hdm::shader::fancy_lines_3d_ptr; 
fancy_lines_3d_ptr->compileShader(vert_src.c_str(), frag_src.c_str(), vlayout); 

void Shader::bind() 
{ 
    assert(_shaderObj); 
    _context.bindShader(_shaderObj); 
} 


void Shader::compileShader(const string &vertexSrc, 
          const string &fragmentSrc, 
          hdm::rendering::VERTEX_LAYOUT vlayout) 
{ 
    _context.compileShader(_shaderObj, vertexSrc.c_str(), vertexSrc.length(), SHADER_TYPE::ST_VERTEX); 
    _context.compileShader(_shaderObj, fragmentSrc.c_str(), fragmentSrc.length(), SHADER_TYPE::ST_FRAGMENT); 
    _context.bindAttributeLocations(vlayout, _shaderObj); 
    _context.linkShader(_shaderObj); 
} 
+0

Warum der Downvote? – benjist

Antwort

1

Wenn es um OpenGL und OOP-Programmierung geht, können keine klaren Antworten gegeben werden. Aufgrund der Art, wie die OpenGL-API den globalen Status mischt, bestimmte Objekttypen, die auf einen einzelnen Kontext beschränkt sind, und andere Objekttypen, die unter mehreren Kontexten geteilt werden können, ist es sehr schwierig, wenn nicht unmöglich, OpenGL perfekt in ein OOP-Modell zu mappen.

Sollte es nicht besser sein, den Kontext einen Shader erstellen, kompilieren und binden zu lassen?

Ja! Tatsächlich ist es sehr sinnvoll, dass ein OpenGL-Kontext eine Factory für OpenGL-Objekte ist.

Und muss ein Shader unbedingt seinen Kontext kennen?

Eigentlich sollte jedes OpenGL-Objekt die Kontexte kennen, zu denen es gehört. Ich empfehle, dies über eine dedizierte abstrakte Kontextreferenzklasse zu implementieren; von dieser Klasse ableiten eine einzigen Kontext Referenz, die durch Objekte instanziiert ist, die nicht zugegriffen werden kann (Shadern, Programme, Framebuffer-Objekte, vaos, ...) und eine gemeinsamen Kontext Referenz, die durch Objekte instanziiert ist, die sind gemeinsam nutzbare (Bilder, Texturen , Pufferobjekte, ...).

Und dann sollten Sie irgendwie implementieren eine Möglichkeit, Context-Sharing-Setup zu verfolgen und diese in den gemeinsamen Kontext Verweis zuordnen.

Verwandte Themen