Seite 1 von 3

Re: [Projekt] Upvoid

Verfasst: 11.03.2013, 16:53
von Artificial Mind
Also unser Terrain hat verschiedene Materialien und nur auf den "Gras"-Materialien wird der Shader ausgeführt. Mit der Steigung wird das Gras ausgeblendet aber es gibt noch eine Noise-Textur, die angibt, wo sich Gras befinden soll. Ist dann aber ein rein optischer Effekt. Wir werden wohl über kurz oder lang auf Vertex-Attribute umsteigen, damit man das Gras auch verändern kann.

Re: [Projekt] Upvoid

Verfasst: 15.03.2013, 11:26
von Artificial Mind
So wir haben ein neues Video!
[youtube]YUSMX53OL9U[/youtube]

Hier nochmal ein paar statische Versionen:
v1_frame_00577.jpg
v3_frame_01580.jpg
v3_frame_01695.jpg
Wir haben den kompletten Code vom vorherigen Prototypen neu geschrieben.
Unsere aktuelle Architektur ist stark multi-threaded (bereits über 30 unabhängige logische Threads + beliebig viele für Terrain, natürlich auf die verfügbaren Kerne gescheduled).
Ich kann euch sagen, es macht kein Spaß seine Architektur auf so viel Parallelität auszulegen, aber es ist den Aufwand in unserem Fall wert. Netter Nebeneffekt: man denkt über viele Entscheidungen zehnmal nach und hackt nicht einfach in seiner Engine rum ;)

Die God-Rays bzw. das Volumetric Light Scattering sind übrigens hiervon inspiriert: CPU Gems 3, Chapter 13.
Empfehlung: Berechnung nur auf halber Auflösung, dann kann man viermal so viele Samples machen wie auf voller ;)

Re: [Projekt] Upvoid

Verfasst: 15.03.2013, 12:50
von RazorX
Sehr schöne Bilder, wie immer! Auf dem dritten Bild sind die rechten Strahlen sehr stark gefächert, ist das gemäß der Standardimplementierung oder ein spezielles Feature? Sieht fast so aus, als würde das das Lens-Flare sein!?

Re: [Projekt] Upvoid

Verfasst: 15.03.2013, 12:58
von Artificial Mind
Achso ne, die Gefächerten, die man dort sieht, sind ein super schlechter Starburst-GIMP-Versuch. Steht auch schon im TODO vom Polishing.
Trotzdem können auch die Godrays so ausfächern, z. B. bei Graskanten.

Re: [Projekt] Upvoid

Verfasst: 15.03.2013, 13:18
von Jonathan
Sieht sehr cool aus. Allerdings hätte ich es schön gefunden, wenn das Video kommentiert gewesen wäre. Am besten natürlich mit Sprache, aber ein paar Texteinblendungen, welchen Effekt man gerade sieht, wäre auch schon gut gewesen. So hat man einfach nur 5 Minuten durch die Luft fliegen und erkennt vielleicht gar nicht, was man da so alles sieht.

Re: [Projekt] Upvoid

Verfasst: 15.03.2013, 13:25
von Schrompf
Technologisch beeindruckend. Wie verteilt, synct und scheduled ihr die Tasks?

Ich mag die God Rays nicht. Und der Wassershader könnte einen simplen Tiefen-Nebel brauchen.

Re: [Projekt] Upvoid

Verfasst: 15.03.2013, 14:02
von Artificial Mind
@Jonathan:
Ja, haben wir auch echt überlegt, aber es hat so schon 5h gedauert, das Video zu produzieren. Wahrscheinlich müssen wir uns einfach eingewöhnen und dann kriegen wir auch eine kommentierte Production zeiteffizient hin.

@Schrompf:
Was stört dich an den God Rays? Einfach generelle persönliche Meinung oder haben wir zu dick aufgetragen oder ist einfach ein Screenspace-Ansatz grundsätzlich zu schlecht?
Wenns persönliche Meinung ist: Ok, ist halt Geschmackssache. Wir haben auch jemanden im Team der grundsätzlich keine Lens Flares mag und die egal wo überflüssig findet. Kann man ausschalten und dann ist's gut ;)
Das Wasser ist meiner Meinung nach auch noch zu unruhig, aber Tiefen-Dreck ist auch ne gute Anmerkung.

