JLI Spieleprogrammierung Foren-Übersicht JLI Spieleprogrammierung

 
 FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen 
 medals.php?sid=95455684e3bd29c1d33f7e26a43c5a73Medaillen   RegistrierenRegistrieren   ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin 

DirectShow

 
Neues Thema eröffnen   Neue Antwort erstellen    JLI Spieleprogrammierung Foren-Übersicht -> Grafik und Sound
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
Azrael
Mini JLI'ler


Alter: 34
Anmeldedatum: 17.02.2007
Beiträge: 9
Wohnort: Westerburg
Medaillen: Keine

BeitragVerfasst am: 20.03.2007, 19:37    Titel: DirectShow Antworten mit Zitat

Hab ein problem mit der grauenvollen DirectShow.

Ich muss erstmal eins sagen: ich versuche grad DirectShow aus einem ziemlich schlampig geschriebenem Buch zu lernen, welches dazu auch noch MFC (ihh!) benutzt und bei welchem die beigelegten Beispiele kein stück funktionieren (und auch nicht mit dem Code im Buch übereinstimmen). Versuchen tu ichs trotzdem, man soll ja froh sein, dass man überhaupt etwas hat...

Natürlich würde ich nie im Leben das abartige Unterwesen MFC anrühren. Deshalb hatte ich mir eine Seite ergoogelt, welche die funktionsweise von DirectShow bestens erklärt, leider jedoch nicht in dem Maße, in welchem ich es benötigt hätte. Denn eine integration von DirectShow in eine (von einer Sterblichen Hand) verwendbare Klasse wird nicht erläutert.

Ich habe versucht, eine art sound+musik+video engine zu bauen, welche man leicht in einem Computerspiel verwenden könnte. Da kein einziger Ansatz geklappt hatte, habe ich ein etwas degradiertes Programm geschrieben, welches eine einzelne Datei wiedergeben soll. Trotzdem bekomm ich auch hier nicht sinnvolleres als sinnlose Fehler. so langsam zweifele ich daran, ob DirectShow eine richtige API ist, oder nur etwas, um leute in den Wahnsinn zu treiben.

Debuggen bringt nichts, es wird stupide eine einzelne Zeile angezeigt, welche, in all ihrer zweifelhaften Schönheit, einen Laufzeitfehler mit einer Zugriffsverletzung erzeugt, und mir gnadenlos in einem Fenster, welches passend zu dem von ihm verursachten Wahnsinn, grau ist, entgegenwirft.

CPP:
while (mMediaEvent->GetEvent(&EventCode, &Param1, &Param2, 0) != E_ABORT)
.......


der gesamte code befindet sich in nur 2 dateien:
CPP:
// MMClass.h
#include <windows.h>
#include <DShow.h>

#pragma comment(lib, "Strmiids.lib")
#pragma comment(lib, "Quartz.lib")
#pragma warning (disable : 4996)

#define WM_GRAPHEVENT   WM_USER      // eigene nachricht

#define MRLS(x) if (x != NULL) \
                    { \
                        x->Release(); \
                        x = NULL; \
                    }

class MMMUSIC
{
private:
   MSG msg;
   HWND hWnd, hWndParent;
   WNDCLASSEX wcex;
   IGraphBuilder*   mGraphBuilder;
   IMediaControl*   mMediaControl;
   IMediaEventEx*   mMediaEvent;
   IMediaPosition*   mMediaPosition;

   // WndProcs
   LRESULT CALLBACK MusicProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
   static LRESULT CALLBACK Static_Proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
public:
   MMMUSIC();
   ~MMMUSIC();
   // MediaWindow - kein Peil, wie mans ohne macht :(
   bool MediaWindow(HWND Parent);
   // DirectShow Initialisieren
   int InitDirectShow();
   // Fensterhandle für Nachrichten festlegen
   void SetNotifications();
   // MessageVerteiler
   int MusicMsgDp();
   // Media-message Verarbeitung
   void OnGraphEvent();
   // Datei laden
   int LoadFile(TCHAR* filename);

