Entwickler-Ecke

Multimedia / Grafik - OpenGL + Szene erscheint nicht


M. Raab - Sa 23.11.02 16:46
Titel: OpenGL + Szene erscheint nicht
Hallo NG,

ich habe folgendes OPENGL Problem - hier der Code:

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:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
227:
228:
229:
//*******************************************************************
 procedure DrawScene;
   var lauf1 : integer;
       lauf2 : integer;
   begin
     lauf2:=1;
        // Erstellung der Szene
     glviewport(0,0,ebene.width,Ebene.height);
     glclear(GL_color_buffer_bit or gl_depth_buffer_bit);
     glbegin(gl_line_strip);
     for lauf1:=1 to BLMPMAX do
       begin
         if BLI[lauf1]=lauf2 then
           begin
             glvertex3f(D3x[lauf1],D3y[lauf1],D3z[lauf1]);
           end else begin
             glend;
             glbegin(gl_line_strip);
             glvertex3f(D3x[lauf1],D3y[lauf1],D3z[lauf1]);
             lauf2:=lauf2+1;
           end;
       end;
     glend;
     swapbuffers(DC);
     glflush();
  end;
//*******************************************************************



//*******************************************************************
procedure T3D.MausMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  if ssleft in shift then begin
   if x<mausx then  // Bewegung nach rechts
     begin
       wglMakeCurrent(dc,HRC);
       glrotate(2,0,1,0);
       drawscene;
       wglMakeCurrent(0,0);
       mausx:=x;
     end;
   if x>mausx then  // Bewegung nach links
     begin
       wglMakeCurrent(dc,HRC);
       glrotate(-2,0,1,0);
       drawscene;
       wglMakeCurrent(0,0);
       mausx:=x;
     end;
   if y>mausy then  // Bewegung nach unten
     begin
       wglMakeCurrent(dc,HRC);
       glrotate(-2,1,0,0);
       drawscene;
       wglMakeCurrent(0,0);
       mausy:=y;
     end;
   if y<mausy then  // Bewegung nach oben
     begin
       wglMakeCurrent(dc,HRC);
       glrotate(2,1,0,0);
       drawscene;
       wglMakeCurrent(0,0);
       mausy:=y;
     end;
  end;

end;
//*******************************************************************

//*******************************************************************
procedure T3D.D3AUS(Sender:TObject);
  begin
    if D3Form<>nil then
      begin
        wglDeleteContext(DC);
        D3Form:=nil;
      end;
  end;
//*******************************************************************


//*******************************************************************
procedure T3D.MausDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin

  mausx:=x;
  mausy:=y;

end;
//*******************************************************************


//*******************************************************************
procedure SetDCPixelFormat(Handle:HDC);
   var pfd          : TPixelFormatDescriptor;
       npixelformat : Integer;
   begin
     fillchar(pfd,sizeof(Pfd),0);
     with pfd do
       begin
         nsize:=sizeof(pfd);
         nVersion:=1;
         dwflags:=pfd_draw_to_window or pfd_support_opengl;
//         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(Handle,@pfd);
     setpixelformat(Handle,npixelformat,@pfd);
   end;
//*******************************************************************



//*******************************************************************
procedure D3Animation;
 Var  varx,vary,varz : array of double;


    procedure normierung;
      Var minx    : double;
          maxx    : double;
          miny    : double;
          maxy    : double;
          minz    : double;
          maxz    : double;
          lauf1   : integer;
      begin


        mausx:=0;
        mausy:=0;

        minx:=9999999999;
        miny:=9999999999;
        minz:=9999999999;
        maxx:=-9999999999;
        maxy:=-9999999999;
        maxz:=-9999999999;


        //Normierung der 3D Vermessungsdaten auf ein -1/1 Niveau
        for lauf1:=1 to BLMPMAX do
          begin
            if BLX[lauf1]<minx then minx:=BLX[lauf1];
            if BLY[lauf1]<miny then miny:=BLY[lauf1];
            if BLZ[lauf1]<minz then minz:=BLZ[lauf1];
            if BLX[lauf1]>maxx then maxx:=BLX[lauf1];
            if BLY[lauf1]>maxy then maxy:=BLY[lauf1];
            if BLZ[lauf1]>maxz then maxz:=BLZ[lauf1];
          end;


        for lauf1:=1 to BLMPMAX do
          begin
            D3X[lauf1]:=(((BLX[lauf1]-minx)/(maxx-minx))*1.4)-0.7;
            D3Y[lauf1]:=(((BLY[lauf1]-miny)/(maxy-miny))*1.4)-0.7;
            D3Z[lauf1]:=(((BLZ[lauf1]-minz)/(maxz-minz))*1.4)-0.7;
          end;
    end;


 begin

  setlength(D3x,BLMPMAX+1);
  setlength(D3y,BLMPMAX+1);
  setlength(D3z,BLMPMAX+1);

  application.createform(TForm,D3Form);
  with D3Form do
      begin
        Caption:='3D Ansicht von: '+form1.label7.caption;
        autosize:=false;
        borderstyle:=bssingle;
        clientheight:=550;
        clientwidth:=750;
        constraints.maxheight:=600;
        constraints.maxwidth:=800;
        constraints.minheight:=600;
        constraints.minwidth:=800;
        cursor:=crHandPoint;
        position:=poscreencenter;
        windowstate:=wsminimized;
        ondestroy:=D3aus;

        ebene:=TPanel.create(D3Form);
        ebene.parent:=D3Form;
        ebene.top:=5;
        ebene.left:=20;
        ebene.cursor:=crhandpoint;
        ebene.visible:=true;
        ebene.height:=550;
        ebene.width:=750;
        ebene.enabled:=true;
        ebene.onmousedown:=mausdown;
        ebene.onmousemove:=mausmove;


        Normierung;
        show;
      end;

