Seite 3 von 9

Re: Auf dem Weg von DDraw nach OpenGL ..

Verfasst: 13.05.2010, 17:27
von Aramis
Ich versuche ja im Moment gemeinsam von Windows und Linux auf die gleiche Datei zuzugreifen.
Ja, aber was haelt dich davon ab /media/D_DRIVE/Kempter/VC9/ZwiAnerOpenGL zu deinen Includepfaden unter Linux hinzuzufuegen und dann #include <Linux/Tests/TestKString/main.h> zu schreiben?

Re: Auf dem Weg von DDraw nach OpenGL ..

Verfasst: 13.05.2010, 17:33
von HeinzK
Also VS hat damit keine Problem, dass Dateien auch aus Linux bearbeitet werden. Daran liegt es nicht.
Die stdafx.h ist auch sicher nicht von Linux bearbeitet worden. Wenn ich das #ifdef/#else/#endif auskommentiere, wird alles ordnungsgemäß geladen und compiliert.
OK, ich schaue mir das genauer an!
Hat jemand eine andere Idee, die gemeinsame Nutzung zu organisieren?

Re: Auf dem Weg von DDraw nach OpenGL ..

Verfasst: 13.05.2010, 17:37
von Aramis
Hat jemand eine andere Idee, die gemeinsame Nutzung zu organisieren?
Naja, grundsaetzlich solltest du doch all deine Dateien irgendwo in einem Verzeichnis haben, Quellcode wie Header. Das Verzeichnis mag dann zwar unter Windows oder Linux an unterschiedlichen Stellen gemounted sein, aber von den cpp–Files sind dennoch alle Header mit einem relativen #include erreichbar –

oder nicht?
Also VS hat damit keine Problem, dass Dateien auch aus Linux bearbeitet werden.
Ja, VC kommt mit allerhand Line-Endings klar. gcc prinzipiell auch. Trotzdem koennte Krishty Recht haben. Um das auszuschließen, koenntest du alle Dateien deines Projektes mal auf einheitliche Zeilenenden umstellen, z.B. via datei / Erweiterte Speicheroptionen in Visual Studio. Dann nochmal auf beiden Plattformen probieren.

Re: Auf dem Weg von DDraw nach OpenGL ..

Verfasst: 14.05.2010, 09:15
von HeinzK
Ja, für die einzelnen Klassen stimmt das schon. Da liegen cpp und h im gleichen Verzeichnis.
Nur die 'tmain' und 'main' machen eine Ausnahme, weil einmal Windows und einmal Ubuntu.
Wenn ich alle Verzeichnisse eingerichtet habe, dann ist natürlich alles mit relativen Pfaden erreichbar.
Im Moment ist es halt noch Baustelle.
Aber das ist nicht das Problem.
a) Wenn ich die Direktiven jeweils passend auskommentiere, kann ich das Programm von Windows (VS) und von Ubuntu (CB) aus ohne Probleme compilieren.
b) Ubuntu (CB) hat kein Problem und compiliert auch mit aktivem #ifdef ohne Fehlermeldung.
OK, das Problem ist nur unter VS vorhanden .. fatal error C1019: Unerwartetes #else.

Re: Auf dem Weg von DDraw nach OpenGL ..

Verfasst: 14.05.2010, 09:25
von HeinzK
Gerade getestet: Generell hat auch VS kein Problem mit der Verschachtelung .. also werde ich weiter versuchen das Problem zu lokalisieren .. bin an der Arbeit.

Re: Auf dem Weg von DDraw nach OpenGL ..

Verfasst: 14.05.2010, 09:48
von HeinzK
Also, es scheint nur ein Problem beim Laden der stdafx.h zu sein:

Code: Alles auswählen

#ifdef _WIN32
  #include "stdafx.h"
#endif
.. unerwartetes #endif
Z.Bsp.:

Code: Alles auswählen

#include "stdafx.h"
#ifdef _WIN32
  #include "KString.h"
#endif
funktioniert einwandfrei.
Ich vermute nun, es ist ein Problem mit den 'vorkompilierten Headers' .. bin weiter am testen ..

Re: Auf dem Weg von DDraw nach OpenGL ..

