Autor |
Beitrag |
glotzer
Beiträge: 393
Erhaltene Danke: 49
Win 7
Lazarus
|
Verfasst: 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:
So sollte es sein:
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.
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; public procedure GameLoop; 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
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.3, 0.4, 0.7, 0.0); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); end;
procedure TOpenGlEngine.Resize(AWidth,AHeight: Cardinal); begin FWidth := AWidth; FHeight := AHheight;
glViewport(0, 0, 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.0, 0.0); glColor3f(0,1,0); glVertex3f( 0.0, 1.0, 0.0); glColor3f(0,0,1); glVertex3f( 1.0,-1.0, 0.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
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)
|
Verfasst: 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 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
Beiträge: 393
Erhaltene Danke: 49
Win 7
Lazarus
|
Verfasst: So 05.08.12 19:28
WOW das war ja einfach
Danke jetzt geht alles
nur falls es später mal wer braucht:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8:
| glBegin(GL_TRIANGLES); glColor3f(0,0,1); glVertex3f( 1.0,-1.0, 0.0); glColor3f(0,1,0); glVertex3f( 0.0, 1.0, 0.0); glColor3f(1,0,0); glVertex3f(-1.0,-1.0, 0.0); glEnd(); |
oder
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
Beiträge: 3661
Erhaltene Danke: 604
Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
|
Verfasst: Mo 06.08.12 00:10
glotzer hat folgendes geschrieben : | 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
Beiträge: 393
Erhaltene Danke: 49
Win 7
Lazarus
|
Verfasst: 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
Beiträge: 3661
Erhaltene Danke: 604
Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
|
Verfasst: 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."
|
|
|