Autor Beitrag
ähM_Key
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 88

Windows XP Professional
D7 Enterprise
BeitragVerfasst: 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 :roll:

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 :oops:

So, nun hier mein Quelltext...vielleicht seht ihr ja, was ich da falsch zusammengeschrieben habe ;)

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:
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;                        // Privátní GDI Device Context
  h_Wnd: HWND;                      // Obsahuje Handle našeho okna
  base: GLuint;                     // Èíslo základního display listu znakù
  cnt1: GLfloat;                    // Pro pohyb a barvu textu
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);               // Länge der pfd-Struktur
    nVersion  := 1;                         // Version
    dwFlags   := PFD_DRAW_TO_WINDOW or PFD_SUPPORT_OPENGL or
                 PFD_DOUBLEBUFFER;          // Flags
    iPixelType:= PFD_TYPE_RGBA;             // RGBA Pixel Type
    cColorBits:= 24;                        // 24-bit color
    cDepthBits:= 32;                        // 32-bit depth buffer
    iLayerType:= PFD_MAIN_PLANE;            // Layer Type
  end;
  nPixelFormat:= ChoosePixelFormat(myDC, @pfd);
  SetPixelFormat(myDC, nPixelFormat, @pfd);
                                            // Farbpalettenoptimierung wenn erforderlich
  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;                                          // Promìnná fontu
begin
  base := glGenLists(96);                                 // 96 znakù
  font := CreateFont(-24,                                 // Výška
                      0,                                  // Šíøka
                      0,                                  // Úhel escapement
                      0,                                  // Úhel orientace
                      FW_BOLD,                            // Tuènost
                      0,                                  // Kurzíva
                      0,                                  // Podtržení
                      0,                                  // Pøeškrtnutí
                      ANSI_CHARSET,                       // Znaková sada
                      OUT_TT_PRECIS,                      // Pøesnost výstupu (TrueType)
                      CLIP_DEFAULT_PRECIS,                // Pøesnost oøezání
                      ANTIALIASED_QUALITY,                // Výstupní kvalita
                      FF_DONTCARE or DEFAULT_PITCH,       // Rodina a pitch
                      'Courier New');                     // Jméno fontu
  SelectObject(h_dc,font);                                // Výbìr fontu do DC
  wglUseFontBitmaps(h_dc,32,96,base);                     // Vytvoøí 96 znakù, poèínaje 32 v Ascii
end;

procedure TForm1.glPrint(text: string);                                     <span style="color: red">- 7 -</span>
begin
  if text = '' then exit;                                 // Byl pøedán text?
  glPushAttrib(GL_LIST_BIT);                              // Uloží souèasný stav display listù
  glListBase(base - 32);                                  // Nastaví základní znak na 32
  glCallLists(length(text),GL_UNSIGNED_BYTE,Pchar(text)); // Vykreslí display listy
  glPopAttrib;                                            // Obnoví pùvodní stav display listù
end;

procedure TForm1.DrawGLScene;                                               <span style="color: red">- 6 -</span>
begin
 { glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);  // Smaže obrazovku a hloubkový buffer
  glLoadIdentity();                                      // Reset matice
  glTranslatef(0.0,0.0,-1.0);   }
                        // Pøesun o 1 do obrazovky

  glColor3f(0,0,1);  // Pulzování barev závislé na pozici
  glRasterPos2f(99, 199);          // Pozice textu
  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);                          // Povolí jemné stínování
  //glClearColor(0.0, 0.0, 0.0, 0.5);                  // Èerné pozadí
  //glClearDepth(1.0);                                // Nastavení hloubkového bufferu
  glEnable(GL_DEPTH_TEST);                          // Povolí hloubkové testování
  glDepthFunc(GL_LEQUAL);                            // Typ hloubkového testování
  glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST); // Nejlepší perspektivní korekce
  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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1048
Erhaltene Danke: 4



BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 88

Windows XP Professional
D7 Enterprise
BeitragVerfasst: Di 08.11.05 15:19 
user profile iconLossy 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.

user profile iconLossy 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.

user profile iconLossy 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?

user profile iconLossy 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.

user profile iconLossy 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! :D

Grüße; ähM_Key

_________________
Alles geht ni! Aber ein bissl' was muss!
Lossy eX
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1048
Erhaltene Danke: 4



BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 88

Windows XP Professional
D7 Enterprise
BeitragVerfasst: 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 :oops:

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!