3D-Engine

Aiju

Gesperrt
Okay, im Moment programmiere ich eine 3D-Engine, weil ich keine gute Cross-Platform-Engine finde, folgende Probleme:
1. Für 3D-Modelle nutzt meine Engine das hauseigene E3-Format, welches binär und
ziemlich simpel ist:
Es gibt nur Dreiecke und Vierecke, die sind so aufgebaut:
FLAGS (1 Byte) : 1 für Viereck (anstatt Dreieck), 2 für texturiert (anstatt einfarbig) oder 3 für beides
X Y Z TX TY (je 1 Float): Für jeden Punkt Koordinaten X/Y/Z und bei Texturen noch die passenden Koordinaten auf dem Bitmap, bei einfarbigen zwei mal 0
Danach noch:
Für einfarbig
R G B (je 1 Byte): Farbwerte
Bei Texturen der Dateiname und ein Null-Zeichen

Hier zwei Prozeduren die ein Viereck/Dreieck auf die Standard-Ausgabe:
C:
void write(float* data, bool quad, char * filename)
{
 if(quad)
  fputc(3, stdout);
 else
  fputc(2, stdout);
 fwrite(data,sizeof(float),(quad)?20:15,stdout);
 printf("%s",filename);
 fputc(0,stdout);
}
void write(float* data, bool quad, unsigned char r, unsigned char g, unsigned char b)
{
 if(quad)
  fputc(1, stdout);
 else
  fputc(0, stdout);
 fwrite(data,sizeof(float),(quad)?20:15,stdout);
 fputc(r,stdout);
 fputc(g,stdout);
 fputc(b,stdout);
}
Sie übernehmen beide ein Float-Array mit 15(Dreieck) oder 20(Viereck) (s.o), dann noch bool obs ein Viereck ist und die Farbwerte/Texturename.

So jetzt kann jemand mir ein gutes 3D-Format beschreiben oder am besten noch einen
Konverter erstellen?
Danke im Voraus

2. Folgende Situation:
Mit der Maus kann man drehen.
Mit der Tastatur (Pfeiltasten) kann man laufen.
Dreht man sich nach rechts, spielt die Steuerung verrückt (ist auch logisch)
Dehalb muss man da irgendwie mit sinus und cosinus die ganzen sachen umrechnen.
Ich hab nur vergessen wies geht :(
 
Zuletzt bearbeitet:
Mein 2. Problem ist gelöst: (vorwärts)
C:
X-Koordinate -= Geschwindigkeit * sin(Drehung * PI / 180. );
Z-Koordinate += Geschwindigkeit * cos(Drehung * PI / 180. );
 
3. Wie kann ich eine Kugel in Dreiecken "annähern"?
Ein Kreis geht so:
C:
glBegin(GL_TRIANGLES);
for(int i=0;i<=360;i+=1)
{
 glVertex3f(0,1,0);
 glVertex3f(sin((i-1)*PI/180.),cos((i-1)*PI/180.),0);
 glVertex3f(sin(i*PI/180.),cos(i*PI/180.),0);
}
glEnd();
 
Nur mal nebenbei, hast Du Dir schon Ogre angesehen? Vor einer Weile war ein Bericht darueber im Linux-Magazin und das hoerte sich alles nicht schlecht an. Auch die Screenshots sehen eigentlich nicht schlecht aus.
Weil eine richtig gute und vor allem Performante 3D-Engine zu schreiben ist ja nicht unbedingt einfach, vor allem wenn man da allein rangeht.
 
C:
// Quelle: OGRE Basic Tutorial 1
#include "ExampleApplication.h"

class TutorialApplication : public ExampleApplication
{
protected:
public:
    TutorialApplication()
    {
    }

    ~TutorialApplication() 
    {
    }
protected:
    void createScene(void)
    {
    }
};

#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
#define WIN32_LEAN_AND_MEAN
#include "windows.h"

INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
#else
int main(int argc, char **argv)
#endif
{
    // Create application object
    TutorialApplication app;

    try {
        app.go();
    } catch( Exception& e ) {
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 
        MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
#else
        fprintf(stderr, "An exception has occured: %s\n",
                e.getFullDescription().c_str());
#endif
    }

    return 0;
}
Ich glaube das erklärt, warum ich eine Engine schreibe.
Und hier mal etwas aus meiner Engine:
C:
#include <exodus3d.h>
#include <iostream>
using namespace std;
float x=0,y=0,z=-6,rx=0,ry=0,rz=0; // Drehung und Verschiebung

int main(int argc, char** argv)
{
 try
 {
  if(argc != 2)
  {
   cout << "USAGE:  " << argv[0] << " FILE" << endl;
   return 1;
  }
  EApp app(800,600,false); // Fenster 800x600 (kein Fullscreen)
  EObject obj; // 3D-Objekt
  obj.loadE3(argv[1]); // Lade E3-Datei
  EDisplayList &list = *obj.getDisplayList(); // Display-List erstellen
 
  bool running = true;
  while(running)
  {
   SDL_Event event;
   while(SDL_PollEvent(&event))
    switch(event.type)
    {
     case SDL_QUIT: running=false;break;
     case SDL_KEYDOWN:
      switch(event.key.keysym.sym)
      {
       case SDLK_LEFT: rz -= 1;break;
       case SDLK_RIGHT:rz += 1;break;
       case SDLK_UP:   rx -= 1;break;
       case SDLK_DOWN: rx += 1;break;
	   case SDLK_PAGEDOWN: z -= 1;break;
	   case SDLK_PAGEUP: z  += 1;break;
      }
     break;
    }
   
   app.clear(); // Bildschirm leeren
   app.move(x,y,z); // Verschiebung einstellen
   app.turn(rx,ry,rz); // Rotation
   list.draw(); // Zeichnen
   app.apply(); // Übernehmen
  }
 }
 catch(EException * e) // Fehler abfangen
 {
  cout << e->message << endl;
  return 1;
 }
 return 0;
}

EDIT:
Ach und (bevor ichs vergess):
Das E3-Format hat sich geändert, jetzt müssen IMMER die Farbwerte angegeben werden (auch bei Textur)
Also:
Code:
FLAGS X Y Z TX TY R G B [TEXTUR]
^BYTE ^ FLOAT --- ^ BYTE ^STRING (Null-terminiert) (Typ)
 
Zuletzt bearbeitet:
Ich finde eine Engine sollte den Code kürzer und verständlicher machen (nicht noch
komplizierter)
EDIT: Punkt. Keine weitere Diskussion ;-)
 
Also lang und unverstaendlich ist die Beispiel-Application doch eher nicht. Okay, da passiert jetzt noch nicht viel, aber trotzdem ist das doch recht logisch gegliedert.

Natuerlich ist es immer einfacher etwas zu verstehen und zu nutzen was man selbst entwickelt hat, jedoch ist die Entwicklungszeit oft laenger als die Einarbeitungszeit in was fertiges.
 
Dennis Wronka hat gesagt.:
Also lang und unverstaendlich ist die Beispiel-Application doch eher nicht. Okay, da passiert jetzt noch nicht viel, aber trotzdem ist das doch recht logisch gegliedert.

Natuerlich ist es immer einfacher etwas zu verstehen und zu nutzen was man selbst entwickelt hat, jedoch ist die Entwicklungszeit oft laenger als die Einarbeitungszeit in was fertiges.
Ich werde jetzt alles weitere was nicht mit meinen Fragen zu tun hat ignorieren. ;)
 
Zurück