//    Set8087CW($133f);  { Alle FPU-Exceptions deaktivieren }
  DC:=GetDC(Ebene.Handle);
  SetDCPixelFormat(dc);
  HRC:=wglCreateContext(dc);
  wglMakeCurrent(dc,HRC);
  drawscene;
  wglMakeCurrent(0,0);

  ---> kurz vor Ausführung der ENDE Anweisung ist die Szene da, mit Ausführung von "end" verschwindet sie.

end;
//*******************************************************************


//*******************************************************************
procedure TForm1.Button10Click(Sender: TObject);
  begin
    D3Animation;
  end;
//*******************************************************************

Auf einem Formblatt habe ich einen Button (Button10) - beim Klick auf den Button wird zur Laufzeit das Formblatt D3FORM und das Panel EBENE erzeugt. Ich habe mit dem Debugger das Programm untersucht und stellte fest, dass die Szene auf dem Panel vorhanden ist bis zu dem obigen Schritt (den ich in der Routine D3ANIMATION gekennzeichnet habe). Sobald die Prozedur mit "end" abgeschlossen ist, wird die Szene gelöscht. Sobald ich aber mit der gedrückten Maustaste drauf klicke und bewege, ist sie da und bleibt da. Wenn ich die Szene nicht auf das Panel lege sondern auf das Formblatt selber, tritt dieser Effekt nicht auf. Da ich aber noch Buttons drauf legen will, wäre mir das Panel lieber, da ich dann noch Platz auf dem Form habe.

Noch ein Effekt: verschiebe ich das Fenster mit der Szene über den Rand des Bildschrims, so dass ein Teil des Fensters nicht sichtbar ist und schiebe dann das Fenster mit der Szene zurück, ist der vorher nicht sichtbare Teil der Szene verschwunden und erscheint erst wieder, wenn ich die MAus bewege und damit neu zeichne.

Letzteres Problem - nun ja, damit kann ich leben.

Aber Problem Nr. 1 -> Hat da jemand ne Lösung parat ???

Gruß

Markus :D :D :D :o :o

(16.12. 09:15 Tino) Code-Tags hinzugefügt.


Aya - Di 26.11.02 21:56

Hi,

also ich hab deinen QuellCode zwar nicht wirklich angeguckt.. aber, zeichnest du die Szene bei jedem OnDraw der Form neu?? Wenn nicht, das solltest du tun... :)

ansonsten kannst du auch einfach das Panel weglassen und dem OpenGL Fenster nur einen bereich deiner Form zuweisen, mußt ja nicht das komplette fenster füllen.

Au'revoir,
Aya


M. Raab - Sa 14.12.02 12:51

Hallo,

danke - jetzt funzts ...

Gruß
Markus


Moritz M. - So 15.12.02 10:01

Hi

Ich hab OpenGl auch mal versucht, dann bin Ich aber auf GlScene umgestiegen(umgestigen stimmt eigentlich nicht;Ich hab mir nur die Komponente zurgezogen)
Und mit GlScene wird alles einfacher!!
Lads dir mal und versuchs mal:
http://www.glscene.org


M. Raab - So 15.12.02 13:04

Hallo,

GLScene --- kenn ich nur vom Namen her. Gibt es da ein Skript um es mal zu lernen/lesen/schnuppern ?

Gruß
Markus


Moritz M. - So 15.12.02 13:17

Lads dir mal runter und installiers. Dann kannst du dir die Demos anschaun. Wenn du willst kann ich dir auch ein kleines EInsteigerprog schicken, musst halt zuerst die Komponenten installiert haben.


Aya - So 15.12.02 19:05

Hi,

also ich bin kein Fan von GLScene.... sicherlich wird vieles einfacher damit, nur... Nun ja, ich bleibe bei meiner "OpenGL.pas"... auch wenn es OpenGL12 etc schon gibt :)

Warum? Wenn ich sowas wie GLScene, DelphiX oder ähnliches nutze, bekomme ich zwar schnell einiges damit hin, nur.... wo ist die kunst dabei?

Wenn ich was mache, möchte ich das gefühl haben, das habe ICH gemacht... und nich, ich hab es einfach zusammen geklickt oder sowas :roll:

Aber, is jedem selbst überlassen *g*

Au'revoir,
Aya~


M. Raab - Mo 16.12.02 10:06

Hallo Aya, Hallo Onz,

an Hand Deiner Beiträge habe ich bemerkt, dass Du tief in OPenGL steckst. Es ist eine Abwägungssache, was ich mache. Ich arbeite mit OPenGL noch nicht so lange - aber einfachere Lösungen wären manchmal nicht schlecht. Also ich würde mich freuen, wenn ich GLScene mal ansehen könnte.

Also wenn Du mir sagst, wo man es ziehen kann bzw. mir zusenden (mr.software@gmxpro.de), wäre ich dankbar.

Gruß

Markus


Aya - Mo 16.12.02 12:51

huhu :)

http://www.glscene.org wenn mich nich alles täuscht.

Au'revoir,
Aya~


torstenheinze - Mi 01.01.03 19:44

jo, da hab ich das auch her, doch ich nutze das eigendlich net :wink2:


Moritz M. - Mi 01.01.03 20:03

Ja, wie Aya schon sagt..ähmm..schreibt, http://www.glscene.org und hier wäre auch der direkte downloadlink: http://switch.dl.sourceforge.net/sourceforge/glscene/GLScene_v09b_Full.zip

M.Raab hat folgendes geschrieben:
an Hand Deiner Beiträge habe ich bemerkt, dass Du tief in OPenGL steckst.

Wen von beiden meinst du?

Wenn du Probleme mit OpenGL hast oder nicht weißt, wo anfangen, dann schreib mir halt irgendwie(ICQ,MSN,PM,Email,Y!,staht alles im Profil)


M. Raab - So 05.01.03 14:05

Hallo Onz,

vielen Dank für Deine Hilfe - langsam aber sicher nähere ich mich an OPENGL an - zumindest bilde ich mir das ein. Ich habe unter

http://www.delphigl.com/

ein gutes Forum gefunden. Ich denke jedoch, die
nerve ich langsam. Dort findet man aber ein RedBook (englisch) und ne Menge TUTs und Samples. Das Problem ist, dass man sich alles selber beibringen muss und man das alles natürlich schon gestern können möchte. Ideal wäre ein Forum, in dem blutige Anfänger wie ich :? an das Thema systematisch (die Betonung liegt auf systematisch) ran geführt werden. Man sucht und sucht ... und stopselt sich dann selber was zusammen.

Nun ja, bei mir wird es besser.

Gruss


Markus


OregonGhost - So 05.01.03 14:41

Ich weiß nicht, ob ich's vielleicht nur überlesen hab', aber die Standard-Einsteiger-Seite ist meiner Meinung nach http://nehe.gamedev.net. Dort wird dir fast alles von vorne erklärt, und das für alle Betriebssysteme.
Auf der Mutterseite findest du auch das Redbook, und wenn ich mich nicht irre auch das Bluebook.


Moritz M. - So 05.01.03 15:43

Hi

Wie schon gesagt, einfacher ist OpenGl.
Ab besten liest du dir folgendes in dieser reihenfolge durch:
1)http://www.phobeus.de/hosting/dgl/main.php?id=2&page=tutorial&tut=lesson2&head=lesson2
2)http://www.phobeus.de/hosting/dgl/main.php?id=2&page=tutorial&tut=lesson3&head=lesson3
Die Befghele kannst du jeweils weglassen, die ändern sich in glscene.
Wenn du die beiden Verstanden hast ist der erste große Schritt hinter dir.
Dann meldest du dich bei mir und ich schick dir ein sehr gut kommentiertes Prog zu, mit dem du dann den Einstig in GlScene wagen kannst.
Wenn du vorhasten sachen in OpenGl zu schrieben, dann kannst du dich auf fröhliches Tippen in einer unübersichtlichen Welt freuen.
Ex0rzist hat folgendes geschrieben:
Also ich kann dir OpenGL nur wärmstens empfehlen. Das ist relativ leicht zu verstehen. Ich hatte mir auch mal DirectX angeschaut, aber mich dann relativ schnell fürOpenGL entschieden.

2D-Programmierung wird in OpenGL nur teilweise unterstützt. Es ist halt eine 3D-Sprache. Wenn du aber dennoch in 2D arbeiten willst, kannst du auch überall einfach nur die Z-Koordinate null setzen. Das ist dann Pseudo-2D. In Diablo haben sie das, glaube ich, auch so gemacht.

Anstatt GLScene zu verwenden, würde ich zu Anfang nur OpenGL nehmen, um erstmal ein Grundverständnis der Materie zu bekommen.

Wenn man sich durch alle Tuts durchgearbeitet hat, geht der Rest nachher fast von allein.


Das stammt aus diesem Thema:http://auq.de/viewtopic.php?t=3767
Lies dir das Thema mal durch und entscheide dich dann für OpenGL oder GlScene, wobei GlScene das ganze halt mächtig erleichtert.