[Projekt] StoneQuestCPP

Hier könnt ihr euch selbst, eure Homepage, euren Entwicklerstammtisch, Termine oder eure Projekte vorstellen.
Forumsregeln
Bitte Präfixe benutzen. Das Präfix "[Projekt]" bewirkt die Aufnahme von Bildern aus den Beiträgen des Themenerstellers in den Showroom. Alle Bilder aus dem Thema Showroom erscheinen ebenfalls im Showroom auf der Frontpage. Es werden nur Bilder berücksichtigt, die entweder mit dem attachement- oder dem img-BBCode im Beitrag angezeigt werden.

Die Bildersammelfunktion muss manuell ausgeführt werden, die URL dazu und weitere Details zum Showroom sind hier zu finden.

This forum is primarily intended for German-language video game developers. Please don't post promotional information targeted at end users.
scheichs
Establishment
Beiträge: 846
Registriert: 28.07.2010, 20:18

Re: [Projekt] StoneQuestCPP

Beitrag von scheichs »

Zudomon hat geschrieben: 09.03.2021, 11:44
Die Frage, die sich mir auch stellt ist, wie am besten präsentieren. Auf den FB-pages? Auf YT? Auf Twitter? Hier?

...
Ich bräuchte irgendwie eine zentrale Stelle... vielleicht doch die eigene Homepage? Bietet natürlich auch alles seine Vor- und Nachteile. Hier im Forum kann man lang und breit diskutieren. Auf FB ist das alles schon etwas eingeschränkter, dafür hat man aber ein Likesystem und neue Posts gehen auch nicht so schnell unter, weil die ja quasi die Threads darstellen. Und Twitter ist gut, um schnell kleine Posts raus zu hauen. Hab gelesen, dass man auf Twitter ruhig mehrmals am Tag was schreiben sollte... aber da wäre dann eben auch viel Belangloses.
Auf die Homepage geht kein Mensch. Vllt wenn's mal releast ist... aber ... nee ... selbst dann nimmer. Ich nutze meist Twitter als "Public Devlog". Dann gibts wohl noch Imgur und Reddit. Die kenne ich aber nicht so gut. FB sehe ich eher als Support-Platform wenns Probleme gibt für Leute, die sich wenig mit Internet auskennen. Discord ist eigentlich zeitgemässer/zielgerichteter.

Zusammengefasst würde ich sagen:
ZFX - Kommunikation mit anderen Entwicklern
Twitter/Imgur/Reddit - potenzielle Spieler/Marketing
FB - eher für die Casual-Spieler interessant
Discord - für Nähe zu aktiver Playerbase
Benutzeravatar
Schrompf
Moderator
Beiträge: 4849
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: [Projekt] StoneQuestCPP

Beitrag von Schrompf »

Ich schreibe meinen Kram nur hier rein, manchmal bei sppro.de, obwohl dort schon quasi tote Hose ist. tigsource.com kann ich empfehlen, da gibt's manchmal gute Kommentare, aber dort ist doch noch heftig was los, da geht sowas schnell unter. Und die haben dort einen seltsamen Fetisch für LowRes-PixelArt mit entsetzlichen Paletten. Ansonsten nehme ich noch Twitter, aber da krieg ich kaum Resonanz. Die meisten Follower habe ich dort gekriegt, nachdem ich mal einen uralten Screenshot unter der "Und was codet ihr so"-Frage eines berühmten VoxelDevs gepostet habe.

Reddit/Instagram und so wollte ich irgendwann mal machen, ist aber irgendwie abschreckend mit ihren "wir wollen Deine Werbung nicht"-Regeln.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
Zudomon
Establishment
Beiträge: 2253
Registriert: 25.03.2009, 07:20
Kontaktdaten:

Re: [Projekt] StoneQuestCPP

Beitrag von Zudomon »

Schrompf hat geschrieben: 09.03.2021, 15:41 Reddit/Instagram und so wollte ich irgendwann mal machen, ist aber irgendwie abschreckend mit ihren "wir wollen Deine Werbung nicht"-Regeln.
Reddit war auch meine Erfahrung... als ich damals das Video mit den 3D Wolken gemacht hatte, hab ich es da eingestellt und noch ein anderes ein wenig später. Beide von dem Bot da als Selfpromotion geflaggt. Hab dann erst kappiert, dass man das da gar nicht darf :D
Da ist Promotion ja quasi nur erlaubt, wenn es andere über dich was posten. Aber auch da darf es dann nicht immer der gleiche sein. Und es gibt da diese 10 zu 1 Regel, auf 10 Allerweltsposts darfst du einmal was von dir machen. Verstehe ja, dass die Werbung damit unterbinden wollen und eine gewisse Kultur damit einhalten. Aber damit ist es natürlich dann auch für unsereins eher uninteressant.
Matthias Gubisch
Establishment
Beiträge: 470
Registriert: 01.03.2009, 19:09

Re: [Projekt] StoneQuestCPP

Beitrag von Matthias Gubisch »