   void play();
   void stop();
   void release();
};

MMMUSIC::MMMUSIC()
{

   // COM initialisieren
   CoInitialize(NULL);
}
MMMUSIC::~MMMUSIC()
{
   CoUninitialize();
}

int MMMUSIC::InitDirectShow()
{
   HRESULT hr;
   hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
   IID_IGraphBuilder,(void**)&mGraphBuilder);
   
   if (FAILED(hr))
      return -1;
   mGraphBuilder->QueryInterface(IID_IMediaControl, (void**)&mMediaControl);
   mGraphBuilder->QueryInterface(IID_IMediaEvent, (void**)&mMediaEvent);
   mGraphBuilder->QueryInterface(IID_IMediaPosition, (void**)&mMediaPosition);
   return 0;
}

void MMMUSIC::SetNotifications()
{
   mMediaEvent->SetNotifyWindow((OAHWND)hWnd, WM_GRAPHEVENT, 0);
   mMediaEvent->SetNotifyFlags(0);
}

LRESULT CALLBACK MMMUSIC::Static_Proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
   if(uMsg == WM_CREATE)
   {
      SetWindowLong(hwnd, GWL_USERDATA, (LONG) lParam);
   }
   static MMMUSIC * mmm = NULL;
   mmm = (MMMUSIC*) GetWindowLong(hwnd, GWL_USERDATA);
   if(!mmm)
      return DefWindowProc(hwnd, uMsg, wParam, lParam);
   else
      return mmm->MusicProc(hwnd, uMsg, wParam, lParam);
}

LRESULT CALLBACK MMMUSIC::MusicProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
   switch (uMsg)
   {
   case WM_GRAPHEVENT:
      OnGraphEvent();   
      break;
   default:
      break;
   }
   return DefWindowProc(hwnd, uMsg, lParam, wParam);
}

int MMMUSIC::MusicMsgDp()
{
   if(PeekMessage(&msg, hWnd, 0, 0, PM_REMOVE))
   {
      if(msg.message == WM_QUIT) return -1;

      TranslateMessage(&msg);
      DispatchMessage(&msg);
   }
   return (int) 1;
}

bool MMMUSIC::MediaWindow(HWND Parent)
{
   hWndParent = Parent;

   FillMemory  (&wcex,sizeof(wcex),0); wcex.cbSize = sizeof (wcex);

      wcex.cbClsExtra      = 0;
      wcex.cbWndExtra      = 0;
      wcex.hbrBackground   = (HBRUSH) GetStockObject(BLACK_BRUSH);
      wcex.hCursor      = NULL;
      wcex.hIcon         = NULL;
      wcex.hIconSm      = NULL;
      wcex.hInstance      = (HINSTANCE) GetWindowLong(Parent,GWL_HINSTANCE);
      wcex.lpfnWndProc   = Static_Proc;
      wcex.lpszClassName   = TEXT("Music");
      wcex.lpszMenuName   = NULL;
      wcex.style         = CS_HREDRAW | CS_VREDRAW;

      if(!RegisterClassEx(&wcex)) return false;
      

   hWnd = CreateWindowEx(NULL, wcex.lpszClassName,
      TEXT("Music"), WS_CHILD | WS_CLIPSIBLINGS,
      0, 0, 0, 0, Parent, NULL,
      wcex.hInstance,(LPVOID) this);
   
   if(!hWnd)
   {
      MessageBox(NULL, TEXT("MMM Fenster konnte nicht erstellt werden!"), TEXT("Fehler"), MB_OK | MB_ICONHAND);
      return false;
   }
   
 
   SetNotifications();
   return true;
}

void MMMUSIC::OnGraphEvent()
{
   long EventCode, Param1, Param2;
   while (mMediaEvent->GetEvent(&EventCode, &Param1, &Param2, 0) != E_ABORT)
   {
      switch (EventCode)
      {
      case EC_COMPLETE:
         mMediaControl->Stop();
            mMediaPosition->put_CurrentPosition(0);
      default:
         break;
      }   
      mMediaEvent->FreeEventParams(EventCode, Param1, Param2);
   }
}
 
