Klassendesign und scope



  • Hallo,

    ich habe 4 Matrizen.

    glm::mat4 projection_matrix;
    glm::mat4 view_matrix;
    glm::mat4 translate_view;
    glm::mat4 scale_view;
    

    Diese müssen für window, für shader, für Mausinteraktion, für Papierformat und für buttons zugänglich bzw. sichtbar sein.

    Nun habe ich eine Frage zum Klassendesign. Soll ich die 4 Variablen in eine Klasse packen? Wie stelle ich sicher, dass es für alle oben genannten zugänglich ist.


  • Mod

    Du wirst ja wahrscheinlich irgendwo Callbacks registrieren, die die Übergabe von Nutzdaten via void* erlauben. Das heißt, du musst sogar alles in irgendeinen zusammengesetzten Datentyp packen und dann ein Objekt davon mit zur Übergabe registrieren.

    Falls meine Antwort total veraltet sein sollte, möge mich jemand korrigieren. Ist eine Weile her, dass ich OpenGl gemacht habe.



  • also ich habe sie in meinen zarten versuchen (allerdings mit C) immer zum zugehörigen zu zeichnenden objekt, d.h. in die struktur, getan. in diesem fall also wohl zur "kamera". die buttons selbst sollten unter c++ eigentlich nicht einmal in die nähe der matrizen kommen, sondern eine funktion bzw. methode aufrufen, die eine funktion bzw. methode aufruft, die...

    weißt du, was ein klassendiagramm ist?



  • Danke für die Antworten 🙂

    @Wade1234 sagte in Klassendesign und scope:

    weißt du, was ein klassendiagramm ist?

    Ja, ungefähr. Ich habe den Eindruck, dass ich oft über die Frage stolpere, dass irgendwelche Variablen zugänglich sein sollten und frage deshalb, ob es dafür bewährte design-patterns oder ähnliches gibt. (Ich vernahm schon oft, dass auf globale Variablen unbedingt verzichtet werden sollte, als anti-pattern).

    OpenGL 3.2 mit wxWidgets funktioniert. Es ging anhand des empfohlenen Beispiels pyramid mit ein paar Änderungen (z.B. glad) und Vereinfachungen.

    class Frame : public wxFrame
    {
    public:
        Frame(const wxString& title, const wxPoint& pos, const wxSize& size);
    
    private:
        void OnHello(wxCommandEvent& event);
        void OnExit(wxCommandEvent& event);
        void OnAbout(wxCommandEvent& event);
    
        std::unique_ptr<GLCanvas> canvas;
    };
    
    
    class GLCanvas : public wxGLCanvas
    {
    public:
    
        GLCanvas(Frame* parent, const wxGLAttributes& canvas_attributes);
    
        void InitOpenGL(wxSizeEvent& event);
    
    private:
    
        void OnPaint(wxPaintEvent& event);
        void OnSize(wxSizeEvent& event);
        void OnMouse(wxMouseEvent& event);
    
        std::unique_ptr<wxGLContext> context;
        std::unique_ptr<Application> application;
    
        int gladLoaded;
    };
    

    Ich habe einfach den Eindruck, es sei zuviel ungeordnet über verschiedene Klassen, abgeleitete Klassen und Objekte in Klassen verteilt und wollte deshalb fragen, ob es bewährte Konzepte gibt, ein Durcheinander zu vermeiden.

    Man könnte z.B. sagen, die Matrizen gehören zu den shadern. Das Problem dabei ist, ich übergebe die gleichen Matrizen an zwei verschiedene shader, simple_shader und font_shader...

    @SeppJ sagte in Klassendesign und scope:

    Du wirst ja wahrscheinlich irgendwo Callbacks registrieren, die die Übergabe von Nutzdaten via void* erlauben.

    Bind(wxEVT_SIZE, &GLCanvas::InitOpenGL, this);
    
    Bind(wxEVT_PAINT, &GLCanvas::OnPaint, this);
    Bind(wxEVT_MOTION, &GLCanvas::OnMouse, this);
    
    Unbind(wxEVT_SIZE, &GLCanvas::InitOpenGL, this);
    Bind(wxEVT_SIZE, &GLCanvas::OnSize, this);
    

    Also bei wxWidgets habe ich dafür Bind gefunden. Connect gäbe es noch, aber Bind sei dynamischer. Oder von früher gibt es noch eine weitere Möglichkeit, habe ich gesehen...



  • Meiner Meinung gehören diese Matrizen in die Kamera-Klasse. Die Shader bekommen dann vom Kamera-Objekt die Matrizen als Input. Die Maus/Oberfläche verändert dann über Setter die Kamera-Position/Ausrichtung/Öffnungswinkel. Das Kamera-Objekt ist dann Teil deiner GrafikEngine. Die Grafik-Engine ist ein weiterse Objekt. Somit kommst du ohne globale Variablen aus.



  • @titan99_ sagte in Klassendesign und scope:

    Danke für die Antworten 🙂

    @Wade1234 sagte in Klassendesign und scope:

    weißt du, was ein klassendiagramm ist?

    Ja, ungefähr. Ich habe den Eindruck, dass ich oft über die Frage stolpere, dass irgendwelche Variablen zugänglich sein sollten und frage deshalb, ob es dafür bewährte design-patterns oder ähnliches gibt. (Ich vernahm schon oft, dass auf globale Variablen unbedingt verzichtet werden sollte, als anti-pattern).

    für genau solche probleme hat man klassendiagramme erfunden. bei design patterns hat nur schon jemand anderes seinen keks angestrengt und ein entsprechendes klassendiagramm erstellt.



  • @XMAMan Danke, so strukturiert es sich.

    @Wade1234 sagte in Klassendesign und scope:

    für genau solche probleme hat man klassendiagramme erfunden. bei design patterns hat nur schon jemand anderes seinen keks angestrengt und ein entsprechendes klassendiagramm erstellt.

    Also hier ist z.B. ein Klassendiagramm von wxGLCanvas (Leider Version 3.0.4, ich weiss nicht wie ich direkt zur aktuellen Version komme). Aber verstehe deine Antwort trotzdem nicht so ganz. Also ich kann sehen, dass es von wxWindows und wxEvtHandler erbt, also ist es ein Fenster und kann Events verarbeiten...



  • So wie ich @Wade1234 verstanden habe, sollst du selber ein Klassendiagramm von deinen Klassen (und deren Abhängigkeiten untereinander) erstellen - so daß du design-technisch die beste Möglichkeit findest, wo diese Daten einzubetten sind.



  • @titan99_ ja genau. Normalerweise entwickelt man erst das Klassendiagramm (und die ganzen anderen Diagramme) und dann wandelt man das in Code um, weil man sonst nur am hin- und herfrickeln ist. Das gilt natürlich nicht, wenn zu Übungszwecken o.ä. irgendwas ausprobiert werden soll.



  • Vereinfacht habe ich im Moment das Fenster mit GrafikEngine und MouseInput.

    class GLCanvas : public wxGLCanvas
    {
        std::unique_ptr<GraphicEngine> graphic_engine;
        MouseInput MouseInput;
    }
    

    In der GraphicEngine hat es vereinfacht die Camera oder View Klasse mit den Matrizen.

    class GraphicEngine
    {
        View view;
    }
    

    Eigentlich wäre es mir so wöhler:

    class GLCanvas : public wxGLCanvas
    {
        std::unique_ptr<GraphicEngine> graphic_engine;
        View view;
        MouseInput MouseInput;
    }
    

    Mal schauen, vielleicht ergibt es sich noch.

    Oder doch nicht?

    class GraphicEngine
    {
    public:
        //View& GetView() //const;
        View* GetView();
        //View GetView();
    private:
        View view;
    }
    

    @Wade1234 sagte in Klassendesign und scope:

    @titan99_ ja genau. Normalerweise entwickelt man erst das Klassendiagramm (und die ganzen anderen Diagramme) und dann wandelt man das in Code um, weil man sonst nur am hin- und herfrickeln ist. Das gilt natürlich nicht, wenn zu Übungszwecken o.ä. irgendwas ausprobiert werden soll.

    Also mit doxygen und graphviz?



  • @titan99_ sagte in Klassendesign und scope:

    @Wade1234 sagte in Klassendesign und scope:

    @titan99_ ja genau. Normalerweise entwickelt man erst das Klassendiagramm (und die ganzen anderen Diagramme) und dann wandelt man das in Code um, weil man sonst nur am hin- und herfrickeln ist. Das gilt natürlich nicht, wenn zu Übungszwecken o.ä. irgendwas ausprobiert werden soll.

    Also mit doxygen und graphviz?

    ich habe das immer mit visio oder einem einfachen blatt papier und bleistift gemacht. die beiden programme an sich kenne ich nicht, ich meine aber, dass doxygen bestehenden code in diagramme umwandelt. also wenn du ein haus bauen willst, zeichnest du ja auch erst pläne und ziehst dann die wände hoch. der grund dafür ist eben, dass sich pläne deutlich einfacher ändern lassen.😉


Log in to reply