| Autor |
Beitrag |
ähM_Key
      
Beiträge: 88
Windows XP Professional
D7 Enterprise
|
Verfasst: Mo 07.11.05 14:13
Hi!
Möchte gerne in mein Programm eine Achsenbeschriftung einbauen und muss dazu Text unter OpenGL darstellen.
Das Problem ist (oder ich glaube zumindest, dass es daran liegt), dass ich ein glOrtho verwende.
Ich habe den entsprechenden QT von NeHe in mein Programm kopiert.
Mir ist weiterhin aufgefallen, dass man an keiner Stelle spezifiert, in welcher Z-Ebene der Text gezeichnet werden soll, wesshalb er vielleicht da ist, sich nur hinter einem anderen Bild versteckt
Ich gebe auch gerne zu, dass ich nicht wirklich im Einzelnen verstanden habe, was die Anweisungen so machen, sprich hab sie in große Teilen einfach so komentarlos übernommen
So, nun hier mein Quelltext...vielleicht seht ihr ja, was ich da falsch zusammengeschrieben habe
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: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196:
| unit Unit_GL; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, OpenGL; type TForm1 = class(TForm) procedure initGL; procedure freeGL; procedure BuildFont; procedure glPrint(text: string); procedure DrawGLScene; procedure Init; procedure Draw; private myDC : HDC; myRC : HGLRC; myPalette : HPALETTE; procedure SetupPixelFormat; public xyborder : word; end;
var Form1 : TForm1;
h_Dc: HDC; h_Wnd: HWND; base: GLuint; cnt1: GLfloat; const xmax = 800; ymax = 700;
implementation
uses Unit_ComRead;
{$R *.dfm}
procedure TForm1.SetupPixelFormat; <span style="color: red">- 3 -</span> var hHeap: THandle; nColors, i: Integer; lpPalette : PLogPalette; byRedMask, byGreenMask, byBlueMask: Byte; nPixelFormat: Integer; pfd: TPixelFormatDescriptor; begin FillChar(pfd, SizeOf(pfd), 0); with pfd do begin nSize := sizeof(pfd); nVersion := 1; dwFlags := PFD_DRAW_TO_WINDOW or PFD_SUPPORT_OPENGL or PFD_DOUBLEBUFFER; iPixelType:= PFD_TYPE_RGBA; cColorBits:= 24; cDepthBits:= 32; iLayerType:= PFD_MAIN_PLANE; end; nPixelFormat:= ChoosePixelFormat(myDC, @pfd); SetPixelFormat(myDC, nPixelFormat, @pfd); DescribePixelFormat(myDC, nPixelFormat, sizeof(TPixelFormatDescriptor),pfd); if ((pfd.dwFlags and PFD_NEED_PALETTE) <> 0) then begin nColors := 1 shl pfd.cColorBits; hHeap := GetProcessHeap; lpPalette:= HeapAlloc (hHeap,0,sizeof(TLogPalette)+(nColors*sizeof(TPaletteEntry))); lpPalette^.palVersion := $300; lpPalette^.palNumEntries := nColors; byRedMask := (1 shl pfd.cRedBits) - 1; byGreenMask:= (1 shl pfd.cGreenBits) - 1; byBlueMask := (1 shl pfd.cBlueBits) - 1; for i := 0 to nColors - 1 do begin lpPalette^.palPalEntry[i].peRed := (((i shr pfd.cRedShift) and byRedMask) *255)DIV byRedMask; lpPalette^.palPalEntry[i].peGreen:= (((i shr pfd.cGreenShift)and byGreenMask)*255)DIV byGreenMask; lpPalette^.palPalEntry[i].peBlue := (((i shr pfd.cBlueShift) and byBlueMask) *255)DIV byBlueMask; lpPalette^.palPalEntry[i].peFlags:= 0; end; myPalette:= CreatePalette(lpPalette^); HeapFree(hHeap, 0, lpPalette); if (myPalette <> 0) then begin SelectPalette(myDC, myPalette, False); RealizePalette(myDC); end; end; end;
procedure TForm1.initGL; <span style="color: red">- 2 -</span> begin form1.myDC:= GetDC(Handle); SetupPixelFormat; <span style="color: red">-> 3</span> myRC:= wglCreateContext(myDC); wglMakeCurrent(myDC, myRC); glEnable(GL_DEPTH_TEST); glClearColor(229/255, 229/255,229/255, 1); glMatrixMode(GL_PROJECTION); glLoadIdentity; glOrtho (0, xmax, 0, ymax, 0, 5); glscale(1,1,-1); draw; end;
procedure TForm1.freeGL; begin wglmakecurrent(0,0); wgldeletecontext(mydc); releasedc(handle,mydc); end;
procedure TForm1.BuildFont; <span style="color: red">- 4 -</span> var Font: HFONT; begin base := glGenLists(96); font := CreateFont(-24, 0, 0, 0, FW_BOLD, 0, 0, 0, ANSI_CHARSET, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY, FF_DONTCARE or DEFAULT_PITCH, 'Courier New'); SelectObject(h_dc,font); wglUseFontBitmaps(h_dc,32,96,base); end;
procedure TForm1.glPrint(text: string); <span style="color: red">- 7 -</span> begin if text = '' then exit; glPushAttrib(GL_LIST_BIT); glListBase(base - 32); glCallLists(length(text),GL_UNSIGNED_BYTE,Pchar(text)); glPopAttrib; end;
procedure TForm1.DrawGLScene; <span style="color: red">- 6 -</span> begin glColor3f(0,0,1); glRasterPos2f(99, 199); glPrint('Test'); <span style="color: red">-> 7</span> end;
procedure TForm1.Init; <span style="color: red">- 1 -</span> begin initGL; <span style="color: red">-> 2</span> glShadeModel(GL_SMOOTH); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST); BuildFont; <span style="color: red">-> 4</span> end;
procedure TForm1.Draw; <span style="color: red">- 5 -</span> var i: word; begin if Form2.CheckBox5.Checked then begin glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); glBegin(GL_Quads); glcolor3f(1,1,1); glVertex3f(0 + xyborder , 0 +xyborder, 4); glVertex3f(xmax , 0 +xyborder, 4); glVertex3f(xmax , ymax, 4); glVertex3f(0 + xyborder , ymax, 4); glEnd(); end;
if Form2.CheckBox9.checked then begin DrawGLScene; <span style="color: red">-> 6</span> end;
[...] SwapBuffers(form1.myDC); end;
end. |
Grüße; ähM_Key
EDIT: Hmm, das mit den farblichen Markierungen, dass man von der Reihenfolge besser durchsieht hat natürlich nciht geklappt; scheinbar kann man keinen Code im Code machen...naja vieleicht sieht man's trotzdem etwas besser; [color=red] fällt ja fast so gut auf, wie eine rote Zahl ^^
_________________ Alles geht ni! Aber ein bissl' was muss!
|
|
Lossy eX
      