int MMMUSIC::LoadFile(TCHAR* filename)
{
#ifndef UNICODE
   int   length;      // length of filename
   WCHAR*   wfilename;   // where we store WCHAR version of filename

   length = strlen(filename)+1;
   wfilename = new WCHAR[length];
   MultiByteToWideChar(CP_ACP, 0, filename, -1, wfilename, length);
   if (FAILED(mGraphBuilder->RenderFile(wfilename, NULL))
      return -1;
   else
      return 0;
#else
   if (FAILED(mGraphBuilder->RenderFile(filename, NULL)))
      return -1;
   else
      return 0;
#endif
}

void MMMUSIC::play()
{
   if(mMediaControl) mMediaControl->Run();
   else MessageBox(NULL, TEXT("Keine Datei Geladen"), TEXT("Fehler"), MB_OK | MB_ICONHAND);
}

void MMMUSIC::stop()
{
   if(mMediaControl) mMediaControl->Stop();
   else MessageBox(NULL, TEXT("Keine Datei Geladen"), TEXT("Fehler"), MB_OK | MB_ICONHAND);
}

void MMMUSIC::release()
{
   MRLS(mMediaPosition);
   MRLS(mMediaEvent);
   MRLS(mMediaControl);
   MRLS(mGraphBuilder);
}

und
CPP:
//main.cpp
#include "MMClass.h"
LRESULT WINAPI WndProc(HWND, UINT, WPARAM, LPARAM);
INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR pszCmdLine, int nShow)
{
   HWND hWnd;
   MSG msg;
   WNDCLASSEX wcex;
   MMMUSIC *mmm = new MMMUSIC;

   wcex.cbSize         = sizeof(WNDCLASSEX);
   wcex.cbClsExtra      = 0;
   wcex.cbWndExtra      = 0;
   wcex.hbrBackground   = (HBRUSH) GetStockObject(BLACK_BRUSH);
   wcex.hCursor      = LoadCursor(NULL, IDC_ARROW);
   wcex.hIcon         = NULL;
   wcex.hIconSm      = NULL;
   wcex.hInstance      = hInstance;
   wcex.lpfnWndProc   = WndProc;
   wcex.lpszClassName   = TEXT("MainWindow");
   wcex.lpszMenuName   = NULL;
   wcex.style         = CS_HREDRAW | CS_VREDRAW;

   if(!RegisterClassEx(&wcex)) return -1;

   hWnd = CreateWindowEx(NULL, wcex.lpszClassName,
      TEXT("ASE - Main Window"), WS_OVERLAPPEDWINDOW,
      0, 0,800, 600, NULL, NULL,
      wcex.hInstance,NULL);
   
   if(!hWnd)
   {
      MessageBox(NULL, TEXT("Fenster konnte nicht erstellt werden!"), TEXT("Fehler"), MB_OK | MB_ICONHAND);
      return -2;
   }
   
   ShowWindow(hWnd, nShow);
   UpdateWindow(hWnd);

   
      mmm->InitDirectShow();
      mmm->MediaWindow(hWnd);
      mmm->LoadFile(TEXT("amr.mp3"));
      mmm->play();
   while(true)
   {
      if(PeekMessage(&msg,hWnd, 0,0, PM_REMOVE))
      {
         if(msg.message == WM_QUIT) break;
         mmm->MusicMsgDp();

         TranslateMessage(&msg);
         DispatchMessage(&msg);
      }
   }
   mmm->stop();
      mmm->release();

   

   return (int)msg.wParam;
}

LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
   switch(msg)
   {
   case WM_CREATE:
      break;
   case WM_DESTROY:
      
      PostQuitMessage(0);
      break;
   default:
      break;
   }
   return DefWindowProc(hWnd, msg, wParam, lParam);
}


p.s: sorry für die ausdrucksweise, ich war jedoch noch nie so nah an ausm fenster springen...
_________________

