Irix > Programmieren, Kompilieren
Eine harte Nuss für C++ Gurus
Brombaer:
Hört sich ja ganz schön fies an ::)
Wie wäre es denn wenn die abgeleitete Klasse gar kein f() definiert (wodurch f der Oberklasse aufgerufen wird) bzw. a::f() aufruft ? Das ist doch kein Laufzeitproblem, wenn ich das richtig verstehe, jede Klasse sollte ja wissen wie der Shader zu deaktivieren ist.
Gruß
Matthias
hchris:
Moin,
koenntest Du nicht einfach jedes unterschiedliche f() in seine eigene kleine (Wrapper-)Klasse stecken und dann als Methode aufrufen ? Damit funktioniert der Vergleich ueber RTTI wieder.
Gruesse,
Chris
majix:
@Matthias:
Ich verstehe nicht ganz, was Du meinst... f soll ja gerade den Shader deaktivieren, und das kann ja von Klasse zu Klasse unterschiedlich sein. Beispiel: Environment Texture Mapping, hier würde f dann glDisable(GL_TEX_GEN_S) etc aufrufen.
@Chris:
Wäre eine Möglichkeit, aber solche komplizierten Konstrukte wollte ich vermeiden.
Ist eigentlich echt ein Witz: Ich will einfach nur die Pointer auf die Funktion vergleichen, genau diese Adressen, die im VTABLE stehen, nur C++ scheint mich da nicht ran zu lassen. Vielleicht schaffe ich es ja doch durch geschicktes casten, da hatte ich gestern zwar keinen Erfolg mit, aber ich werde es nochmals versuchen. Das MUSS doch irgendwie gehen.
Grüße,
Kaya
Jasper:
--- Zitat ---
Es hierbei um folgendes: Ich habe verschiedene Shaderklassen, und jede Klasse besitzt eine virtuelle Methode zum aktivieren des Shaders und eine zum deaktivieren. Wenn ich nun einen neuen Shader aktiviere, dessen Deaktivierungs-Funktion mit der des aktuellen Shaders übereinstimmt, dann brauch ich den alten auch erst gar nicht zu deaktivieren. Spart ein paar OpenGL-Aufrufe. Denn in vielen Fällen werden unterschiedlich Shader identisch dektiviert, aber verschieden aktiviert.
--- Ende Zitat ---
Hallo Kaya,
generell finde ich es keine so tolle Idee, das Laufzeitsystem aus Performancegründen überlisten zu wollen. Meistens weder portabel noch nachvollziehbar. Ausserdem verbirgst Du dann die Implementierung nicht vor dem verwendenden Programm.
Du könntest z.B. Metainformationen mittels (leeren) Interfaces und Mehrfachvererbung organisieren, ähnlich wie das in Java geht, die z.B. nur klassifizieren, welche Shader eine gemeinsame Deaktivierung besitzen. Dann müsstest Du mit RTTI an die gewünschte Information kommen können. Ein optimierender Compiler sollte da nicht viel langsameren Code generieren.
Gruss
JM
sgt_barnes:
Also das wäre mein Vorschlag (ist dem von Chris ähnlich):
Zuerst ein paar Basisklassen:
--- Code: ---
class Activator
{
public:
virtual void activate () = 0;
};
class Deactivator
{
public:
virtual void deactivate () = 0;
};
--- Ende Code ---
Von denen leitest Du für jede Möglichkeit, die Dir im Moment einfällt, eine Klasse ab. Diese registrieren sich bei einem Factory-Objekt:
--- Code: ---
class Factory
{
public:
static Activator *getActivator (const char *name);
static Deactivator *getDeactivator (const char *name);
static registerActivator (Activator *act, const char *name);
static registerDeactivator (Deactivator *deact, const char *name);
...
};
--- Ende Code ---
Die Shader-Basis-Klasse:
--- Code: ---
class Shader
{
public:
Shader (Activator *a, Deactivator *d)
: m_activator (a)
, m_deactivator (b)
{ }
virtual ~Shader ()
{
delete (m_activator);
delete (m_deactivator);
}
Activator *activator () { return (m_activator); }
Deactivator *deactivator () { return (m_deactivator); }
void begin ()
{
if ((m_lastActivator == 0) || (m_lastActivator != m_activator)
{
m_activator->activate ();
m_lastActivator = m_actiavator ();
}
}
void end ()
{
if ((m_lastDeactivator == 0) || (m_lastDeactivator != m_deactivator)
{
m_deactivator->activate ();
m_lastDeactivator = m_deactivator ();
}
}
private:
Activator *m_activator;
Deactivator *m_deactivator;
static Activator *m_lastActivator;
static Deactivator *m_lastDeactivator;
};
// static initializations (lives in Shader.cpp file)
Activator *Shader::m_lastActivator = 0;
Deactivator *Shader::m_lastDeactivator = 0;
--- Ende Code ---
Jetzt bastelst Du Dir einen Shader zusammen:
--- Code: ---
class MyShader : public Shader
{
public:
MyShader ()
: Shader (Factory::getActivator ("test"), Factory::getDeactivator ("test"))
{ }
...
};
--- Ende Code ---
Das letzte Problem ist jetzt, dass Du eigentlich die Shader::begin() und Shader::end() nicht implementieren kannst, wenn Du nicht weisst, welcher Shader als nächstes kommt. Aber das sollte auch kein Problem sein, wenn Du beide Funktionen in die Renderer-Klasse einbaust, die die Shader benutzt.
MfG,
Tilmann
Navigation
[0] Themen-Index
[#] Nächste Seite
[*] Vorherige Sete
Zur normalen Ansicht wechseln