Zum Schedulen:
Ein Task hat im wesentlichen drei Einstellungen: TimingMode, CpuLoad und Responiveness.
  • TimingMode: As fast as possible (AFAP ;) ) oder FixedTimestep
    - gibt an, wie oft der Task asugeführt werden soll
  • CpuLoad: Light, Heavy oder Unpredictable
    - gibt die zu erwartene Last an (z. B. Light für Inputbehandlung, Heavy für die Terrain Generierung und Unpredictable für Netzwerk-Empfang)
  • Responsiveness: Immediate, Continuous oder Don't Care
    - gibt an, wie man Rückmeldung vom Thread haben will/muss (z. B. Input ist Immediate, Physik ist Continuous und Terrain Generierung ist Don't Care)
Dann gibt es noch ein besonderes Flag bei Tasks, wenn sie im UI Thread laufen müssen (z. B: Rendering oder auch Geometry-Upload)
Mit dieser Kategorisierung von Tasks können wir nun für alle non-UI Tasks echte Threads erstellen:
  1. Jeder Immediate-Task bekommt einen eigenen High-Prio Thread (z. B: Input, Netzwerk)
  2. Jeder Continuous-Task bekommt einen eigenen Normal-Prio Thread (z. B: Physik, Weltlogik, Skriptlogik)
  3. Anzahl der Kerne minus Anzahl Continuous-Threads minus 1 (UI) ergibt die Anzahl der "Heavy-Threads" (mindestens jedoch einer). Alle noch nicht zugewiesenen Tasks kommen in einen Task-Pool, aus denen sich jeder Heavy-Thread fröhlich bedient und ausführt.
Die Continuous-Tasks haben meistens einen Fixed Timestep und wissen deswegen wann sie das nächste Mal ausgeführt werden müssen, sodass der Thread für die Zwischenzeit sleepen kann.

Die Aufteilung der Tasks auf Threads hat noch Optimierungspotential:
Man kann Continuous-Tasks auf einen Thread legen, wenn beide ihr Scheduling einhalten können, auch wenn sie sequentiell ausgeführt werden.
Man könnte alle Light-Tasks in einen Pool werfen und sie bei allen anderen Threads "piggybacken".
Aber generell hat die bisherige Aufteilung schon dafür gesorgt, dass es auch auf schwachen Notebooks wieder gut läuft.

Re: [Projekt] Upvoid

Verfasst: 15.03.2013, 14:29
von Schrompf
Danke für die Ausführungen, ich finde das sehr interessant! Eine letzte Frage dazu aber: nutzt ihr TBB, die neuen C++11-Features oder was eigenes? Ihr werdet ja neben Tasks zumindest auch Mutexe, Atomics und Lockless Queues brauchen.
Artificial Mind hat geschrieben:Was stört dich an den God Rays? Einfach generelle persönliche Meinung oder haben wir zu dick aufgetragen oder ist einfach ein Screenspace-Ansatz grundsätzlich zu schlecht?
Zum Einen ist Screenspace dafür meiner Meinung nach ungeeignet. Es ist ein sehr präsenter Effekt, der dann aber mit hoher Frequenz erscheint und verschwindet, weil sich ja bei jeder Kamerabewegung die Ausgangslange ändert. Unschön. Und ihr habt ja mit dem Voxel-Feld tatsächlich die Daten da, um echte Volumen-Lichtstreuung zu berechnen. Aber ich vermute, das hat Zeit bis viel später.

Und zum Anderen ist der Effekt sehr scharf abgegrenzt. God Rays sind für mich eher eine subtile Sache, mit beleuchteten Partikeln, die langsam zwischen Hell und Dunkel hin- und herschweben. Etwa so hier (der Effekt wurde bereits per Nachbearbeitung verstärkt, glaube ich) Bild Ich gebe aber zu, dass das echt schwer zu erreichen ist - gleichzeitig eine gute Auflösung zu bewahren und einen weichen Look hinzubekommen.
Das Wasser ist meiner Meinung nach auch noch zu unruhig, aber Tiefen-Dreck ist auch ne gute Anmerkung.
Das ist im Orginal ein Deferred Renderer, oder? In dem Fall reicht ja im Wasser-Shader ein schlichtes

Code: Alles auswählen

output.a = 1.0f - exp( -TiefeDesFragments / SuchDirWasAus);
Hm... aber nur, wenn dann in der Farbe auch was Passendes drin steht. Ok, ist wohl doch nicht so einfach.

Re: [Projekt] Upvoid

Verfasst: 15.03.2013, 14:49
von mnemonix
Wow, saubere Arbeit. Gefällt mir! Bin immer wieder überrascht, wie schnell du neue Sachen umsetzt (ist fast wie Magie). Hast ein gutes Problem-Lösung-Denken und programmierst dazu noch schnell. ;D

Könntest du noch kurz was über die verwendeten Bibliotheken und APIs sagen, die ihr in eurem Projekt nutzt (Grafik: Direct3D/OpenGL (EXT-Loader), Mathe, Physik, Audio, Laden von Bildern, Netzwerk, Input, GUI, ...)?

Was noch cool wäre, wenn du eine kleine Wasser-Simulation drin hättest (evtl. über kleine grobe Wasserkügelchen (Metaballs)). ;D Sieht irgendwie komisch aus, wenn das Wasser wie durch Magie festgehalten wird und nicht abfließt, aber sonst alles recht realistisch aussieht. Eventuell ist das jedoch nicht umsetzbar, weil schon etliche andere Sachen im Hintergrund laufen.

Re: [Projekt] Upvoid

Verfasst: 15.03.2013, 15:11
von Artificial Mind
@Schrompf:
Vielen Dank für die Erläuterung.
Also wir sind etwas in den C++11-Features eingeschränkt, da wir momentan noch VS 2010 unterstützen (müssen) und dort vieles noch nicht geht.
Wir nutzen Qt für GUI, Threads, Filesystem und Unicode-Strings.

Ja, das mit den Screenspace Godrays ist echt ein Problem. z. B. scheinen die Berge auch in den Vordergrund, was eigentlich Quatsch ist. Durch das Volumen könnte wir das natürlich ausrechnen, aber halt nur auf der Volumen-Auflösung und das ändert sich ja auch mit dynamischen Objekten und unterschiedlichem Sonnenstand. Ich kann mir auch gut vorstellen das von Meta-Daten abhängig zu machen (z. B. Höhlen-Ausgänge).
Mal gucken wie gut man das hinbekommt, ich find den Screenspace in den richtigen Situation allerdings schon ziemlich ansprechend ;)