5=1,7
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen MSN Messenger
Maxim
Senior JLI'ler



Anmeldedatum: 28.03.2004
Beiträge: 249

Medaillen: Keine

BeitragVerfasst am: 20.03.2007, 20:22    Titel: Antworten mit Zitat

Also ich habe DirectShow benutzt und finde es einfach zu verwenden. Mit MFC hab ich auch programmiert und programmiere zum Teil immer noch. Wenn du beides für Sch**** hällst, dann ist es deine Sache. Wenn du das nicht verwenden kannst, liegt es an dir und nicht an DirectShow. Ich würde dir vorschlagen erst mal ein wenig Erfahrung zu sammeln und sich zum Beispiel einen besseren Programmierstil aneignen Wink

Ich weiß dass ich mir damit keine Freunde hier mache, aber ich helfe dir absichtlich nicht! Einfach so!

PS: Entschuldigung für die Ausdrucksweise Wink
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Azrael
Mini JLI'ler


Alter: 34
Anmeldedatum: 17.02.2007
Beiträge: 9
Wohnort: Westerburg
Medaillen: Keine

BeitragVerfasst am: 20.03.2007, 20:54    Titel: Antworten mit Zitat

schon gut ^^". Sitze halt schon länger an dem problem. Bin deswegen bissl etwas genervt. Und naja - ich hab ja geschrieben, dass das programm ein kleines bissl degradiert ist. damit ist auch der Stil gemeint. So schlecht bin ich ja nun auch wieder nicht *rotwerd*

und @
Zitat:
aber ich helfe dir absichtlich nicht!


naja - wenn ich es nicht schaffe, meine Fehler zu verstehen. siehts schlecht aus...

und MFC zu lernen würde den Zeitrahmen, in welchem ich das fertig stellen sollte, sprengen, außerdem funktionieren die Beispiele aus dem Buch nicht, was die sache auch noch zusätzlich erschwert. Also: nö zu MFC.

EDIT: hab grad gemerkt, dass ich wfilename zu löschen vergessen habe, so viel zum guten stil^^"""
_________________

5=1,7
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen MSN Messenger
Maxim
Senior JLI'ler



Anmeldedatum: 28.03.2004
Beiträge: 249

Medaillen: Keine

BeitragVerfasst am: 20.03.2007, 22:16    Titel: Antworten mit Zitat

also ich sehe dass dein problem nicht nur directshow ist.....also hier hast du ein einfaches beispiel für abspielen von mp3s (auf minimum reduziert):

CPP:
#include <iostream>
#include <windows.h>

#include <dshow.h>

#pragma comment(lib, "Strmiids.lib")
#pragma comment(lib, "Quartz.lib")

int main(void)
{
   IGraphBuilder*   GraphBuilder;
   IMediaControl*   MediaControl;

   CoInitialize(NULL);

   CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC,
                  IID_IGraphBuilder,reinterpret_cast<void **>(&GraphBuilder));
 
   GraphBuilder->QueryInterface(IID_IMediaControl, reinterpret_cast<void **>(&MediaControl));

   GraphBuilder->RenderFile(L"mp3.mp3", NULL);

   std::cout<<"Start"<<std::endl;

   MediaControl->Run();

   while(true)
   {
      Sleep(1000);
      std::cout<<"Update"<<std::endl;
   }

   CoUninitialize();

   GraphBuilder->Release();
   MediaControl->Release();

   return 0;
}
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Azrael
Mini JLI'ler


Alter: 34
Anmeldedatum: 17.02.2007
Beiträge: 9
Wohnort: Westerburg
Medaillen: Keine

BeitragVerfasst am: 20.03.2007, 22:31    Titel: Antworten mit Zitat

CPP:
while(true)
   {
      Sleep(1000);
      std::cout<<"Update"<<std::endl;
   }


endet das? Oo

naja - eine mp3 abspielen hab ich schon geschafft ^^""""""""""""""""", so hoffnungslos bin ich nicht xD. COM-grundlagen hab ich mir denk ich mal auch angeeignet (Wikipedia-artikel, die sache im Buch + auf der oben erwähnten Seite). DirectShow sieht doch grob so aus->

