Autor Beitrag
glotzer
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 393
Erhaltene Danke: 49

Win 7
Lazarus
BeitragVerfasst: So 05.08.12 16:41 
Hallo zusammen,
ich hab jetzt hier mit einem OpenGL Tutorial angefangen und das ein bischen angepasst.
Einziges Problem: man sieht nix.

So sieht es aus:
sein

So sollte es sein:
sollen

Ich hab den Code eigentlich 1 zu 1 übernommen, nur halt in eine Klasse gepackt. Ist jemand so nett und schaut sich das mal kurz an?
Ist ganz sicher nur irgendeine Kleiningkeit die ich einfach nicht sehe.

Vielen Dank.




Das Formular, wobei hier eigentlich nix passiert.
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
unit Main;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, OpenGlEngine, Vcl.AppEvnts, dglOpenGL;

type
  TMainForm = class(TForm)
    OpenGlTarget: TPanel;
    ApplicationEvents: TApplicationEvents;
    procedure FormDestroy(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure FormActivate(Sender: TObject);
    procedure FormResize(Sender: TObject);
  private
    Engine: TOpenGlEngine;
    { Private-Deklarationen }
  public
    procedure GameLoop;
    { Public-Deklarationen }
  end;

var
  MainForm: TMainForm;

implementation

{$R *.dfm}

procedure TMainForm.FormActivate(Sender: TObject);
begin
  GameLoop;
end;

procedure TMainForm.FormDestroy(Sender: TObject);
begin
  Engine.Free;
end;

procedure TMainForm.FormResize(Sender: TObject);
begin
  Engine.Resize(self.ClientWidth,self.ClientHeight);
end;

procedure TMainForm.FormShow(Sender: TObject);
begin
  Engine := TOpenGlEngine.Create(OpenGlTarget.Handle);
  Engine.Resize(self.ClientWidth,self.ClientHeight);
end;

procedure TMainForm.GameLoop;
begin
  while not Application.Terminated do
  begin
    Application.ProcessMessages;
    if Engine.CanRender then Engine.Render;
  end;
end;

end.


Meine kleine Möchtegern-Engine
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
unit OpenGLEngine;

interface

uses
  dglOpenGL, Windows;

type
  TOpenGlEngine = class
    protected
      FRC: Cardinal;
      FDC: Cardinal;
      FWindowHandle: Hwnd;
      FWidth,FHeight: Cardinal;
      FCanRender: boolean;
    protected
      procedure SetupOpenGL;
    public
      constructor Create(AWindowHandle:Hwnd);
      destructor Destroy; override;
    public
      procedure Resize(AWidth,AHeight: Cardinal);
      procedure Render;
    public
      property CanRender: boolean read FCanRender;
      property Width: Cardinal read FWidth;
      property Height: Cardinal read FHeight;
  end;

implementation

const
  NearClipping = 1;
  FarClipping  = 1000;

constructor TOpenGlEngine.Create(AWindowHandle:Hwnd);
begin
  inherited Create;
  FDC := 0;
  FWidth := 0;
  FHeight := 0;
  FCanRender := false;
  FWindowHandle := AWindowHandle;
  if not InitOpenGL then halt;

  FDC := GetDC(AWindowHandle);
  FRC := CreateRenderingContext(FDC,[opDoubleBuffered],32,24,0,0,0,0);
  ActivateRenderingContext(FDC, FRC);

  SetupOpenGL;

  FCanRender := true;

end;

destructor TOpenGlEngine.Destroy;
begin
  DeactivateRenderingContext;
  DestroyRenderingContext(FRC);
  ReleaseDC(FWindowHandle,FDC);
  inherited;
end;

procedure TOpenGlEngine.SetupOpenGL;
begin
  glClearColor(0.30.40.70.0);
  glEnable(GL_DEPTH_TEST);
  glEnable(GL_CULL_FACE);
end;

procedure TOpenGlEngine.Resize(AWidth,AHeight: Cardinal);
begin
  FWidth := AWidth;
  FHeight := AHheight;

  glViewport(00, Width, Height);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity;
  gluPerspective(45.0, Width/Height, NearClipping, FarClipping);

  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity;

  Render;
end;

procedure TOpenGlEngine.Render;
begin
  glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);

  glMatrixMode(GL_PROJECTION);
  glLoadIdentity;
  gluPerspective(45.0, Width/Height, NearClipping, FarClipping);

  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity;

  glTranslatef( -1.5,  0,  -6);

  glBegin(GL_TRIANGLES);
      glColor3f(1,0,0);
      glVertex3f(-1.0,-1.00.0);
      glColor3f(0,1,0);
      glVertex3f( 0.01.00.0);
      glColor3f(0,0,1);
      glVertex3f( 1.0,-1.00.0);
  glEnd();


  SwapBuffers(FDC);
end;