Zum Wasser: Wir haben keinen Deferred Renderer.
Wir nutzen einen hippen Z-Prepass, dann einen Opaque und dann einen Transparent+Distortion+Glow (quasi die "transluzenten" Passes).
Wasser besteht aus Transparent + Distortion und hat Zugriff auf die Opaque Depth.
Wir müssen das btw. aus Sortierungsgründen mit ins Transparente nehmen, damit das funktioniert.

@mnemonix:
Also wir nutzen folgende APIs:
  • Grafik: OpenGL mit Glew
  • Physik: Bullet
  • Mathe: GLM (weil es wie GLSL-Mathe ist)
  • Qt für Filesystem, Gui, Threads, Unicode-Strings, Netzwerk
  • Audio: OpenAL-Soft, ogg
  • Cooleres Mathe: Eigen (für SVD und so)
  • Debug: AntTweakBar
  • Testing: Googletest
  • Assets: Assimp ;)
Das Wasser soll später über mehrere Stufen simuliert werden. Weit entfernt über Heightmaps, näher dran Voxel + Partikel.

Re: [Projekt] Upvoid

Verfasst: 15.03.2013, 15:17
von Schrompf
Nochmal Danke für die Antwort und die Auflistung! Keine weiteren Fragen, Eurer Ehren :-)

Re: [Projekt] Upvoid

Verfasst: 15.03.2013, 19:02
von LONy
Sieht wieder sehr cool aus, danke für die ständig neuen Infos :) Als E-Techniker steig ich da leider nimmer ganz durch, hatte mit OpenGL noch nichts zu tun :lol:

Was euer Video noch einen Tick besser machen würde, wäre wenn die Kamerabewegung nicht so abgehackt wäre sondern wenn die Bewegungen weicher wären... Aber es ist ja kein Verkaufsvideo sondern nur ein Zwischenstand was eure engine kann.... Daumen hoch! :D