Com initialisieren
Interfaces ähm.. instanzieren ^^"
graph erstellen (renderfile, bei manuellen war ich noch nicht)
run()
messageverarbeitung
stop()
release()
com uninitialisieren.

hab ein riesenproblem damit, eine einfach zu verwendbare klasse zu erstellen, die sich dann ungefähr so verwenden lässt:

mmm->load(TCHAR *filename);
mmm->play()
mmm->stop()
mmm->release()

Im groben. ich muss da noch funktionen für Video einbauen. Lautstärkeregelung, hWnd für ausgabe, uvm. Da ich aber momentan an ziemlich elementaren dingen hänge, komm ich aber grad nicht weiter...
_________________

5=1,7
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen MSN Messenger
Maxim
Senior JLI'ler



Anmeldedatum: 28.03.2004
Beiträge: 249

Medaillen: Keine

BeitragVerfasst am: 21.03.2007, 05:33    Titel: Antworten mit Zitat

ja, das endet....mit dem klick auf schließen-button (im gegensatz zu deinem beispiel) Laughing
klar ist das eine endlosschleife...wollte zuerst einbauen, dass es so lange läuft bis das stück zu ende ist, dachte mir dann aber, dass es das beispiel verkomplizieren wird....


wo liegt denn das problem mit der klasse? fange klein an und probiere nicht alles auf ein mal unterzubringen.

die Methoden ...
mmm->load(TCHAR *filename);
mmm->play()
mmm->stop()
mmm->release()

...sind ja schon richtig.


kommentiere den rest aus und probiere ob es geht

ach ja, und wenn du deine klasse zu laufen bringen willst, dann ändere mal die methode ab

CPP:
bool MMMUSIC::MediaWindow(HWND Parent)
{
   hWndParent = Parent;
 
   SetNotifications();
   return true;
}


dann noch ein paar andere sachen:
- speicher freigeben (delete)
- wenn ein stück zu ende ist, stopt es automatisch, dafür braucht man keine events
- deine hauptschleife ist nicht gut
- dein programm wird nicht per schließen-button beendet
- sinn von Static_Proc?

MfG Maxim
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Azrael
Mini JLI'ler


Alter: 34
Anmeldedatum: 17.02.2007
Beiträge: 9
Wohnort: Westerburg
Medaillen: Keine

BeitragVerfasst am: 21.03.2007, 16:02    Titel: Antworten mit Zitat

Maxim hat Folgendes geschrieben:
ja, das endet....mit dem klick auf schließen-button (im gegensatz zu deinem beispiel)

Mein beispiel endet auch mit dem schließen button Razz
CPP:
if(msg.message == WM_QUIT) break;

Zitat:

CPP:
bool MMMUSIC::MediaWindow(HWND Parent)
{
   hWndParent = Parent;
 
   SetNotifications();
   return true;
}
dann ist hWnd aber undefiniert... und wenn du meinst, ich soll die messages an den Parent schicken, wird das zwar klappen, wenn man einen direkt zugreifbaren WndProc für dieses Fenster hat, aber das Projekt nutzt eine andere Engine für grafikausgaben, die einen internen WndProc in einer DLL hat... deshalb hab ich auch 2 HWNDs in der Klasse^^""
Zitat:

dann noch ein paar andere sachen:
- speicher freigeben (delete)

joa, delete hab ich schon bemerkt...
Zitat:

- wenn ein stück zu ende ist, stopt es automatisch, dafür braucht man keine events

möchte, dass es dann wieder am anfang ist
Zitat:
- deine hauptschleife ist nicht gut

was ist daran nicht gut? Oo
Zitat:
- dein programm wird nicht per schließen-button beendet