Beiträge: 1048
Erhaltene Danke: 4
|
Verfasst: Di 08.11.05 13:56
Oh je. Wo soll ich anfangen. Also Code einfach so reinkopieren bringt selten etwas, außer du weißt was der Code bewirkt und da gehe ich in deinem Falle mal nicht von aus. Das macht aber nichts dazu kann man das lernen.
Also glOrtho stellt die Ansicht auf den Orthomodus. Also 2D. Zum Zeichnen von BitmapFonts wird dieser benötigt.
Die Auskommentierte Zeile mit glClear solltest du schleunichst wieder einkommentieren, da diese dafür sorgt, dass dein Bildschirm und der Inhalt des Tiefenbuffers gelöscht werden.
Wenn du nur 2 Koordinaten (2D) angiebst ist die 3te automatisch 0. Wird also direkt auf dem zNear von glOrtho gezeichnet. Das zNear und zFar stell eich persönlich immer ganz gerne auf -1 und 1.
Zum zeichnen von 3D Objekten musst du gluPerspective aufrufen, damit deine Perspektive eingestellt werden kann.
Außerdem finde ich nirgendswo den Aufruf von glViewport. Das ist zwar meines wissens nicht zwingend vorrausgesetzt bietet sich aber immer an. Speziell, wenn du dein Fenster in der Größe verändern kannst zwingend vorrausgesetzt.
Außerdem solltest du dir mal hier die Tutorials ansehen. Speziell das Quickstart und dann auch noch das 2D.
_________________ Nur die Menschheit ist arrogant genug, um zu glauben sie sei die einzige intelligente Lebensform im All. Wo nicht mal das nachhaltig bewiesen wurde.
|
|
ähM_Key 
      