end.
Einloggen, um Attachments anzusehen!
_________________
ja, ich schreibe grundsätzlich alles klein und meine rechtschreibfehler sind absicht


Zuletzt bearbeitet von glotzer am So 05.08.12 16:51, insgesamt 4-mal bearbeitet
Xion
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
EE-Maler
Beiträge: 1952
Erhaltene Danke: 128

Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
BeitragVerfasst: So 05.08.12 19:13 
Ich habe da eine Vermutung (musste erst das Tutorial daneben legen um es zu sehen):

Du zeichnest die Eckpunkte deines Dreiecks in einer anderen Reihenfolge, als im Tutorial. Das heißt, es guckt nach hinten (hat was mit dem Normalenvektor zu tun). Da du Cull-Face aktiviert hast, es also von hinten nicht gerendert wird, ist es nicht sichtbar. Du guckst sozusagen von hinten durch das Dreieck durch ;) Drehe mal die Reihenfolge der Vertex-Befehle um (= gegen den Uhrzeigersinn).

Bei solchen Sachen (fast immer wenn ich was mit Licht benutze sehe ich am Anfang nichts) lass ich das Objekt mal animieren mit einem glRotate (kommt noch im Tutorial ;) ), und hoffe, dass wenigstens kurz mal was zu sehen ist :mrgreen: Dann kommt man eher dahinter, woran es liegt.

Am Rande: Deine "GameLoop" Konstruktion gefällt mir nicht. Ich benutze immer einen Timer, der schont die Ressourcen.

_________________
a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
glotzer Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 393
Erhaltene Danke: 49

Win 7
Lazarus
BeitragVerfasst: So 05.08.12 19:28 
WOW das war ja einfach :D
Danke jetzt geht alles

nur falls es später mal wer braucht:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
  glBegin(GL_TRIANGLES);
    glColor3f(0,0,1);
    glVertex3f( 1.0,-1.00.0);
    glColor3f(0,1,0);
    glVertex3f( 0.01.00.0);
    glColor3f(1,0,0);
    glVertex3f(-1.0,-1.00.0);
  glEnd();


oder

ausblenden Delphi-Quelltext
1:
  glEnable(GL_CULL_FACE);					

löschen

wegen der GameLoop:
der Timer wird am Ende nicht wesentlich besser sein, da kommen noch sleeps rein.
Nur mit der GameLoop ist es einfacher die FrameRate konstant zu halten.

Oder gibt es wesentliche Argumente dagegen?

_________________
ja, ich schreibe grundsätzlich alles klein und meine rechtschreibfehler sind absicht
Martok
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 3661
Erhaltene Danke: 604

Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
BeitragVerfasst: Mo 06.08.12 00:10 
user profile iconglotzer hat folgendes geschrieben Zum zitierten Posting springen:
Oder gibt es wesentliche Argumente dagegen?
Neben der Tatsache, dass das für eine Eventbasierte Anwendung nicht wirklich sinnvoll ist? Die Framerate sollte dir auch egal sein: Timebased Movement geht anders.

_________________
"The phoenix's price isn't inevitable. It's not part of some deep balance built into the universe. It's just the parts of the game where you haven't figured out yet how to cheat."
glotzer Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 393
Erhaltene Danke: 49

Win 7
Lazarus
BeitragVerfasst: Di 07.08.12 03:47 
Timebased Movement kenn ich ja, das kommt auch noch später.
Events sind doch GERADE mit so einer GameLoop besser zu machen. Ich habe eh nicht vor dafür die Delphi eigenen
Events zu verwenden, sondern einen eigenen EventManager der sich darum kümmert und unter anderem die Tastatur abfragt.
Ich finde einfach das man mit einer Game Loop viel mehr Kontrolle hat. Vorallem muss ich nicht nach jedem Frame sämtliche Eingabegeräte abfragen, alle 50ms reicht ja auch (sowas wäre z.b. mit OnIdle nicht möglich soweit ich weis)

_________________
ja, ich schreibe grundsätzlich alles klein und meine rechtschreibfehler sind absicht
Martok
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 3661
Erhaltene Danke: 604

Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
BeitragVerfasst: Di 07.08.12 04:39 
Framelimiter sind auch im OnIdle einfach, der Unterschied ist ja nur woher der Aufruf kommt ;-)

Einen nicht ganz genau gehenden (je nach Last wird z.B. aus 60 Sollwert irgendwas zwischen 55 und 65) kannst du dir bei Kali angucken. Nicht von der Funktion Run verwirren lassen - das ist kein Gameloop, das ist Application.Run nachgebaut, um noch ein paar Sachen zusätzlich zu machen. Die wird dann im Projekt anstatt Application.Run aufgerufen.

_________________
"The phoenix's price isn't inevitable. It's not part of some deep balance built into the universe. It's just the parts of the game where you haven't figured out yet how to cheat."