Re: [Projekt] Upvoid

Verfasst: 15.03.2013, 19:13
von Jeason
Soweit ich das aus eurem Blog rauslesen konnte plant ihr Mono für Scripting einzusetzen.
Habt ihr schon eine konkrete Vorstellung wie ihr eure Klassen an Mono anbinden wollt?
Zum Beispiel: Schwarze Magie oder "C-API" Wrapper selber schreiben?

Re: [Projekt] Upvoid

Verfasst: 15.03.2013, 19:34
von Artificial Mind
Jeason hat geschrieben:Soweit ich das aus eurem Blog rauslesen konnte plant ihr Mono für Scripting einzusetzen.
Habt ihr schon eine konkrete Vorstellung wie ihr eure Klassen an Mono anbinden wollt?
Zum Beispiel: Schwarze Magie oder "C-API" Wrapper selber schreiben?
Also das funktioniert bereits. Der einfache Kugel-Character-Controller, den man im Video erahnen kann, ist aus einem C#-Mod heraus erstellt.
Wir nutzen die "Embedding Mono"-API, um aus C++ heraus .NET Code auszuführen.
Von C#-Seite aus kann man einfach DllImports von der Dll "__Internal" machen und kriegt damit Funktionen, die aus unserer C++-Binary exportiert werden.
Also ja, wir haben quasi ne "C-API". Man kann allerdings structs direkt in Mono nutzen (wird per value oder per reference genutzt) und damit können wir z. B. glm::vec2 und glm::vec3 ohne Probleme übergeben. Strings werden gemarshallt und so weiter, eigentlich relativ komfortabel. Ein Problem sind noch unterschiedliche Calling Conventions unter Windows und Linux, aber auch das lässt sich lösen.

Btw: gestern hat ein Mitstreiter eine PHP.NET-dll erstellt und die geladen, geht auch wunderbar.

Re: [Projekt] Upvoid

Verfasst: 15.03.2013, 19:59
von mnemonix
Artificial Mind hat geschrieben: @mnemonix:
Also wir nutzen folgende APIs:
  • Grafik: OpenGL mit Glew
  • Physik: Bullet
  • Mathe: GLM (weil es wie GLSL-Mathe ist)
  • Qt für Filesystem, Gui, Threads, Unicode-Strings, Netzwerk
  • Audio: OpenAL-Soft, ogg
  • Cooleres Mathe: Eigen (für SVD und so)
  • Debug: AntTweakBar
  • Testing: Googletest
  • Assets: Assimp ;)
Das Wasser soll später über mehrere Stufen simuliert werden. Weit entfernt über Heightmaps, näher dran Voxel + Partikel.
Cool, danke. Eins hab ich vorhin noch vergessen zu fragen. Welche Schattentechnik habt ihr implementiert?

Re: [Projekt] Upvoid

Verfasst: 15.03.2013, 20:04
von Artificial Mind
Kein Problem ;)
Die Schattentechnik ist Exponential Shadow Maps (ESM). Später wird das noch um mehrere Kaskaden erweitert werden müssen, momentan ist das eine 2048² große Shadowmap.

Re: [Projekt] Upvoid

Verfasst: 29.03.2013, 23:32
von Artificial Mind
Wir machen viel Fortschritt!
Aktuell ist Weekly Update #6.

Hier nochmal ein paar schöne Screenies:
2013-03-29 - vulcan - 2.jpg
2013-03-29 - underwater - 2.jpg
trees.jpg
2013-03-29 - blacksmoke - 3.jpg
Edit: Hier nochmal das neue Video:
[youtube]ZZAd5avw9MA[/youtube]

Re: [Projekt] Upvoid

Verfasst: 30.03.2013, 12:18
von Schrompf
Das Partikelsystem sieht gut aus! Partikel zu beleuchten ist mutig, aber wenn man die Partikel dicht genug generiert und auf die Fillrate scheißt, sieht das richtig gut aus. Und endlich gibt es Bäume! <3 Die sehen allerdings aus wie generiert - benutzt ihr da irgendeine Lib für?

Re: [Projekt] Upvoid