Beiträge: 88
Windows XP Professional
D7 Enterprise
|
Verfasst: Di 08.11.05 15:19
Lossy eX hat folgendes geschrieben: | | Die Auskommentierte Zeile mit glClear solltest du schleunichst wieder einkommentieren, da diese dafür sorgt, dass dein Bildschirm und der Inhalt des Tiefenbuffers gelöscht werden. |
Das Löschen des Bildschirms und des Tiefenpuffers passiert schon vorher (Zeile 178), würde ich das dort mit hineinnehmen, würde ich mir den grade gemalten weißen Hintergrund wieder löschen.
Lossy eX hat folgendes geschrieben: |
Wenn du nur 2 Koordinaten (2D) angiebst ist die 3te automatisch 0. Wird also direkt auf dem zNear von glOrtho gezeichnet. Das zNear und zFar stell eich persönlich immer ganz gerne auf -1 und 1. |
Ich habe mal versucht bei 'glRasterPos2f(X, Y);' (Zeile 154) einen dritten, also Z-Wert hinzuzufügen, was allerdings nicht funktioniert hat..."Zu viele Parameter". Ich habe zNear auf 0 und zFar auf 4, womit ich wunderbar meine (im Moment) 4 versch. Ebenen übereinander anordnen kann.
Lossy eX hat folgendes geschrieben: |
Zum zeichnen von 3D Objekten musst du gluPerspective aufrufen, damit deine Perspektive eingestellt werden kann. |
Ich will doch aber garkein 3D-Objekt zeichnen, sondern nur Schrift (oder ist das ein 3D-Objekt? [bei dieser Variante der Schriftdarstellung]). Weiterhin habe ich doch garkeine Perspektive im üblichen Sinne, wenn ich im glOrtho arbeite, da ich ja sozusagen flach von oben auf die Ebene und schaue und nicht von einem best. Punkt aus.
Anders gesagt, ist nicht mein glOrtho für'n A****, wenn ich dann gluPerspective aufrufe? (Wenn ich's mache kann ich nix mehr darstellen (was vorher noch ging). Liege ich falsch?
Lossy eX hat folgendes geschrieben: |
Außerdem finde ich nirgendswo den Aufruf von glViewport. Das ist zwar meines wissens nicht zwingend vorrausgesetzt bietet sich aber immer an. Speziell, wenn du dein Fenster in der Größe verändern kannst zwingend vorrausgesetzt.. |
Bin mir dessen bewusst, habe eine Form mit bsDialog als BorderStyle verwendet.
Lossy eX hat folgendes geschrieben: |
Außerdem solltest du dir mal hier die Tutorials ansehen. Speziell das Quickstart und dann auch noch das 2D. |
Meine 2D-Darstellungen laufen und funktionieren ja alle wunderbar...muss man denn auch das funktionierende Verändern, um Schrift darstellen zu können?
So, schwer darf das doch ni sein!
Grüße; ähM_Key
_________________ Alles geht ni! Aber ein bissl' was muss!
|
|
Lossy eX
      
