Quantcast
Channel: Think for yourself!
Viewing all 65 articles
Browse latest View live
↧

SOPA PIPA Groove

$
0
0
Was für ein Tag.
Das Internet trägt Schwarz.
Jedenfalls das amerikanische Internet. Aber auch deutsche Seiten beteiligen sich.
https://plus.google.com/photos/109494794478503346057/albums/5698915312787560865

Und Warum das Ganze?
Na wegen SOPA PIPA!
http://blog.zdf.de/hyperland/2012/01/sopa-wie-das-web-gegen-netzsperren-auf-die-barrikaden-geht/


Und nun hat auch noch GrooveShark seine deutsche Seite dicht gemacht:
Ganz und gar unschuldig sind sie selber aber nicht:
https://www.gema.de/presse/aktuelle-pressemitteilungen/presse-details/article/grooveshark.html

Jetzt sind also wieder neue Quellen gefragt.
Zum einen funktioniert noch der HTML5 Player von GrooveShark:
http://html5.grooveshark.com/#/search/flobots
Aber dies ist nur sehr rudimentär.

Als richtige Alternative würde ich da wohl eher Musicuo empfehlen:
http://www.musicuo.com/?lg=en#/search/q:Flobots

Vielleicht simfy?
http://www.simfy.de/artists/1975-Flobots

Simfy und Musicuo haben beide nicht Bop Skizzum:
http://www.bopskizzum.com

Also was gäbe es da sonst noch für Anbieter?
↧

Oil Rush Kurz-Review

$
0
0

In den letzten Tage habe ich mich endlich mal dazu durch gerungen Oil Rush durch zu spielen.

Inhaltlich ist Oil Rush in der nahen Zukunft angesiedelt. Nach einem Nuklearkrieg ist die Welt überflutet. Die wichtigste und einzige Ressource zum Fortbestehen und der Weiterentwicklung ist Öl.

In dem Strategiespiel, in dem alle Handlungen in Echtzeit ablaufen, steuert der Spieler Einheiten, setzt Verteidigungen und aktiviert Spezialfähigkeiten. Die Interaktionen erinnern dabei eher an ein Tower Defence Spiel.

Die Einheiten können nur von einer Plattform zu einer anderen geschickt werden. Freie Bewegungen sind nicht möglich. Ebenso gibt es keine Einzelselektion der Einheiten. Zur Auswahl wählt man die entsprechende Plattform, um die die gewünschten Einheiten kreisen. Es ist auch möglich mehrere Plattformen gleichzeitig zu markieren um von dort Einheiten an einen Punkt zu befehlen. Um die Auswahl ein wenig zu differenzieren, kann man zwischen 25%, 50% und 100% der Einheitenanzahl wählen. Man darf außerdem sich noch entscheiden, welche Einheitentypen man verschicken will.

Zur Verteidigung kann man bis zu fünf Selbstschussanlagen um seine Plattform postieren. Zur Auswahl stehen hier drei verschiedene Verteidigungstürme, die durch Bezahlung von Öl mehrmals verbessert werden können.

Die Spezialfähigkeiten können im Verlauf eines Spielabschnitts durch Einsatz von gewonnenen Erfahrungspunkten erworben werden. Es stehen dabei drei unterschiedliche Bäume zur Verfügung. In jedem Baum gibt es aktive und passive Fähigkeiten, die zum Beispiel Angriff und Verteidigung von Einheiten erhöhen oder neue Einheiten, wie Reparationsschiffe und U-Boote zum Kauf ermöglichen.

Mein Spielsystem ist ein AMD x4 2500MHz mit AMD HD4770 Grafikkarte und 6GB Ram. Darauf läuft ein Debian Testing in 64Bit.

Oil Rush setzt auf die Unigine Engine der Unigine Corp und wurde von Unigine Corp entwickelt und vertrieben. Es läuft nativ unter Windows, Mac und Linux. Eine PS3 Version soll ebenfalls folgen. Weitere Informationen und die Möglichkeit zum direkten Kauf von Oil Rush aus dem hauseigenen Unigine Store gibt es hier: http://oilrush-game.com/

Auf geht es ins Spiel!

Als Spieler kann man sich entscheiden, ob man die Kampagne spielt, oder sich gegen die künstliche Intelligenz oder Spieler aus aller Welt misst.

Zum Messen stehen 15 Karten für zwei bis vier Spieler zur Auswahl. Die Spieler können sich auch in Teams zusammen finden. So können schnelle Partien ausgeführt werden, die aber auch unter Umständen sich über einige Stunden hinziehen können.

Die Kampagne enthält vier Kapitel. Jedes Kapitel hat mehrere Storypunkte und ist in einer anderen Umgebung angesiedelt. Die Punkte verteilen sich wie folgt: Kapitel 1 - 4 Punkte, Kapitel 2 - 5 Punkte, Kapitel 3 - 4 Punkte und Kapitel 4 - 3 Punkte. Insgesamt hat man somit 16 spielbare Storypunkte.

Im leichtesten Schwierigkeitsgrad habe ich ungefähr 9 Stunden für die komplette Story gebraucht. Der Schwierigkeitsgrad lässt sich für jeden Storypunkt individuell auswählen. Für ein Strategiespiel ist das sehr wenig. Allerdings handelt es sich hier nicht um ein normales Strategiespiel. Der Basisaufbau, welcher oft eine enorme Zeit in Anspruch nimmt, entfällt hier. Das Spiel kommt an sich somit ganz flüssig voran.

Durch diese Kürze wird dem Spieler auch mit jedem Abschnitt etwas neues geboten. Zum einen erweitert sich der Spezialfähigkeitenbaum und zum anderen kommen neue Einheiten und Spielmodie zum Einsatz.

Der normale Modus ist das komplette Besiegen des Gegners. Dafür müssen alle Plattformen eingenommen und alle gegnerischen Einheiten vernichtet werden. Im weiteren Verlauf trifft man auf typische Tower Defence Level. An einer Route müssen Verteidigungstürme errichtet und gehalten werden um die gegnerischen Einheiten aufzuhalten. Ein weiterer Modi ist Flucht. Am Levelbeginn steht eine bestimmte Anzahl von Einheiten, die durch unsicheres Gebiet geleitet werden muss. Meist drängt von hinten der Feind. Schwierig wird es, wenn man Karawane begleiten muss und diese gerne etwas trödeln.

Als Vorbesteller durfte ich das Spiel schon seit März letzten Jahres spielen. Es gab allerdings nur die Schnellspiele gegen die künstliche Intelligenz und später auch mit und gegen richtige Spieler. Ein Match ab und an und ständig verbesserte Versionen waren sehr erfrischend.

Mit dem Spielen der "fertigen" Version und somit der Kampagnen bin ich im Prinzip ziemlich zufrieden. Einige Abschnitte musste ich zweimal spielen um zu gewinnen. Gerade, da ich auf einfach gespielt habe, war ich doch etwas verwundert darüber.

Besonders finde ich, dass das Unigine Team maximal 10 Leute umfasst, die komplette Engine ist selbst geschrieben und sowohl die Engine, als auch das Spiel native für Linux verfügbar sind. Auch ist der Support des Teams hervorragend. Wir Spieler hatten viele Vorschläge unterbreitet, von denen viele mit eingeflossen sind. Fehler wurden fix behoben.

Noch fehlen einige Dinge, wie das Mod-SDK, die Demo und der Master-Server für nicht-Steam-Benutzer. Für letzteres hat die Community vorerst ein eigenes kleines Projekt auf die Beinge gestellt (http://adrian.batzill.com/oilrush/vpnusers.php).

Alles in allem bin ich sehr zufrieden; sowohl mit dem Spiel, als auch mit dem Team Unigine.

Ein großes Lob an Unigine. Macht weiter so.

Hier noch einmal der direkte Verweis zum Spiel: http://oilrush-game.com/

(Wünsche, Anregungen, Verbesserungen, Kritik etc. sind gerne gesehen.)

↧
↧

Finished: Not Alone

$
0
0
After days and days and maybe weeks of work I finally I kind of finished my game "Not Alone". It started as a little idea on Ludum Dare 22 (http://www.ludumdare.com/compo/ludum-dare-22/?action=preview&uid=5888). And now I made a bit more out of it for a project at university.

You are a big  ball and try to get into the goal together with your little ball. On that way your companion must go through doors and you must collect monkeys and trigger a trigger.
Simple as that.

I used some stuff from "the internet". Thanks for sharing, dudes!
<--= Blender =-->

"Andreas Esau" for "easyEmit"
http://blenderartists.org/forum/showthread.php?241656-easyEmit-*Update*-TestAddon-available
http://dl.dropbox.com/u/1250100/easyEmit/EasyEmit.blend

"Martins Upitis" for "unlimited planar reflections & refraction"
http://blenderartists.org/forum/showthread.php?242940-unlimited-planar-reflections-amp-refraction-%28update%29
http://dl.dropbox.com/u/11542084/water_surface_1.0.blend

"MrLarodos" for "MiniMap"
http://larodos.de/?page_id=2
http://www.youtube.com/watch?v=pYqJzjrTnHQ

Blender
http://www.blender.org/


<--= Sound =-->

"Synthirius" for "Discomatic"
http://www.jamendo.com/en/album/105822

"CorrodedMaster" for "2329__Jovica__STAB_004_mastered_16_bitREMIX.wav"
http://www.freesound.org/people/CorrodedMaster/sounds/120872/

"jnr hacksaw" for "11221__jnr-hacksaw__zap.flac"
http://www.freesound.org/people/jnr%20hacksaw/sounds/11221/

<--= Done =-->


Now if you wanna play this game then grab all files from:
http://code.google.com/p/manuel-bellersen/source/browse/?repo=gt4--not-alone
and start MainMenu.blend from Blender.

Have fun!

------zip-----
I managed to put up some zips:
One for Windows 64Bit:
http://code.google.com/p/manuel-bellersen/downloads/detail?name=manuel-bellersen.gt4--not-alone.zip

and a generic one where you need Blender to start it:
https://bitbucket.org/Urfoex/gt4-not-alone.manuel-bellersen/get/d700455c06e9.zip





↧

COGLAINI-B GameEngine

$
0
0
Ein neues Semester hat begonnen. Die letzten Projekte aus dem alten Semester sind beendet. Darunter war auch "COGLAINI-B".

"COGLAINI-B" ist eine Gameengine.
Folgende Features sind enthalten:
- geschrieben in C++
- Buildsystem CMake
- Grafik: OpenGL 3.3
- Physik: Bullet
- Grundfunktionen (Maus, Tastatur, Sound, ...): SFML
- Kinect: OpenNi, Nite
- Model-Dateien: Assimp

Programmiert und getestet wurde unter Linux und Windows. Mac sollte ggf. ebenso funktionieren. Sie steht jetzt frei unter der GPL (siehe Repo) zur Verfügung. Vielleicht kann ja irgendjemand daraus etwas lernen ^__^

Hier liegt's:
https://bitbucket.org/Urfoex/coglaini-b/


Viel Spaß!



PS: Hier noch ein bisschen Text aus der "coglaini-b README.txt":
-=== GT3 ===-

=== Was ist drin ===

  • C++, 
  • OpenGL3, 
  • Bullet Physics (nicht animierten Meshes haben Physics, animierte siehe Kick-Teil), 
  • Grafik (Shader, Texturen, Licht, Debugansichten), 
  • Animation, 
  • Skelett, 
  • Hintergrundmusik, 
  • Sound, 
  • mehrere umschaltbare Szenen und Kameras (kamera mit physik),
  • Kinect (OpenNI, NITE), 
  • shoot physics box

=== gesplittet in 2 Teile ===

  • Masterbranch (Hauptbranch, versch. Szenen (wechseln mit "n") mit Physics, Features siehe oben, Steuerung siehe unten)
  • Kick (Physics an animiertem bone "befestigt", der fallende Kisten wegkickt)

=== Hinweis ===

FPS Kamera besser zur ansicht (einschalten mit "v")

=== Steuerung ===

  • W - forward
  • S - backward
  • A - strafe left
  • D - strafe right

  • left Ctrl - fly down
  • Space - fly up
  • Q - roll left
  • E - roll right

  • C - change camera number
  • V - toggle camera FLY - FPS mode
  • P - toggle draw mode (POINT LINE FACE)
  • N - switch scene

  • F1 - toggle debug draw
  • F2 - toggle debug draw mode ( WIREFRAME FACE)
  • F3 - toggle ghost mode

  • Z - next song
  • U - previous song

  • Return - shoot box

  • Mouse move - rotate camera
  • Mouse press - shoot box

== Kinektsteuerung Masterbranch ==

  • Handbewegung zum Kalibrieren
  • Hand -> Maus (Bewegung links, rechts, hoch, runter)
  • Hand nach vorne -> Box schiessen

↧

Zulassung zum Indipendent Courseworks 1

$
0
0
In diesem und im nächste Semester sind zwei Indipendent Courseworks vorgesehen. Die Themenfindung ist soweit abgeschlossen. Folgendes ist dabei herausgekommen:

Titel:
Entwicklung eines Entwicklungskits auf Basis von iodoom3 und Demos und
SDKs von Doom3 und Quake4.

Typ:
Independent Production

Kurzbeschreibung:
Die id Tech 4 Engine wurde am 22.11.2011 als iodoom3 unter der GPLv3
freigegeben.(1)(2)(3)
Doom3 war das erste Spiel, dass auf diese Engine setzt. Aktuelle Titel
sind Brink[2011] und Prey 2[2012].(4)
Des weiteren existieren Demos und SDKs für Doom3 (7) und Quake4 (8).
Auf Basis dieser verschiedenen Pakete (Source Code, Demos, SDKs) soll ein
Entwicklungskit, ähnlich Unity3D, UDK und CryEngine SDK, gebaut werden.
Das Entwicklungskit soll auf den bereits gegebenen Betriebssystemen,
Windows, Linux und Mac, nutzbar sein.
Der Einstieg in die Nutzung des Kits soll durch die Bereitstellung eines
Startprojektes ähnlich dem des UDK vereinfacht werden.
Gegebenenfalls sollen Tools zur Automatisierung und Vereinfachung von
Abläufen erschaffen werden.

Weiterführung:
Für das Indipendent Coursework 2 ist angedacht, die zur Verfügung
stehenden Werkzeuge und Editoren zum Beispiel auf ihre
Funktionstüchtigkeit auf den verschiedenen Betriebssystemen zu analysieren
und gegebenenfalls zu portieren bzw. durch Alternativen zu ersetzen.
In der Masterarbeit soll das entstandene Entwicklungskit am Beispiel der
dokumentierten Erstellung eines Spieles getestet werden.

Stichwörter:
Gaming, Entwicklungskit

Abgabe:
Entwicklungskit + Dokumentation

Links:
(1) https://github.com/TTimo/doom3.gpl
(2) https://github.com/id-Software/DOOM-3
(3) http://www.iodoom3.org/

(4) http://en.wikipedia.org/wiki/Id_Tech_4#List
(5) http://www.iddevnet.com/
(6) http://www.modwiki.net

(7) ftp://ftp.idsoftware.com/idstuff/doom3/
(8) ftp://ftp.idsoftware.com/idstuff/quake4/
↧
↧

The Humble Indie Bundle V -- on Debian 64

$
0
0
The Humble Indie Bundle V
is going around.
You can find it currently here: https://www.humblebundle.com/

Trying to run those games I got some error.
First: Superbrothers: Sword & Sworcery EP

After extracting the tar.gz I run the run.sh getting this:
$ ./run.sh
dirname: extra operand `Indie'
Try `dirname --help' for more information.
./run.sh: 20: ./run.sh: ./swordandsworcery: not found
The problem arises from having the game in a location with spaces that looks like this "/Humble Indie Bundle 5/".
So I changed the run.sh to look like this:
#!/bin/sh
# Get game directory
GAMEDIR=`dirname "$(readlink -f "$0")"`
LIB=$GAMEDIR/lib
BIN=$GAMEDIR/bin

# Ensure the log directory exists
LOGDIR=~/.capy/SwordAndSworcery
mkdir -p $LOGDIR

# For multi-monitor displays, choose a screen to display on to avoid having
# the game be displayed in the middle across both screens in fullscreen mode
#export SDL_VIDEO_FULLSCREEN_DISPLAY=0

# Modify library paths here
export LD_LIBRARY_PATH="$LIB":"$LD_LIBRARY_PATH"

# Run the game and try to log any errors if any
cd "$BIN"
./swordandsworcery $@ 2>&1 | tee -a $LOGDIR/log.txt

exit
(You could also move the game to a position where is no space inside the path.)
Second: LIMBO
It is not a native game as it runs within wine that comes with the package. Using the launch-limbo.sh I haven't encountered any problems so far.
I'm not quite happy seeing games using wine inside a bundle. But at least it is packed good enough for endusers to nearly not notice.

Third: Bastion
$ ./Bastion-HIB-2012-05-29-2.sh
Verifying archive integrity... All good.
Uncompressing Installer for Bastion.............
Uncompressing sub archive...........................................................................................................
Collecting info for this system...
Operating system: linux
CPU Arch: x86_64
Error: Couldn't find any suitable frontend for your system
There might be different reasons why this happens.
Maybe it really couldn't find a suitable frontend or your /tmp is full.
Therefore you can try some frontends like this:
$ ./Bastion-HIB-2012-05-29-2.sh --frontend=ncurses

Or the long way:
1) Extract it (Be sure to have NO space in the extraction path):
$ ./Bastion-HIB-2012-05-29-2.sh --target ~/BastionExtract --noexec --keep
Creating directory ~/BastionExtract
Verifying archive integrity... All good.
Uncompressing Installer for Bastion.............
2) Move into the new folder:
cd ~/BastionExtract

