Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi OpenGL Pong (https://www.delphipraxis.net/167326-opengl-pong.html)

acidrain 24. Mär 2012 11:43

OpenGL Pong
 
Wunderschönen guten Tag!
Bin ziemlich neu in Sachen OpenGL und bräuchte eure Hilfe bei meinem Facharbeitsprojekt.
Das Problem ist, dass ich mit OpenGL die Schläger erstellt habe und die Bewegung auf die Tasten W/S (Spieler1) und Pfeiltasten hoch/runter (Spieler2) eingestellt habe, jedoch bewegt sich nichts.

Hier etwas Quelltext, ich bereue schon meine dummen Anfängerfehler und bedanke mich schonmal!

Schläger von einem Spieler:
Code:
//Spieler 1
  glTranslatef(-60, 0, 0);
  glTranslated (0, s1, 0);
glBegin(GL_QUADS);
  glColor3f(0, 1, 0); glVertex3f(-1,1,-1);
  glColor3f(0, 1, 0); glVertex3f(-1,-9,-1);
  glColor3f(0, 1, 0); glVertex3f(1,-9,-1);
  glColor3f(0, 1, 0); glVertex3f(1,1,-1);
glEnd;
OnKeyDown Ereignisse:
Code:
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
if Key = word('W') then
 Spieler1hoch := true;

 if Key = word('S') then
 Spieler1runter := true;

if Key = VK_UP then
 Spieler2hoch := true;

if Key = VK_DOWN then
 Spieler2runter := true;
end;
Timer zum Bewegen der Schläger:
Code:
procedure TForm1.Timer1Timer(Sender: TObject);
begin
 if Spieler1hoch then
  begin
   s1:= s1+5;
   Spieler1hoch:= false;

 if Spieler1runter then
  begin
   s1:= s1-5;
   Spieler1runter:= false;
end;
end;
end;

Grüße,
Acid

DeddyH 24. Mär 2012 11:46

AW: OpenGL Pong
 
Ich habe von OpenGL keine Ahnung, aber wird da wirklich automatisch neu gezeichnet, wenn sich der Wert einer Variable ändert? Das kann ich mir nur schwer vorstellen, daher denke ich, Du müsstest im Timer auch eine Aktualisierung anstoßen.

[edit] P.S.: sry, willkommen in der DP :dp: [/edit]

acidrain 24. Mär 2012 11:49

AW: OpenGL Pong
 
Ich bin da auch sehr neu, in der Schule haben wir das leider nicht gemacht, aber danke für den Denkanstoß!:)

FlatIron 24. Mär 2012 11:54

AW: OpenGL Pong
 
Du musst deine Rendering-Funktion aus deinem Timer bzw. deiner Hauptschleife herraus aufrufen. Sonst tut sich da nichts. Du veränderst zuerst die Zustände und dann musst du OpenGL sagen, dass es die Änderungen ausgeben soll.

Guck mal hier:

http://wiki.delphigl.com/index.php/Tutorial_Quickstart

EWeiss 24. Mär 2012 11:55

AW: OpenGL Pong
 
Zitat:

aber wird da wirklich automatisch neu gezeichnet
Definitiv nicht!
Er benötigt eine GLDraw procedure oder was auch immer in dem das GLWindow gelöscht die Matrix neu erstellt und das Window aktualisiert werden muss.
Ich vermisse auch den Bezug zur Render Routine (GLDraw)

gruss

DeddyH 24. Mär 2012 11:57

AW: OpenGL Pong
 
Emil, die Frage war eigentlich rhetorischer Natur ;). Es sollte ja wurscht sein, ob OpenGL oder GDI oder GDI+, wenn sich etwas Darstellungsrelevantes ändert, muss man eine Aktualisierung anstoßen.

EWeiss 24. Mär 2012 11:58

AW: OpenGL Pong
 
Zitat:

Zitat von DeddyH (Beitrag 1158284)
Emil, die Frage war eigentlich rhetorischer Natur ;). Es sollte ja wurscht sein, ob OpenGL oder GDI oder GDI+, wenn sich etwas Darstellungsrelevantes ändert, muss man eine Aktualisierung anstoßen.

:thumb:
Ah so hast natürlich recht..

gruss

FlatIron 24. Mär 2012 11:59

AW: OpenGL Pong
 