Verfasst: 30.03.2013, 12:58
von Artificial Mind
Die opaquen Partikel zu beleuchten ist gar nicht wild, die Transparenten sollte man allerdings nur beleuchten wenn man weiter weg ist. Fullscreen durch den ganzen beleuchteten Rauch gucken ist momentan tatsächlich nicht zu empfehlen :D Ich habe auch endlich rausgefunden wie man gute Rauchpartikelsysteme günstig macht: Große, wenige Partikel und fertige Rauchtextur (z. B. soetwas: http://www.cgtextures.com/textures.php? ... 044&page=6 )

Momentan ist das eigentlich nur ein Baum(astwerk), das einer von uns kurzerhand in Blender zusammengeklickt hat. Im Video sieht man kurz den Trick mit den Quads für die Blätter. Ich kann mir sehr gut vorstellen dass man nachher das grobe Astwerk prozedural generiert und dann die Blätter mit dieser Technik rendert. Jedenfalls für "mid-range". "far-range" würde ich zu Billboards übergehen, "super-far-range" schwebt mir die Lösung von diesem Paper vor: http://www.gamedev.net/page/community/i ... rests-r187 (allerdings auch nur die Bäume im Hintergrund. Die im Vordergrund sind quasi mit Lightmaps gerendert und das frisst zu viel Speicher und Performance und unterstützt nur wenig Variation). Im Nahbereich möchte ich dann zu soetwas übergehen: http://simonschreibt.blogspot.de/2013/0 ... trees.html oder wenn es die Grafikkarte zulässt noch irgendeine extremere Tesselation-Lösung. Aber das ist alles noch etwas Zukunftsmusik ;)

Re: [Projekt] Upvoid

Verfasst: 30.03.2013, 13:38
von mnemonix
Wie immer wieder sehr beeindruckende Bilder, Artificial. Gefällt mir alles sehr gut. Bis auf die Unterwasser Bilder, die im Video aber etwas besser aussehen durch die Kompression. ^^ Finde dieses krasse Rauschen nicht so schön. Fände Tiefennebel + ne Art DoF schöner (+ evtl. noch ne Caustics Textur über den Boden scrollen lassen). :D

Edit: Und die scharfen Schnittkanten, wenn du mit ner Kugel ins Volumen reinschneidest, könnte man vielleicht noch glätten, wenn das geht.

Re: [Projekt] Upvoid

Verfasst: 30.03.2013, 13:48
von Artificial Mind
In bewegt sieht Unterwasser eigentlich gar nicht schlecht aus, imho (also in Originalqualität mit dem Rauschen). Aber zugegeben, im Bild kommt das sehr krass rüber, während man im Video kaum noch was erkennt. Bevor wir nicht eine Binary rausgeben kann ich wahrscheinlich auch nicht zeigen wie es in bewegt aussieht.

Was mir richtig gut am aktuellen "Rausch"-Shader gefällt ist, dass er nur zwei Texture-Lookups hat: Einen in eine Random-Map (lässt sich vll noch durch "berechnetes Random" ersetzen) und nur einen in die Farbtextur. Alles was in Richtung DoF oder Blur geht hat gleich wieder super viele Lookups.

Caustics fehlen auf alle Fälle noch, hab ich ganz vergessen. Tiefennebel gibt es schon ins bläuliche, aber da kann man auch noch viel Fine-Tuning betreiben. Mir fehlen auch noch Blubberblasenpartikel ;)

EDIT: Zu den Schnittkanten: das ist ein sehr wichtiges Feature und war auch nicht ganz einfach zu implementieren. Bei den meisten Marching-Cubes-Voxel-basierten Engines kommt halt nur "Organisches" raus, keine harten Kanten. Wir können halt jetzt beides. Jedes Material hat einen Winkel, ab dem die Normale gesmooth'd wird. Es wird nachher noch andere Terrain-Modifikationen als "distance(sphereCenter, position) - radius" geben ;)

Re: [Projekt] Upvoid

Verfasst: 30.03.2013, 21:44
von Niki
Klasse! Wirklich klasse! Da kommt mir doch ein wenig das Sabbern :)

Rein aus Interesse: Wie handhabst du den Übergang von Überwasser nach Unterwasser? Ich hab's noch nie ausprobiert, aber mich schon oft gefragt wie man das am besten bewerkstelligen kann. Ist das einfach nur "Wenn Kamera unter Ebene dann wird alles blauer" oder steck da mehr dahinter? Berücksichtigst Du eventuell sogar Wellen?