Zudomon hat geschrieben: 09.03.2021, 11:44 @OpenGL/Vulkan
Ja, ich würde gerne hinterher auf Vulkan umsteigen. OpenGL war für mich vor allem ein Zwischenschritt, um den Umstieg nicht direkt von DirectX9 aus machen zu müssen. Allerdings, und das habe ich mir jetzt auch mit der Engineüberabeitung gedacht, ist es sicher einfacher, erstmal wo es möglich ist, den alten Code zu übernehmen. Ist ja quasi dann wie ein Buch zu übersetzen. Wenn man da dann anfängt die Geschichte umzuschreiben, dauert es eventuell wesentlich länger als wenn man später dann nochmal entsprechend überarbeitet.
Meine Erfahrung war dass eine auf OpenGL/DirectX11 ausgelegte Engine zwar auf Vulkan/DirectX12 umgestellt werden kann, es aber nicht ganz trivial ist das dann so umzubauen dass man auch die Vorteile nutzten kann wenn man schon einen API wie Vulkan verwendet.
Das war mit ein ausschlaggebender Grund meine Engine nochmal von Grund auf neu zu schreiben. Die Umbauarbeiten um nicht am Ende OpenGL mit viel mehr Sourcecode zu haben waren einfach zu groß.
Multithreaded Rendering, GPU MemoryManagment, Anordnung und Aufteilung der Renderpasses (ok das war in meiner alten Version einfach schlecht gemacht...) sind ein paar der Dinge die nicht so einfach ein-/umzubauen waren.
Krishty hat geschrieben: 09.03.2021, 11:11
Matthias Gubisch hat geschrieben: 09.03.2021, 09:17BTW ich wuerde dir Vulkan anstatt OGL empfehlen, ist zwar erst mal etwas länglich für das erste Dreieck, aber dafür deutlich leichter zu debuggen als OGL und wenn man mal eine gewisse Abstraktionsebene in seiner Codebase erreicht hat merkt man eh nicht mehr viel davon ob jetzt OGL oder Vulkan dahinter steckt. Eine Portierung auf andere Plattformen und auch Mobile wird damit IMO auch leichter als mit OGL.
Mich hat von Vulkan immer abgehalten, dass der User eine bestimmte Mindest-Treiberversion braucht. Sind die Treiber jetzt garantiert präsent, wo Windows 7 weg ist?
Die Frage kann ich dir ehrlich gesagt gar nicht beantworten, da ich auf meinen System die Treiber immer aktuell halte, hab ich mich bisher noch nie wirklich damit beschäftigt
Bevor man den Kopf schüttelt, sollte man sich vergewissern einen zu haben
Spiele Programmierer
Establishment
Beiträge: 426
Registriert: 23.01.2013, 15:55

Re: [Projekt] StoneQuestCPP

Beitrag von Spiele Programmierer »

Matthias Gubisch hat geschrieben: 09.03.2021, 09:17 C++ ist halt die Sprache die man immer benutzten KANN.
Es ist sicher nicht immer das perfekte Werkzeug, aber eins das zu 99% funktioniert.
Ich kann damit halt von Assembler/Intrinsics bis hin zu OOP oder Templates alles machen. Diese Vielseitigkeit ist sicher auch verantwortlich fuer die weite Verbreitung.
Meine Erfahrung ist halt tatsächlich, dass C++ unglaublich gut darin ist, Dinge zu können, die du NICHT machen willst. Das geht schon bei so trivialen Dingen wie String-Funktionen und Daten in eine Datei schreiben los. Die standard C++ Streams sind zwar mehrfachvererbte Template-Klassen mit kryptischen Verwaltungsfunktionen und States, die unglaublich komplex selbst zu implementieren sind, aber du kannst z.B. nicht die Dateigröße reduzieren, ohne die Datei komplett zu überschreiben und musst hässliche wchar_t-Spielereien machen, weil sonst Windows-Benutzer viele Dateien gar nicht öffnen können.

Zu wie viel prozent die Alternativen funktionieren im Vergleich zu C++, ist schwer zu beurteilen.
MSVC++ kann für x64 übrigens KEIN Inline-Assembler. Rust und auch Zig können das. Rust und Zig können auch Intrinsics.

Wenn du wirklich tief in die OOP gehen willst, wird man bei Rust und Zig nicht glücklich. Dafür kannst du mit Rust-Traits viele Abstraktionen ausdrücken, die dir in C++ unmöglich ausgedrückt werden können (soviel zur Flexiblität) oder du verschiedene "Duck-Typed" Varianten mit "Concepts" usw. schreiben bzw. lernen müsstest. Die Template-Funktionalität von Rust ist tendentiell leicht reduziert, dafür gibt es ein "Compiler-Plugin"-System, dass bei weitem alles übersteigt, was du mit C++ hinbekommst. Zig ist hier absolut Spitze, die Flexiblität übertrifft C++ hier leicht.
Zudomon hat geschrieben: 09.03.2021, 11:44 Die Frage, die sich mir auch stellt ist, wie am besten präsentieren. Auf den FB-pages? Auf YT? Auf Twitter? Hier? Und meine Motivation mich überhaupt so selbst zu dokumentieren lässt eh zu wünschen übrig.
Für ein technisches Publikum: Hier. ;)

Auch wenn ich selten was in die Projektthemen schreibe, habe ich dein Projekt gerne verfolgt. Für Facebook und Twitter, könntest du mich vermutlich nicht überreden.
D-eath
Beiträge: 51
Registriert: 28.08.2009, 19:37
Alter Benutzername: TrunkZ
Echter Name: Thomas

Re: [Projekt] StoneQuestCPP

Beitrag von D-eath »

Im Endeffekt haben die Kollegen ja alles gesagt. Wenn du doch noch C++ machen solltest, kann ich dir CMake mit vcpkg ans Herz legen. Ist zwar eine Einstiegshürde, aber Dependency Management wird damit unglaublich vereinfacht, vor allem, wenn du dann Visual Studio benutzt. Ich benutze es in meiner eigenen Engine (nach Versuchen mit Conan und Hunter) und es fluppt.
Viel Spaß beim Lernen!
Benutzeravatar
Zudomon
Establishment
Beiträge: 2253
Registriert: 25.03.2009, 07:20
Kontaktdaten:

Re: [Projekt] StoneQuestCPP

Beitrag von Zudomon »

Ja, ich werde es mit C++ probieren. Kannst du nochmal genauer erklären, was du damit meinst? Also die Vorteile? Aus Anfängersicht kann ich nämlich damit nicht viel anfangen. Ich mach VC auf, schreib das Programm rein und drück Play... "Anfängerkenntnisstand" :D
D-eath
Beiträge: 51
Registriert: 28.08.2009, 19:37
Alter Benutzername: TrunkZ
Echter Name: Thomas

Re: [Projekt] StoneQuestCPP

Beitrag von D-eath »

Naja, falls du mal cross-platform gehen möchtest, was sich ja empfiehlt, hast du zumindest einen guten Buildfile-Generator (kann bspw. Ninja generieren) und VS kann nativ mit CMake-Projekten umgehen. Außerdem kannst du mit vcpkg halt Libraries wie Assimp, GLFW, GLEW, ..., laden und einfach nutzen, ohne dich mit dem ganzen Trara drumherum rumzuschlagen.
Matthias Gubisch
Establishment
Beiträge: 470
Registriert: 01.03.2009, 19:09

Re: [Projekt] StoneQuestCPP

Beitrag von Matthias Gubisch »

Kann da nur zustimmen vcpkg macht das einbinden externer libs echt deutlich einfacher und das Leben damit angenehmer ;)
Die CMake Unterstützung von VS muss ich jetzt auch mal probieren, aber ich scheue mich noch immer meine Projekte darauf umzustellen.
Bevor man den Kopf schüttelt, sollte man sich vergewissern einen zu haben
Benutzeravatar
Zudomon
Establishment
Beiträge: 2253
Registriert: 25.03.2009, 07:20
Kontaktdaten:

Re: [Projekt] StoneQuestCPP

Beitrag von Zudomon »

Kann man diese Trennung zwischen .h und .cpp Dateien eigentlich vermeiden? In Delphi hat man Header und Implementation ja in einer Datei.
(Soviel zu den Guidelines :D hahaha)
Matthias Gubisch
Establishment
Beiträge: 470
Registriert: 01.03.2009, 19:09

Re: [Projekt] StoneQuestCPP

Beitrag von Matthias Gubisch »

Kurz Nein.

Du kannst versuchen das ganze mittels Modules zu machen, aber selbst da wirst du die Trennung vermutlich nicht komplett vermeiden können.
Ist aber ein C++20 Feature und noch nicht von allen Compileren komplett supported.
Ich selbst hab noch nicht so richtig damit experimentiert, gibt aber hier im Forum einen Thread der sich mit dem Thema beschäftigt und demnach scheint das auch alles nicht sonderlich toll zu sein.
Bevor man den Kopf schüttelt, sollte man sich vergewissern einen zu haben
NytroX
Establishment
Beiträge: 360
Registriert: 03.10.2003, 12:47

Re: [Projekt] StoneQuestCPP

Beitrag von NytroX »

Jain.

Also ich versuche es größtenteils, wenn ich doch mal wieder was in C++ machen muss.

Und so gehts (ein Vorschlag):
- Nimm eine main.cpp mit nur der main-Funktion und ansonsten nur *.h dateien mit den kompletten klassen/structs/funktionen drin
- Erinnerung: #include copy-pasted nur Code
- Alle Dependencies zwischen den Klassen müssen richtig aufgelöst werden. D.h. du darfst jeden Header nur einmal einlesen, und das muss an der richtigen Stelle passieren. (generell eine super Übung)
- Deklariere deine Klassen immer vor (vorwärts-deklaration), bevor du sie verwendest
- mach jede Funktion oder Methode "inline" (wird unbedingt benötigt, sonst kommt C++ durcheinander. und hat mit inlineing GARNIX zu tun ... frag nicht...)
- Strukturiere das Gesamt-Programm mit statischen Libraries. Solange du alles mit demselben Compiler compilest, ist das kein Problem.
Benutzeravatar
Krishty
Establishment
Beiträge: 8232
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [Projekt] StoneQuestCPP

Beitrag von Krishty »

Das nennt sich Unity Build und vermasselt einem bspw. Multi-threading beim Kompilieren, Incremental Builds, Incremental Linking, usw.

Wird durchaus aktiv betrieben und einige stehen drauf, ist aber echt maximalinvasiv. Wenn man das später wieder ändern möchte, viel Spaß!

Just saying.
NytroX hat geschrieben: 10.03.2021, 18:01D.h. du darfst jeden Header nur einmal einlesen, und das muss an der richtigen Stelle passieren. (generell eine super Übung)
Mache ich auch; ist es wirklich!
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Zudomon
Establishment
Beiträge: 2253
Registriert: 25.03.2009, 07:20
Kontaktdaten:

Re: [Projekt] StoneQuestCPP

Beitrag von Zudomon »

Krishty hat geschrieben: 10.03.2021, 18:19 Das nennt sich Unity Build und vermasselt einem bspw. Multi-threading beim Kompilieren, Incremental Builds, Incremental Linking, usw.
Ah, das kann ich sogar nachvollziehen. Weil ja durch die Includes der vollen Sourcen im Endeffekt nur eine riesige Quellcode Datei entsteht.
Interessant, dass bei Delphi die Incremental Builds bei diesem Konzeptansatz funktionieren.

Danke euch für die Einschätzung! Ist wohl besser, ich gewöhne mich an die Gepflogenheiten und trenne dann lieber schön die Header von den Implementierungen :D
Benutzeravatar
Zudomon
Establishment
Beiträge: 2253
Registriert: 25.03.2009, 07:20
Kontaktdaten:

Re: [Projekt] StoneQuestCPP

Beitrag von Zudomon »

Sooooo... nun aber! Dreieck Nummer 1 ist geschafft...
20210311.png
Was sich jetzt nochmal geändert hat ist:
GLFW ist wieder raus geflogen. Das hat ja selbst das Fenster erzeugt und dafür Verwaltung und Input bereitgestellt.
Ich möchte das aber lieber selbst machen und nicht deren Callbacks nutzen. Deswegen wird nun über WinAPI ein Fenster erzeugt und darauf OpenGL initialisiert.
Ich hätte jetzt gerne allerdings die 3 Stunden zurück, die ich das letzte mal fürs Icon ändern gebraucht hatte :D
Benutzeravatar
starcow
Establishment
Beiträge: 523
Registriert: 23.04.2003, 17:42
Echter Name: Mischa Schaub
Kontaktdaten:

Re: [Projekt] StoneQuestCPP

Beitrag von starcow »

Wie es Hermann Hesse ja so schön formuliert hatte: "Und jedem Anfang wohnt ein Zauber inne, ..."
Wünsche dir in diesem Sinne auch viel Vergnügen beim "Restart"!
Ich fand jetzt auch die Diskussion, die dadurch entstanden ist sehr spannend. Der Umstand mit den ganzen Zusatz-Bibliotheken wie "GLUT, GLU, GLFW" und wie sie alle heissen, hatte mich auch schon immer interessiert.
Das heisst, du hast es jetzt ganz ohne solche Bibliotheken gelöst? War das aufwändig (schwierig)?

LG, starcow
Zuletzt geändert von starcow am 11.03.2021, 13:01, insgesamt 1-mal geändert.
Freelancer 3D- und 2D-Grafik
mischaschaub.com
D-eath
Beiträge: 51
Registriert: 28.08.2009, 19:37
Alter Benutzername: TrunkZ
Echter Name: Thomas

Re: [Projekt] StoneQuestCPP

Beitrag von D-eath »

GLFW kümmert sich halt auch um Joypad-Input, Attachment von Controllern und alles mögliche andere, was hier aber nicht relevant zu sein scheint.
Ansonsten hilft hier meist NeHe: https://nehe.gamedev.net/tutorial/creat ... %29/13001/

Edit: https://www.khronos.org/opengl/wiki/Cre ... text_(WGL)
Benutzeravatar
Zudomon
Establishment
Beiträge: 2253
Registriert: 25.03.2009, 07:20
Kontaktdaten:

Re: [Projekt] StoneQuestCPP

Beitrag von Zudomon »

starcow hat geschrieben: 11.03.2021, 08:41 Ich fand jetzt auch die Diskussion, die dadurch entstanden ist sehr spannend.
Ja, fand ich auch.
starcow hat geschrieben: 11.03.2021, 08:41 Das heisst, du hast es jetzt ganz ohne solche Bibliotheken gelöst? War das aufwändig (schwierig)?
Ich würde sagen, der Hauptaufwand war jetzt vor allem, das zu begreifen und mit meinen holprigen Vorwissen "irgendwie" letztendlich zusammen zu bauen. Wenn man sich aber schon auskennt, dann sollte das recht simpel sein, was ich nicht gedacht habe.

Ich kann gerne mal etwas detaillierter beschreiben...
Mir hat es sehr geholfen mal zu verstehen, wofür die einzelnen Dinge gebraucht werden. Das sind dann einfach so Informationen, die mir vorher nicht bewusst sind und weshalb ich dann halb blind da rum probieren muss.
Also GLFW (was für die Fensterverwaltung und Verbindung zu OpenGL gebraucht wird) und Glad (welches scheinbar die Extensions hinzubringt) sind jetzt raus. GLFW ersetzt durch native WinAPI. Und Glad durch gl3w.
Eine Übersicht der Libs mit Beschreibung hab ich hier gefunden. Das hört sich sicher behämmert an, aber vorher bin ich nur auf Tutorials, auf Stackoverflow und sonst was gestoßen. Das da auf der Khronos Seite direkt das alles so schön aufgelistet ist, tja, da kommt man dann hin, wenn man es nicht mehr erwartet.
Bei dem gl3w muss man per Python Skript den Source bauen lassen und kann den dann einbinden. Nein auch Python hatte ich nicht drauf. Also mich bremst da einfach nur die mangelnde Erfahrung aus.
Und hier dann, wie man das mit WinAPI realisiert. Das hat bei mir erstmal nicht geklappt... hab dann bei VC ein neues Projekt als Desktopanwendung erzeugt. Da baut der ja dann schon einiges drum herum. Hauptfenster + Aboutfenster + Menü + Resourcen usw.
Nachdem sich der erste Schreck gelegt hat (wegen der Code-Menge ) und ich mir das genauer angesehen habe, muss ich sagen, dass der Code aber dann doch verständlich ist. Und ja, besser ist, wenn man von Grund auf das selbst machen würde, wegen Lerneffekt und so. Aber so könnte ich das nicht Strukturieren, weil mir da eben die Erfahrung für fehlt. Da behalte ich das lieber bei. Jedenfalls das Fenster per WinAPI erzeugen ist da ja dann schon mit drin... und dann kann man das Beispiel da mit einbauen. Hab dann auch noch verstanden, dass letztlich einfach eine Linkereinstellung entscheidet, ob Konsolenanwendung oder Fenster (was den Haupteinsprungspunkt verändert). Jedenfalls wenn alles klappt, bekommt man durch das Beispiel schon die Ausgabe, welche OpenGL Version Möglich ist. Was mir dann hinterher bewusst wurde, dass man damit schon die Verbindung zwischen Fenster und OpenGL bekommt.
Sobald man gl3w mit einbaut, crashed es erstmal, wenn man nur die Header einbindet und das gl3w nicht über dessen Init Funktion aktiviert.
Nochmal kurz zum Verständnis: OpenGL 1.1 ist quasi schon im System enthalten und man kann dieses direkt über GL/gl.h einbinden. Die Lib noch mit einbinden "#pragma comment (lib, "opengl32.lib")". Damit man nun ein aktuelles OpenGL nutzen kann, kommt eben gl3w dazu... oder eben auch Glad oder sowas. Kann man natürlich auch per Hand machen. Aber erstens müsste ich dann erstmal lernen, was man da genau machen muss, ist dann natürlich auch immer mit Fehlern behaftet... und wenn man sich die Dateien anschaut (gl3w.h oder glad.h) die ja mit einem Generator entstehen... dann wird klar, dass man sich davor lieber drücken sollte.
D-eath hat geschrieben: 11.03.2021, 09:50 GLFW kümmert sich halt auch um Joypad-Input, Attachment von Controllern und alles mögliche andere, was hier aber nicht relevant zu sein scheint.
Das ich das lieber über nativer WinAPI machen wollte hat ja auch einen Grund. In Delphi hab ich mir das ja schon alles zurecht gebaut. Input, Fensterverwaltung mit Fullscreenswitchen und noch so einiges mehr. Da müsste ich das für GLFW nun zersplittern und die Parts, die anders sind, über deren Callbacks und so weiter integrieren. Also auch erstmal lernen, was die da genau machen.
Ich denke, letztendlich ist es da einfacher, wenn ich jetzt nur meinen Code übersetzen muss.
Benutzeravatar
Jonathan
Establishment
Beiträge: 2363
Registriert: 04.08.2004, 20:06
Kontaktdaten:

Re: [Projekt] StoneQuestCPP

Beitrag von Jonathan »

Zudomon hat geschrieben: 10.03.2021, 15:47 Kann man diese Trennung zwischen .h und .cpp Dateien eigentlich vermeiden? In Delphi hat man Header und Implementation ja in einer Datei.
(Soviel zu den Guidelines :D hahaha)
Wo wir gerade schon darüber reden: C++ trennt ja leider auch nicht Schnittstelle von Implementierung, sondern die Header enthalten fast immer auch teile der Implementierung. Wenn du beispielsweise einen privaten Member hast muss dieser im Header stehen und der passende Typ muss auch korrekt inkludiert werden (zumindest falls forward declaration nicht ausreicht), was ich oft zum Kotzen finde. Und schon wenn man nur die Reihenfolge zweier privater Member ändert (etwa, weil einem die Initialisierungsreihenfolge wichtig ist), muss man den Header ändern und potentiell das halbe bis ganze Programm neu kompilieren. Das ist nur ein weiteres Indiz dafür, wie kaputt C++'s Buildsystem ist. (IMO ist der einzige Grund dafür, dass der Compiler die Byte-Größe eines Objektes kennen muss? Na toll...)