Delphi-Quellcode:
procedure TForm1.Timer1Timer(Sender: TObject);
begin
   inc(FrameCount);
   Render;                               //4. Zeile!!! Aufruf der Rendering-Methode
   If FrameCount = 20 then
      begin
           ErrorHandler;
           FrameCount := 0;
      end;
end;
Entscheidend ist die 4. Zeile. Hier müsste z.B. deine Rendering-Methode aufgerufen werden.

acidrain 24. Mär 2012 12:02

AW: OpenGL Pong
 
Könntet ihr mir das zumindest irgendwie im Prosatext verdeutlichen, denn ich kenn mich wirklich nicht mit OpenGL aus und hab mir erst vor kurzem ein paar Tutorials angeguckt.:cry:

Vielen Dank im Vorraus!

DeddyH 24. Mär 2012 12:05

AW: OpenGL Pong
 
Passt denn das Beispiel von FlatIron nicht?

FlatIron 24. Mär 2012 12:09

AW: OpenGL Pong
 
Du Veränderst nur die Koordinaten. Aber danach machst du nichts mehr. Die Koordinaten sind jetzt zwar nicht mehr die alten, zumindest im Speicher, aber auf dem Bildschirm betrachtest du immer noch die alte Ausgabe. D.h. du musst deine Grafiken neu rendern! Dies geschieht normalerweise in deiner Rendering-Methode, die du aus deiner Hauptschleife raus aufrufst. In der Rendering-Methode werden deine Objekte mit den neuen Koordinaten auf dem Bildschirm ausgegben. Die Änderungen, die du zuvor nur im Speicher vorgenommen hast, werden nun sichtbar.
Wie das genau funktioniert musst du in diversen Tutorials nachlesen.

EWeiss 24. Mär 2012 12:09

AW: OpenGL Pong
 
Zitat:

Zitat von acidrain (Beitrag 1158288)
Könntet ihr mir das zumindest irgendwie im Prosatext verdeutlichen, denn ich kenn mich wirklich nicht mit OpenGL aus und hab mir erst vor kurzem ein paar Tutorials angeguckt.:cry:

Vielen Dank im Vorraus!

Dann schau doch in den Tutorials nach der procedure meistens GLDraw.

Beispiel!
Delphi-Quellcode:
procedure TForm1.Timer1Timer(Sender: TObject);
 begin
  GLDraw;
  if Spieler1hoch then
   begin
    s1:= s1+5;
    Spieler1hoch:= false;
 
 if Spieler1runter then
   begin
    s1:= s1-5;
    Spieler1runter:= false;
 end;
 end;
 end;
Delphi-Quellcode:
procedure DrawSchläger
begin
//Spieler 1
   glTranslatef(-60, 0, 0);
   glTranslated (0, s1, 0);
 glBegin(GL_QUADS);
   glColor3f(0, 1, 0); glVertex3f(-1,1,-1);
  glColor3f(0, 1, 0); glVertex3f(-1,-9,-1);
   glColor3f(0, 1, 0); glVertex3f(1,-9,-1);
  glColor3f(0, 1, 0); glVertex3f(1,1,-1);
glEnd;
end;
Delphi-Quellcode:
procedure GLDraw;
begin

  // Clear The Screen And The Depth Buffer
  glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);

  // Change Matrix Mode to Projection
  glMatrixMode(GL_PROJECTION);
  // Reset View
  glLoadIdentity;
  gluPerspective(45, (320 / 240), 1, 1000.0);
  // Change Projection to Matrix Mode
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
 
  DrawSchläger
 
  // Update the display
  SwapBuffers(h_Dc);
end;
So in etwa aber das varriiert von Anwendung zur Anwendung...

gruss

acidrain 24. Mär 2012 12:12

AW: OpenGL Pong
 
Also brauche ich zusätzlich noch eine Prozedur, bei der die Bewegung steht, die im Timer derzeit ist und dann im Timer erwähnt wird?:oops:

EWeiss 24. Mär 2012 12:15

AW: OpenGL Pong
 
Zitat:

Zitat von acidrain (Beitrag 1158292)
Also brauche ich zusätzlich noch eine Prozedur, bei der die Bewegung steht, die im Timer derzeit ist und dann im Timer erwähnt wird?:oops:

Siehe mein kleines Beispiel.

gruss

acidrain 24. Mär 2012 12:24

AW: OpenGL Pong
 
Also liegt der Fehler lediglich an der Projektion und nicht irgendwo an der Tastenbelegung oder irgendeinem anderen Fehler, den ich mit OpenGL gemacht hab?:roll:

EWeiss 24. Mär 2012 12:30

AW: OpenGL Pong
 
Zitat:

Zitat von acidrain (Beitrag 1158294)
Also liegt der Fehler lediglich an der Projektion und nicht irgendwo an der Tastenbelegung oder irgendeinem anderen Fehler, den ich mit OpenGL gemacht hab?:roll:

Du mußt OpenGL Initialisiere.
Den GeräteContext ermitteln
Renderkontext erstellen
Renderkontext aktivieren

Delphi-Quellcode:
  // OpenGL-Funtionen initialisieren
  InitOpenGL;
  // Gerätekontext holen
  h_DC := GetDC(_FNormal.Handle);
  // Renderkontext erstellen (32 Bit Farbtiefe, 24 Bit Tiefenpuffer, Doublebuffering)
  h_RC := CreateRenderingContext(h_DC, [opDoubleBuffered], 32, 24, 0, 0, 0, 0);
  // Erstellten Renderkontext aktivieren
  ActivateRenderingContext(h_DC, h_RC);
Dein Timer so wie ich es im Beispiel gezeigt habe mit dem Anstoßen von GLDraw sollte so in Ordnung sein.
Bedenke aber das meine perspektive nicht unbedingt deinen Ansprüchen gerecht wird.

Gruss

acidrain 24. Mär 2012 12:37

AW: OpenGL Pong
 
Brauche ich dann trotzdem noch den IdleHandler oder kann ich den auslassen, wegen dem Timer?

EDIT: h_DC & h_RC werden bei mir nicht erkannt, hab wohl einen veralteten Header :s

FlatIron 24. Mär 2012 12:43

AW: OpenGL Pong
 
Was dir bei deinem Projekt helfen könnte, wäre ein Blick auf diese Seite:

http://wiki.delphigl.com/index.php/Hauptseite

Dort findest du auch eine schnelle Einführung in OpenGL: http://wiki.delphigl.com/index.php/Tutorial_Quickstart
(habe ich bereits gepostet)
Für die Mathematik empfehle ich dir zusätzlich diese Seite: http://oberprima.com/
- Dort findest du gute Videotutorials, die dir sicher helfen werden.

DAS klassische OpenGL Tutorial findest du auf NeHe's Homepage: http://nehe.gamedev.net/

Viel Spaß und viel Glück

h_DC und h_RC sind Variablen! Guck dir wirklich nochmal die Grundlagen an.
BTW: Ich würde dir den OpenGL-Header von DelphiGL empfehlen

acidrain 24. Mär 2012 12:44

AW: OpenGL Pong
 
Den hab ich ja auch, aber bei dem sind die beiden Variablen auch nicht deklariert

FlatIron 24. Mär 2012 12:47

AW: OpenGL Pong
 
Die musst DU ja auch deklarieren! Das macht kein Header für dich. Erstell dir doch erstmal mit den Tutorials einen Rahmen für dein Projekt und versuche die Grundlagen zu verstehen. Ist schwer, dass weiß ich, aber sonst wird das nichts.

So sieht das Template aus (Quelle: DelphiGL):

Delphi-Quellcode:
TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure IdleHandler(Sender: TObject; var Done: Boolean);
    procedure FormResize(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private   { Private-Deklarationen }
    StartTime, TimeCount, FrameCount : Cardinal; //FrameCounter
    Frames, DrawTime                 : Cardinal; //& Timebased Movement
    procedure SetupGL;
    procedure Render;
    procedure ErrorHandler;
  public   { Public-Deklarationen }
    DC                               : HDC; //Handle auf Zeichenfläche
    RC                               : HGLRC;//Rendering Context
  end;

acidrain 24. Mär 2012 12:48

AW: OpenGL Pong
 
Das hatte ich ja auch alles gemacht, trotzdem ist es ein einziges Wirrwarr in meinem Kopf, auf Wunsch kann ich mein ganzes Projekt als Quelltext zeigen :oops:

EWeiss 24. Mär 2012 12:49

AW: OpenGL Pong
 
Zitat:

Zitat von acidrain (Beitrag 1158296)
Brauche ich dann trotzdem noch den IdleHandler oder kann ich den auslassen, wegen dem Timer?

EDIT: h_DC & h_RC werden bei mir nicht erkannt, hab wohl einen veralteten Header :s

Zeig doch mal mehr Code!
Was ist denn da so geheim ?

Hat mit dem Header nichts zu tun sondern ist eine vom mir festgelegte Variable (GLOBAL)
Du benötigst aber das DC wie du es benennst ist letztendlich egal.
DC: HDC oder was auch immer das ist der Gerätekontex also das DC von deiner Render Form bzw. Image oder was du als GLWindow verwendest.

Ansonsten hat FlatIron doch schon alles ausführlich erklärt. ;)

