Render Manager



  • Hallo,

    Ich bin's schon wieder! 😃
    Und ich hab schon wieder eine Frage vorbereitet:

    Wie sollte eine Renderer-Klasse aussehen?

    Ich habe mittlerweile einige Klassen zusammen, und viele bringen "render()" mit. Eine kleine Kameraklasse hab ich auch schon. Daher erwartet Render auch einen Zeiger auf diese Kamera: render(kamera*)

    Nun stehen in der render(kamera*)-Methode einige Opengl-Befehle drin. Ich habe aber auch schon oft von renderer-Klassen gehört, die sich dann etwa durch ogl3 (statt 2.1) oder eine andere API ersetzen lassen. Aber wie soll ich die aufbauen?

    - konstruktor()
    - ~konstruktor()

    - <Funktionen zum zeichnen?>
    - get_frustum?
    - get_mv_matrix?

    - ...?

    Wie bau ich sowas möglichst gut? Was muss rein, darf nicht rein, um unabhängig zu bleiben? Meine provisorische render_manager-Klasse geht einfach alle objekte durch und ruft render() auf... 😃 🕶

    Wie ist das mit Texturen die geladen werden? Und in welchem Format sollte ich die Vertices dann ablegen? (wg. LINES, TRIANGLE_STRIP, QUAD, FAN, ...)
    Ich bin mir gar nicht sicher, ob ich eine Render-Klasse brauche...

    Danke, langeweile



  • Hallo

    Was redest du da? Ziemlich wirr. Falls ich das soweit kapiert habe: Besorg dir die OpenGL-API und schreibe ne Standard-Initialisierung für die OpenGL-Komponenten. Dann bastelste dir einfach nen Fesnterchen und schreibst die Rendering-Funktion. Für geometrische-Initialisierungen nutzt du eine extra Funktion, da die Rendering-Funktion genug zu tun hat. Das würed dann alles neu durchgelaufen, daher ist das nicht zu empfehlen.

    Ich habe mittlerweile einige Klassen zusammen, und viele bringen "render()" mit. Eine kleine Kameraklasse hab ich auch schon. Daher erwartet Render auch einen Zeiger auf diese Kamera: render(kamera*)

    Verstehe ich nicht. Welchen Renderer meinst du (den Programm-lokalen oder den "Klassenrenderer")?

    Nun stehen in der render(kamera*)-Methode einige Opengl-Befehle drin. Ich habe aber auch schon oft von renderer-Klassen gehört, die sich dann etwa durch ogl3 (statt 2.1) oder eine andere API ersetzen lassen. Aber wie soll ich die aufbauen?

    Falls ich das verstanden hab, siehe erste Zitatantwort. AFAIK wird sowas nicht gemacht, ergebe für mich auch garkeinen Sinn. Wäre ja auch Quatsch, dann würdest du die komplette Rendering-Schnittstelle neuinitialisieren. Reicht wenn du das einmal machst und dann deinen Rendering-Code darin aufrufst.

    Wie ist das mit Texturen die geladen werden?

    Ganz ruhig Brauner, step by step. Texturen kannst du (später) mit ner Extra-Lib laden (glaube GLAUX?) oder dir selber einen Decoder schreiben. Hatte ich auch so gemacht, mit der GLUT könnteste das ganze über die AUX_RGBImageRec laden, falls du dir beispielsweise eine Bitmap (ziemlich einfache Datenstruktur, Kompressionsverfahren werden auch auf diversen Seiten beschrieben (RLE_2, RLE_4, RLE_8 (Run length Encoding))) decodieren willst, brauchste nur noch die Standard-OpenGL Parameter wie glTexParameteri() und so'n Zeugs. Aber das nur so am Rande.

    Und in welchem Format sollte ich die Vertices dann ablegen?

    Hum, wo möchtest du sie denn ablegen? Als was? Wie? Falls du den Rendering-Teil meinst: Überlass es dem Programmierer, welche Ausgabe er machen möchte. Was spricht gegen "glBegin()-glEnd()"?

    Ich fand deinen Post etwas schlecht beschrieben und vorallem unübersichtlich. Vielleicht das nächste mal mehr Mühe geben, damit man deinen Post nicht wie Hyroglyphen entziffern muss. Danke (:

    EDIT:
    Vielleicht hier nochmal durchlesen:
    http://www.lighthouse3d.com/opengl/glut/
    Beschreibt das ganze schön, einfach und verständlich. (Und unten nicht das weiterblättern vergessen (;)

    Mfg.
    way



  • Okay,

    Also hab ich dich jetzt richtig verstanden?

    Eine Klasse die OpenGL wrapt und die dann statt der direkten Calls nehmen... Klingt gut.
    Texturen laden und anzeigen, blending ist kein Problem, aber mich stört es halt, wenn alle Quelldateien OGL-Calls enthalten. Sieht doof aus...

    Dann habe ich:
    ---
    class gl_wrapper (Hier steht dann der O-GL_kram auf low-level niveau drin)
    (mit ".draw_from_cam_pos(kamera*)", "swap_buffer()", ...)

    class kamera
    class texturmanager (#include ogl_wrapper_kram_für_textur_gen)
    class render_manager (mit std::vector für alle "renderbare_objekte")
    class renderbare_objekte (Enthält dann alles als Vertex-Arrays und eine Typ-Variable (FAN, STRIP, ...) pro Vertex-Array)
    class renderbare_objekte.render(kamera*) greift dann auf ogl_wrapper zu.
    ---

    Glfw und den ogl_wrapper instanziere ich dann direkt in der main() Funktion, und übergebe alle Calls hier hin...



  • Also die meisten Engines implementieren einen API Abstraction Layer(auch wenn sie ihn nicht so benennen). Um so etwas zu implementieren, musst du erst einmal Interfaces definieren, die dieser erfüllen muss.

    In einer Engine, an der auch ich mitentwickelt habe sind das folgende:

    IRenderDevice
    IResourceManager

    IDynamicResource
    IStaticResource

    und einige Spezialisierungen der Resourcen (Texturen, Shader, Meshes).

    Gruß Wally



  • Meine provisorische render_manager-Klasse geht einfach alle objekte durch und ruft render() auf...

    Bisher hat es sich bewaehrt, einfach eine Liste von Materialien abzuarbeiten.
    Da jedes Material deutlich unterschiedliche Daten und Vorgaenge benoetigt (zB zusaetzliche Tangent-Space Vektoren bei Normal-Mapping oder Extrahierung einer Kanten-Silhouette bei Cartoon-Shading), kann es diese selbststaendig aus den "Mesh-Rohdaten" erzeugen und in einer optimalen Vertexstruktur ablegen.

    Daher erwartet Render auch einen Zeiger auf diese Kamera

    Eine Kamera enthaelt eine Position, eine Ausrichtung (evtl gegeben durch ein Zielobjekt) und ein Field of View (Skalierung), im Endeffekt also eine Transformationsmatrix. Da die alle anderen Objekte auch haben, unterscheide ich gar nicht mehr zwischen Kameras und anderem Kram (vereinheitlicht zb das Rendern von Shadowmaps).

    Eine Klasse die OpenGL wrapt und die dann statt der direkten Calls nehmen...

    Das ist zwar nuetzlich aber erst wirklich sinnvoll wenn man tatsaechlich mehrere APIs benutzt und vor allem beherrscht weil man sonst schlecht ein gemeinsames Interface definieren kann.


Anmelden zum Antworten