Verfasst: 14.05.2010, 10:06
von HeinzK
OK, Ursache gefunden .. es waren die 'Vorkompilierten Headers' ..
Sobald das '#include stdafx.h' innerhalb einer #ifdef liegt, kann ich die
'Vorkompilierten Headers' nicht erzeugen, geschweige denn verwenden!

Hat jemand eine andere Idee, wie man meinen Wunsch umsetzten kann?
Wunsch:
Pfad: ../ZwiAnerOpenGL
darunter:
../Gemeinsam
../Linux
../Windows
Unter ../Gemeinsam liegen alle cpp und h die ohne Änderungen von
Windows und Unbuntu verwendet werden können.
Unter ../Linux bzw. ../Windows liegen die jeweiligen Startdateien, also main bzw. tmain und die speziellen Fälle.

Ich will die Redundanz so gering wie möglich halten!

PS:
Ich arbeite normalerweise immer ohne die Vorkompilierten Headers. Aber im Testprojekt waren diese halt automatisch voreingestellt.

Re: Auf dem Weg von DDraw nach OpenGL ..

Verfasst: 14.05.2010, 13:50
von HeinzK
Ich habe es nun schon auf dem 2. Rechner probiert und bin jededsmal abgeschmiert.
Das Update von Ubuntu 9.10 (aktuelle Version) auf 10.0!
Es läuft bis zu '> Installing the upgrades'/'About 4 minutes remaining' dann kommt eine Dialogbox: 'Configuring grub-pc'.
Dort ist der Button 'Forward' aktiv. Ich kann in zwar betätitgen, aber nicht geht mehr.
Hinweis: Ich habe diese Frage nun auch im Ubuntu-Forum gestellt!
http://www.ubuntu-forum.de/artikel/5088 ... eiter.html

Re: Auf dem Weg von DDraw nach OpenGL ..

Verfasst: 14.05.2010, 13:58
von Aramis
Probier mal das grub-pc–Paket manuell zu entfernen und dann nochmals zu installieren.

Re: Auf dem Weg von DDraw nach OpenGL ..

Verfasst: 14.05.2010, 17:55
von HeinzK
Danke, aber ich habe keine Ahnung, wie ich das grub-pc manuel löschen muss .. einfach das Verzeichnis löschen?
Aber ich glaub' am Besten hole ich mir das 10er einfach als neue installation.
Bin gerade dabei auszutesten, wie ich meine LoopBremse am Besten unter Linux einsetze.
Dabei habe ich mal unter Windows getestet, wie gut meine KString-Klasse gegen CString abschneidet.
Hier das Ergebnis:

Code: Alles auswählen

for (int i=0; (i < 5000); i++)
{
if (true)
{
sTraceK.Format("dLoopReserve= %0.6f(%0.6f)", dLoopReserve, (1000.0 - dLoopReserve));
} else
{
sTraceC.Format(_T("dLoopReserve= %0.6f(%0.6f)"), dLoopReserve, (1000.0 - dLoopReserve));
}
}
5000 * KString.Format = 23 ms.
5000 * CString.Format = 31 ms.
Also (31 - 23) / 23 >> Ich bin sogar 35% schneller geworden. :D
EDIT:
Aber jetzt die Überraschung! CString ist ca. 3 mal schneller als std::string!
Getestet: .Left, .Right, .Mid, .MakeLower, .MakeUpper, .Compare, .CompareNoCase und .Empty :!:

Re: Auf dem Weg von DDraw nach OpenGL ..

Verfasst: 14.05.2010, 21:35
von Aramis
Aber jetzt die Überraschung! CString ist ca. 3 mal schneller als std::string!
Getestet: .Left, .Right, .Mid, .MakeLower, .MakeUpper, .Compare, .CompareNoCase und .Empty
Nicht dass es eine Rolle spielte … aber zeig bitte mal deinen Testcode, wie auch die Implementierung aller genannten Memberfunktionen. Ansonsten sind solche Mikro-Benchmarks eher irrelevant. Außer, du schreibst Code bei dem die Stringverarbeitung das absolute Bottleneck ist.