gruss

acidrain 24. Mär 2012 12:53

AW: OpenGL Pong
 
Ich hab nichts zu verbergen ;)
Hier ist alles:
Code:
unit uPong;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, DGLOpenGL, ExtCtrls;

type
  TForm1 = class(TForm)
    Timer1: TTimer;
    procedure FormCreate(Sender: TObject);
    procedure SetupGL;
    procedure FormResize(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
{    procedure IdleHandler(Sender: TObject; var Done: Boolean);  }
    procedure ErrorHandler;
    procedure Render;
    procedure Schlaeger;
    procedure GLDraw;
    procedure InitOpenGL;
    procedure FormKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure Timer1Timer(Sender: TObject);
  private
     StartTime, TimeCount, FrameCount : Cardinal;
     Frames, DrawTime                 : Cardinal;
  public
    DC: HDC;
    RC: HGLRC;
  end;

const
 NearClipping = 1;
 FarClipping = 1000;

var
  Form1: TForm1;
  Spieler1hoch: boolean;
  Spieler1runter: boolean;
  Spieler2hoch: boolean;
  Spieler2runter: boolean;
  s1, s2: Integer;

implementation

{$R *.dfm}

procedure TForm1.InitOpenGL;
begin
  // Gerätekontext holen
  h_DC := GetDC(_FNormal.Handle);
  // Renderkontext erstellen (32 Bit Farbtiefe, 24 Bit Tiefenpuffer, Doublebuffering)
  h_RC := CreateRenderingContext(h_DC, [opDoubleBuffered], 32, 24, 0, 0, 0, 0);
  // Erstellten Renderkontext aktivieren
  ActivateRenderingContext(h_DC, h_RC);
begin;

procedure TForm1.FormCreate(Sender: TObject);
begin
 DC:= GetDC(Handle);
  if not InitOpenGL then Application.Terminate;
  RC:= CreateRenderingContext( DC,
                               [opDoubleBuffered],
                               32,
                               24,
                               0,0,0,
                               0);
  ActivateRenderingContext(DC, RC);
  SetupGL;
end;

procedure TForm1.SetupGL;
begin
 glClearColor(0.0, 0.0, 0.0, 0.0);
 glEnable(GL_DEPTH_TEST);
 glEnable(GL_CULL_FACE);
end;

procedure TForm1.FormResize(Sender: TObject);
var tmpBool : Boolean;
begin
 glViewport(0, 0, ClientWidth, ClientHeight);
 glMatrixMode(GL_PROJECTION);
 glLoadIdentity;
 gluPerspective(45.0, ClientWidth/ClientHeight, NearClipping, FarClipping);

 glMatrixMode(GL_MODELVIEW);
 glLoadIdentity;
 {IdleHandler(Sender, tmpBool);}
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
 DeactivateRenderingContext;
 DestroyRenderingContext(RC);
 ReleaseDC(Handle, DC);
end;

{procedure TForm1.IdleHandler(Sender: TObject; var Done: Boolean);
begin
  StartTime:= GetTickCount;
  Render; Schlaeger;
  DrawTime:= GetTickCount - StartTime;
  Inc(TimeCount, DrawTime);
  Inc(FrameCount);
 
  if TimeCount >= 1000 then begin
    Frames:= FrameCount;
    TimeCount:= TimeCount - 1000;
    FrameCount:= 0;
    Caption:= InttoStr(Frames) + 'FPS';
    ErrorHandler;
  end;
 
  Done:= false;
end;   }

procedure TForm1.ErrorHandler;
begin
 Form1.Caption:= gluErrorString(glGetError);
end;


procedure TForm1.Render;
begin


  glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);

  glMatrixMode(GL_PROJECTION);
  glLoadIdentity;
  gluPerspective(45.0, ClientWidth/ClientHeight, NearClipping, FarClipping);

  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity;

// Ball

  glTranslatef(30, 0, 0);