Beiträge: 1048
Erhaltene Danke: 4
|
Verfasst: Di 08.11.05 15:46
| Zitat: | | Das Löschen des Bildschirms und des Tiefenpuffers passiert schon vorher (Zeile 178), würde ich das dort mit hineinnehmen, würde ich mir den grade gemalten weißen Hintergrund wieder löschen. |
Okay. Habe ich übersehen. Aber dort ist es auch nicht ganz richtig. Das muss eigentlich drüber, weil CheckBox9 gesetzt sein kann aber CheckBox5 nicht. Und somit würde es nicht aufgerufen werden. Also glClear in deinem Falle auf jeden Fall aufrufen.
| Zitat: | | Ich habe mal versucht bei 'glRasterPos2f(X, Y);' (Zeile 154) einen dritten, also Z-Wert hinzuzufügen, |
Ja genau. glRasterPos ist auch nur für reines 2D. Und dann auch nur dafür gedacht mit glBitmap bitmaps zu zeichnen. Und bei einem Bitmapfont wird intern glBitmap aufgerufen. Und dabei werden lediglich Pixel gesetzt oder nicht gesetzt.
Das mit zNear/zFar kannst du natürlich so machen wie du es magst. Ich zeichne aber ungern direkt am Rand des Bereiches, da es einige seltsame OpenGL Implementationen gibt. Also lasse ich leider ein wenig luft.
| Zitat: | | Anders gesagt, ist nicht mein glOrtho für'n A****, wenn ich dann gluPerspective aufrufe? |
Also zum generellen Verständniss. OPENGL IST EINE STATEMASCHINE. Sinn und zweck einer Statemaschine ist es einstellungen entgegenzunehmen, damit etwas zu machen und dann andere Einstellungen entgegenzunehmen. Das zu begreifen ist sehr wichtig. Das was du in OpenGL einstellst ist nur so lange gültig bist du etwas neues einstellst. Also 2D an. Schrift zeichnen. 3D an. Was anderen Zeichnen. 2D an. Noch mal Schrift zeichnen. Ist ohne Probleme möglich. das erste mal 2D macht nicht unbedingt sinn und vergeudet reichlich Leistung aber es wäre möglich.
Du kannst aber auch rein 2D bleiben. Habe das wohl vorhin falsch verstanden. Wenn du nur 2D haben willst, dann musste nichts dran ändern.
Und um Schrift zeichnen zu können solltest du eigentlich nichts verändern müssen. Wobei ich deine ZWerte ein wenig seltsam finde, wenn ich ehrlich bin. Also Positive ZWerte aber zu begin ein glScale mit -1 als ZWert. :-/ Das ist mit verlaub gesagt unüblich und verwirrend.
Versuche aber mal folgendes. Deaktiviere mal vor dem Zeichnen der Schrift deinen Tiefentest. Also glDisable(GL_DEPTH_TEST); und anschließend glEnable(GL_DEPTH_TEST);. Und wenn er dann angezeigt wird, dann hat etwas mit deinen Tiefen nicht so richtig. Wobei sich das eigentlich ausgleich sollte. Also das was du gemacht hattest.
| Zitat: | | So, schwer darf das doch ni sein! |
Wenn man es ein wenig kann und sich an gewisse Dinge hält ist es alles andere als Schwer. 
_________________ Nur die Menschheit ist arrogant genug, um zu glauben sie sei die einzige intelligente Lebensform im All. Wo nicht mal das nachhaltig bewiesen wurde.
|
|
ähM_Key 
      
Beiträge: 88
Windows XP Professional
D7 Enterprise
|
Verfasst: Di 08.11.05 16:39
Hm, es soll aber grade so sein, dass es nicht gelöscht wird. Aber du ganz Unrecht hast du auch nicht...ich hab's in die Initilaisierung mit reingenommen.
Ok, die Sache mit dem Negativen war wirklich etwas sinnlos...wieder so ne Sache, die ich einfach übernommen hatte
Das Verändern von GL_DEPTH_TEST vor und nach dem Dartsellen der Schrift hat auch nix gebracht...sie will einfach nicht erscheinen!
...hab mal das Proggi angehängt, wäre echt schön, wenn wir das noch hinbekommen würden!
Gruß, ähM_Key
Einloggen, um Attachments anzusehen!
_________________ Alles geht ni! Aber ein bissl' was muss!
|
|
|