Re: Auf dem Weg von DDraw nach OpenGL ..

Verfasst: 15.05.2010, 09:20
von HeinzK
Sobald ich meine Loopbremse (also mein Zeitmanagement) von Windows auf Ubuntu übertragen habe, werde ich
die Test's veröffentlichen (mit Quellcode). Auf den Vergleich der Betriebsysteme bin ich sehr gespannt.

Re: Auf dem Weg von DDraw nach OpenGL ..

Verfasst: 15.05.2010, 09:58
von Alexander Kornrumpf
Loopbremse? Sind die 90er Jahre zurück? :)

Re: Auf dem Weg von DDraw nach OpenGL ..

Verfasst: 15.05.2010, 10:02
von HeinzK
Loopbremse: Ich brauch' für mein Spiel eine konstante Anzahl von Berechnungszyklen!

Re: Auf dem Weg von DDraw nach OpenGL ..

Verfasst: 15.05.2010, 10:05
von Alexander Kornrumpf
Bist du sicher dass du nicht einen konstanten Timestep brauchst? =>Substepping

EDIT:
Etwas genauer:

Natürlich bin ich mir bewusst dass man einen wirklich konstanten Timestep so nicht in Echtzeit hinbekommt. Aber für die allermeisten Spiele sollte es reichen.

Re: Auf dem Weg von DDraw nach OpenGL ..

Verfasst: 17.05.2010, 15:31
von HeinzK
Hier der versprochene 'Benchmark':
Bild
Declaration von CKString:

Code: Alles auswählen

#pragma once
#include <stdarg.h>
#include <algorithm>
#include <string>
#include <iostream>
#include <memory.h>
#include <stdio.h>
using namespace std;
class CKString
{
  public:
    CKString(void);
    CKString(const string &sStr);
    virtual ~CKString(void);
    string Empty(void);
    string Format(const char *pFrm, ...);
    string Left(const int &iCn);
    string Right(const int &iCn);
    string Mid(const int &iC1, const int &C2);
    string MakeLower(void);
    string MakeUpper(void);
    int Compare(CKString &sStr);
    int CompareNoCase(CKString &sStr);
    void SetString(const string &sStr);
    int GetLength(void);
    string GetString(void);
  private:
    string k_sStr;
    void Ini(void);
    string KFormatArgmList(const char *pFrm, va_list Argm);
};
Implementation von CKString:

Code: Alles auswählen

