Brainer Napisano Czerwiec 27, 2007 Zgłoś Share Napisano Czerwiec 27, 2007 Hej. Chcę sobie zrobić program, który renderowałby grafikę przy użyciu wątków za pomocą klasy TThread. Oto kodzik: { .: Brainer's OpenGL Framework :. Y [N ]Z][bG&6ćW6&Vvć6uusGGv6gGv&2ćźź((QĄąŃŃibute it and/or modify it under the terms of the GNU Les[[XXX[HXYHHYH&RfVćFFVFW fW'6\"bFRĆ6V6R\"ŃąŃ(((QĄątributed in the hope that it will be useful, but WITHOUTSHTSN]]][H[YY[HQTD$E\"dDU52d\"%D5T U%4R6VRFR9T1Aą1(Ńą))t UMain; interface {$WARNINGS OFF} {$HINTS OFF} [YY][X[726G&2f&2FĆw2VtWfG3Ś67@AM}M5==Y()Ń(QI QąQĄ(QIBTriangleThread = class(TThread) protected { ProtectedX][bYH^X]J NYN[D&VUVEF&VBD&VUVEF&VB6Ć72EF&V(ŃŃ(AŃŃąŃ(ecute(); override; end; { .: TMainForm :. } TMainFoHHĘJBX][][X][][&6VGW&Rf&FW7G&6VćFW#D&ŚV7B&6VGW&RfIĄMQ=( ŃĄMQbject); procedure ApplicationEventsIdle(Sender: TObject;NX[NYHTZ[ [X &fFP&fFRFV6Ć&F2&6VGW&RF&VćI Qą(I ąE(ą( { Public declarations } DC: HDC; RC: HGLRC; S[YKN[ [N[Y&6VGW&RćDVt&6VGW&R6WGWVf&BD3!(IM((MŃŃQg(); function GetTimeElapsed(): Single; procedure Di^QĘ[U[YN[JN[XZ[Nf&ÓG&ćvĆSE$t%G&ćvĆUF&VCVCD&VUVEF()ąŃŃ()H()QI QąQĄ procedure TRGBTriangleThread.Execute; begin while not TeZ[]YY[X][ÓYYĘ Nć6&ćŚRf&F&VćFW%$t%G&ćvĆRVćCŚVćCD&VEQĄ()Q ąEQĄŃ)(Ąe not Terminated do begin Application.ProcessMessages(N[^JXZ[K[YT]XY N[[Df&&6VGW&RDf&Ć6FWfVG4FĆR6VćFQ= ą)(ąŃQMą)n Done := False; deltaTime := GetTimeElapsed(); Displ^QĘ[U[YJN[[J N[YHXZ[F7Će267BFVFFS6ćvĆRŚ&Vv7F'EFćrALALŹźąŃQ(%ĄAM(ĄAM= FPS_SMOOVE) then begin FPSC := 0; FPS := (FPS / ÓSÓJN[HX] NX[ÓKH Kbg2b33e5e2ŁVćCŚVćC&6VGW&RDII Qą)(ąQąŃ-6.0); glBegin(GL_TRIANGLES); glColor3f(1.0, 0.0, 0.0)^K NK NfW'FW6bÓÓv6Ć#6bvfŃ(ą)()Q5DoRenderBlueQuad; begin glTranslatef(3.0, 0.0, 0.0); glCKKK NY[ÓUPQĘN^LvfW'FW6bvfW'FW6b(ąYŃ(ąend; procedure TMainForm.FormCreate(Sender: TObject); begin]YTX[Q]Y[JJNHHG&ćvĆRŁE$t%G&ćvĆUF&VB7&VFRG'VRVBŁ ąEQĄ ŃĄQ((ŃĄ!ą(MŃixelFormat(DC); RC := wglCreateContext(DC); wglMakeCurr[ ĘN[][Ó NX[K[YJ N]XYVRŚVćC&6VGW&RDf&f&FW7G&6VćFW#D&ŚV7B)(Qą(E)()Q5inForm.FormPaint(Sender: TObject); begin RenderScene(); enYHXZ[KT^J[X NY[vfWw'BvGFVvBvG&FRt$T5D8(ą1%ŃŃ(Ą!ĄŃĄ(!Ą1; gluPerspective(60.0, (Width / Height), 0.1, 100.0); gX]^[JÓÓSŃSQUĘN[[[XZ[K][YQ[6VC6ćvĆSf CCcCŚ&VvVW'W&f&ć6T6VFĄP(IąĄPMŃŃQź)()edure TMainForm.InitOpenGL; begin glClearColor(0.0, 0.0, 0 N[XJÓŃTT NXJÓĘNv7VĆf6Rt$4ŚVćC&6VGW&RDf&&VćFW%66Vć)(ą ąĄ1} =1=I} UI} %P1}AQ!} UI} %P; glLoadIdentity(); SwapBuffers(DC); end; procedure TMZ[K]^[X] ĘNVSPUU45$D\"6ŚS6ŚTbETd$DDU45$D\"Y(ąA}MUAA=IQ}=A90A}I]}Q=}INDOW or PFD_DOUBLEBUFFER; iPixelType: PFD_TYPE_RGN]Y]YYŃ&VV&G34w&VV6gC4&VT&G34&VU6gC(ąĄ ŃąĄMĄ( Ń(cAccumRedBits: 0; cAccumGreenBits: 0; cAccumBlueBitsX[P[P]Ń]M[[&G34W'VffW'3ĆW%GSdESI(15Ź(Yą5Ź( dwDamageMask: 0; ); var pixelFormat: Integer; begin ^[X]HT^[X] NY]^Vf&BD2Vf&BfBFVWCŚVćC&6VGWQ5MŃŃQ)(EA ŃĄMŃtTime); end; end. Czemu to nie działa? Jeśli wykonam ten kodzik bez użycia wątków, to wszystko śmiga elegancko. Z góry dzięki! .: Brainer :. patrick.nusbaum@gmail.com Link do komentarza Udostępnij na innych stronach More sharing options...
Toster Napisano Czerwiec 27, 2007 Zgłoś Share Napisano Czerwiec 27, 2007 moze zadam glupiue pytanie ale: co nie dziala ? po drugie z tego ce zerknalem uzywasz synchronize czyli de facto wszystko zwalnia bo masz tam waskie gardlo. Always Dark<br /> Link do komentarza Udostępnij na innych stronach More sharing options...
Brainer Napisano Czerwiec 27, 2007 Autor Zgłoś Share Napisano Czerwiec 27, 2007 CYTAT(Toster @ śro, 27 cze 2007 - 11:25) moze zadam glupiue pytanie ale: co nie dziala ? Nie działa renderowanie! Nic się nie wyświetla. po drugie z tego ce zerknalem uzywasz synchronize czyli de facto wszystko zwalnia bo masz tam waskie gardlo. W takim razie, podaj jakąś inną metodę na to, żeby to realizować wątkami. Może BeginThread? .: Brainer :. patrick.nusbaum@gmail.com Link do komentarza Udostępnij na innych stronach More sharing options...
Toster Napisano Czerwiec 27, 2007 Zgłoś Share Napisano Czerwiec 27, 2007 synchronize de facto zapewnia ci ze podana metoda zostanie wywolana z glownego watku, czyli jak masz 10 watkow ktore beda renderowac to tak naprawde ustawia sie one ladnie pod drzwiami i tylko jedne w jednej chwili bedzie renderowal inne beda czekac. Metod synchronizacji jest kilka: 1. Critical section 2. Semafory 3. Mutexy 4. Synchronize 5. Message i pewnie n o ktorych nie slyszalem. Aby zrobic wydajny system wielowatkowy nie wystarczy siasc i napisac kod uzywajac klasy obudowujacej watek, tylko trzeba najpierw wszystko zaprojektowac i dobrac architekture ktora najlepiej spelni swoje zadanie (trzeba tylko wiedziec co jest dla ciebie najwazniejsze) Inna sprawa ze karty maja kilka potokow renderujacych wiec proponowalbym poczytac o tym i uzyc mechnizmow ktore zostaly do tego stworzone i pod tym katem zoptymalizowane Always Dark<br /> Link do komentarza Udostępnij na innych stronach More sharing options...
Brainer Napisano Czerwiec 27, 2007 Autor Zgłoś Share Napisano Czerwiec 27, 2007 Hehe, dzięki za odpowiedź! Przeczytałem na GameDev.net, że OpenGL nie jest bezpieczne wątkowo (thread-safe), czyli dwa wątki nie mogą wywoływać poleceń OpenGL. Z drugiej strony, jeden z userów napisał, że możliwa jest synchronizacja wątków przy pomocy sekcji krytycznych. Prawdę powiedziawszy, nigdy wcześniej nie próbowałem używać wątków bez korzystania z klasy TThread i funkcji BeginThread. Chyba najwyższy czas spróbować. Przy okazji, masz jakieś tutoriale na temat sekcji krytycznych? Obojętnie czy w Delphi, czy w C++. Znam oba. Gdzieś kiedyś miałem książkę, w której było napisane o tych sekcjach (bodajże Delphi 6. Vademecum profesjonalisty). Muszę zerknąć... Dzięki za odpowiedź, Toster! .: Brainer :. patrick.nusbaum@gmail.com Link do komentarza Udostępnij na innych stronach More sharing options...
Toster Napisano Czerwiec 27, 2007 Zgłoś Share Napisano Czerwiec 27, 2007 no problem. Z sekcjami krytycznymi nie ma wielkiej tajemnicy, zerknij do helpa sa dobrze opisane, przeczytalem i od razu zalapalem, wiec nie sadze abys mial z tym problemy. Always Dark<br /> Link do komentarza Udostępnij na innych stronach More sharing options...
KKKas Napisano Czerwiec 27, 2007 Zgłoś Share Napisano Czerwiec 27, 2007 Przepraszam, ale jaki sens ma Application.ProcessMessages(); w wątku (innym niż główny) ? ҉ Link do komentarza Udostępnij na innych stronach More sharing options...
Brainer Napisano Czerwiec 27, 2007 Autor Zgłoś Share Napisano Czerwiec 27, 2007 Przepraszam, ale jaki sens ma Application.ProcessMessages(); w wątku (innym niż główny) ? To polecenie pozwala przetworzyć komunikaty wysyłane do okienka. Kiedyś gdzieś widziałem użycie tego polecenia w wątkach pobocznych. Ale ja też nie widzę sensu jego użycia. .: Brainer :. patrick.nusbaum@gmail.com Link do komentarza Udostępnij na innych stronach More sharing options...
Toster Napisano Czerwiec 27, 2007 Zgłoś Share Napisano Czerwiec 27, 2007 sleep powinno byc ale nie chcialo mi sie o tym pisac (lenia dzisiaj mam) Always Dark<br /> Link do komentarza Udostępnij na innych stronach More sharing options...
Brainer Napisano Czerwiec 27, 2007 Autor Zgłoś Share Napisano Czerwiec 27, 2007 sleep powinno byc ale nie chcialo mi sie o tym pisac (lenia dzisiaj mam) Hehe. Jak widać, mam małe doświadczenie w wątkach. Ale czemu Sleep? .: Brainer :. patrick.nusbaum@gmail.com Link do komentarza Udostępnij na innych stronach More sharing options...
Toster Napisano Czerwiec 27, 2007 Zgłoś Share Napisano Czerwiec 27, 2007 bo glowny watek jak nie jest w procce to w idlu sam pobiera message. A watki poboczne nie musza mu w tym pomagac. Pozatym nie dajac sleepa watkowi zamulasz mocno ssytem i nie dajesz czasu innym watka aby sobie poszalaly Tak czy siak w glownej pewli watkow zazwyczaj daje sie jakiegos malego sleepa np 10-50 ms. Zalezy tez do czego waki sa, bez sensu np mielic 100% CPU na watku ktory czeka na polaczenie sieciowe, mozesz go uspic na 100ms a pozniej sprawdzic czy cos sie zmienilo, jesli tak to zaczac cos robic jesli nie to znowu idziesz spac. czesto jest tak ze jeden watek czeka az sie cos wydarzy (np drugi watek cos skonczy, albo na dostep do jakis zasobow) w tym czasie moze sie spokojnie przekimac zanim ponowi probe. Always Dark<br /> Link do komentarza Udostępnij na innych stronach More sharing options...
KKKas Napisano Czerwiec 27, 2007 Zgłoś Share Napisano Czerwiec 27, 2007 To polecenie pozwala przetworzyć komunikaty wysyłane do okienka. Kiedyś gdzieś widziałem użycie tego polecenia w wątkach pobocznych. Ale ja też nie widzę sensu jego użycia. Wiem, co wykonuje ProcessMsgs. Ale w wątku to IMO nie ma kompletnie sensu. 1. Jeśli nie synchronizujesz niczego przez TThread.Synchronize(), to wątek główny i tak się wykonuje więc sam przetwarza komunikaty. 2. Jeśli synchronizujesz, to i tak ProcessMsgs nic nie da w tym miejscu. Prędzej gdzieś w procedurze synchronizowanej. No, ale to OT ;-) EDIT: Spóźniłem się ;-) ҉ Link do komentarza Udostępnij na innych stronach More sharing options...
Brainer Napisano Czerwiec 27, 2007 Autor Zgłoś Share Napisano Czerwiec 27, 2007 Ja tam się rzadko bawie w wątki. Teraz chciałem spróbować renderowania wielowątkowego, bo w moim silniczku chcę umożliwić właśnie takie wyświetlanie grafiki. Sądziłem, że to będzie o wiele prostsze. A tu muszę się zagłębiać w wątki. .: Brainer :. patrick.nusbaum@gmail.com Link do komentarza Udostępnij na innych stronach More sharing options...
KKKas Napisano Czerwiec 27, 2007 Zgłoś Share Napisano Czerwiec 27, 2007 Co do wątków, to tu są ważne informacje: http://www.delphi.org.pl/zlot/2000/po/mate...wyk_swiatkowski a dokładnie tu: http://www.delphi.org.pl/zlot/2000/po/x_ma...wski_wyklad.zip ҉ Link do komentarza Udostępnij na innych stronach More sharing options...
Polecane posty
Zarchiwizowany
Ten temat jest archiwizowany i nie można dodawać nowych odpowiedzi.