Re: [Projekt] Upvoid

Verfasst: 30.03.2013, 21:49
von Artificial Mind
Wasser ist bei uns keine Ebene sondern ein eigenes Material im Terrain. Insbesondere kann man momentan Wasser-Kugeln erstellen und auch durch das Wasser hindurch graben und baut es damit ab ;)

Meine momentane Lösung zum Übergang ist auch eher eine Notlösung: Ich gucke für die aktuelle Kameraposition die 8 benachbarten Materialwerte nach und mache dann lineare Interpolation wenn Wasser dabei ist. Damit sind die meisten Übergänge ok, aber da die Dreiecke sich nicht ganz an die Volumendaten halten kann es halt auch etwas daneben sein. Mal gucken ob man das noch schöner machen muss, erstmal tut es seinen Dienst.
Die momentanen Wellen sind btw. nur ein Fragmentshader-Effekt basierend auf zwei gegeneinander verschobenen Texturen.

Re: [Projekt] Upvoid

Verfasst: 30.03.2013, 21:56
von Niki
Material im Terrain... das gibt mir vielleicht ein paar Ideen sobald ich zur Wassergenerierung in meinem Projekt komme.

Ich habe mir das bei Oblivion mal ganz genau angeschaut, denn da kann man ja tauchen. Vielleicht war ich einfach nur zu ungeschickt, aber ich habe es nicht geschafft das sich die Wasserlinie in der Mitte des Bildschirms befindet. Es sah beinahe so aus als würde die Wasserlinie immer zum oberen oder unteren Frustum-Rand hin-snappen. Vielleicht ist ja jemand anders so geschickt und kann mir das Gegenteil beweisen :D

Re: [Projekt] Upvoid

Verfasst: 02.04.2013, 16:20
von Jonathan
Das selbe ist mir schon bei diversen Spielen aufgefallen. Heutzutage scheint es einfach nicht mehr möglich zu sein, dass die Kamera nur halb im Wasser ist. Früher gab es noch Spiele, da wurde der Unterwassernebel Bildschirmfüllen aktiviert, wenn man unterhalb der Wasseroberfläche war - mit dem netten Nebeneffekt, dass man, solange man nur ein ganz bisschen im Wasser war, dort noch keinen Nebel hatte und ganz normal weit gucken konnte.

Re: [Projekt] Upvoid

Verfasst: 04.05.2013, 18:03
von Artificial Mind
Hier ist unser neustes Video:
[youtube]gvpPdpgDrkY[/youtube]

Dies ist ein Mod, der nahezu komplett in C# geschrieben ist und die Mod-API unserer Engine nutzt.

Andere (technische) News:
  • Dank AsmJit werden die Funktionen, aus denen das Terrain generiert wird, per eigenem JIT-compiling in natives SSE übersetzt und ausgeführt.
  • Wir haben Mesh Voxelization eingebaut, sodass man nun auch (zusätzlich zu impliziten Funktionen) z. B. in Blender eine Burg erstellen kann und diese auch einfach in das Terrain integrieren kann. Wichtig dabei ist eigentlich nur, dass nicht mehr als ein Feature-Vertex pro Voxel (momentan 0.5m x 0.5m x 0.5m) da ist, dann können die meisten Meshes nahezu perfekt rekonstruiert werden.
  • Wir haben mit dem Path Finding angefangen und das ist ein besonderer Spaß auf so dynamischem Terrain. Momentane Idee: grobes Pathfinding auf Chunk-Basis für Waypoints und dann die Terraingeometrie als Nav-Mesh nehmen und lokal per D* Pathfinding zu den nächsten Waypoints machen. Mal gucken wie performant das alles wird.
  • Ich schreibe gerade an einem Tool, dass uns den Großteil der C# Api (und dem entsprechenden C++ Wrapper) direkt aus unserem C++ Code erzeugt. Dazu werden Annotationen in Kommentaren eingeführt (z. B. "//!Api ApiObject" für eine C++ Klasse, die in C# abgebildet werden soll (inklusive Polymorphie), oder "//!Api Getter" für einen C++-Member, der in C# als Property mit public get modelliert werden soll)
Ein kleines Bild aus dem Mod:
background_med.jpg

Re: [Projekt] Upvoid

Verfasst: 10.05.2013, 23:56
von Artificial Mind
So, ich habe jetzt die Apigenerierung größtenteils fertig (bis auf Callback-Delegates, die müssen noch manuell geschrieben werden).

Hier mal ein kleines Beispiel wie das aussieht (Ich hab einige normalen Kommentare rausgeschnitten, um das Beispiel etwas kleiner zu machen. Normalerweise werden alle C++-Kommentare auch in die API kopiert)

World.hh (normaler C++ Code von uns)

Code: Alles auswählen

namespace model
{

//!Api ApiObject
class World
{
private:
    //!Api Getter
    const std::string mName;

    //!Api Getter
    WorldMetadata *mMetadata;

    //!Api Getter
    physics::PhysicsWorld *mPhysics;

public:
    
    //!Api Func
    void attachCamera(CameraBase *_camera);

    [...]
};
}
WorldApi.cc (autogenerierte C-style Wrapper Code, hat noch eine ähnliche .hh)

Code: Alles auswählen

#include "WorldApi.hh"

// Auto-generated includes:
#include <Model/World.hh>

// Auto-generated usings:
using namespace model;
using namespace physics;

extern "C"
{

// Auto-generated functions:
GENESIS_API(void) API_Model_World_Function_AttachCamera_CameraBase(model::World *_this, model::CameraBase * _camera)
{
    _this->attachCamera(_camera);
}

/**
 * Auto-generated Property Getter of World:
 * World metadata
 **/
GENESIS_API(model::WorldMetadata *) API_Model_World_Property_Metadata_Getter(model::World *_this)
{
    return _this->getMetadata();
}

/**
 * Auto-generated Property Getter of World:
 * world name
 **/
GENESIS_API(const char *) API_Model_World_Property_Name_Getter(model::World *_this)
{
    return (_this->getName()).c_str();
}

/**
 * Auto-generated Property Getter of World:
 * ref to the world physics
 **/
GENESIS_API(physics::PhysicsWorld *) API_Model_World_Property_Physics_Getter(model::World *_this)
{
    return _this->getPhysics();
}

}
World.cs (autogenerierter C# API Code)

Code: Alles auswählen

// AUTO-GENERATED FILE

using Engine.Model;
using Engine.Physics;
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;

namespace Engine
{
    namespace Model
    {
        /// <summary>
        /// One World is a model part with a global coordinate system
        ///
        /// Creation and Deletion is handled by the Universe
        /// </summary>
        public partial class World : ApiObject
        {

            #region Properties

            /// <summary>
            /// world name
            /// </summary>
            public string Name
            {
                get
                {
                    return Marshal.PtrToStringAnsi(apiPropertyGetterName(UnmanagedObject));
                }
            }

            /// <summary>
            /// World metadata
            /// </summary>
            public WorldMetadata Metadata
            {
                get
                {
                    return ObjectResolver<WorldMetadata>.GetObject(apiPropertyGetterMetadata(UnmanagedObject), ptr => new WorldMetadata(ptr));
                }
            }

            /// <summary>
            /// ref to the world physics
            /// </summary>
            public PhysicsWorld Physics
            {
                get
                {
                    return ObjectResolver<PhysicsWorld>.GetObject(apiPropertyGetterPhysics(UnmanagedObject), ptr => new PhysicsWorld(ptr));
                }
            }

            #endregion

            #region Constructors

            /// <summary>
            /// internal c'tor of ApiObject World
            /// </summary>
            internal World(IntPtr _unmanagedPtr) :
                base(_unmanagedPtr, false)
            {
            }

            #endregion

            #region Functions

            public void AttachCamera(CameraBase _camera)
            {
                apiFunctionAttachCameraCameraBase(UnmanagedObject, (_camera == null ? ApiObject.InvalidHandle : _camera.UnmanagedObject));
            }

            #endregion

            #region API Dll Imports

            [DllImport("__Internal", CharSet=CharSet.Ansi, CallingConvention=CallingConvention.Cdecl, EntryPoint="API_Model_World_Function_AttachCamera_CameraBase")]
            private static extern void apiFunctionAttachCameraCameraBase(HandleRef _unmanagedWorld, HandleRef _camera);

            [DllImport("__Internal", CharSet=CharSet.Ansi, CallingConvention=CallingConvention.Cdecl, EntryPoint="API_Model_World_Property_Metadata_Getter")]
            private static extern IntPtr apiPropertyGetterMetadata(HandleRef _unmanagedWorld);

            [DllImport("__Internal", CharSet=CharSet.Ansi, CallingConvention=CallingConvention.Cdecl, EntryPoint="API_Model_World_Property_Physics_Getter")]
            private static extern IntPtr apiPropertyGetterPhysics(HandleRef _unmanagedWorld);

            [DllImport("__Internal", CharSet=CharSet.Ansi, CallingConvention=CallingConvention.Cdecl, EntryPoint="API_Model_World_Property_Name_Getter")]
            private static extern IntPtr apiPropertyGetterName(HandleRef _unmanagedWorld);

            #endregion
        } // class World
    } // namespace Model
} // namespace Engine
An dem Beispiel sieht man schon, dass kompliziertes und vielschichtiges Marshalling mit in Betracht gezogen werden muss (z.B. bei std::string, aber auch bei Pointern generell). Vieles davon wird bereits richtig umgesetzt, aber es ist echt mühselig. Die C# Klassen werden alle als partial deklariert, damit wird ganz einfach manuelle API-Erweiterungen einbauen können, ohne dass die Dateien in Konflikt geraten.

Re: [Projekt] Upvoid

Verfasst: 11.05.2013, 00:41
von CodingCat
Und die C++-API bekommt auch Getter generiert? :D
Immer wieder erschreckend, wie eklig solche C-APIs ohne Overloading werden. Und Dinge wie ObjectResolver machen mir .NET noch madiger als es eh schon ist. ;) Unabhängig davon, wieder fantastisch, in welcher Vielfalt ihr in diesem Projekt tätig seid. Wenn ihr das rechtzeitig für was anderes als Games/3D nutzt, könnt ihr danach vielleicht richtig was verdienen. :P