3) Execute the installer:
$ ./startupinstaller.sh
Uncompressing sub archive....................................................................
Collecting info for this system...
Operating system: linux
CPU Arch: x86_64
Nixstaller version 0.5.2, Copyright (C) 2006 - 2011 of Rick Helmus
Nixstaller comes with ABSOLUTELY NO WARRANTY.
Nixstaller is free software, and you are welcome to redistribute it
under certain conditions; see the about section for details.
Some people are having an "exception error in Bastion when they move their mouse under Linux" with a strange DLL problem like this:
Unhandled Exception: System.TypeInitializationException: An exception was thrown by the type initializer for OpenTK.Input.Mouse ---> System.DllNotFoundException: libXi
at (wrapper managed-to-native) OpenTK.Platform.X11.Functions:XISelectEvents (intptr,intptr,OpenTK.Platform.X11.XIEventMask&,int)
(Thanks to Sebastian B. for pointing out:
http://urfoex.blogspot.de/2012/06/humble-indie-bundle-v-on-debian-64.html?showComment=1338670600798#c1059912225799058008)

The solution to this:
in the bastion folder (probably: /usr/local/games/Bastion ) in the mono folder. Edit the "config" file.
Add the following line between the <configuration> tags:
<dllmap dll="libXi" os="linux" target="libXi.so.6">
(http://blog.humblebundle.com/post/24135140832/introducing-humble-indie-bundle-v#comment-544763669)


"For people with Intel graphics and a black screen in Bastion, try this:

Quote:
To fix Bastion on Intel integrated cards, do something like the following:
force_s3tc_enable=true ./Bastion.bin.x86_64
Setting this environment variable enables a specific texture compression algorithm in the video driver. With this, the game runs great on my Intel chipset.
I followed all the tricks given here for Bastion and then ran into the black screen problem (I got a cursor and the menu was there, I just couldn't see it). Found this tip here:
https://bbs.archlinux.org/viewtopic.php?pid=1109245
Seems to work now."

"I installed the package driconf and was able to enable the option in that utility. The screen is blank no more!"


(There is also a new update available. Changelogs:
http://support.humblebundle.com/customer/portal/articles/585756-bastion-6-11-12)


Fourth: Psychonauts
(Still downloading … Will be added when done.)

Fifth: Amnesia: The Dark Descent
I got that one long time ago. So I don't test this package yet as I guess that they have made a decent work here again.
↧

C++11: fixing a bug to use chrono with clang

$
0
0
Working with chrono in C++11 is working with gcc but fails with clang on my Debian system. Reports are in:
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=666539
http://llvm.org/bugs/show_bug.cgi?id=12893



The error looks like this:

In file included from ../main.cpp:3:
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/chrono:240:10: error: cannot cast from lvalue of type 'const long' to rvalue reference type 'rep' (aka 'long &&'); types
      are not compatible
          : __r(static_cast<rep>(__rep)) { }
                ^~~~~~~~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/chrono:128:13: note: in instantiation of function template specialization 'std::chrono::duration<long &&, std::ratio<1,   
      1000000> >::duration<long, void>' requested here
            return _ToDur(static_cast<__to_rep>(__d.count()));
                   ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/chrono:182:9: note: in instantiation of function template specialization                                                  
      'std::chrono::__duration_cast_impl<std::chrono::duration<long &&, std::ratio<1, 1000000> >, std::ratio<1, 1>, long &&, true, true>::__cast<long, std::ratio<1, 1000000> >' requested here
        return __dc::__cast(__d);
               ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/chrono:247:10: note: in instantiation of function template specialization                                                 
      'std::chrono::duration_cast<std::chrono::duration<long &&, std::ratio<1, 1000000> >, long, std::ratio<1, 1000000> >' requested here
          : __r(duration_cast<duration>(__d).count()) { }
                ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/chrono:471:9: note: in instantiation of function template specialization 'std::chrono::duration<long &&, std::ratio<1,    
      1000000> >::duration<long, std::ratio<1, 1000000>, void>' requested here
        return __ct(__lhs).count() < __ct(__rhs).count();
               ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/chrono:682:7: note: in instantiation of function template specialization 'std::chrono::operator<<long, std::ratio<1,      
      1000000>, long, std::ratio<1, 1000000> >' requested here
                    < system_clock::duration::zero(),
                    ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/chrono:128:13: error: call to implicitly-deleted copy constructor of                                                      
      'std::chrono::duration<long &&, std::ratio<1, 1000000> >'
            return _ToDur(static_cast<__to_rep>(__d.count()));
                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/chrono:182:9: note: in instantiation of function template specialization                                                  
      'std::chrono::__duration_cast_impl<std::chrono::duration<long &&, std::ratio<1, 1000000> >, std::ratio<1, 1>, long &&, true, true>::__cast<long, std::ratio<1, 1000000> >' requested here
        return __dc::__cast(__d);
               ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/chrono:247:10: note: in instantiation of function template specialization                                                 
      'std::chrono::duration_cast<std::chrono::duration<long &&, std::ratio<1, 1000000> >, long, std::ratio<1, 1000000> >' requested here
          : __r(duration_cast<duration>(__d).count()) { }
                ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/chrono:471:9: note: in instantiation of function template specialization 'std::chrono::duration<long &&, std::ratio<1,    
      1000000> >::duration<long, std::ratio<1, 1000000>, void>' requested here
        return __ct(__lhs).count() < __ct(__rhs).count();
               ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/chrono:682:7: note: in instantiation of function template specialization 'std::chrono::operator<<long, std::ratio<1,      
      1000000>, long, std::ratio<1, 1000000> >' requested here
                    < system_clock::duration::zero(),
                    ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/chrono:233:12: note: explicitly defaulted function was implicitly deleted here                                            
        constexpr duration(const duration&) = default;
                  ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/chrono:349:6: note: copy constructor of 'duration<long &&, std::ratio<1, 1000000> >' is implicitly deleted because field  
      '__r' is of rvalue reference type 'rep' (aka 'long &&')
        rep __r;
            ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/chrono:182:9: error: call to implicitly-deleted copy constructor of 'typename enable_if<__is_duration<duration<long &&,   
      ratio<1, 1000000> > >::value, duration<long &&, ratio<1, 1000000> > >::type' (aka 'std::chrono::duration<long &&, std::ratio<1, 1000000> >')
        return __dc::__cast(__d);
               ^~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/chrono:247:10: note: in instantiation of function template specialization                                                 
      'std::chrono::duration_cast<std::chrono::duration<long &&, std::ratio<1, 1000000> >, long, std::ratio<1, 1000000> >' requested here
          : __r(duration_cast<duration>(__d).count()) { }
                ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/chrono:471:9: note: in instantiation of function template specialization 'std::chrono::duration<long &&, std::ratio<1,    
      1000000> >::duration<long, std::ratio<1, 1000000>, void>' requested here
        return __ct(__lhs).count() < __ct(__rhs).count();
               ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/chrono:682:7: note: in instantiation of function template specialization 'std::chrono::operator<<long, std::ratio<1,      
      1000000>, long, std::ratio<1, 1000000> >' requested here
                    < system_clock::duration::zero(),
                    ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/chrono:233:12: note: explicitly defaulted function was implicitly deleted here                                            
        constexpr duration(const duration&) = default;
                  ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/chrono:349:6: note: copy constructor of 'duration<long &&, std::ratio<1, 1000000> >' is implicitly deleted because field  
      '__r' is of rvalue reference type 'rep' (aka 'long &&')
        rep __r;
            ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/chrono:255:11: error: rvalue reference to type 'long' cannot bind to lvalue of type 'long'                                
        { return __r; }
                 ^~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/chrono:247:39: note: in instantiation of member function 'std::chrono::duration<long &&, std::ratio<1, 1000000> >::count' 
      requested here
          : __r(duration_cast<duration>(__d).count()) { }
                                             ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/chrono:471:9: note: in instantiation of function template specialization 'std::chrono::duration<long &&, std::ratio<1,    
      1000000> >::duration<long, std::ratio<1, 1000000>, void>' requested here
        return __ct(__lhs).count() < __ct(__rhs).count();
               ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/chrono:682:7: note: in instantiation of function template specialization 'std::chrono::operator<<long, std::ratio<1,      
      1000000>, long, std::ratio<1, 1000000> >' requested here
                    < system_clock::duration::zero(),
                    ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/chrono:681:21: error: static_assert expression is not an integral constant expression                                     
      static_assert(system_clock::duration::min()
                    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/chrono:681:21: note: undefined function 'operator<<long, std::ratio<1, 1000000>, long, std::ratio<1, 1000000> >' cannot be
      used in a constant expression
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/chrono:465:7: note: declared here
      operator<(const duration<_Rep1, _Period1>& __lhs,
      ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/chrono:141:40: error: cannot cast from lvalue of type 'const intmax_t' (aka 'const long') to rvalue reference type        
      'long &&'; types are not compatible
              static_cast<_CR>(__d.count()) / static_cast<_CR>(_CF::den)));
                                              ^~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/chrono:182:9: note: in instantiation of function template specialization                                                  
      'std::chrono::__duration_cast_impl<std::chrono::duration<long, std::ratio<1, 1> >, std::ratio<1, 1000000>, long &&, true, false>::__cast<long, std::ratio<1, 1000000> >' requested here
        return __dc::__cast(__d);
               ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/chrono:694:21: note: in instantiation of function template specialization                                                 
      'std::chrono::duration_cast<std::chrono::duration<long, std::ratio<1, 1> >, long, std::ratio<1, 1000000> >' requested here
        return std::time_t(duration_cast<chrono::seconds>
                           ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/chrono:154:40: error: cannot cast from lvalue of type 'const intmax_t' (aka 'const long') to rvalue reference type        
      'long &&'; types are not compatible
              static_cast<_CR>(__d.count()) * static_cast<_CR>(_CF::num)));
                                              ^~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/chrono:182:9: note: in instantiation of function template specialization                                                  
      'std::chrono::__duration_cast_impl<std::chrono::duration<long, std::ratio<1, 1000000> >, std::ratio<1000000, 1>, long &&, false, true>::__cast<long, std::ratio<1, 1> >' requested here
        return __dc::__cast(__d);
               ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/chrono:582:22: note: in instantiation of function template specialization                                                 
      'std::chrono::duration_cast<std::chrono::duration<long, std::ratio<1, 1000000> >, long, std::ratio<1, 1> >' requested here
        return __time_point(duration_cast<_ToDur>(__t.time_since_epoch()));
                            ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/chrono:702:9: note: in instantiation of function template specialization                                                  
      'std::chrono::time_point_cast<std::chrono::duration<long, std::ratio<1, 1000000> >, std::chrono::system_clock, std::chrono::duration<long, std::ratio<1, 1> > >' requested here
        return time_point_cast<system_clock::duration>
               ^
7 errors generated.



Not awesome.

Funny thing: there is a fix to it:
http://clang.llvm.org/libstdc++4.7-clang11.patch

So I tried the following:
1) Opening the file: /usr/include/c++/4.7/type_traits
2) Going down to line 1749
3) Changing the line to what the patch said:
{ typedef typename decay<decltype(true ? declval<_Tp>() : declval<_Up>())>::type type; };

 Done.

