Suche GUI-Entwickler für Textur-Generator (.NET) / GUI developer for hire

Willkommen in der Transport Fever Community

Wir begrüßen euch in der Fan-Community zu den Spielen Transport Fever und Train Fever, den Wirtschaftssimulatoren von Urban Games. Die Community steht euch kostenlos zur Verfügung damit ihr euch über das Spiel austauschen und informieren könnt. Wir pflegen hier einen freundlichen und sachlichen Umgang untereinander und unser Team steht euch in allen Fragen gerne beiseite.

 

Die Registrierung und Nutzung ist selbstverständlich kostenlos.

 

Wir wünschen euch viel Spaß und hoffen auf rege Beteiligung.

Das Team der Transport-Fever Community



  • Hallo zusammen,


    die Texturierung meiner Triebwagenhalle hat mir echte Kopfschmerzen bereitet. Die Seitenflächen sind wahnsinnig groß und ich konnte keine wirklich passenden Texturen finden. Alles was halbwegs meine gewünschten Farben hatte, war nur als Kachel verfügbar und selbst riesige Texturen in anderen Farben waren nicht groß genug, um einen realistischen Maßstab zu erhalten. Ein Ziegelstein sollte nunmal nicht einen Meter lang sein ;-)


    Also mußte ich kacheln. Hier, das ist eine seamless Kachel, die perfekt meine Vorlage imitiert:


    Also hab ich gekachelt. Und es sah furchtbar aus. Wirklich furchtbar:


    Die Kacheln sind zwar seamless, aber Schmutz und Schattierungen wiederholen sich nunmal und da ich besonders große Flächen habe, mußte ich besonders viele Kacheln verwenden. Ich hab es mit Tricks versucht, wie Kacheln spiegeln, drehen und versetzen, um etwas Zufälligkeit reinzubringen, aber das sah noch schlimmer aus. Dann hab ich versucht, es mit zusätzlichem Schmutz zu maskieren, aber auch das brachte nicht den gewünschten Effekt. Es sah so unecht aus, daß ich mein Projekt fast eingestellt hätte.


    Aber dann hatte ich eine Idee: Warum nicht selbst mauern?


    Also nahm ich die Kachel und schnitt Ziegelsteine aus. Alle Ziegelsteine - außer die Halbsteine. Ich bekam insgesamt 52 Steine aus dieser Textur in all den unterschiedlichen Farben.
    Dann schrieb ich eine kleine Console Application in .NET und baute mir die Steine zu einer Mauer zusammen. Dabei wird per Zufallsgenerator einer der 52 Steine ausgewählt, eingesetzt und der nächste Stein per Zufall ausgewählt, eingesetzt usw. Das Resultat sah so aus:


    Besser, oder?


    Nun hab ich das Tool so geschrieben, daß es sehr flexibel ist und für alles mögliche eingesetzt werden kann. Folgende Features sind drin:

    • Kacheln können versetzt werden - so kann man Fliesen machen, wie ein Schachbrett oder um 50% versetzt, wie eine Ziegelmauer, oder jeden beliebigen anderen Versatz (in Prozent)
    • Die Kacheln werden normalisiert - d.h. wenn die einzelnen Ziegelstein-Bilder (oder was auch immer Ihr als Kacheln verwenden wollt) nicht alle die selbe Größe haben, werden sie einzeln auf eine vorher festgelegte einheitliche Größe skaliert
    • Die Dicke der Fugen kann in Pixeln angegeben werden
    • Die Farbe der Fugen kann in RGB mit Alphakanal angegeben werden - ich hab meine Fugen transparent gemacht, so daß ich in Gimp die Fugenfarbe jederzeit per Hintergrundbild ändern kann
    • Die Anahl der "Spalten und Zeilen" muß vorher angegeben werden, also wieviele Kacheln in X- und Y-Richtung erzeugt werden sollen
    • Der Speicherort der einzelnen Kachelgrafiken und der Ausgabeort der fertigen Textur müssen separat angegeben werden

    Was fehlt eigentlich?


    Eine GUI! Für meine Zwecke hat eine Konsolenanwendung gereicht. Alle zu konfigurierenden Werte hab ich in die app.config getan un dann meine Textur auf der Shell generiert. Aber so kann man das natürlich niemandem anbieten.


    Warum mache ich die GUI nicht selbst?


    Ich bin nicht gut im UI-Design, ich mag kein WindowsForms, ich hab wenig Erfahrung mit WPF und eine Webanwendung wäre wünschenswert, aber ich hab keinen Hoster für .NET. Außerdem hat das Tool seinen Zweck erfüllt: ich hab meine Textur und die Triebwagenhalle ist fertig, also warum noch mehr Zeit investieren?


    Aber ich hab alle Logik in einer DLL. Man kann also statt meiner Konsolenanwendung einfach eine Fensteranwendung - oder eine Website - obendraufsetzen.


    Hat jemand Lust und Interesse?


    Wenn ja, kann ich die DLL hier teilen und eine knappe Schnittstellendokumentation reinsetzen. Also wenn jemand von Euch eine GUI machen möchte, laß uns zusammenarbeiten!


    [line][/line]
    Short version in English:


    I made a texture generator, that combines tiles in a matrix. The first image above is my original seamless tile. The second image is a brickwall created by repeating this tile - it shows how bad it looks due to the repeating pattern. The third image shows a generated wall texture composed of 52 single bricks, which I cut out of the seamless tile and which I combined randomly to generate a wall of any arbitrary size. My texture generator is simply taking any random tile from a folder, normalizes it to a specified size and combines it to a matrix of a specified size to get rid of the pattern and make a truly random texture. All I made is a DLL and a console application with app.config which did the job for me.


    Now if someone could create a GUI to replace the console application, everyone could use this tool for their own textures.

  • Die Idee find ich super! Diese Probleme bei den Texturen sind immer ein graus und so ein Tool ist echt nützlich. Leider beschränken sich meine Programmierkenntnisse auf einfache Dinge, sowas komplexes ist nicht drinne. Wäre aber wirklich super wenn einer unserer Modder sich dem Problem annimmt und ne GUI "drüberzieht" :)

  • Ja sehr cool! Wir haben keinen Zeitdruck, also nur nicht hetzen lassen. Ich hab mal die DLL angehängt. Einfach referenzieren.


    Das ist mein Code in der Console-Application:



    Die Config benötigt folgende Werte:


    Property
    Description
    Note
    TilesLocationOrdner in dem all die Ziegelsteine liegen
    OutputFilenameOrdner und Dateiname für die zu generierende Texturimmer PNG
    TileMatrixSizeAnzahl der Ziegelsteine in x- und y-Richtung"width" sind die Spalten, "height" sind die Zeilen
    TileSizeEinheitliche Größe jeder Ziegelstein-Grafik; alle Ziegelsteine werden auf diese Einheitsgröße skaliert width/height in Pixel
    GapSizeDicke der Fugenin Pixel
    BackgroundColorFarbe der FugenSystem.Drawing.Color
    StaggeredRatioVersatz der Zeilen in Prozent0.5 (=50%) entspricht einem Versatz von einer halben Ziegelsteinlänge
    TextureWidth
    Breite auf welche die zu generierende Textur skaliert wird
    Dieses Feature ist im Augenblick deaktiviert


    ITileFactory


    Die 'RandomTileFactory' implementiert IFileFactory und macht nichts weiter als zufällig einen Ziegelstein aus dem Ordner (in 'TilesLocation') zu fischen und auf die Einheitsgröße zu skalieren.


    ILogger


    Den ILogger müßtest Du selbst implementieren.


    Code
    namespace ImageTiler.Domain
    {
     public interface ILogger
     {
     void Log(string message);
     }
    }


    Ich hab auf die Console ausgegeben und mir daher einen ConsoleLogger geschrieben. Das geht ja bei Dir nicht. Also entweder Du implementierst einen eigenen ILogger oder zu verzichtest auf Logging und instanziierst einfach den 'DefaultLogger'.


    EDIT: Du kannst eigentlich komplett auf den Logger verzichten. Ich hab ihn nur geschrieben, um die Zeilennummern auszugeben, damit ich auf der Konsole den Fortschritt sehen kann. Sonst logge ich nichts - ergibt also keinen Sinn, das in ein Logfile zu schreiben.


    TilingProcessor


    Der TilingProcessor macht die eigentliche Arbeit. Er benötigt die Config, die TileFactory und den Logger.


    GUI


    Es sollte nicht viel Arbeit sein. Die denkbar einfachste GUI wäre einfach ein simples Form, in dem man alle Config-Werte eingibt, einen Knopf drückt und die Textur wird dann erzeugt. Das wars.


    Wenn man es etwas luxuriöser haben will, könnte ich mir folgende Features vorstellen:
    - Locations könnte man per FileOpen-Dialog (Browse) einstellen, statt nur ein Textfeld.
    - Man könnte erlauben, die Werte zu speichern/laden, damit man nicht jedesmal alles neu eingeben muß.
    - Man könnte die generierte Textur direkt anzeigen.


    Aber Du bist der UI-Mensch, Du solltest freie hand/Entscheidungsfreiheit haben, wie Du es gern umsetzen möchtest.


    Probleme


    Je nach Größe der Matrix kann das resultierende File extrem groß werden! Für meine Triebwagenhalle hab ich eine Textur erzeugt, die über 20.000 Pixel breit war (360x170 Ziegelsteine). Ich hab erst versucht, das File direkt im Programm runterzuskalieren (daher der Config-Value 'TextureWidth'), aber es gab haufenweise OutOfMemoryExceptions, dahr ist der Code auskommentiert. Ich hab dann die generierte 20.000-Pixel-Datei mit Irfanview runteskaliert auf meine 2048 und das ging auch.


    Wenn Du Fragen hast, jederzeit. :-)

  • Hallo


    Zuerst: Spitzenidee


    Also nahm ich die Kachel und schnitt Ziegelsteine aus. Alle Ziegelsteine - außer die Halbsteine. Ich bekam insgesamt 52 Steine aus dieser Textur in all den unterschiedlichen Farben.


    Du hast ja, aus handwerklicher Sicht, eine Halbsteinmauer (11.5cm Dicke) gebaut. Deine Beschreibung lässt mich vermuten, dass der Einsatz von Halbsteinen vom Programm nicht berücksichtigt wird.


    Ließe sich einrichten (den Aufwand kenne ich nicht), dass der Interessierte Nutzer eine Konfiguration (z.B. als Textdatei) der Steine vorgeben kann, bei der Halbsteine enthalten sind? Ob man das in TF überhaupt sieht, weiß ich nicht, aber solch ein Programm wäre ja auch jenseits von TF interessant. Das Problem mit den sich allzu schnell wiederholenden Texturen ist ja nicht nur hier bekannt.


    Tschö, Auge

  • Achso, also ja ich kenne mich da nicht so aus. Ich meinte mit Halbstein die senkrecht verbauten Ziegel, die da in den drei Reihen der ausgangskachel zu sehen sind.


    Wenn ich Dich richtig verstehe, möchtest Du unterschiedlich große Steine verbauen? Also der Algorithmus skaliert alle Steine auf eine einheitliche Größe. Es können Kacheln jeder Form und Größe verwendet werden, aber am Ende sind alle gleich groß. Ein spezielles Muster wäre sehr aufwendig. Ich möchte eigentlich nicht mehr weiter dran arbeiten - ich wollte meine fertige Arbeit nur allen verfügbar machen, daher suche ich eine GUI.

  • Achso, also ja ich kenne mich da nicht so aus. Ich meinte mit Halbstein die senkrecht verbauten Ziegel, die da in den drei Reihen der ausgangskachel zu sehen sind.


    Hehe, senkrecht sind die nicht, das sind die kurzen Seiten der Ziegel.


    Ich möchte eigentlich nicht mehr weiter dran arbeiten - ich wollte meine fertige Arbeit nur allen verfügbar machen, daher suche ich eine GUI.


    Schade, ist aber ok. Oder magst du die DLL so lizensieren, dass das jemand anders implementieren kann und darf?


    Tschö, Auge

  • Ja die kurzen Seiten meinte ich doch :-D Die sind halt um 90 Grad gedreht, von oben gesehen senkrecht.


    Ja also ich stelle gerne den Quellcode zur Verfügung, kein Problem. Ist aber echt keine Raketenwissenschaft. Nur ein paar Schleifen und die Draw-Library von Microsoft. Richtige Muster mit verschiedenen Steinen zu generieren ist definitiv echter Aufwand. Der Rest ist Pipikram dagegen ;-)


    Du kannst Dir aber theoretisch auch einfach drei Texturen generieren: eine mit 5 Reihen normale Steine, eine Reihe "senkrechte" und drei Reihen normal. Die drei Texturen fügst Du dann einfach zusammen. Mir ging es ja vordergründig um das Erzeugen von zufälligen Texturen und das Vermeiden von Mustern. Und das kannst Du ja tun.

  • Hab mir mal eben ne Stunde Zeit genommen und schnell was zusammen geklickt. So ungefähr stelle ich mir das vor. Denke ich brauch da nichts weiter zu erklären. Vielleicht mach ich unten noch ein TextFeld für die Logs rein aber ich muss erstmal schauen was da überhaupt als Output kommt.


    Was man sich noch überlegen müsste ist wo Zahlen mit Kommastellen sinnvoll sind bei den NumericUpDown Elementen und welche Min/Max Werte da sinnvoll sind.


    Zitat

    - Locations könnte man per FileOpen-Dialog (Browse) einstellen, statt nur ein Textfeld.
    - Man könnte erlauben, die Werte zu speichern/laden, damit man nicht jedesmal alles neu eingeben muß.
    - Man könnte die generierte Textur direkt anzeigen.


    Kurz gesagt: Soweit alles drin, inklusive ColorPicker, Resizeable usw... Muss jetzt quasi nur noch das Bild an sich generieren. ;) Außerdem würde ich es gleich multilingual machen (Englisch/Deutsch)



    PS: Entschuldigt bitte das Win XP, habe auf meinem MacBook hier keine andere VM mit VisualStudio. :whistling:

  • Geil! Sehr geil! Preview und Save brauchen wir aber nicht zu trennen. Wenn Du die Methode processor.Tile(); aufrufst, wird direkt in die Output-Location geschrieben. Der Previewbereich ist also entweder nutzlos - oder er zeigt eben nur an, was gerade gesaved wurde, was ich natürlich cool fände. Falls Dir das nicht gefällt, könnte man im Preview vielleicht die einzelnen Tile-Images anzeigen, die im Inputfolder liegen, aber das ist zusätzliche Arbeit, die vielleicht nicht nötig ist.


    Wenn Du irgendwas von mir brauchst oder Änderungswünsche für die API hast, nur her damit. Ich kann alles ändern wie Du es gern möchtest.

  • Ich hab mir halt gedacht das man in der Output Location nur den Ordner festlegt. Wenn ich dann auf Preview klicke erstelle ich erstmal was temporäres. Erst wenn ich auf Save drücke öffnet sich der FileDialog inkl Dateinamen.


    Eventuell komme ich vielleicht auch an einen ASP.NET Server, mache ich aber nach der "Client" Version.

  • Hmm... Naja wir können eine Preview natürlich machen, das ist kein Thema und wenn Du das möchtest, bekommst Du es von mir. Aber mal ganz sachlich betrachtet ergibt es keinen Sinn. Um das Preview zu erzeugen müssen wir es trotzdem speichern - dann halt im Temp-Folder. Und wenn Du dann "save" klickst, generieren wir die ganze Textur nochmal von vorne (also doppelt), diesmal in den eigentlichen Output-Folder. Mir erschließt sich der Sinn nicht so ganz. Dann kann ich es auch gleich in den Outputfolder rendern und bin verschwende weniger Zeit. Und je nach Größe der Matrix und Kacheln kann es durchaus ne Weile dauern, bis die Textur gerendert ist, vielleicht bis zu ca. 30 Sekunden oder so. Und: die Textur kann mitunter gigantisch groß werden und ich spreche hier von mehreren hundert MB (20.000 Pixel breit - ja zwanzigtausend!) =O Ich kann ja mal ein paar Benchmarks machen...

  • Ansich finde ich den Ansatz und die Idee nicht schlecht, aber im Ergebnis erhältst du eine Textur, wie ich es erlese, von TextureWidth = 2048.
    Das bringt natürlich ein riesen Performanceproblem für den V-RAM, da die Wand nicht die einzige Textur ist.


    Als Regel gilt immer: 1 Pixel pro Zentimeter (max. 1 Pixel pro 2 cm), dementsprechend muss man das Modell baulich strukturieren und eine qualitativ hochwertige Texturvorlage haben die bspw. 256, oder 512 nicht überschreitet.

  • Du hast es falsch erlesen - eigentlich hast Du das ganze Thema nicht verstanden.
    Zum einen ist das ein Konfigurationswert, den Du als User angibst. Die Idee war, daß Du dort jeden beliebigen Wert angeben kannst den Du möchtest und die Textur dann in der Größe ausgegeben wird. Aber da steht auch eindeutig "Dieses Feature ist im Augenblick deaktiviert" und ich erkläre sogar ausführlich warum:

    Zitat von Jan

    Je nach Größe der Matrix kann das resultierende File extrem groß werden! Für meine Triebwagenhalle hab ich eine Textur erzeugt, die über 20.000 Pixel breit war (360x170 Ziegelsteine). Ich hab erst versucht, das File direkt im Programm runterzuskalieren (daher der Config-Value 'TextureWidth'), aber es gab haufenweise OutOfMemoryExceptions, dahr ist der Code auskommentiert. Ich hab dann die generierte 20.000-Pixel-Datei mit Irfanview runteskaliert auf meine 2048 und das ging auch.


    Und drittens, wir generieren hier keine fertigen Texturen, sondern Muster für Deine Texturen. Wenn Du Dir ein Backsteinmuster aus dem Netz runterlädtst, mußt Du es ja auch noch anpassen, oder? Mit diesem Tool ist es nichts anderes.

  • Ich habe das schon verstanden, worauf ich mich beziehe ist die bauliche Umsetzung, die sich auf die 2048er bezieht und das ist falsch.
    Wenn man eine entsprechende Engine hat, dann geht das sogar generell mit einer 128er. Static ist nicht Vehicle.

BlueBrixx