doch ^^"""""
CPP:
if(msg.message == WM_QUIT) break;

Zitat:
- sinn von Static_Proc?

Man kann einen WndProc nicht einfach in eine Klasse stecken, denn die fensterklassenstruktur (WNDCLASSEX) möchte umbedingt einen statischen WndProc haben.
CPP:
      wcex.lpfnWndProc   = Static_Proc;
deswegen definiere ich einen statischen, den alle instanzen der klasse teilen, und einen member - WndProc, der zugriff auf nicht-statische membervariablen und funktionen hat. wenn du schaust, wie ich die hWnd erstelle:
CPP:
hWnd = CreateWindowEx(NULL, wcex.lpszClassName,
      TEXT("Music"), WS_CHILD | WS_CLIPSIBLINGS,
      0, 0, 0, 0, Parent, NULL,
      wcex.hInstance,(LPVOID) this);

kannst du sehen, dass ich beim letzten parameter den this zeiger übergebe, der wandert in die lParam der WM_CREATE - Nachricht. wenn du dir jetzt den StaticProc anschaust:
CPP:
LRESULT CALLBACK MMMUSIC::Static_Proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
   if(uMsg == WM_CREATE)
   {
      SetWindowLong(hwnd, GWL_USERDATA, (LONG) lParam);
   }
   static MMMUSIC * mmm = NULL;
   mmm = (MMMUSIC*) GetWindowLong(hwnd, GWL_USERDATA);
   if(!mmm)
      return DefWindowProc(hwnd, uMsg, wParam, lParam);
   else
      return mmm->MusicProc(hwnd, uMsg, wParam, lParam);
}

siehst du, dass der Zeiger auf das jeweilige Objekt in den Speicher vom Fenster geschrieben wird, wenn die Nachricht WM_CREATE ist. danach wird ein zeiger auf eine MMMUSIC instanz erzeugt, dann bekommt er den zeiger zugewiesen, der im Fensterspeicher rumliegt. danach gibts noch ne prüfung, ob der Zeiger gültig ist, wenn nicht, wird der defaultproc verwendet, sonst der Instanzeigene MusicProc.... schon bissl fortgeschritten, die sache^^". aber das ist ja nicht mein problem >.<. Ich kriege einen Sinnlosen Zugriffsverletzungsfehler angezeigt... hab irgendwo die reihenfolge falsch? Ich glaub nicht, bin aber auch kein DirectShow profi. Verstehe nicht, warums nicht klappt >.< >.<
_________________

5=1,7
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen MSN Messenger
Maxim
Senior JLI'ler



Anmeldedatum: 28.03.2004
Beiträge: 249

Medaillen: Keine

BeitragVerfasst am: 21.03.2007, 16:09    Titel: Antworten mit Zitat

wie du meinst Wink hab probiert dir zu helfen, aber dir ist nicht mehr zu helfen ^^ zumindest solange nicht, bis du eine neue klasse schreibst Wink
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Azrael
Mini JLI'ler


Alter: 34
Anmeldedatum: 17.02.2007
Beiträge: 9
Wohnort: Westerburg
Medaillen: Keine

BeitragVerfasst am: 21.03.2007, 16:24    Titel: Antworten mit Zitat

aso - nur ma so nebenbei - die datei spielt er ab, aber ein fehler kommt trotzdem xDDDDDDDDDDDDDDDD
_________________

5=1,7
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen MSN Messenger
Azrael
Mini JLI'ler


Alter: 34
Anmeldedatum: 17.02.2007
Beiträge: 9
Wohnort: Westerburg
Medaillen: Keine

BeitragVerfasst am: 21.03.2007, 16:25    Titel: Antworten mit Zitat

joa - eine klasse ohne benachrichtigungen hatte ich schon geschrieben, die klappt auch^^". und diese hier spielt ja auch was ab, aber hat ein problem mit GetEvent()....
_________________

5=1,7
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen MSN Messenger
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    JLI Spieleprogrammierung Foren-Übersicht -> Grafik und Sound Alle Zeiten sind GMT
Seite 1 von 1

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.


Powered by phpBB © 2001, 2005 phpBB Group
Deutsche Übersetzung von phpBB.de

Impressum