Now I can use clang to compile my code even if it uses chrono.
Awesome.

↧

Ein Handlungsreisender mit evolutionären Strategien

$
0
0
Im Laufe des Studiums bin ich über so manch eine Aufgabe gestolpert.
Dieses Mal geht es um das Problem des Handlungsreisenden (http://de.wikipedia.org/wiki/Problem_des_Handlungsreisenden).

Kurz gesagt:
Ein Reisender will eine Anzahl von Städten besuchen, und das auf dem dafür kürzesten Weg.

Wir habe über die Distanzen der Städte zueinander.
Wo es los geht, ist im Prinzip egal. Da wir alle gegebenen Städte besuchen wollen, können wir, nachdem wir die Algorithmen für uns gearbeitet haben lassen, die Reihenfolge im Kreis drehen, bis wir unseren geliebten Startpunkt wieder haben.

Als Algorithmus nehmen wir uns die evolutionären Strategien.
Auf dieser Seite im Abschnitt "The Travelling Salesman Problem" (TSP) ist eine gute Erklärung:
http://www.bionik.tu-berlin.de/user/giani/esdemos/evo.html


Für uns zählt (1+1)-ES → (1 Elternteil + 1 Kind) - evolutionäre Strategie.
Das heißt, dass aus einem Elternteil durch Mutation ein Kind entsteht und nur diese beiden verglichen werden.


Grob kann man sagen:
  1. Bildung eines Elternteils
  2. Bildung eines Kindes durch Mutation
  3. Auswahl des Kindes, wenn
    1. das Kind besser ist als sein Elternteil, oder
    2. beide gleich gut sind und der Zufall das so will, oder
    3. wenn das Elternteil besser ist, aber eine bestimmte kleiner werdende Variable kleiner ist, als ein Zufallswert
  4. Verringerung des variablen Wertes
  5. Erhöhung des Iterationszählers
  6. Wenn der Iterationszähler das Maximum an Iterationen überschritten hat, ist Schluss, ansonst zurück zu Schritt 2


Schritt 1 ist einfach:
Man lege willkürlich eine Reihenfolge, eine Route, durch alle Städte fest.

Für Schritt 2 brauchen wir Mutationen. 4 sind auf der Webseite  oben zum TSP beschrieben. Das sind:

  • Inversion (Invertierung eine Reihenfolge von Städten)
  • Insertion (Entfernung einer Stadt und Platzierung an einer anderen Stelle)
  • Displacement (Verschiebung einer Reihe von Städten)
  • Reciprocal Exchange (Vertauschung zweier Städte)
Zuerst erstellen wir eine Kopie des Elternteils. Per uniformen Zufall wählen wir uns dann eines dieser Mutationen aus und wenden das auf das Kind an.

Innerhalb der Mutationsalgorithmen kommen Zufallszahlen zur Anwendung.
Für den Anfang nehmen wir dafür uniforme Zufallszahlen.

Im dritten Schritt schauen wir, ob wir das Kind akzeptieren und als neues Elternteil wählen.
Als erstes vergleichen wir die sogenannte Fitness der beiden Individuen. Als Fitness verstehen wir in diesem Problem die Gesamtlänge der Rundreise. Ist also die Gesamtlänge der Rundreise des Kindes kleiner als die des Elternteiles, so wird das Kind gewählt.
Sind beide Gesamtlängen gleich, so wählen wir per Zufall das Kind. Das geschieht ca. so:
if Gesamtlänge(Elternteil) equals Gesamtlänge(Kind) then
    if ZufallswertZwischen(true,false) gleich true then 
        wähle Kind
Als dritte Möglichkeit gibt es noch, dass das Elternteil besser ist. In diesem Fall schauen wir uns einen variablen Wert an und vergleichen den mit einem Zufallswert. Ist ersterer kleiner, so wählen wir wieder das Kind.
Dies erlaubt es uns aus möglichen lokalen Minima zu entkommen.
Die Suche nach der kürzesten Route gleicht grafisch gesehen einer welligen Kurve. In unserer Suche schmeißen wir einen Ball auf die Kurve. Der Ball fällt und roll und kann dabei in Einkärbungen (lokale Minima) stecken bleiben. Um dies zu vermeiden, "rütteln" wir. Wir erlauben "schlechtere" Kinder um aus dem Minima zu entkommen. Das Rütteln wird dabei von mal zu mal schwächer. Mit etwas Glück gelangen wir so in den Trichter des globalen Minimum, in den wir hinein wollen.
Als Funktion habe ich mir hier die "Gaussian Density" gewählt:
if gaussianDesnity (delta( Parent, Child), stdDev) > ZufallszahlZwischen(0,1) then …
 Die Funktion ist hier auf Seite 2 zu finden:
http://web.mst.edu/~tauritzd/courses/ec/fs2002/project/Koenig.pdf



Im Punkt 4 wird der variable Wert verringert. In diesem Fall ist es die "standard deviation" (stdDev). Sie wird innerhalb der gaussianDesnity und im weiteren im inneren der Mutationen verwendet. Je nach Anzahl der Iterationen und des Startwertes der "standard deviation" lässt sich eine Senkung mittels Multiplikation mit etwas weniger als 1 relativ gut verarbeiten.
(Zum Beispiel: Iteration von 100000, Multiplikator von 0.99)

Schritt 5 und 6 benötigen, glaube ich, keine weiteren Kommentare.

Soweit zur Theorie.
Auf zum Code.


Als Basis nehmen wir uns folgendes:
http://www.codeproject.com/Articles/26758/Simulated-Annealing-Solving-the-Travelling-Salesma

Hier finden wir das passende Problem mit Lösung in Form von "Simulated Annealing".
Die Herangehensweise ist ähnlich:
Ein Elternteil erzeugt eine Kopie und mutiert diese mittels "Reciprocal Exchange" (hier als "GetNextArrangement"). Für Punkt 3.3 kommt folgende Funktion anstelle von "gaussianDesnity" zum Einsatz:
Math.Exp(-deltaDistance / temperature)

Die Iterationen werden außen vor gelassen. Stattdessen wird die aktuelle Temperatur mit einem Minimum verglichen und ggf. abgebrochen.

Im Groben entspricht also der Code schon der evolutionären Strategie.
Bauen wir also ein paar Verbesserungen ein:
  1.  Die Übernahme des Kindes: die Funktion für Punkt 3.3 wird ersetzt und ein zusätzliche Abfrage für 3.2 (gleiche Fitness) eingefügt.
  2. Einbau der Abbruchbedingung über die maximale Anzahl an Iterationen.
Das dürfte ohne weitere Erklärung von alleine Funktionieren ;-)

Schwieriger ist das Hinzufügen der Mutationen, insbesondere derer, die von der Standardabweichung und der Normalverteilung abhängen.

Die integrierte Mutation verwendet Zufallswerte aus dem uniformen Raum. D.h., dass alle Werte gleichwahrscheinlich sind.
Für uns ist die Normalverteilung (auch gaussche Normalverteilung) besser geeignet. Diese Verteilung hat eine Glockenform. Werte um den "Mean" werden bevorzugt auftreten.
In C# muss dies selber programmiert werden (oder man kopiert sich etwas ;-)):

Bei mir sieht das dann wie folgt aus:
double randomOfGaussianDistribution (double stdDev = 1){
    double mean = 0;
    double u1 = random.NextDouble (); //these are uniform(0,1)
    double u2 = random.NextDouble ();
    double randStdNormal = Math.Sqrt (-2.0 * Math.Log (u1)) * Math.Sin (2.0 * Math.PI * u2);
    double randNormal = mean + stdDev * randStdNormal; //random normal(mean,stdDev^2)
    return randNormal;
}
double randomOGD (double stdDev){
    return (randomOfGaussianDistribution (stdDev) + 1)/2;
}
int randomOGDMean (int mean, int start, int end, double stdDev){
    var rand = randomOfGaussianDistribution (stdDev);
    var newMean = mean + rand;
    var length = end - start;
    if (newMean < start) newMean = length - (-newMean) % length;
    if (newMean > end) newMean = (newMean % length);
    return (int)Math.Floor (newMean);
}
int randomOGDCount (int min, int max){
    var rand = Math.Min (1, Math.Max (-1, randomOfGaussianDistribution (1)));
    return min + (int)Math.Floor (rand * Math.Sign (rand)) * (max - min);
}
Die unteren Methoden sind speziell für die Mutationen. Zum einen wird ein Zufallswert um den "Mean" gesucht und bei dem anderen wird ein Zufallswert für eine bestimmte Anzahl gesucht.
Als Beispiel sei hier die "Inversion" angebracht:
void operatorInversionGauss (){
    var start = random.Next (0 + 1, nextOrder.Count - 2);
    var count = randomOGDCount (2, nextOrder.Count - start);
    nextOrder.Reverse (start, count);
}
Bei der "Inversion" wird eine Reihe von Elementen invertiert.
Der erste Wert wird aus der uniformen Verteilung gewählt und ist der Startwert. Die Anzahl ist dann vom ersten Wert abhängig und zählt nach "rechts".

 randomOGDMean ist gut am Beispiel von "Reciprocal Exchange" erklärbar:
void operatorReciprocalExchangeGauss (double stdDev){
    var first = random.Next (0 + 1, nextOrder.Count);
    var second = randomOGDMean (first, 0, nextOrder.Count, stdDev);
    var tmp = nextOrder [first];
    nextOrder [first] = nextOrder [second];
    nextOrder [second] = tmp;
}
Der erste Wert wird ganz uniform zufällig gewählt. Der zweite Wert hängt vom ersten ab. Zusätzlich spielt die Standardabweichung mit ein. Je kleiner diese ist, desto näher liegen die beiden zu vertauschenden Elemente.
Innerhalb der "randomOGDMean" wird der Überlauf der Grenzen beachtet.


Nur zur Erwähnung noch die letzten beiden Mutationen mit Gauss:
void operatorDisplacementGauss (double stdDev){
    var start = random.Next (0 + 1, nextOrder.Count - 1);
    var count = randomOGDCount (1, nextOrder.Count - start - 1);
    var place = randomOGDMean (start, 0, nextOrder.Count - count, stdDev);
    var sublist = new List<int> ();
    for (int i = 0; i < count; ++i) sublist.Add (nextOrder [start + i]);
    nextOrder.RemoveRange (start, count);
    nextOrder.InsertRange (place, sublist);
}
void operatorInsertionGauss (double stdDev){
    var start = random.Next (0 + 1, nextOrder.Count);
    var place = randomOGDMean (start, 0, nextOrder.Count, stdDev);
    var item = nextOrder [start];
    nextOrder.Remove (item);
    nextOrder.Insert (place,item);
}
Als sollte noch folgendes beachtet werden:
Dank der Verringerung von "stdDev" kann ab einem bestimmt kleinen Wert der entsprechende Mutationsoperator nicht mehr angewandt werden. Ist die "stdDev" kleiner als 1, so wird immer nur der "Mean" zurück gegeben. Das bringt nichts.
Aus diesem Grunde empfiehlt es sich die Mutationen ab dort wieder mit uniformen Zufallszahlen zu bestücken.



Hier noch ein Zitat von Dr. Jesús Emeterio Navarro Barrientos:
"the idea is to do the same as in the example code using simulated annealing to solve the TSP, but now with evolutionary strategies, i.e. use Gaussian random values instead of Uniform random values, and instead of cooling out the solution using a D=C(S')-C(S') e^D/T, reducing the temperature T every iteration, now for ES you decrease the standard deviation of the Gaussian random numbers every iteration. That would be roughly the main task, of course modifying the way to get new solutions S' would be also a plus." 
Kurz zerpflückt:

  • use Gaussian random values instead of Uniform random values
  • decrease the standard deviation  instead of cooling out
Heißt also, wie oben erwähnt:
  • anstelle der uniformen Zufallszahlen sollen Gauss-Zufallszahlen genommen werden
  • anstelle von Abkühlung (

    • temperature *= coolingRate;
    • Math.Exp(-deltaDistance / temperature) > random.NextDouble()
  • soll die Anpassung der Standardabweichung und damit der Gauss-Zufallszahlen geschehen (Diese Anpassung ist wie bei der Abkühlung nur z.B. ein "stdDev *= 0.99;" pro Iteration.)
Zusätzlich wäre es fein, wenn neue Mutationsoperatoren eingebaut werden (zum Beispiel solche, wie oben ;-)).




Das sollte es eigentlich gewesen sein.
Fragen etc. einfach in die Kommentare.

PS:
Kompletter Code ist hier:
http://code.google.com/p/manuel-bellersen/downloads/detail?name=TSP_1.zip

↧

Brettspiel für 4 Spieler

$
0
0
Vor ein paar Wochen haben wir eine neue Aufgabe im Brettspielkurs bekommen:
→ im Spiel soll man Gebiet einnehmen können
→ und man soll Gegner schlagen können

Folgendes ist dabei heraus gekommen:



Hier kann sofort losgespielt werden:
(Hierfür wird das Burster-Plugin benötigt:
http://geta3d.com/index.php?option=com_content&view=article&id=38&Itemid=18)



Falls dieses nicht bzw. nicht richtig funktionieren sollte, ist hier noch eine andere Anlaufstelle (hierfür wird ebenfalls das Burster-Plugin benötigt):
http://geta3d.com/index.php?option=com_content&view=burster&id=50&file=b5d73ad691250950dd76fcbeeb016d01

Hier ist der "Source Code", die originale Blender-Blend-Datei:
http://code.google.com/p/manuel-bellersen/downloads/detail?name=main_2.62.blend


Hier ist die Windows-EXE:
https://docs.google.com/open?id=0B-DgjzoFZxxwNU1YcFc2Z3pSazg


Gespielt wird wie folgt:
Tastatur:

  • Pfeiltaste (Arrows) bewegen den Charakter
  • Leertaste (Space) wechselt den aktuellen Charakter
  • Umschalttaste (Shift) wechselt den aktuellen Würfel und gibt an anderen Spieler ab
  • Zurück (?)(Backspace) macht den letzten Schritt rückgängig
GamePad:
  • DPad (Steuerkreuz) bewegen den Charakter
  • 4 (Y) wechselt den aktuellen Charakter
  • 2 (X) wechselt den aktuellen Würfel und gibt an anderen Spieler ab
  • 3 (B) macht den letzten Schritt rückgängig
  • [sind mehrere GamePads angeschlossen, so werden diese nacheinander bei Spielerwechsel aktiviert]
Maus (zum "Einmauern"):
  • linke Maustaste setzt ein freies Feld in der Farbe des aktuellen Spielers bzw. entfernt es
  • rechte Maustaste setzt ein Feld mit Spur in der Farbe des aktuellen Spielers bzw. entfernt es
  • rechte Maustaste entfernt Spieler vom Feld

Spielregeln:
  • jeder Spieler hat 4 Spielfiguren der gleichen Farbe
  • wenn ein Spieler dran ist, hat er 2 Würfel ("Die 1" und "Die 2"), die er setzen muss
  • pro Würfel muss eine Spielfigur gesetzt werden (es darf auch 2 mal die Gleiche sein)
  • auf dem weißen Feld zieht der Spieler eine Spur hinter sich her
  • schafft es die Spielfigur wieder auf ein gesichertes Gebiet, so wird die Spur zu einer Mauer
    • links und rechts dieser Mauer sind freie Gebiete, das kleinere davon darf für den Spieler "eingemauert" werden
    • befindet sich eine andere Spielfigur (auch der gleichen Farbe) in dem einzumauernden Gebiet, so muss sie entfernt werden
    • "Einmauern" funktioniert nur, wenn alle Schritte für den aktuellen Würfel getan sind ("Steps left with current Die" ist "0")
  • landet ein Spieler auf der Spielfigur eines anderen, so wird sie mit Zugende entfernt
  • wird ein Spieler entfernt oder läuft ein Spieler durch die Spur eines anderen, so wird dessen Spur entfernt
  • das Zerstören einer Spur und das Erstellen einer Mauer kann nicht rückgängig gemacht werden
  • gewonnen hat der Spieler mit den meisten Punkten

Viel Spaß!
↧
↧

First steps into iodoom3 & dhewm3

$
0
0
I got it!

I got enough files together to start iodoom3 and dhewm3, load a map and do some editing.
Here they are:
https://docs.google.com/open?id=0B-DgjzoFZxxwUndJVTBBdkxFWTQ

[[!! This file contains bigchars.tga from the Doom3 demo. Check the Doom3 demo licensing for how to handle that thing. !!]]

So what is this all about and how did I get to that point?

For university I'm doing a project that I described here:
http://urfoex.blogspot.com/2012/05/zulassung-zum-indipendent-courseworks-1.html

Short version:
I try to build up a little SDK pack for iodoom3 and especially dhewm3.

The base engine is "id tech 4" and powers games like Doom 3 and Quake 4.
Both games had SDKs which could be used to create e.g. mods.
Now (late last year) the engine code is open sourced as iodoom3 (https://github.com/TTimo/doom3.gpl). Some people already improved it (https://github.com/dhewm/dhewm3) (https://github.com/omcfadde/dante). But still an easy ready to start pack to get into the engine and create e.g. a game with it is missing.

If you are on Windows and have Doom3 you have a quite good starting point. But without that you are alone in the dark.


Let's get started!

Where to start?
I started on Linux with the dhewm3 code base. Cloned it to me harddrive, run cmake, run make and I was ready to start.
Staring dhewm3 …
… missing file "default.cfg"
OK. Just an empty file called that way doesn't work. There must be at least one line inside. Mine says: "unbindall".
The next missing thing was "_default" material followed by doom_main.script and doom_defs.script.
Here is this base package: https://docs.google.com/open?id=0B-DgjzoFZxxwcDM2dUZ1ajBjbHM
dhewm3 is starting up to something where you can open the console with that " ` " thing. As I started dhewm3 from a terminal I could follow the output of the things I typed on the console. But that is not that much awesome. I works but it would be nice to see those stuff also inside. For that a bigchars.tga is needed. I grabbed mine from the Doom3 demo. You might use the one from e.g. OpenArena (http://openarena.ws/svn/gfx/2d/bigchars.tga) or build it by yourself. For that you would need to know how the original looks like. Later more on that.

You can also do a step and use the assets from here:
http://wiki.iodoom3.org/Minimum_Assets
(Be prepared to have to change some code.)

Creating a map

Just hopping inside the console is not enough as you might guessed already.
The problem is:
How to create a map and what is needed for that?

To create a map I needed a map editor.
There are about two (2) for this engine out there. One is DoomEdit which is internally inside id tech 4. The other is DarkRadiant. I can't use DarkRadiant on my Linux version. The prepacked Ubuntu version has some dependencies my system doesn't meet and the version I compiled by my own crashes on startup. I did a bug report but don't see any patches or things like that. ( I also look inside the code where it crashes but currently don't know what happens around there and what should be expected.)
DoomEdit would be the next with one big problem: mfc
Because of that this editor is bound to Microsoft Windows. I got it running with wine but that wasn't a pleasant experience (same with DarkRadiant).

So on that point I was kind of forced to start my Windows partition.
I'm not quite shure if the dhewm3 version still has the editor inside for the Windows version.
From Alexander Zubov I got the tip to use the doom3.gpl verion: https://plus.google.com/u/0/116768004614082942458/posts/WcAMVcbZUdt

So I took that. There are some things that makes it a bit less easy. But a long description can be found here:
http://www.iodoom3.org/forums/topic/tutorial-compile-in-visual-studio-2010-express/

Being a student helped this time. Instead of doing fancy stuff with the express version I took the professional version from MSDNAA.


Running iodoom3 on Windows

Setting iodoom3 up and getting it compiled was not that much of a problem. Still not as easy as I used to have it on Linux.
Running doom3.exe brought up the same things I had to add on Linux. So I reused those files.
Inside the console I started the editor by typing "editor" <return>. That was the easy part.
Because every time I clicked  somewhere the editor crashed. Debugging showed some weird accesses to brushes. Nothing that really helps on how to make it stop crashing.
Somehow I found out that the editor likes a file called "doom.qe4". This is how it looks like:
http://www.katsbits.com/tutorials/idtech/quake-edit-radiant-set-up.php#resetting

Thanks to that the editor didn't crash anymore (or at least just in some strange ways…).

(PS: There is also DarkRadiant on Windows. It works. They are nearly the same, but still different. )

DMAP & MAP

Now that the editor was running I could build my first little room. Saving as map and … ERROR.
As I clone "doom3.gpl" I got that " . " in my path which wasn't liked much by the editor. Fixing that dot by removing it made that error disappear. (Bear in mind: no special characters inside the path.)
To create proc and cm files from the map 'dmap' is the best choice. It's called like this: "dmap myAwesome.map"
Any errors and warnings will be reported. My first was a missing "_tracemodel" material. Also some warning about leaks showed up. Why? I guess it was because no player start point was set. But still I could try loading the map be calling: "map myAwesome.map"
Again errors showed up.
Missing classnames, script objects, variables, functions…
Problematic are always crashes. On that way I got two crashes: one because of missing weapon definitions and the other because of missing gui. At the end I got one remaining crash (or better application shutdown because of a memory leak) that appears when a map is loaded and a "reloadEngine" is initiated. But that one is just with the iodoom3 version on Windows.
As mentioned before the player start point is important. For that a definition was needed. After creating that it could be used as an entity inside the editor.

On Windows I already had the little patch coming with the minimum assets applied. It just converts some error messages to warnings. That way joints for the player and ammo_type isn't needed. So I could get my map running.
Everything was black. By selecting the walls inside the editor and then the bigchars.tga from the textures panel those got that texture applied. Ingame I could see around.


Awesome. Right?


Back to Linux: Joints

Yes and no.
I took all those files I had created on Windows and put them on my Linux machine. Because the patch wasn't applied there I needed more to do.
Joints.
Fiddling around I found out: I needed a model with bones.
And what do I need for that? md5mesh and md5anim files.
Blender can do it. Thanks do some fine people the exporter is ready to use: http://www.katsbits.com/tools/#md5
http://www.katsbits.com/smforum/index.php?topic=167.0

The forum is full with stuff, also with a hint to read the readme that comes with the plugin. It helps. Just like the entries on the forum.
[Short hints:
→ you need three (3) bones
→ you need some keyframes
→ you need a mesh with material
→ on export select first the mesh and shift selecting second the bones
→ be prepared that files will be replaced without re-questioning]

That is how it can be done:

The bones must have names that correspond to the names in the definition.
And then it also run on Linux:


And all the additional files are just those:

Some of those will be created from the executable itself (like doomkey, xpkey, config.spec, dhewm.cfg, DoomConfig.cfg, editor.cfg, warnings.txt). Again those files can be found here: https://docs.google.com/open?id=0B-DgjzoFZxxwUndJVTBBdkxFWTQ

[[!! This file contains bigchars.tga from the Doom3 demo. Check the Doom3 demo licensing for how to handle that thing. !!]]


The End

Clicking through http://www.katsbits.com/ I also found some stuff to export Blender to ASE which then can be used in id tech 4 and there are also tutorials in how to build maps using Blender and export them to map. (You still need to do things like entity placement inside a Radiant like DoomEditor.)

In the end I also tried opening the map inside DarkRadiant and it worked:



On my way through that all I took some notes on what missing thing I'm stuck next. Maybe it helps someone else when starting. Here it is:
// Wichtig!
// keine Sonderzeichen (z.B. '.') im Pfad

base:
default.cfg [mindestens eine Zeile]
materials/default.mtr [_default material]
script/doom_main.script
script/doom_defs.script

aus Demo:
textures/bigchars.tga [zum Anzeigen von Text in z.B. Konsole]
doom.qe4 [*.prj] [looks like: http://www.katsbits.com/tutorials/idtech/quake-edit-radiant-set-up.php]
[benötigt, um Editor ohne Crashes zum Laufen zu bekommen]
dmap [zum "Erstellen" der map-Erweiterungen aus der .map]

// Hinweis:
// Player und Weapon sind bearbeitet, sodass bestimmte Dinge (Joints/Bones, Ammo_Types) weggelassen werden können

dmap a.map:
_tracemodel [Material, materials/default.mtr]

map a.map:
classname worldspawn [def/default.def]
classname player_doommarine [def/default.def]
script object player [script/player.script]
for player: AI_* [script/player.script]
info_player_start [def/default.def :: def/info.def]
crash because of missin def_weapon[0-n] [def/default.def]
script object weapon_fists [script/weapon_fists.script]
def object def/weapon_fists.def
weapon_scriptobject for weapon_fists [script/weapon_fists.script]
for weapon_base: WEAPON_* [script/weapon_base.script]
fkt: RaiseWeapon in player [script/player.script]
!!( loading map second time → CRASH)
crash@GUI: needs guis/mainmenu.gui & msg.guis
shutdown because of memleak: map loaded & reloadEngine

Joint '' for bone_hips:
→ create a model with at least 3 bones
→ hip, chest, head
def/default.def

// Hinweis:
// Map muss (mehr oder weniger) mit DoomEdit || DarRadiant erstellt werden
// "kann" mit z.B. Blender erstellt werden (siehe KatBits)
// aber Entities etc. müssen über Radiant gesetzt werden

What's next?

I still have time left for this part of this project.
Creating a better overview would be nice. (www.iddevnet.com)
Where do I need to edit what to do something.

How to use the assets from the demos of Doom3 and Quake4 with this pack?
What is connected to what?
To start creating e.g. a game with an engine is always easier if there is already something. As the demos are free to get I guess it should not be to problematic to reuse them for that purpose.

↧

IMHO: Why is nearly nobody using Unigine - comments by me

$
0
0
Why is nearly nobody using the Unigine engine?
It has nice visuals as demonstrated by Unigines benchmarks and it runs on most platforms. There are some games that show that the engine can compete with others. But what about the editor and tools and documentation? You can find some screenshots and a few videos but then there is the end of knowledge.

Looking at other engines during some comments on Phoronix in the end the question turns and becomes:
Why should somebody use the Ungine engine?


Here are now the two comments I made at Phoronix:

Posted by sgtGarcia:
That's why:
1. Unity - free version ( not to comparable to full version but something to test with )
2. CryEngine - full version for testing & non-commercial use
3. Unreal Engine - If I'm not mistaken - full version for testing & non-commercial use
I can download each of them, test them, check work pipeline, etc.

Unigine - I see that there is website where You can request Evaluation Kit http://unigine.com/evalkit/
but I think they will give it only to companies not single developers & people who want to learn ( but who knows ).

How I see it:
- hobbyist/amateur have small/zero interest in Unigine, that comes from lack of a free for non-commercial SDK;
- indie small interest in Unigine comes from lack of free SDK and/or lack of documentation/tutorials & probably licensing/pricing;
- small companies - could probably target Unigine but they already have well documented, used in at least class A+ games to choose from ( CryEngine, Unity, UDK );
- big companies avoid Unigine - because most of them already got big, massive engine.

So they are closing they own door from developers that's already on the market & from future developers that cannot access SDK & learn it.

Comment by me:
You say it.

Just to add my experience:

1. Unity free version is a bit pain in the ass if you want to make something better but for lots of small things it's enough. And you can sell it:
" Can we sell games and make money with the free version of Unity?
Yes! You certainly can-- and without royalties nor paying any revenue share! If your game is a commercial success, we hope you'll upgrade to Unity Pro! :)"
There are lots of people using it and the documentation is good. So if you need help you nearly always find something.

2. CryEngine - full version for non-commercial use. And if you are Indie you can sell it for cheap:
"We’ll offer a royalty-only license model for Independent Developers, where Crytek require only 20% of the developer’s revenues from the commercial launch of their game."

The visuals are awesome – but from what I heard from some people trying to use it was a real pain if you want to do something else then what is there. There is not a big community and the documentation is not so great. But hey, you get awesome visuals for free.

3. Unreal Engine - you get nearly everything of the real version and can use it for non-commercial use. And selling is also not a problem:
"He would need to purchase our $99 license and then pay us royalties of 25% of his earnings after the first $50,000 he makes."

A big community and a big documentation. There is everything you need.

4. Unigine -
" UNIGINE SDK is available on a per-case basis (an average deal is about 30,000 USD per project). "
"Please take into account that we provide Evaluation Kit only to companies working on commercial projects."
I also wrote them some mails and got answers: No evalKit, no free license, not even for student projects, nothing.
There isn't even an SDK for OilRush (their game) which might have worked like UDK or such.
Some Indies won a license some time ago but nothing has shown up yet. Instead some are simply throwing it away with good reason:http://www.gamingonlinux.com/index.php?threads/tomes-of-mephistopheles-alpha-funding-available.751/page-2#post-3453]


So to sum up:
For nearly everything you can use UDK.
If you need it simple and have less expactations use Unity.
If you wanna clone Crysis with more awesome visuals use CryEngine.
If you are on Linux you can choose from lots of other engines: http://devmaster.net/devdb/engines
Blender Game Engine is getting better. Crystal Space had a nice new release lately. Ogre3D with some extensions. iodoom3/idTech4 with some dhewm3 and glsl.
With SourceEngine comming to Linux I guess they also release there SourceSDK for Linux.

Why would you choose Unigine?
Probably when you have lots of money and tried lots of engines that all sucked for you.


Btw.:
On my university game designers and computer scientists are having classes in Unity and UDK and are makeing games of lots of semesters with them.
From the beginning they are trained to use at least one of those two engines.
On new projects they always want to stick with the engine they already know.


PS: If you really want to do something with Unigine Engine
you can find really old GPL versions from Unigine engine on here: http://frustum.unigine.com/
http://phoronix.com/forums/showthread.php?72677-Showing-Off-The-Linux-Friendly-Unigine-Renderer&p=278983#post278983



Posted by chelobaka:
Why Unigine is so unpopular in game developer circles when its creators claim its superiority and low price? Something is wrong when devs choose Unity for Linux support when this support only in a state of baking.

 Comment by me:
Easy answer:
You get a free light version of Unity3D with which you can do like everything, even sell games. The Pro version costs about $1500 per developer.
Unigine costs around $30000 per project.
So you would need 30000/1500 = 20 developer to compensate this price.
An Indie studio doesn't have so many developer.
Even those bigger studios crowedfunding on kickstarter and those alike are not 20 devs.

Not to mention that you can do more then one project with one Unity3D Pro license.

Also not to mention the also freely available documentation and lots of tutorials and snippets for Unity3D while there is just some hidden intern stuff for Unigine.


The Linux part in Unity3D that now everyone is praising and willing to put out for there games is just a marketing gag.
The export for different platforms in Unity3D is really simple. Now that Unity3D gets Linux output (which is not that hard to provide considering the technologies it's build on, like Mono, C#, JS, OpenGL) every little studio can easily put out their games on Linux.
If those Linux support wouldn't be in, they probably still would have used Unity3D but no hype on the Linux people would have been.


Proof?
The Unity3D Editor still doesn't run native or in Wine on Linux. And there is nothing said about it being able to do so with version 4. So devs will need to do stuff on Windows or Mac. They don't care about Linux else they would have taken another engine (a lot listed here: http://www.devmaster.net/engines/). If I care about Linux I would run it and then I also would like to dev on it. So I choose my tools according to my platform. Those people don't.



So: Why choosing Unigine?
Little studios don't have the money and won't get crow-knowledge as with Unity3D and UDK.
Studios which care about Linux already are using different engines like HPL by Frictional Games or DarkPlaces and id Tech 4 by Kot-In-Action.
Bigger studios are using less Unity3D and more UDK because of e.g. features. There is also CryEngine for free.
And the next step are inHouse engines which are used by even bigger studios.




One big question:
Why should someone use Unigine?
http://phoronix.com/forums/showthread.php?73503-Unigine-Gets-Overhauled-Takes-On-Latest-GL-Features&p=285496#post285496
↧

Studium: Dokumentation von Projektphase 1

$
0
0
 Wieder ist ein Semester vorbei und wieder ist dabei etwas herausgekommen. In diesem Fall handelt es sich um eine etwas längere Beschreibung der ersten Projektphase.

"Im zweiten Semester des Studiengangs "`Internationale Medieninformatik Master"'(IMI M) liegt die erste Projektphase. Hierbei müssen verschiedene Studenten zusammen ein Thema bearbeiten. Ich habe meinen Platz im "`Game Design Kooperationsprojekt"' gefunden. Innerhalb dieses Projektes werden IMI Studenten unterschiedlichen Spielprojekten der Game Designer zugeordnet und dürfen für diese die Programmieraufgaben erledigen. Am Ende des Semesters werden die gelungenen Spieleprototypen vor öffentlichem Publikum vorgestellt.

In diesem Dokument ist die erste Projektphase dokumentiert. Anfangs gehe ich auf die Entstehung des Teams und den Verlauf der Entwicklung ein. Der nachfolgende Punkt, der Schwerpunkt dieser Arbeit, liegt auf der Erläuterung der von mir bearbeiteten Aufgaben und der damit verbundenen Probleme.  Abschließend knüpfe ich an die Showtime an und gebe zu guter Letzt eine Bewertung zu den jeweiligen Teilbereichen."


Hier ist das komplette Dokument als PDF:
https://docs.google.com/open?id=0B-DgjzoFZxxwNWM5RTl2dVRWLVk
↧

[C++] Moving own classes in standard container

$
0
0
Question
Got a question from a friend yesterday.
He had the following codes: 

The question was: "Why is the destructor called two times?"

The code is simple.
You create an object on stack and use the C++11 function move to move the object into a queue or a vector. In the end you remove that element from the container.

So you have:
- one call to constructor when the object is build
- one call to move constructor when the object is moved into the container
- and two calls to the destructor

Thinking of move there should be no construction. And where there is no construction there should be no destruction. Right?

Wrong!

Move is like a box. Or like gift wrap.
You put the present inside the box or gift wrap and give it to somebody. That one will probably take the gift out of the wrap and destroy the wrap.

That is what move is doing. You are giving an object to another object and that takes what it needs. Afterwards the remains of the old object is destroyed.

Demonstration-Code
I wrote a bit of code to demonstrate it:

There are to simple classes, with and without move-constructor, and a class holding a unique_ptr which forces to include a move-constructor when using move. Normally a class has a default move-constructor. It would move all members of the other object to this by calling their move-constructors. In this case the unique_ptr has not such thing. Clang shows messages like:
"note: function has been explicitly marked deleted here"
and
"error: call to implicitly-deleted copy constructor"

GCC shows:
"error: use of deleted function"
and 
"implicitly deleted because the default definition would be ill-formed"

The handwritten move-constructor just moves the unique_ptr over.
And here is the point where you see that move is a wrapper. With the move-constructor and "empty" object is created and then all data from the given object is cut out and taken over. After the move-constructor is done the destructor of the other object is called. In the output you can see the destruction of an FooBar object with a nullptr unique_ptr shown as upT->id[].


Just a hint:
Don't initialize members in the class definition, like I did for "id". As you can see those initializations are done for every constructor. Also for the move-constructor where you normally would take over data from somewhere else. Especially for bigger data structures it's a waste. Just imagine creating a new object for the unique_ptr at line 51 just to throw it away in the move-constructor. 
On the other hand there are some use-cases where an initialization inside the class definition is good. But those aren't many.


To demonstrate the move with those classes I used the standard containers vector and queue. They have methods like push and emplace to take over objects. The objects are either real objects from stack or unique_ptr.


Demonstration-Output
Using push and stack objects results in the use of the move-constructor. A lot of constructor and destructor calls can be seen. Especially the vector without a reserved size has a lot more of them. 
Emplace with stack objects and push and emplace with unique_ptr are much more efficient. Doing emplace with a stack object creates the object inside the container. Doing push creates the object first and then moves it inside the container. That's way there are to constructor (normal and move) calls. So emplacing would be a better way. 
Moving a pointer around is not a big deal. That goes for push and emplace. Comparing the use of pointer with the use of stack objects the pointer will win.
Why?
Because you don't need to care about the move-constructor of your own class. The different constructors for the unique_ptr are given. And it is just changing some pointer. In your own class you would need to take care of the different members and that each is taken over. If you add some member later you can easily forget to add it to your different constructors and create a bug there.


Results
Feed container with pointer and not stack objects.
Reserve space for the vector you gonna fill.
Prefer emplace over push.
Don't initialize members in the class definition.
Move.
↧
↧

[C++11] Reducing compile time using forward declaration and pimpl

$
0
0
Just thought about how to reduce some compile time.
Things like dependencies and therefor forward declaration and pimpl.
Here is a rather long example a came up with:

To hide data that could  be changed from my "class B" I shadowed it putting it in an extra class and having a pointer to it to access it. The good old pimpl. http://www.gotw.ca/gotw/024.htm
Instead of normal * I use a std::unique_ptr. For std::shared_ptr there is std::make_shared. The some is missing for std::unique_ptr because they forgot to include it. Here is a simple implementation
http://herbsutter.com/gotw/_102/
I tried returning a normal std::string from getData() but couldn't set up a forward declaration because std::string is just a typedef and those can't be forward declared.
http://www.gotw.ca/gotw/034.htm
So I've put the std::string in a class. For a little bit more abstraction  that one is capsuled again.

Accessing the data as shown in the main() isn't short and clean. Not awesome.
So I changed some lines and then it looked like this:

Making the method getData() a template with an explicit instance using std::string as T inside the class  definition helps saving a lot of code and strange capsule classes.

Doing template specialization I now have a getData() I can use to get int and std::string. Also the method now returns an object of the requested type instead of a std::shared_ptr like before. Dereferencing inside main() isn't needed anymore.
Here is that code including the code for make_unique():

 In the end I tried making a bit of nested code:

The header files just include what is necessary. In this case just memory for std::unique_ptr. All other classes could be forward declared or template-tized.  This way nice little object files could be created for each header-source-pair.

The good thing:
→ If you change a class declaration no other class declaration will change.
Here is some more about those changes and when a recompile should take place:
http://stackoverflow.com/questions/4033487/c-when-recompilation-is-required

The bad thing:
→ Pointer.
Pointer itself aren't bad. But each access through a pointer will take some time. More time then if you could access it directly. So if you have a lot of data in your Data-class and a lot of access to it through the pimpl you will get a performance decrease.
Also when you want to access a method of the real class you need a pointer to that one. (In my D2-Data class this is the member _b.) 
(More details about those problems here:
http://www.gotw.ca/gotw/024.htm)

And not enough: If your real class has some methods that are protected you need to friend your Data-class to to able to use those them from there. But that shouldn't give you any performance problems and it's easy to setup.
A bit annoying is also that you have to include the headers for the class of the object you want to use and also the forward declared classes from inside. Just imagine a nested class structure with members being from different classes and always just being forward declared you will get a really long list of includes when using that object. In that case you might want to consider putting the needed includes for your forward-declare-only-header as comment in its head. That way you can copy-paste it when using and won't forget any includes.


One thing from the last sample that can clearly be seen:
Try to have a complete class declaration early on.
 

If I change the declaration of class B I have to compile this and all those that include it again. Having B ready set up and just need to fill e.g. the method definitions inside the source file won't change any other code. Same goes for it's data behind the pimpl.

You will get shorter compile times or better to say re-compile times. But you will lose runtime-performance and get lots of includes in your source-files.


Think before you start to code.


The best way should be to combine all possible ways.
If the pointer overhead doesn't matter - use some pimpl.
You may also put some data-intensive methods right into the data-class.
If you don't mind having lots of includes - forward declare classes.
std::unique_ptr and std::shared_ptr are your friends.
iosfwd has some forward declaration for the ios-header (input-output-stream).
Try templates if you have problems with typedefs (but be warned of the compile-time increase for using templates). Also try instantiation and specialization.

But always:


Think before you start to code.




What are your tips and tricks for using forward declaration, pimpl, and how do you try to reduce compile time?
↧

IC 1 Ende & IC 2 Start

$
0
0

IC 1


Am 06.10.2012 habe ich die Dokumentation meiner Arbeit mit der iodoom3 Engine abgegeben. Wer will, kann diese hier lesen: https://docs.google.com/open?id=0B-DgjzoFZxxwTFl4em53UnRwYnc

Abstrakt:
Mit der Veröffentlichung des Quellcodes von Doom3 ist in mir das Interesse daran geweckt worden. Seit der Veröffentlichung ist etwas Zeit vergangen und ein wenig hat sich an der Engine getan. Neuigkeiten, dass Entwickler nun auf diese Engine setzten, sind kaum zu sehen. Um sich mit der Engine auseinandersetzen zu können, ist mir die Idee gekommen, ein Entwicklerkit dafür zu erstellen. Die frei verfügbaren Daten der Demo und des SDKs von Doom3 sollten dabei helfen. Neben diversen Werkzeugen für die Entwickler sollte auch ein Beispiellevel, wie es in etwa im Startprojekt von UDK zu finden ist, enthalten sein. Durch diverse integrierte Beispiele ist es einfacher sich in die Engine bzw. die Entwicklung von Spielen mittels der Engine einzuarbeiten. Aufbauend auf Gespräche und Erfahrungen anderer, sowie diverser Hilfeseiten, konnte ich mich langsam in der Handhabung der Engine nach vorne tasten. Mit diesen Grundlagen stellte ich das Startpaket zusammen. Am Ende steht jetzt ein Repository mit plattformunabhängigen Assets und diversen Repositories mit Quellcode auf iodoom3-Basis, sowie einem speziellen Startpaket für Windows, in dem Assets und ausführbare Binärdateien integriert sind. Im Anhang dieser Dokumentation befinden sich unterschiedliche Webseiten, die mir besonders zum Verständnis der Engine und dessen Nutzung beigetragen haben.

Die Hauptarbeit lag weniger im C++ Code, sondern mehr im Testen und Probieren und Verstehen, wie und wo die Assets eingebaut werden müssen. Dabei half, dass die Script- und Beschreibungsdateien in normalem Textformat vorlagen. So konnte ich letztendlich auf ein demonstratives Level mit u.a. Daten der Demo-Version erstellen. Mit den Demo-Daten, dem Source-Code und einigen kleinen Anpassungen lässt sich recht gut mit der Engine arbeiten.
Mit Verbesserungen, wie Dante [https://github.com/omcfadde/dante] und Sikk [http://www.moddb.com/mods/sikkmod] hatte ich leider weniger Erfolg. Sikk zeigt deutlich, dass aus der Engine noch einiges herauszuholen ist. Der Code, der auf das SDK aufsetzt, ist mit im Paket. Dante bringt GL ES und GLSL ins Spiel, wobei noch ein paar Shader für Doom3 fehlen.
Die in iodoom3 vorhandenen Editoren funktionieren. Mehr oder weniger. Und nur unter Windows. Anfangs waren die Abstürze des Editors sehr schnell herbeigeführt. Scheinbar werden gewisse Daten und Definitionen einfach vorausgesetzt und wenn diese fehlen, ist Ärger vorprogrammiert.

Letztendlich war die Arbeit mit iodoom3, bzw. besser dhewm3, recht interessant. Ein Weiterführen, wie anfangs geplant, wird es jedoch nicht geben. Neben der Portierung der Editoren müssten diverse Codes und Grafiken neu erstellt werden, um nicht in eventuelle rechtliche Probleme wegen Nutzung derer aus dem Demo-Version zu kommen. Hinzu käme die Zusammenführung von Dante und dhewm3, und auch die Integration von Sikk wäre wünschenswert, was natürlich zu sehr viel Testen führen würde.
Zudem ist noch die Frage offen, wie sich wohl Doom3 BFG in diese ganze Suppe herein mischen ließe, wenn dann dessen Code da ist [https://twitter.com/ID_AA_Carmack/status/259369191369502720]. Wahrscheinlich ist auch deswegen gerade etwas weniger im Umkreis von iodoom3 los [http://www.phoronix.com/scan.php?page=news_item&px=MTIzMjU].

Mal sehen, was die Zukunft bringt…



IC 2

Für dieses Semester ist ein neuer Independent Coursework angesetzt. Der Plan lautet wie folgt:


=====> Independent Coursework 2 <=====

Titel:
Entwicklung eines Rennspiels nach dem Vorbild "Ballistics"

Typ:
Independent Production

Kurzbeschreibung:
Im Rennspiel Ballistics(1) aus dem Jahr 2001 steuert der Spieler sein Hoverbike mit Hochgeschwindigkeit durch Röhren und weicht dabei Hindernissen und Gegenspielern aus. Booster erhöhen die Geschwindigkeit. Cooler senken den erlittenen Schaden.

Im Independent Coursework 2 soll der Prototyp eines Klons des Spiels Ballistics erstellt werden.

Der Spieler steuert sein Gefährt durch ein Tunnelsystem. Anders als im Original sollen Abzweigungen enthalten sein. Nach einem kurzen Streckenabschnitt führen diese wieder zusammen. Dem Spieler stehen dadurch alternative Routen zur Verfügung, wodurch er unter anderem sich von seinen Mitspielern kurzzeitig entfernen oder unterschiedliche Power-Ups einsammeln bzw. nutzen kann.
Neben "Super Booster", "Flip-Score" und "Ice" sind weitere Power-Ups vorgesehen, wie zum Beispiel Gegner verlangsamen, Booster des Gegners entfernen oder "Ghosten", bei dem der Spieler kurzzeitig durch Hindernisse hindurch kann.
Die Steuerung ist mittels Maus-Tastatur-Kombination bzw. Gamepad angedacht. Haftet der Spieler an der Wand, so kann er sich seitwärts, vorwärts und rückwärts bewegen. Ist er losgelöst, so kann er sich zusätzlich um seine Achsen drehen. Der Einsatz des Boosters und des Coolers erfolgen auf Tastendruck.
Neben den bekannten Hindernissen, dem roten X, I, dem kleinen Bumper und diversen Wänden, sollen auch wandfüllende Hindernisse vorhanden sein, sodass der Spieler gezwungen ist seine Haftung zu lösen und durch das Loch des Hindernisses zu fliegen. Eine Fahrer-KI soll dem Prototyp nicht enthalten sein. Dafür soll aber ein weiterer Spieler über Split-Screen mitspielen können. Multiplayer über Netzwerk ist für einen späteren Zeitpunkt vorgesehen. Die Erstellung des Spiels soll mit Hilfe von Blender und der Blender Game Engine geschehen.
Die grafische Ausrichtung ist an das Spiel "Megagolf"(2) angelehnt.

Ablauf:
- Erstellung einer Beispielröhre und einem einfachen Gefährt
- Erstellung der Steuerung
- Testen von Geschwindigkeit und Kollisionen
- Einbau von Split-Screen
- Erstellung von Power-Ups
- Einbau von Netzwerk-Multiplayer
- Erstellung von Assets (verschiedene Fahrzeuge, Hindernisse,
Röhrenabschnitte, Power-Ups, Shader)
- Aufbau eines Levels
- Einbau eines HUD
- Einbau eines Menü
[extra: Portierung auf Android]

Zielplattformen: Windows, Linux, evtl. Android

Stichwörter:
Gaming, Prototyping, Blender, Blender Game Engine, Multiplayer

Abgabe:
Spiel + Dokumentation

Links:
(1) http://en.wikipedia.org/wiki/Ballistics_%28video_game%29
(2) http://blenderartists.org/forum/showthread.php?158258-Megagolf
↧

[Bash] Play Flash-video with mplayer

$
0
0
Just a little script I made to play flash-videos from Firefox using mplayer.
Some flash-player put the video at
/proc/$pid/fd/$filedescriptor
That one can be played with using e.g. mplayer or vlc.
The script tries to find the right $pid and $fd and plays it.

Here it is:
( http://paste.kde.org/623894/ )
#!/bin/sh
pid=`pgrep -f flashplayer.so`
echo "$pid"
for p in $pid
do
echo "ls -l1 /proc/$p/fd/ | grep deleted"
deles=`ls -l1 /proc/$p/fd/ | grep deleted`
echo "deles: $deles"
wcDeles=`echo $deles | wc -w`
wlDeles=`ls -l1 /proc/$p/fd/ | grep -c deleted`
echo "WC: $wcDeles"
echo "WL: $wlDeles"

wPerLine=`expr $wcDeles / $wlDeles`
echo $wPerLine
offset=3
i=1
dval=""
for d in $deles
do
dval=$d
for numLine in `seq 1 $wlDeles`
do
pos=`expr $wPerLine \* $numLine - $offset`
#echo "expr $wPerLine \* $numLine - $offset"
#echo "P: $pos"
if [ $i -eq $pos ]
then
#echo "V: $dval"
echo "playing /proc/$pid/fd/$dval"
mplayer /proc/$pid/fd/$dval
fi
done
i=`expr $i + 1`
done
done
↧

[Bash] Play Flash-video with your player

$
0
0
I just improved my code from yesterday (http://urfoex.blogspot.de/2012/12/bash-play-flash-video-with-mplayer.html).

The player of choice is now nvlc which is a ncurses version of VLC. I took it because it still is command line but also has some console user interface with playlist and such things.
Why?
Because now the scripts not just plays "deleted" videos but also videos that are still lying around in cache. This is kind of the old style of how to access flash-movie e.g. for saving it.
The search-path for that is
"~/.mozilla/firefox/*.*/Cache" for firefox and
"~/.cache/chromium/*/*" for chromium.

For the playlist that is created a temporary file in "/tmp/browserFlashFiles.cache.log" is used and after finishing it will be deleted.
The minimum filesize of the videos is set to 1M.

Oh. There is also vim involved. It is used to delete some characters from the playlist. I guess there is an easy way without it. But hey! It works ;-)


YouTube uses some other way to save there videos. Therefor this script won't play those files.
Youtube-dl ( http://rg3.github.com/youtube-dl/ ) is a good place to start. When you start to download a video you should immediately be able to also play the still growing file.

The way would be for example:
youtube-dl -oyt_dl http://www.youtube.com/watch?v=VKDiap_6wGo & nvlc yt_dl.part


Another way is to use http://en.savefrom.net/
For a YouTube-video like e.g. 
http://www.youtube.com/watch?v=VKDiap_6wGo
you add "ss" before the youtube.com/... so it looks like this:
http://www.ssyoutube.com/watch?v=VKDiap_6wGo

You should be getting to a website with some download links on the right site for e.g. MP4 360p and MP4 720p. For different videos there are different versions available. Copy your preferred link location and open it with your player.
For me it looks like this:
mplayer "http://r18---sn-i5h7ln76.c.youtube.com/videoplayback?upn=BLCvLQhSTJY&sparams=cp%2Cid%2Cip%2Cipbits%2Citag%2Cratebypass%2Csource%2Cupn%2Cexpire&fexp=909713%2C927900%2C910019%2C910207%2C922401%2C912806%2C925703%2C925706%2C928001%2C922403%2C922405%2C929901%2C913605%2C913546%2C913556%2C920201%2C901632%2C911116%2C901451%2C902556&key=yt1&expire=1355371144&itag=22&ipbits=8&sver=3&ratebypass=yes&mt=1355346792&ip=94.223.213.238&mv=m&source=youtube&ms=au&cp=U0hUSlNST19JTkNONF9LTFNCOi1rQmVxYzVGbEpZ&id=54a0e26a9ffac06a&newshard=yes&signature=8CDA08919F0C6B8CD77A4F7B823C92E7ED543F99.7F40EABAA9B0598C9B02DFC3B24E26F150F8053D&quality=hd720&title=QtDD12%20-%20Welcome%20-%20Kalle%20Dalheimer"


Happy watching!



Btw.: Now here is the new code:
( http://paste.kde.org/624344/ )
#!/bin/sh
#You should be able to change this variable to the player of your liking
myplayer=nvlc

pid=`pgrep -f flashplayer.so`
cacheFile="/tmp/browserFlashFiles.cache.log"
pathFF=~/.mozilla/firefox/*.*/Cache
pathChrome=~/.cache/chromium/*/*

`echo "" > $cacheFile`
rm $cacheFile
for p in $pid
do
    deles=`ls -l1 /proc/$p/fd/ | grep deleted`
    wcDeles=`echo $deles | wc -w`
    wlDeles=`ls -l1 /proc/$p/fd/ | grep -c deleted`

    wPerLine=`expr $wcDeles / $wlDeles`
    offset=3
    i=1
    dval=""
    for d in $deles
    do
        dval=$d
        for numLine in `seq 1 $wlDeles`
        do
            pos=`expr $wPerLine \* $numLine - $offset`
            if [ $i -eq $pos ]
            then
                echo "/proc/$pid/fd/$dval" >> $cacheFile
            fi
        done
        i=`expr $i + 1`
    done
done

`find $pathFF -size +1M -type f -exec file {} \; | grep -E "(Media|Video)" >> $cacheFile`
`find $pathChrome -size +1M -type f -exec file {} \; | grep -E "( Media|Video)" >> $cacheFile`
vim $cacheFile "+%s/:.*//" "+wq"
cat $cacheFile
$myplayer `cat $cacheFile`
rm $cacheFile
↧
↧

[BGE+GLSL] Finding interest points

$
0
0
Interest Points
I learned a bit in a class called "Computer Vision".
One thing was "finding interest points". 
Basically when you have a picture and give it to your computer it doesn't know anything what to do with it. It's just plain boring data. Every point is as interesting as every other. On some images you might have the same feeling. On others you recognize things which gives it more value then just color. 

But what makes the difference?
How do you see something?

Contrast is a good starting point. If the picture is just like one color, everything blurry, a low contrast then it's hard to see something. With high contrast especially between objects it's much easier to stop objects.
Those places with high contrast are probably also good interest points. That's why we try to find them, or better: let the computer find them so he knows some interesting points on the image.

SIFT
The following algorithm bits are part of SIFT.
At first you have your image. You make at least 4 blurred copies of it with each having a different blur-strength. Then you take two neighbors and make a difference of them. As a result you have 3 difference-pictures (1-2, 2-3, 3-4). Now in the last step you put those 3 difference-pictures virtually over each other. Walking over each pixel without the surrounding of the middle picture you check if the pixel is the absolute biggest or absolute smallest around its 26 neighboring pixels (3x3x3 - center, 9 above, 9 below, 8 on same).  If it is then you put a 1 on an extra final image at that place, else a 0. All those "1" spots now mark interest points.

Just one sample and one code
Just for the fun of it I tried implementing that inside the Blender Game Engine using GLSL code. The first implementation is probably the worst you can do. 
The image goes into the shader. At the fragment-shader you just have the value of the pixel of the current place on the texture. Because I need 27 difference-of-blur pixels I need to get those on the fly. So I get the neighboring pixels, blur them, do a difference and then do the check. 
It's really bad because most of those difference-of-blur pixels are calculated again and again and …
But it works!
(With about 4000ms taken for calculating…)

Here are the files for it:

image to find interest points in
interest points of the image


Many samples and some code
Having written nearly the same algorithm in Java getting around 400ms to find those interest points the GLSL-results weren't pleasing. 
In Java I used different pictures for the different results. That way I won't calculate needed points again and again. The same I tried inside Blender.
The problems:
→ How do I get the image blurred?
→ How do I create a difference of two blurred images?
→ How do I compare three images?

If you can't wait, here are the files for it:

"Use Frame Rate" on

"Use Frame Rate" off
the setup
As you can already see the setup for this way is much bigger then for the first version. I used 16 planes, 9 cameras and about 9 images for the different textures. 

Blurring with GLSL
The first step: getting the image blurred with different strength.
 Two substeps are therefore needed:
1] Get the image that should be blurred.
2] Blur it via GLSL.

I could have just used the texture I used for the main-plane but I choose a different way. A camera above the targeted plane is used to render the plane and create a texture from that.
The module-code is rather simple:
    1) own = cont.owner
    2) camSrc = scene.objects[own['Cam']]
    3) matID = texture.materialID(own, 'IM'+own['Tex']+own['ID'])
    4) own['RenderedTexture'] = texture.Texture(own, matID)
   5) own['RenderedTexture'].source = texture.ImageRender(scene, camSrc)
    6) own['RenderedTexture'].refresh(False)
With "texture.materialID" I query the id of the texture I want to render on. Then I create a new texture with "texture.Texture". The important part here is to save this new texture somewhere or else it will be destroyed when leaving the module. The call to "texture.ImageRender" does the actual rendering.
Having the desired image the next step is blurring it. GLSL is a fancy way of doing stuff to the texture and object. The object itself is irrelevant for here. I just needed the texture-changing. OK, it does not actually change the texture but the rendered view of it. There are ways to save the changes back to the texture itself via OpenGL and GLSL but it's not part of this project.
The code is divided in 3 parts: 
→ python-code to to set up the shader
→ a vertex shader
→ a fragment shader

You can write the shaders in the python file e.g. as a string and bind and use all that together. I like to split those in separate files. Having my shader-code loaded the setup-code looks like this:
for mat in mesh.materials:
        shader = mat.getShader()
        if shader != None:
            shader.setSource(vs,fs,1)
            shader.setSampler('Image',0)
            shader.setUniform1f('width', 1.0/mainCam['width'])
            shader.setUniform1f('height', 1.0/mainCam['height'])
            shader.setUniform1f('M_PI', math.pi)
            shader.setUniform1i('BlurFactor', own['BlurFactor'])
With "setSource" the code to use is set. "setSampler" is the method to tell the shader which texture to use.  The string should be in the shader-code, the number is the number of the texture in you texture-slot. Via "setUniform" some variables can be set. Here I tell the shader the step-size for width and height, the value of PI and the blur factor. Normally the projection, view and model matrices should also be given over at this point. But somehow I messed up. I need to investigate that further at a later point.
Having set this up just the shader code is missing.
Like I sad I won't need any object changes. Therefore the vertex-shader is as simple as this:
gl_TexCoord[0] = gl_MultiTexCoord0;
position = gl_ModelViewProjectionMatrix*gl_Vertex;
gl_Position = position;
Setting the UV-texture coordinates to use and the actual position.
Now to the fragment-shader with the blurring.
To blur a pixel you also need some of the pixels around. I used the Gaussian blur here. The sum of the the value at a position multiplied by its gauss-value is created for all points in a diameter of 11. Because of the formula of the Gaussian formula the sum can't be greater then 1. So we can use the result as the value of the color.
Now we have the second row with all 4 blurred images.

As you can see in the setup-picture above I have two rows with planes. That is because the GLSL code doesn't actually change the texture and therefore when I want to use the blurred images and just try using their textures they aren't changed like you think they should be. That's why I need to render the GLSL changed planes to textures so I can use those.

Difference of blurred
The third row contains those images that are the difference of two blurred images. The GLSL is similar to the one above. Because two images are needed as input two samples are given into the shader. Calculating the difference in the fragment-shader is quite simple:
texture(Image0, st)-texture(Image1, st)
Right?
Normally: Yes.
And the main-camera will show it just fine. But when you render it e.g. to a texture you will get problems. A color consists of 4 parts: Red Green Blue Alpha. The Alpha will make a problem here because "1 - 1 = 0". The input-samples will probably have an Alpha of 1 each. The result will get an Alpha of 0. Not good. That's why you should take care and turn the resulting Alpha to 1.

Maximum of 27
The last row is the initial image with the interest points in it. So you need 4 samples in the shader: the initial image and the three difference images.
It's plain simple: take all 3x3x3 = 27 points and check if the center is the biggest. If it is then put a white dot at the current place, else just show the normal image.

Results
As you might have already seen the time to find/calculate the the interest points is much lower then before. One thing I don't understand is that turning the frame rate limiter off results in heavy load on the Rasterizer being about 13 times bigger with about the same result in Frametime. I guess that this might be a bug in the BGE.
Another difference to the calculation in one step except that this runs much faster is that this isn't done in one step. More precise not done in one frametime. In the first round the normal image is rendered. The different cameras just see black and render that. Then the camera of the main image sees something and the planes with the not jet blurred are getting a copy of the render. With that the GLSL blur shader can do the work on that. A round later the cameras over the blurred are seeing things and create textures of those which will go the difference-planes. Later those get GLSL-worked on, and then again rendered to texture. And then searching the maximum. Done.
If you would have just one frametime time to do it it won't work. But in the end we have like 60 render rounds per second. The result is much faster here then with the single approach from before.

Possible extensions
Having thought about the code a bit more I would say that there is a lot of improvement left. To name some simple things:
→ The calculation is done on a black-n-white image. With 4 channels per color 3 are unused. Worse: needless calculated. So e.g. all 4 blur-images code be create with in one texture. The problem here is with render-to-texture. The Alpha would kill you. A better way would be the right GLSL function to write the texture back or change the texture accordingly. Another problem would be that you couldn't simply show the texture unless you write a shader to just show the correct channel.
The same could be done with the difference-images and the maximum-storage.
→ Use the texture of the initial image a input for the blur-images. Don't render-to-texture it.
→ Having:
    → one initial image
    → one image with four blur
    → one image with three difference and one maxima
    All those could be put into one shader. So just one shader would have to be written to do it all. 
→ Having no image except the initial one. Just thinking: if a shader creates a global array. Is that still there in the next render round? If so all those extra images could be arrays. So you would just move inside those arrays instead of the images. It should give a performance boost I guess.
→ Avoid this kind of interest point detection. There are faster ones out there. E.g. have a look at SURF


The End
Doing this I learned a lot about image filtering, GLSL, BGE.
Maybe someone finds this round-up useful.
Ideas, comments, critics etc. are welcome.

See Ya!
↧

[BGE + GLSL] Py GL Rant

$
0
0
Let's do this.

Blender Game Engine.
It is nice.

But it also has its problems. Just like everything else.
This time I had a hard time doing some GLSL shaders. Not the normal ones.

GLSL viewer
Just for testing I did a little GLSL viewer in BGE:
https://docs.google.com/file/d/0B-DgjzoFZxxwV1lhZ20ySTFrZzQ/edit?usp=sharing

Just edit the simple.fs as you like. The code inside is taken from http://glsl.heroku.com/e#6952.0

You can find more nice codes here:
http://glsl.heroku.com/
https://www.shadertoy.com/


But with this little sample I got a problem:
How do I find out if an uniform is active?

Answer: glGetUniformLocation
http://www.opengl.org/sdk/docs/man3/xhtml/glGetUniformLocation.xml
This should return -1 if the uniform isn't active.
The function is not in the python api.
So currently I have no choice but to just pass all uniforms I know and get lots of messages about some not being in the shader.


RenderToTexture
Here I tried using the RenderToTexture feature to create a texture for an object on the fly:
https://docs.google.com/file/d/0B-DgjzoFZxxwYzd6TjcxVS1zQWs/edit?usp=sharing

Short answer: I couldn't get it working.
The problems:
1) How do I switch between shaders without recreating them all the time?
2) How do I use another texture to render on then just the first?
3) How can I hide shader compile messages?

Don't wanna talk about the performance issue…
Or that it won't work as I thought it could.

So to get some answers:
1) glUseProgram
http://www.opengl.org/sdk/docs/man3/xhtml/glUseProgram.xml
Currently the shader program is part of BL_Shader. And it is capsuled pretty good. So BL_Shader should be exchangeable. So some "setShader" would be nice inside KX_BlenderMaterial.

2) RAS_IPolyMaterial just has one texture. BL_Material has access to more. Same goes for KX_BlenderMaterial. As KX_BM is a RAS_IPM there might be a way to query the the texturename with a virtual method.

3) Create a state that disables the output of those messages.


Framebuffer objects
My first intend was to improve the interest detection I talked about last time [http://urfoex.blogspot.de/2013/02/bgeglsl-finding-interest-points.html]. Therefor I thought about using framebuffer objects.
http://www.songho.ca/opengl/gl_fbo.html
http://www.opengl.org/wiki/Framebuffer_Object

Simply said it is the same as RenderToTexture. You create a buffer and then render to it instead of to the screen. When done you can just the buffer e.g. as a texture for the real screen rendering.
It is not the thing I had hoped for but at least it is something that could have helped a bit. My real intention was to have a buffer in GLSL that I could read and write to. The buffer should be on GPU. The shader could access and modify it each round.
The framebuffer could do the trick. The steps would be the following:
  1. create as much framebuffers as needed
  2. bind first fb, bind shader for first fb
  3. render just the object to the fb
  4. repeat step 2 and 3 until all framebuffers are used, consider using previous fbs as samplers
  5. set shaders, fb-samplers and other things for real rendering
  6. for each following rendering: skip step 1
(Idea: That could also help to create dynamic textures. )

Here are my first tries:
https://docs.google.com/file/d/0B-DgjzoFZxxwNVpMT2dRQW5SZHM/edit?usp=sharing
https://docs.google.com/file/d/0B-DgjzoFZxxwbW43bnJPRTE2Q1E/edit?usp=sharing
https://docs.google.com/file/d/0B-DgjzoFZxxwaXpETU5MeDMzR0k/edit?usp=sharing

They don't work.
Why?
I'm not quite sure. Using PyOpenGL is simple. But somehow it is not.
Or at least not in combination with BGE.

I had found a sample on how to include it:
http://www.blender.org/documentation/blender_python_api_2_60_1/bge.types.html?highlight=kx_polygonmaterial#bge.types.KX_PolygonMaterial

But "yeahy!" that just is for single-texture-mode (see http://blenderartists.org/forum/showthread.php?277025-KX_PolygonMater*ial-and-KX_BlenderMater*ial-question&highlight=KX_PolygonMaterial).

Writing some code I could get some framebuffer-code but for using the FB afterwards I would need to set it as a sampler. But how to do this without proper access the the shader? By building the shader via PyOpenGL. If it would give me more then just an error:
"Shader.py", line 68, in load
File "/usr/local/lib/python3.3/dist-packages/PyOpenGL-3.0.2-py3.3.egg/OpenGL/GL/shaders.py", line 220, in compileShader
glCompileShader( shader )
File "/usr/local/lib/python3.3/dist-packages/PyOpenGL-3.0.2-py3.3.egg/OpenGL/latebind.py", line 41, in __call__
return self._finalCall( *args, **named )
File "/usr/local/lib/python3.3/dist-packages/PyOpenGL-3.0.2-py3.3.egg/OpenGL/GL/VERSION/GL_2_0.py", line 137, in GLSLCheckError
description= glGetInfoLog( cArguments[0] )
OpenGL.error.GLError: GLError(
description = b"Vertex shader failed to compile wit...,
baseOperation = glCompileShader,
cArguments = (14,)
)
So no PYOGL shader for me.


Afterthoughts
It's a pain if you just want to code and get things done and it just doesn't work as you want. Python moves forward but its modules doesn't follow. PyOpenGL just has experimental support for Python 3.2. Especially its acceleration support isn't working with Python 3.3. On the other hand: OpenGL has moved to version 4.3 over a long period. But you can't just use it via Python in the BGE. It's not even in the C++ code.
Looking at those problems I have they mostly arise from trying to code only using Python. Extending the engine would do the trick and might help others too.

Most time in game making you probably won't notice those problems I had. Shaders don't change on the fly. RenderToTexture is expensive and so used just like one or to times for e.g. mirrors.
Most shaders from e.g. shader-site like those above simply work inside the BGE. As far as I can see most of them should work too:
https://github.com/id-Software/DOOM-3-BFG/tree/master/base/renderprogs

One thing that could also be easily implemented, but for now just is a bit annoying: creating an own GLSL shader.
It's not the shader itself but the corresponding lighting and shadowing and such things. If you use material-nodes to do your tricks everything is just fine. But if you create your shader you loose everything for the corresponding object or better 'material'. Every extra like light and shadow you need to insert for yourself.
As an idea I thought about providing the main shader that should come with BGE and having some includes and functions in there. Via python you could set the right file to include and so the right function to call.

E.g. something like this:
mainFrag.glsl:
#include "mainShader.glsl"
#include "myShader.glsl"

out vec4 glFragColor;

void main(){
    vec4 diffuse = myDiffuseShader();
    vec4 specular = mySpecularShader();
    vec4 normal = myNormalShader();
    vec4 ambient = myAmbientShader();
    glFragColor = mainShader(diffuse, specular, normal, ambient);
}
myShader.glsl:
vec4  myDiffuseShader(){
    return vec4(0,0,0,1);
}
vec4  mySpecularShader(){
    return vec4(0,0,0,1);
}
vec4  myNormalShader(){
    return vec4(0,0,0,1);
}
vec4  myAmbientShader(){
    return vec4(0,0,0,1);
}

myOtherShader.glsl:
vec4  myDiffuseShader(){
    return vec4(1,0,0,1);
}
vec4  mySpecularShader(){
    return vec4(0,1,0,1);
}
vec4  myNormalShader(){
    return vec4(0,0,1,1);
}
vec4  myAmbientShader(){
    return vec4(0,0,0,1);
}
 myShader.py:
def useShader():
    fragShader = read(mainFrag.glsl)
    fragShader.replace("myShader.glsl", "myOtherShader.glsl")
    object.setShader(fragShader)
Shouldn't that work?
I think I try that another day.


Random rants:
→ nullptr instead of 0
→ no goto
→ shared_ptr instead of normal *
→ mercurial / git instead of svn
→ no "spit"ting around. usage of clog and cerror or even better logging
→ newest Python 3.3 with nearly no module working but really old OpenGL
→ C++ code that needs refactoring

↧

[SVN + Mercurial] Mirroring and using an SVN repository with Mercurial

$
0
0
For trying some code changes in the Blender Game Engine I needed its code. It is accessible via SVN from https://svn.blender.org/svnroot/bf-blender/trunk/
With Git and Mercurial around I'm used to do local changes, commit them locally and maybe undo them if I made mistakes. With SVN this is not possible.

Why do they still use SVN?
http://wiki.blender.org/index.php/Dev:Doc/FAQ#Why_not_switch_to_distributed_version_control.3F_.28git.2Fmercurial.2Fbazaar.29

There is even a discussion on the mailinglist:
http://lists.blender.org/pipermail/bf-committers/2011-May/032082.html

And?
Still SVN.
The Git mirror mentioned in the Wiki seems outdated.
But there are some unofficial ones on github:
https://github.com/ldo/blender-main
https://github.com/nicholasbishop/blender/

But compiling them gives you messages about missing locale, addons and addons_contrib. Those folders are normally pulled via SVN externals. So if you are using the Git mirror you still need to get those extra folders from somewhere. A way might be Git-Submodules.

Looking around I found hgsubversion: http://mercurial.selenic.com/wiki/HgSubversion
A simple one:
  • add hgsubversion to your extensions list
  • hg clone svn+repository
You should have plenty of time or a PC in the back to do that job because it really takes a long time for big repositories. It reads like every SVN commit and puts it into the Mercurial repository. You will have a nice version history afterwards.
The same I did for
"Locale" did again take a long time because most files in it are binary. That's why in the end it had a size of about 300MB. The SVN co of it is just about 50MB.
In the meantime I pushed the repositories to new created repositories on https://bitbucket.org/

After that I had the following:
The next step was to include the former SVN externals via Mercurial subrepositories http://mercurial.selenic.com/wiki/Subrepository
Just create a .hgsubs file in your hg root folder and insert the appropriate lines. Just like this:
release/datafiles/locale = [svn]https://svn.blender.org/svnroot/bf-translations/trunk/locale
release/scripts/addons = https://bitbucket.org/Urfoex/addons
release/scripts/addons_contrib = https://bitbucket.org/Urfoex/addons_contrib
You can use Mercurial, Git and Subversion repositories here.
I'm not sure right now if I had to checkout / clone those repositories myself for it to initially work. At least for SVN HG complained about locale "is not a working copy". But right now if I clone my repository and go to the right branch Mercurial pulls all subrepositories in without my help. It works just like with SVN and SVN externals.


Sounds easy so far.

Looking at the commit graph shows that I had some problems.
I simply can't delete branches. I made some to test if I can put some commits in the branch and then put commits from default to it to, like "rebase". Didn't really work as I thought and now I have some branches "just because". This also includes some commits that I made that I can't remove. Not reverting. That works. But real deletion.
Branches could be removed in 3 ways: http://mercurial.selenic.com/wiki/PruningDeadBranches
None worked for me. I finally merged and closed them but they are still there.  The clone-method somehow didn't work with hgsubversion. It technically worked but doing a "hg pull" that normally pulled new SVN changes in resulted in an error.
Another commit and another branch was just locally. "hg strip" did fine to remove those. (http://webcache.googleusercontent.com/search?q=cache:jYnn0rwFlkIJ:mercurial.selenic.com/wiki/EditingHistory+&cd=2&hl=de&ct=clnk&gl=de)
Somehow I managed to accidentally put a commit in the default branch. And hgsubversion created a new head for the new SVN incomings. Now I have two heads for the default branch and don't now how to safely change that. Every time I pull the changes from SVN in it create a new head. If I don't mind I can push that and have two heads. Or I merge those two heads together. That creates a commit and looks a bit ugly. But at least the last commit will unsure that the specific subrepo-changes are in.

One thing I would like to know is: What happens when my local hgsubversion repository that I use to pull SVN changes and push them to Mercurial gets deleted? How do I then push SVN changes? Can I simply create a new local hgsubversion repository and my pushes will work on top?


At least it works for now.

Btw.: If you gonna push to a different path then you pull you can tell hg to do so in the .hg/hgrc file. Just like this:
[paths]
default = svn+https://svn.blender.org/svnroot/bf-blender/trunk/blender
default-push = https://bitbucket.org/Urfoex/blender

I also create a very simple script for updating the  repositories:
$ cat update.sh
#!/bin/sh
echo "+==============================================+"
echo "-------------------- ADDONS --------------------"
echo "+==============================================+"
cd addons
hg pull
hg push
cd ..

echo "+==============================================+"
echo "---------------- ADDONS_CONTRIB ----------------"
echo "+==============================================+"
cd addons_contrib
hg pull
hg push
cd ..

echo "+==============================================+"
echo "------------------ BLENDER-HG ------------------"
echo "+==============================================+"
cd blender-hg
hg pull
echo "+==============================================+"
echo "!! Don't forget to merge changes for subrepos !!"
echo "+==============================================+"
hg push
cd ..

echo "+==============================================+"
echo "----------------- BL_HG_CLONE ------------------"
echo "+==============================================+"
cd bl-hg-clone
hg pull
hg push
cd ..

echo "+==============================================+"
echo "-------------------- LOCALE --------------------"
echo "+==============================================+"
cd locale
hg pull
hg push
cd ..

:-D
Very simple.


In the end it is possible to move a SVN repository to Mercurial or just use one that way. Moving it over is a nice opportunity.
But using it as a wrapper is a bit painful. It feels much better with just Mercurial or just Git.


Back to changing BGE code…
↧
Viewing all 65 articles
Browse latest View live