glBegin(GL_QUADS);
  glColor3f(0, 1, 0); glVertex3f(-1,1,-1); //lo
  glColor3f(0, 1, 0); glVertex3f(-1,-1,-1); //lu
  glColor3f(0, 1, 0); glVertex3f(1,-1,-1); //ru
  glColor3f(0, 1, 0); glVertex3f(1,1,-1);  //ro
glEnd;

SwapBuffers(DC);



end;

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
if Key = ord('W') then
 Spieler1hoch := true;

 if Key = ord('S') then
 Spieler1runter := true;

if Key = VK_UP then
 Spieler2hoch := true;

if Key = VK_DOWN then
 Spieler2runter := true;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
GLDraw;
if Spieler1hoch then
  begin
   s1:= s1+5;
   Spieler1hoch:= false;

 if Spieler1runter then
  begin
   s1:= s1-5;
   Spieler1runter:= false;
end;
end;
end;

procedure TForm1.Schlaeger;
begin
  glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);

  glMatrixMode(GL_PROJECTION);
//Spieler 1
glTranslatef(-60, 0, 0);
  glTranslated (0, s1, 0);
glBegin(GL_QUADS);
  glColor3f(0, 1, 0); glVertex3f(-1,1,-1); //lo
  glColor3f(0, 1, 0); glVertex3f(-1,-9,-1); //lu
  glColor3f(0, 1, 0); glVertex3f(1,-9,-1); //ru
  glColor3f(0, 1, 0); glVertex3f(1,1,-1);  //ro
glEnd;

// Spieler 2
glTranslatef(30, 6, -50);
  glTranslated(0, s2, 0);
glBegin(GL_QUADS);
  glColor3f(0, 1, 0); glVertex3f(-1,1,-1); //lo
  glColor3f(0, 1, 0); glVertex3f(-1,-9,-1); //lu
  glColor3f(0, 1, 0); glVertex3f(1,-9,-1); //ru
  glColor3f(0, 1, 0); glVertex3f(1,1,-1);   //ro
glEnd;
end;

procedure TForm1.GLDraw;
begin
  // Clear The Screen And The Depth Buffer
  glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);

  // Change Matrix Mode to Projection
  glMatrixMode(GL_PROJECTION);
  // Reset View
  glLoadIdentity;
  gluPerspective(45, (320 / 240), 1, 1000.0);
  // Change Projection to Matrix Mode
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
 
  Schlaeger;

  // Update the display
  SwapBuffers(h_DC);
end;

end.

EWeiss 24. Mär 2012 12:55

AW: OpenGL Pong
 
Rauswerfen!

Delphi-Quellcode:
procedure TForm1.InitOpenGL;
 begin
   // Gerätekontext holen
   h_DC := GetDC(_FNormal.Handle);
   // Renderkontext erstellen (32 Bit Farbtiefe, 24 Bit Tiefenpuffer, Doublebuffering)
   h_RC := CreateRenderingContext(h_DC, [opDoubleBuffered], 32, 24, 0, 0, 0, 0);
   // Erstellten Renderkontext aktivieren
   ActivateRenderingContext(h_DC, h_RC);
 begin;
Delphi-Quellcode:
procedure TForm1.GLDraw;
 begin
   // Clear The Screen And The Depth Buffer
   glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
 
  // Change Matrix Mode to Projection
   glMatrixMode(GL_PROJECTION);
   // Reset View
   glLoadIdentity;
   gluPerspective(45, (320 / 240), 1, 1000.0);
   // Change Projection to Matrix Mode
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
   
  Schlaeger;
 
  // Update the display
   SwapBuffers(h_DC);
 end;
OPENGL wird doch schon in FormCreate initialisiert.
Sorry so wird das nichts mit Copy und Paste.

gruss

acidrain 24. Mär 2012 12:57

AW: OpenGL Pong
 
Also dem Problem bin ich mir bewusst, vor dem ich stehe, aber ich wüsste nicht, wie das zu ändern ist. Nach den ganzen Tipps, die ihr mit gegeben habt ist das Problem, dass die Schläger nicht angezeigt werden.

EDIT: Ich muss ja entweder IdleHandler oder den Timer rausschmeissen, denn das ist ja das gleiche. Ich würde ja gerne den IdleHandler rausschmeißen, aber der wird bei FormResize aufgerufen

EWeiss 24. Mär 2012 13:02

AW: OpenGL Pong
 
Zitat:

Zitat von acidrain (Beitrag 1158309)
Also dem Problem bin ich mir bewusst, vor dem ich stehe, aber ich wüsste nicht, wie das zu ändern ist. Nach den ganzen Tipps, die ihr mit gegeben habt ist das Problem, dass die Schläger nicht angezeigt werden

Wenn du den IdleHandler deaktivierst kann auch nichts Rendern
denn da wird die Render procedure und das anschließende neu zeichnen von Schläger ausgeführt.

gruss

FlatIron 24. Mär 2012 13:05

AW: OpenGL Pong
 
EWeiss hat es schon gesagt - du hast dir da einfach etwas schnell zusammen kopiert. Die Lösung: Alles löschen und von vorne anfangen. Geh draußen schnell ne runde joggen oder mach irgendwas, wobei du den Kopf frei kriegst, und dann leg einfach nochmal los.

Dann fängst du einfach mit dem Grundlagentutorial an - liest es dir durch. Lädst dir das Listing runter. Vergleichst den Quellcode mit dem Tutorial und versuchst so zu verstehen. Danach kannst du, wenn du unter Zeitdruck bist, einfach das Template übernehmen oder du schreibst es einfach nochmal mit der Anleitung neu. Das wäre Schritt 1.
Danach versuchst du die folgenden Tutorials zu verstehen und dann kannst du dir die wichtigen Punkte raussuchen, die du für die Umsetzung deines Projekts brauchst - vgl. die Tutorials einfach mit deinen Aufzeichnungen/Konzept oder was du dir sonst handschriftlich notiert hast (einfach drauflos programmieren bringt nichts).

Dann kannst du erstmal loslegen deinen Ball zu programmieren bzw. die Schläger. Wenn diese Komponenten deines Spiels unabhängig voneinander funktionieren kannst du dich mit deiner Kollisionsabfrage beschäfftigen.

So wird dein Projekt nach und nach zu einem Spiel. Wichtig ist aber, dass du verstehst was du da grade machst.
Wir können dir das Spiel nicht programmieren noch können wir dir helfen OpenGL sofort zu verstehen. - Fang lieber mal strukturiert an.

Ich hoffe für dich, dass Montag nicht schon der Abgabetermin ist. Ich wünsche dir trotzdem viel Spaß und Erfolg.

MFG
FlatIron

acidrain 24. Mär 2012 13:08

AW: OpenGL Pong
 
Dann kann ich das doch auch ganz einfach in den Timer reinpacken. Ich brauch ja nicht mehr wie 25FPS für Pong.


EDIT: Danke FlatIron, das werd ich wohl tun! Ne, Abgabetermin ist noch was bisschen hin, hab erstmal das schriftliche gemacht und wollte mich zuletzt an's Programmieren setzen.
Ich guck mir alles nochmal von vorne an und melde mich, falls nötig!:thumb:

FlatIron 24. Mär 2012 13:11

AW: OpenGL Pong
 
Mach das.

[OT]
Darf ich fragen wie das Thema der Facharbeit lautet? Und welches Fach das ist? Mathe? Info?
[/OT]

EWeiss 24. Mär 2012 13:14

AW: OpenGL Pong
 
Versuch das mal..

Delphi-Quellcode:
unit uPong;
 
interface
 
uses
   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
   Dialogs, DGLOpenGL, ExtCtrls;
 
type
   TForm1 = class(TForm)
     procedure FormCreate(Sender: TObject);
     procedure SetupGL;
     procedure FormResize(Sender: TObject);
     procedure FormDestroy(Sender: TObject);
     procedure IdleHandler(Sender: TObject; var Done: Boolean);
     procedure ErrorHandler;
     procedure Render;
     procedure Schlaeger;
     procedure FormKeyDown(Sender: TObject; var Key: Word;
       Shift: TShiftState);
   private
      StartTime, TimeCount, FrameCount : Cardinal;
      Frames, DrawTime                : Cardinal;
   public
     DC: HDC;
     RC: HGLRC;
   end;
 
const
  NearClipping = 1;
  FarClipping = 1000;
 
var
   Form1: TForm1;
   s1, s2: Integer;
 
implementation
 