Was dagegen hilft sind Techniken wie Pimpl (https://en.cppreference.com/w/cpp/language/pimpl), die aber auch ihrerseits wieder eigene Kosten und vor allen Dingen mehr Schreibarbeit mit sich bringen.
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
Benutzeravatar
xq
Establishment
Beiträge: 1581
Registriert: 07.10.2012, 14:56
Alter Benutzername: MasterQ32
Echter Name: Felix Queißner
Wohnort: Stuttgart & Region
Kontaktdaten:

Re: [Projekt] StoneQuestCPP

Beitrag von xq »

Das ist nur ein weiteres Indiz dafür, wie kaputt C++'s Buildsystem ist. (IMO ist der einzige Grund dafür, dass der Compiler die Byte-Größe eines Objektes kennen muss? Na toll...)
Ne, das liegt daran, dass du auch gerne aus anderen Dateien auf "Point.x" zugreifen möchtest, und dafür musst du das Layout der Struktur kennen (du musst ja ein read auf pointer + offset emittieren, um ein structfeld zu lesen)

Das ist leider bei allen Native Sprachen der Fall, nur lösen andere es doch wesentlich besser :D
War mal MasterQ32, findet den Namen aber mittlerweile ziemlich albern…

Programmiert viel in ⚡️Zig⚡️ und nervt Leute damit.
Benutzeravatar
Krishty
Establishment
Beiträge: 8232
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [Projekt] StoneQuestCPP

Beitrag von Krishty »

xq hat geschrieben: 11.03.2021, 11:41Ne, das liegt daran, dass du auch gerne aus anderen Dateien auf "Point.x" zugreifen möchtest
Dann macht man sich einen Getter, der Point const & als Parameter erwartet. Der Getter ist zusammen mit Point implementiert. Der Compiler braucht außerhalb dieser Implementierung keine Größe kennen.

Genau so funktioniert C. In C++ kann man es auch machen, aber eben nicht mit Methoden, sondern nur mit freien Funktionen. Und das ist grundsätzlich kaputt.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
starcow
Establishment
Beiträge: 523
Registriert: 23.04.2003, 17:42
Echter Name: Mischa Schaub
Kontaktdaten:

Re: [Projekt] StoneQuestCPP

Beitrag von starcow »

Was man von euch alles so "nebenbei" lernen kann, ist wiedermal ein echter Knaller! (-:
Jonathan hat geschrieben: 11.03.2021, 10:40 (etwa, weil einem die Initialisierungsreihenfolge wichtig ist)
Das hatte ich bislang nicht auf dem Radar. Wieso ist das nochmal wichtig? :->

Zudomon hat geschrieben: 11.03.2021, 10:28 Damit man nun ein aktuelles OpenGL nutzen kann, kommt eben gl3w dazu... oder eben auch Glad oder sowas. Kann man natürlich auch per Hand machen. Aber erstens müsste ich dann erstmal lernen, was man da genau machen muss, ist dann natürlich auch immer mit Fehlern behaftet... und wenn man sich die Dateien anschaut (gl3w.h oder glad.h) die ja mit einem Generator entstehen... dann wird klar, dass man sich davor lieber drücken sollte.
Sehr interessant. Vielen Dank für die Ausführung.
Sorry für die blöde Frage, aber wolltest du nicht das ganze jetzt ohne externe Bibiliotheken wie gl3w machen? Oder habe ich es falsch verstanden...?
Krishty hat geschrieben: 11.03.2021, 11:53
xq hat geschrieben: 11.03.2021, 11:41Ne, das liegt daran, dass du auch gerne aus anderen Dateien auf "Point.x" zugreifen möchtest
Dann macht man sich einen Getter, der Point const & als Parameter erwartet. Der Getter ist zusammen mit Point implementiert. Der Compiler braucht außerhalb dieser Implementierung keine Größe kennen.

Genau so funktioniert C. In C++ kann man es auch machen, aber eben nicht mit Methoden, sondern nur mit freien Funktionen. Und das ist grundsätzlich kaputt.
Krishty, du bist für mich sowas wie ne Kompetenz-Bestie! :->
Ich hab das Beispiel jetzt leider noch nicht ganz verstanden...
Also, im wesentlichen programmierst du C mit ein paar "sanften" C++ Ergänzungen? Als nach wie vor ein Anfänger in vielen Fragen, kann man sich da an dich halten?

LG, starcow
Freelancer 3D- und 2D-Grafik
mischaschaub.com
D-eath
Beiträge: 51
Registriert: 28.08.2009, 19:37
Alter Benutzername: TrunkZ
Echter Name: Thomas

Re: [Projekt] StoneQuestCPP

Beitrag von D-eath »

starcow hat geschrieben: 11.03.2021, 13:51 Was man von euch alles so "nebenbei" lernen kann, ist wiedermal ein echter Knaller! (-:
Jonathan hat geschrieben: 11.03.2021, 10:40 (etwa, weil einem die Initialisierungsreihenfolge wichtig ist)
Das hatte ich bislang nicht auf dem Radar. Wieso ist das nochmal wichtig? :->
Geklautes Beispiel:

Code: Alles auswählen

class MyString {
public:
  MyString(const MyString& s);              // copy constructor
  // ...
protected:
  char*    data_;    
  unsigned len_;  
};

MyString::MyString(const MyString& s)
  : len_ (s.len_)  
  , data_(new char[len_ + 1u])  // using uninitialized len_ here.     
{ 
   // now len_ is initialized and can be used.                 
   memcpy(data_, s.data_, len_ + 1u);
}         
Da data_ vor len_ definiert ist, wird erst data_ initialisiert, unabhängig von der Reihenfolge im Kopierkonstruktor, wobei aber data_ hier auf dem (uninitialisierten) len_ basiert -> Bug.
Benutzeravatar
Zudomon
Establishment
Beiträge: 2253
Registriert: 25.03.2009, 07:20
Kontaktdaten:

Re: [Projekt] StoneQuestCPP

Beitrag von Zudomon »

starcow hat geschrieben: 11.03.2021, 13:51 Sorry für die blöde Frage, aber wolltest du nicht das ganze jetzt ohne externe Bibiliotheken wie gl3w machen? Oder habe ich es falsch verstanden...?
Also nicht zwingend. Wäre bei GLFW geblieben, aber merke halt dass ich dann noch mehr umbauen als ohne hin schon und nicht einfach meine Sachen übersetzen kann. Z.B. meine Inputverwaltung, funktioniert ja schon und hat schon einiges an Sonderfälle hinter sich. In wie weit meins da Konkurrenzfähig ist sei mal dahin gestellt. Aber es ist leichter (für mich), meine Sachen zu übersetzen, als mich da jetzt bei GLFW entsprechend zu integrieren.
Benutzeravatar
Jonathan
Establishment
Beiträge: 2363
Registriert: 04.08.2004, 20:06
Kontaktdaten:

Re: [Projekt] StoneQuestCPP

Beitrag von Jonathan »

D-eath hat geschrieben: 11.03.2021, 14:14
starcow hat geschrieben: 11.03.2021, 13:51 Was man von euch alles so "nebenbei" lernen kann, ist wiedermal ein echter Knaller! (-:
Jonathan hat geschrieben: 11.03.2021, 10:40 (etwa, weil einem die Initialisierungsreihenfolge wichtig ist)
Das hatte ich bislang nicht auf dem Radar. Wieso ist das nochmal wichtig? :->
Geklautes Beispiel:

Code: Alles auswählen

class MyString {
public:
  MyString(const MyString& s);              // copy constructor
  // ...
protected:
  char*    data_;    
  unsigned len_;  
};

MyString::MyString(const MyString& s)
  : len_ (s.len_)  
  , data_(new char[len_ + 1u])  // using uninitialized len_ here.     
{ 
   // now len_ is initialized and can be used.                 
   memcpy(data_, s.data_, len_ + 1u);
}         
Da data_ vor len_ definiert ist, wird erst data_ initialisiert, unabhängig von der Reihenfolge im Kopierkonstruktor, wobei aber data_ hier auf dem (uninitialisierten) len_ basiert -> Bug.
Ergänzend sei hinzugefügt: Member werden in der Reihenfolge initialisiert in der sie in der Klassendeklaration stehen, und nicht in der Reihenfolge wie sie in der Initialisierungsliste des Konstruktors stehen. Denn es könnte mehrere Konstruktoren geben, mit unterschiedlichen Reihenfolgen. Da es aber nur einen Destruktor gibt und garantiert ist, dass Member in der selben Reihenfolge zerstört werden wie sie erstellt wurden, müssen alle Konstruktoren die selbe Reihenfolge verwenden. Und die ist eben durch die Klassendeklaration festgelegt.

Meinem Empfinden nach hätte man abweichende Reihenfolgen in Initialisierungslisten illegal (-> Compilerfehler) machen sollen. Denn in D-eath Beispiel schaut es ja so aus, als sei die Reihenfolge korrekt. Und außer Schlampigkeit will mir partout kein Grund einfallen, wieso man die Initialisierungsliste falsch sortieren wollen sollte.
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
Benutzeravatar
Krishty
Establishment
Beiträge: 8232
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [Projekt] StoneQuestCPP

Beitrag von Krishty »

starcow hat geschrieben: 11.03.2021, 13:51
Krishty hat geschrieben: 11.03.2021, 11:53
xq hat geschrieben: 11.03.2021, 11:41Ne, das liegt daran, dass du auch gerne aus anderen Dateien auf "Point.x" zugreifen möchtest
Dann macht man sich einen Getter, der Point const & als Parameter erwartet. Der Getter ist zusammen mit Point implementiert. Der Compiler braucht außerhalb dieser Implementierung keine Größe kennen.

Genau so funktioniert C. In C++ kann man es auch machen, aber eben nicht mit Methoden, sondern nur mit freien Funktionen. Und das ist grundsätzlich kaputt.
Krishty, du bist für mich sowas wie ne Kompetenz-Bestie! :->
Ich hab das Beispiel jetzt leider noch nicht ganz verstanden...
Also, im wesentlichen programmierst du C mit ein paar "sanften" C++ Ergänzungen? Als nach wie vor ein Anfänger in vielen Fragen, kann man sich da an dich halten?
Besser nicht – ich stecke ziemlich tief in solchem Kram drin; meine Ratschläge sollte man nur befolgen, wenn man auch versteht, was sie tun. Als ob dir ein Rennfahrer erzählt, dass es sich mit gesperrtem Differential besser fährt, und dann wurschtelst du lustig am Auto rum und wunderst dich, warum du nicht mehr einparken kannst.

Du kennst das vielleicht, dass du eine Klasse komplett definieren musst, bevor du sie verwenden kannst:

    class Point {
    public:
        …
        int getX() const { return x; }
        int getY() const { return y; }
    private:
        int x;
        int y;
    };


Aber in C/C++ kann ich eine Datenstruktur deklarieren, ohne dass ich sie definiere:

    struct Point;

Ich kann auch Funktionen deklarieren, die diese Datenstruktur nutzen. Dafür muss die Datenstruktur nicht definiert, sondern nur deklariert sein:

    int getX(Point);
    int getY(Point);


Das löst erst einen Compiler-Fehler aus, sobald ich Point tatsächlich instanziere (z. B. als lokale Variable oder Parameter) oder getX()/getY() aufrufe.

Was bringen mir ein Typ und zwei Funktionen, die ich nicht benutzen kann?! Nicht viel. Aber änder den Parameter der Getter von Value zu Reference:

    int getX(Point const &);
    int getY(Point const &);


… und nun kannst du getX() und getY() benutzen, ohne die Implementierung von Point zu kennen. Wo immer du ein Point als Zeiger oder Referenz bekommst, kannst du getX() und getY() aufrufen – obwohl Point dem Aufrufer nie definiert wurde. Die Definition liegt irgendwo weit weg, wo auch die Getter definiert sind.

Und das reduziert die Abhängigkeiten. Hast du eine Monsterklasse Player mit Gettern für Position, Sounds, Grafik, und so weiter – dann brauchen die ganzen abhängigen Klassen nicht definiert sein. Die Deklarationen der Datenstrukturen reichen aus, und du kannst sogar damit arbeiten, so lange du keine Instanzen kopierst oder neu anlegst. Dein SoundManager (oder was auch immer) braucht kein #include "Graphics" mehr, bloß, weil das in Player vorkommt.

Das löst nicht alle Probleme, aber schonmal ganz schön viele.

Und das funktioniert nur mit freien Funktionen, nicht mit Methoden. Denn Methoden müssen in der Klasse deklariert sein. Und da müssen auch die privaten Member hin. Wenn du also Point::getX() aufrufen willst, muss Point vollständig definiert sein, samt aller Abhängigkeiten. Und wenn das ebenfalls Klassen mit Methoden sind, auch samt der Abhängigkeiten der Abhängigkeiten usw. Jetzt hast du ein exponentielles Problem und den Grund, warum C++ länger kompiliert als die meisten anderen Sprachen.

Bei getX(Point const &) gibt es den Ärger nicht. Dafür gibt es IMO keinen vernünftigen Grund (außer „als wir das 1985 implementiert haben, war das halt so“). Darum finde ich class in C++ scheiße und das C++-Buildsystem grundsätzlich kaputt.

(Auch virtuelle Funktionen sind kein Grund: Ich könnte theoretisch jede Funktion vom Compiler hinter einem automatisch generierten, nicht-virtuellen Wrapper verstecken lassen und die Entscheidung, ob es ein virtueller Aufruf ist oder nicht, zur Implementierung verschieben.)

Um den Bogen nach oben zu schlagen: Das bedeutet nicht „Krishty sagt, benutzt keine Klassen!“ :) Es bedeutet: „Bedenk, was du dem Rest des Projekts antust, wenn du class schreibst. Und wäg es dann mit deinen Zielen ab.“
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Chromanoid
Moderator
Beiträge: 4255
Registriert: 16.10.2002, 19:39
Echter Name: Christian Kulenkampff
Wohnort: Lüneburg

Re: [Projekt] StoneQuestCPP

Beitrag von Chromanoid »

Bei C++ blutet die Legacy echt direkt beim Programmieren in den Code... da muss man gar nicht selbst dran denken... :)
Benutzeravatar
Zudomon
Establishment
Beiträge: 2253
Registriert: 25.03.2009, 07:20
Kontaktdaten:

Re: [Projekt] StoneQuestCPP

Beitrag von Zudomon »

Kann mir jemand sagen, warum der die Funktionen "Create" und "Process" unterkringelt und meint, dass die Funktionsdefinition nicht gefunden wird?
Es werden keine Warnungen oder so erstellt und das Programm läuft auch einwandfrei.
Wenn ich mit [Strg] drauf klicke, springt er auch an die richtige Stelle... also scheint er es doch irgendwie zu finden.
Bei der Funktion "CreateWin" die von der Hilfebox verdeckt liegt, macht der das nicht... der einzige Unterschied ist, dass diese noch Parameter mit bekommt.
cpp.png
Benutzeravatar
Krishty
Establishment
Beiträge: 8232
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [Projekt] StoneQuestCPP

Beitrag von Krishty »

Weil Visual Studio Bugs ohne Ende hat. Bei mir findet er regelmäßig hunderte Funktionsdefinitionen nicht :) So lange du es nicht auf einen winzigen Repo reduzieren kannst, bearbeiten sie auch keine Bug Reports dazu.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Zudomon
Establishment
Beiträge: 2253
Registriert: 25.03.2009, 07:20
Kontaktdaten:

Re: [Projekt] StoneQuestCPP

Beitrag von Zudomon »

Krishty hat geschrieben: 13.03.2021, 02:32 Weil Visual Studio Bugs ohne Ende hat. Bei mir findet er regelmäßig hunderte Funktionsdefinitionen nicht :) So lange du es nicht auf einen winzigen Repo reduzieren kannst, bearbeiten sie auch keine Bug Reports dazu.
Dann ist ja gut. Dachte ich würde da irgendwas falsch machen und wollte schon am Anfang gucken, dass es sauber ist.
Antworten