#include "KString.h"
CKString::CKString(void)
{
  Ini();
}
CKString::CKString(const string &sStr)
{
  k_sStr = sStr;
}
CKString::~CKString(void)
{
}
void CKString::Ini(void)
{
  Empty();
}
string CKString::Empty(void)
{
  k_sStr.clear();
  return k_sStr;
}
string CKString::KFormatArgmList(const char *pFrm, va_list Argm)
{
  if (!pFrm)
  {
    return "";
  }
  long lRes = -1;
  long lMaxLen = 4096;
  long lLen = 1024;
  char *cBuff = 0;
  while (lRes == -1)
  {
    if (cBuff != NULL)
    {
      free(cBuff);
    }
    cBuff = (char *)malloc(lMaxLen); 
    memset(cBuff, 0, lLen + 1);
    #ifdef _WIN32
      lRes = _vsnprintf_s(cBuff, lMaxLen, lLen, pFrm, Argm);
    #else
      lRes = vsnprintf(cBuff, lLen, pFrm, Argm);
    #endif
    if (lRes < 0)
    {
      if (lLen < lMaxLen)
      {
        lLen *= 2;
      } else
      {
        lRes = -2;
      }
    }
  }
  string sFrm;
  sFrm.clear();
  if (lRes > 0)
  {
    sFrm.assign(cBuff, lRes);
  }
  if (cBuff != NULL)
  {
    free(cBuff);  
  }
  return sFrm;
}
string CKString::Format(const char *pFrm, ...)
{
  va_list Argm;
  va_start(Argm, pFrm);
  k_sStr = KFormatArgmList(pFrm, Argm);
  va_end(Argm);
  return k_sStr;
}
string CKString::Left(const int &iCn)
{
  return k_sStr.substr(0, iCn);
}
string CKString::Right(const int &iCn)
{
  int iR = (k_sStr.length() - iCn);
  return k_sStr.substr(iR, iCn);
}
string CKString::Mid(const int &iC1, const int &iC2)
{
  return k_sStr.substr(iC1, iC2);
}
string CKString::MakeLower(void)
{
  transform(k_sStr.begin(), k_sStr.end(), k_sStr.begin(), ::tolower);
  return k_sStr;
}
string CKString::MakeUpper(void)
{
  transform(k_sStr.begin(), k_sStr.end(), k_sStr.begin(), ::toupper);
  return k_sStr;
}
int CKString::Compare(CKString &sStr)
{
  return k_sStr.compare(sStr.GetString());
}
int CKString::CompareNoCase(CKString &sStr)
{
  string sS1(k_sStr);
  string sS2(sStr.GetString());
  return sS1.compare(sS2);
}
void CKString::SetString(const string &sStr)
{
  k_sStr = sStr;
}
int CKString::GetLength(void)
{
  return k_sStr.length();
}
string CKString::GetString(void)
{
  return k_sStr;
}
Hinweis: CString.Empty == std::string.clear
Für mich wäre es wichtig, wenn die folgenden Testroutinen auf möglichst vielen Plattformen getestet werden könnten!
Linux: http://www.zwianer.de/$PCSpiel$/Probleme/KStringLinux
Windows: http://www.zwianer.de/$PCSpiel$/Problem ... indows.exe
Da ich Linux/Ubuntu nur in einer virtuellen Maschine nutze, wäre ich für alle Rückläufe von 'richtigen' Maschinen sehr dankbar!
Außerdem bin ich auf Linux/Ubuntu absoluter Anfänger. Schon deshalb wäre interessant zu wissen, ob ich das Programm 'KStringLinux' richtig erzeugt habe?
PS:
Wer den ganzen Quellcode als vollständiges Projekt haben will, einfach per EMail anfordern: Heinz.Kemper@ZwiAner.de

Re: Auf dem Weg von DDraw nach OpenGL ..

Verfasst: 17.05.2010, 15:34
von Krishty
Ändere GetString() mal zu

Code: Alles auswählen

string const & CKString::GetString(void) const
{
    return k_sStr;
}
(Dann gibt er eine Referenz auf den String zurück, statt eine temporäre Kopie zu erzeugen.) Damit werden dann auch Compare() und CompareNoCase() wieder konkurrenzfähig.

Und die ganzen ints bei Left(), Right() usw brauchst du nicht als Referenz übergeben, by-value ist bei solchen Typen gleich schnell oder schneller.

Edit: Sicher, dass CompareNoCase() so funzt, wie es soll?

Außerdem kannst du deinen Code mit [ code = cpp ] (ohne Leerzeichen) einläuten, dann geht die Formatierung nicht verloren und ich hole mir keinen Augenkrebs. Könnte vielleicht auch mal ein Admin als Default einstellen, denn a) wird hier zu 90 % C++ samt Derivaten gepostet und b) sehen die übrigen zehn Prozent am =cpp, wie sie ihre eigene Sprache einbauen. Bei der grünen Listenformatierung kotze ich mittlerweile Regenbögen, da muss sich was ändern.

Re: Auf dem Weg von DDraw nach OpenGL ..

Verfasst: 17.05.2010, 15:53
von Aramis
Noch eine Kleinigkeit, die mir weiter oben entfallen war:

Es gibt tatsaechlich einen idiomatischen Weg, einen std::string, std::vector, std::deque, usw. … dazu zu zwingen, allen Speicher freizugeben:

Code: Alles auswählen

std::string s = getMyMonsterString();
std::string().swap(s);
… move–Semantics à la Cpp03.
Außerdem bin ich auf Linux/Ubuntu absoluter Anfänger. Schon deshalb wäre interessant zu wissen, ob ich das Programm 'KStringLinux' richtig erzeugt habe?
Zum Programm: funktioniert tadellos (Fedora, x86). Ist auch richtig gelinkt (ELF).

Re: Auf dem Weg von DDraw nach OpenGL ..

Verfasst: 17.05.2010, 16:01
von Alexander Kornrumpf
Das würd ich gerne mal hijacken:

Habe neulich erstmal boost pointer benutzt und brauchte eine Möglichkeit den Pointer zu nullen. Habe auch swap als weg dazu gegooglet. Semantisch ergibt das für mich keinen Sinn, dass swap etwas löschen sollte.
Also ihr "Modern C++" Cracks, was geht da vor sich?

Re: Auf dem Weg von DDraw nach OpenGL ..

Verfasst: 17.05.2010, 16:03
von Aramis
Im obigen Beispiel wird die Tatsache dass du Memberfunktionen auf temporaeren Objekten (rvalues) aufrufen kannst, dazu ausgenutzt den Inhalt eines per Default–c‘tor erzeugten, leeren Containers mit einem existierenden zu tauschen.

Im Prinzip ein Hack, der es geschafft hat als ‘idiomatic C++’ zu gelten, soweit ich das beurteilen kann :-)

Re: Auf dem Weg von DDraw nach OpenGL ..

Verfasst: 17.05.2010, 16:06
von Krishty
::std::swap() löscht nichts, aber der Destruktor des temporären Objekts, mit dem du deinen Kram getauscht hast, löscht.
Eine „echte“ Move-Semantic ist es nur, wenn die Container intern den berüchtigten statischen Puffer benutzen, sonst hat man wie gehabt eine zusätzliche Allokation.

(Als nicht-boost’ler) Wie – keine Möglichkeit, einen Pointer zu nullen? Was geht da vor sich? Ich meine, wenn er sich nicht nullen lässt, ist er kein Zeiger, sondern eine Referenz, oder? … kann mir sowas bei boost eig nicht vorstellen.

Re: Auf dem Weg von DDraw nach OpenGL ..

Verfasst: 17.05.2010, 16:08
von Aramis
Haette boost::shared_ptr<T>::reset() nicht den Zweck auch erfuellt?
void reset(); // never throws
Effects: Equivalent to shared_ptr().swap(*this).

Re: Auf dem Weg von DDraw nach OpenGL ..

Verfasst: 17.05.2010, 16:15
von Alexander Kornrumpf
Sorry, das war doppelt dumm von mir.

Kurz gesagt, ich hab zweimal

foo().bar() als foo::bar() gelesen.

Lange Version:

Es war so: Gegooglt, das gefunden was Aramis aus der Doku gepostet hat, vergessen dass das reset hieß, die Doku als "ptr.reset() ist äqivalent zu ptr.swap(ptr)" falsch gelesen. Jetzt geglaubt ein Muster wiederzuerkennen wieder nicht richtig gelesen und alle verwirrt.

Re: Auf dem Weg von DDraw nach OpenGL ..

Verfasst: 17.05.2010, 16:25
von Krishty
Mach string Empty() mal zu void Empty() und schmeiß return k_sStr; raus. Du erzeugst nämlich jedes Mal, wenn du Empty() aufrufst (also u.a. jedes Mal, wenn eine Instanz erzeugt wird) einen temporären ::std::string und zerstörst ihn wieder.

Und in deiner Signatur fehlen ein Komma und ein „zu“ ;)

Re: Auf dem Weg von DDraw nach OpenGL ..

Verfasst: 17.05.2010, 19:02
von HeinzK
OK, CString.Empty ist auch als void declariert.
OK, std::string const &GetString(void) const;
OK, CompareNoCase konnte noch nicht funktionieren, hab's geändert!
Danke für die Hinweise Kristhy.
Zum Programm: funktioniert tadellos (Fedora, x86). Ist auch richtig gelinkt (ELF).
Danke Alex.
PS:
KStringLinux und KStringWindows.exe sind aktualisiert.

Re: Auf dem Weg von DDraw nach OpenGL ..

Verfasst: 17.05.2010, 19:58
von Krishty
Da läuft irgendwas grundlegend schief. Selbst so trivialer Quatsch wie GetLength() ist dreimal so langsam wie in CString … ganz vorsichtig gefragt: Du kompilierst doch mit voller Optimierung (auch unter Linux mit -O3), oder? Und ohne Debug-Symbole?

Übrigens, warum ist der D’tor von CKString virtual? Erbst du irgendwo?

Re: Auf dem Weg von DDraw nach OpenGL ..

Verfasst: 17.05.2010, 20:37
von HeinzK
virtual: Ich will den gleichen Quellcode so weit wie möglich für Windows und Linux benutzen. Unter Windows leite ich alles von CObject ab,
hauptsächlich wegen 'Serialize'. Diesen Teil muss ich noch unter Linux noch nachprogrammieren. Aber zuerst kommt ein Ersatz für 'CStdioFile' an die Reihe.
Optimierung: Arbeite im Moment mit den Standard-Einstellungen, d.h., ich habe nichts geändert.

Re: Auf dem Weg von DDraw nach OpenGL ..

Verfasst: 19.05.2010, 14:01
von HeinzK
Problem mit dem Einsatz von CKString. Ich bin gerade dabei mir einen
'Wrapper' für 'CStdioFile' bzw. 'CKFile' für meine Anwendungsfälle zu programmieren.

Declaration:

Code: Alles auswählen

#pragma once
#include <stdarg.h>
#include <algorithm>
#include <string>
#include <iostream>
#include <memory.h>
#include <stdio.h>
using namespace std;
class CKString
{
  public:
    CKString(void);
    CKString(const string &sStr);
    virtual ~CKString(void);
    void Empty(void);
    string Format(const char *pFrm, ...);
    string Left(const int &iCn);
    string Right(const int &iCn);
    string Mid(const int &iC1, const int &C2);
    string MakeLower(void);
    string MakeUpper(void);

    int Compare(const CKString &sStr);

    int CompareNoCase(const CKString &sStr);
    void SetString(const string &sStr);
    int GetLength(void);
    const string &GetString(void) const;
  private:
    string k_sStr;
    void Ini(void);
    string KFormatArgmList(const char *pFrm, va_list Argm);
};
Implementation:

Code: Alles auswählen

int CKString::Compare(const CKString &sStr)
{
  return k_sStr.compare(sStr.GetString());
}
Anwendung:

Code: Alles auswählen

bool CKFile::Open
             (
               const CKString &sFname,
               const CKString &sMode
             )
{
  //if (sMode.Compare("r") == 0)
  
  CKString sMd(sMode);
  CKString sM("r");
  int iCmp = sMd.Compare(sM); 
  if (iCmp == 0)
  {                                                            
    k_bLesend = true;    //> Read:
    ifstream *k_iFn = new ifstream;
    k_iFn->open(sFname.GetString().c_str());
  } else
  {
    k_bLesend = false;   //> Write: 
    ofstream *k_oFn = new ofstream;
    k_oFn->open(sFname.GetString().c_str());
  }
}
Ich möchte gerne folgende Schreibweise verwenden:
(sMode.Compare("r") == 0)
erhalte aber folgende Fehlermeldung:
: error C2662: 'CKString::Compare': this-Zeiger kann nicht von 'const CKString' in 'CKString &' konvertiert werden

Ich benutze diese Schreibweise in meinen vorhandenen Windows-Programmen sehr oft.
CString hat hier kein Problem mit dem 'const'!
Kann mir jemand einen Tipp geben, wie ich dazu 'Compare' umgestalten muss?

Re: Auf dem Weg von DDraw nach OpenGL ..

Verfasst: 19.05.2010, 14:14
von Krishty
Mit int CKString::Compare(const CKString &sStr) const { kann die Funktion auch auf Objekte aufgerufen werden, die const deklariert sind.

Re: Auf dem Weg von DDraw nach OpenGL ..

Verfasst: 19.05.2010, 14:17
von HeinzK
Hab' ich schon versucht, die Fehlermeldung ist dann:
: error C2664: 'CKString::Compare': Konvertierung des Parameters 1 von 'const char [2]' in 'const CKString &' nicht möglich
1> Ursache: Konvertierung von 'const char [2]' in 'const CKString' nicht möglich
1> Quelltyp konnte von keinem Konstruktor angenommen werden, oder die Überladungsauflösung des Konstruktors ist mehrdeutig