{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
 begin
  DC:= GetDC(Handle);
   if not InitOpenGL then Application.Terminate;
   RC:= CreateRenderingContext( DC,
                                [opDoubleBuffered],
                                32,
                                24,
                                0,0,0,
                                0);
   ActivateRenderingContext(DC, RC);
   SetupGL;
 end;
 
procedure TForm1.SetupGL;
 begin
  glClearColor(0.0, 0.0, 0.0, 0.0);
  glEnable(GL_DEPTH_TEST);
  glEnable(GL_CULL_FACE);
 end;
 
procedure TForm1.FormResize(Sender: TObject);
 var tmpBool : Boolean;
 begin
  glViewport(0, 0, ClientWidth, ClientHeight);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity;
  gluPerspective(45.0, ClientWidth/ClientHeight, NearClipping, FarClipping);
 
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity;
  IdleHandler(Sender, tmpBool);
 end;

procedure TForm1.FormDestroy(Sender: TObject);
 begin
  DeactivateRenderingContext;
  DestroyRenderingContext(RC);
  ReleaseDC(Handle, DC);
 end;
 
procedure TForm1.IdleHandler(Sender: TObject; var Done: Boolean);
begin
   StartTime:= GetTickCount;
   Render;
   DrawTime:= GetTickCount - StartTime;
   Inc(TimeCount, DrawTime);
   Inc(FrameCount);
 
   if TimeCount >= 1000 then begin
     Frames:= FrameCount;
     TimeCount:= TimeCount - 1000;
     FrameCount:= 0;
     Caption:= InttoStr(Frames) + 'FPS';
     ErrorHandler;
   end;
 
   Done:= false;
end;
 
procedure TForm1.ErrorHandler;
begin
  Form1.Caption:= gluErrorString(glGetError);
end;
 

procedure TForm1.Render;
begin
  glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
 
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity;
  gluPerspective(45.0, ClientWidth/ClientHeight, NearClipping, FarClipping);
 
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity;
 
  Schlaeger;

  // alter code gehört zu Ball
  {glTranslatef(30, 0, 0);

  glBegin(GL_QUADS);
    glColor3f(0, 1, 0); glVertex3f(-1,1,-1); //lo
    glColor3f(0, 1, 0); glVertex3f(-1,-1,-1); //lu
    glColor3f(0, 1, 0); glVertex3f(1,-1,-1); //ru
    glColor3f(0, 1, 0); glVertex3f(1,1,-1); //ro
  glEnd; }
 
  SwapBuffers(DC);
end;
 
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
   Shift: TShiftState);
begin
 if Key = ord('W') then
  s1:= s1+5;

 if Key = ord('S') then
   s1:= s1-5;

 if Key = VK_UP then
  s2:= s2+5;

 if Key = VK_DOWN then
  s2:= s2-5;

 Render;
end;

procedure TForm1.Schlaeger;
begin
 //Spieler 1
 glTranslatef(-60, 0, 0);
 glTranslated (0, s1, 0);
 glBegin(GL_QUADS);
   glColor3f(0, 1, 0); glVertex3f(-1,1,-1); //lo
   glColor3f(0, 1, 0); glVertex3f(-1,-9,-1); //lu
   glColor3f(0, 1, 0); glVertex3f(1,-9,-1); //ru
   glColor3f(0, 1, 0); glVertex3f(1,1,-1); //ro
 glEnd;
 
// Spieler 2
 glTranslatef(30, 6, -50);
 glTranslated(0, s2, 0);
 glBegin(GL_QUADS);
   glColor3f(0, 1, 0); glVertex3f(-1,1,-1); //lo
   glColor3f(0, 1, 0); glVertex3f(-1,-9,-1); //lu
   glColor3f(0, 1, 0); glVertex3f(1,-9,-1); //ru
   glColor3f(0, 1, 0); glVertex3f(1,1,-1);  //ro
 glEnd;
end;

end.
Habs mal getestet!
Also da ist einiges im argen Koordinaten usw..
Der linke Schläger wird aber jetzt gezeichnet wenn du die Tasten verwendest.

gruss

acidrain 24. Mär 2012 14:14

AW: OpenGL Pong
 
Fach: Informatik GK
Thema: Die Verwendung von OpenGL unter Anwendung von "Pong".

EWeiss 24. Mär 2012 14:16

AW: OpenGL Pong
 
Habe es nochmal editiert!
Als anfang sollte das reichen.

Lese bitte die Bemerkungen :)

gruss

acidrain 24. Mär 2012 14:44

AW: OpenGL Pong
 
Ich hab's zu Anfang mal umgesetzt, wie du es geschrieben hast. Natürlich selbst geschrieben und kein copy&paste :wink:
Also angezeigt wird immerhin der linke Schläger, nur bewegen tut er sich bei mir nicht, wenn ich W oder S drücke.
Trotzdem danke für soviel Hilfe! Ich schau da auch selber noch mehrmals drüber und benutze Tutorials zur Hilfe.