Re: [Projekt] Upvoid

Verfasst: 11.05.2013, 00:44
von Artificial Mind
Ne, die C++-API wird nicht nachbearbeitet. Ich hatte die getter nur aus dem Beispiel rausgelöscht um es kleiner zu machen. Solange man sich an unsere Naming Conventions hält, haben wir ein "CLASS_GETTER(type, varname)"-Makro, welches uns dort zu viel copy'n'paste erspart.

ObjectResolver ist übrigends von mir selbst geschrieben, weil es momentan die sicherste Lösung war, vernünftige Objekteidentitäten zu haben (zwei gleiche zurückgegebene IntPtr ergeben das gleiche C#-Objekt).

Re: [Projekt] Upvoid

Verfasst: 01.02.2014, 04:41
von Artificial Mind
Auch wenn ich hier lange nichts mehr gepostet habe: Wir haben viel geschafft und suchen jetzt Alpha-Tester für unser erstes Tech Demo Game!
Man kann sich dafür auf dieser Seite registrieren: https://upvoid.com/miner/about/

Hier unser neues Video mit voice-over von Marcus:
[youtube]aSiFBJQ7heo[/youtube]

Auch wenn sich grafisch nicht besonders viel verändert hat, so haben wir viel interne Technik geschafft.
Ein besonders wichtiger Schritt war die Verwendung von .NET unter Windows. (Wir nutzen Mono 3.2 unter Linux, aber das hat sich unter Windows als zu instabil erwiesen)
Es ist zwar einiges an Arbeit gewesen, trotzdem haben wir jetzt die Api-Anbindung unserer Engine in C++/CLR geschrieben.
Dabei sind auch wirklich nur die Dateien, die auf .NET zugreifen müssen mit /clr kompiliert, sodass der Rest vom Code immer noch garantiert nativ ist.

Weiterhin sind wir von Dual Contouring zu Cubical Marching Squares übergegangen, welches ein wenig die Vorteile von Dual Contouring (Feature Sensitivity) mit denen von Marching Cubes (unabhängige Zellen, mehr geometrisches Detail) vereint.
Dort ist zwar noch nicht alles implementiert, trotzdem kann ich diese Technik bereits sehr empfehlen.