EDIT: Wäre es nicht um vieles einfacher, wenn ich einfach normale Panels nehmen würde und die dann mit OpenGL "anmale"?

EWeiss 24. Mär 2012 15:43

AW: OpenGL Pong
 
Habe mal das projekt angehängt..
Was aber seltsam ist das sich die beiden Schläger nicht trennen lassen.
Eigentlich sollte das mit glLoadIdentity(); machbar sein will aber aus irgendeinen grund nicht.
Liegt wohl daran das ich das projekt nicht komplett selbst geschrieben habe.

Sorry finde den fehler jetzt auf die schnelle nicht. Die Koordinaten stimmen aber.

Delphi-Quellcode:
procedure TForm1.Schlaeger;
begin
 //Spieler 1
 glLoadIdentity;
 glTranslatef(-60, 0, 0);
 glTranslated(0, s1, 0);
 glBegin(GL_QUADS);
   glColor3f(0, 1, 0); glVertex3f(-1,1,-1); //lo
   glColor3f(0, 1, 0); glVertex3f(-1,-9,-1); //lu
   glColor3f(0, 1, 0); glVertex3f(1,-9,-1); //ru
   glColor3f(0, 1, 0); glVertex3f(1,1,-1); //ro
 glEnd;

 //Spieler 2
 glLoadIdentity;
 glTranslatef(30, 6, -50);
 glTranslated(0, s2, 0);
 glBegin(GL_QUADS);
   glColor3f(0, 1, 0); glVertex3f(-1,1,-1); //lo
   glColor3f(0, 1, 0); glVertex3f(-1,-9,-1); //lu
   glColor3f(0, 1, 0); glVertex3f(1,-9,-1); //ru
   glColor3f(0, 1, 0); glVertex3f(1,1,-1);  //ro
 glEnd;

end;
Macht keinen unterschied ob Form oder panel der einzige ist halt das man es nicht Resizen kann.
Schläger läßt sich bewegen ;)

gruss

acidrain 24. Mär 2012 16:30

AW: OpenGL Pong
 
Danke, dass du dir solche Mühe gibst. Ich hab's jetzt auch selber geschafft. Bei mir bewegen sich beide Schläger, lassen sich aber auch nicht von einander trennen, wie ich gemerkt habe. Ich versuch's mal weiter und bedanke mich nochmal!

EWeiss 24. Mär 2012 16:52

AW: OpenGL Pong
 
Zitat:

Zitat von acidrain (Beitrag 1158352)
Danke, dass du dir solche Mühe gibst. Ich hab's jetzt auch selber geschafft. Bei mir bewegen sich beide Schläger, lassen sich aber auch nicht von einander trennen, wie ich gemerkt habe. Ich versuch's mal weiter und bedanke mich nochmal!

Hab ich gern getan.. Vielleicht findet sich noch jemand der dir bei den letzten Porblem noch helfen kann.
Edit:
Habe es auch mit
glPushMatrix();
glPopMatrix();
versucht trennt aber auch nicht die Schläger.. seltsam alles

gruss .. Schönes Wochenende.

acidrain 24. Mär 2012 17:10

AW: OpenGL Pong
 
Das Problem hat sich erledigt, ich hab's mit glPushMatrix und glPopMatrix gelöst.

Ich hätte noch eine Frage und bräuchte eine Hilfestellung.
1. Bei mir ist das ja jetzt so, dass nur ein Spieler die Tasten drücken kann, wenn der andere seine zugehörigen Tasten gleichzeitig drückt, dann passiert nichts.
Das verschafft ja ein unfaires Spielerlebnis für denjenigen Spieler, der später reagiert.

2. Wie sollte ich das mit den Kollisionen klären? Ich weiss ja nicht, wo genau das Spielfeld bei meiner Fenstergröße endet bzw. wo genau die Schläger sind.
Ich hab mich Gestern ein bisschen durchgelesen und hab immer nur gesehen, dass die Leute Variablen nehmen nur die Deklarationen sind nirgends vorzufinden.
Also wäre die genaue Frage, wie ich die genauen Koordinaten einlesen kann, dass ich mit stinknormalen IF Schleifen die Kollisionen festlegen kann.+


Vielen Dank im Vorraus,
acidrain


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:26 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz