03. september 2002 - 13:54Der er
12 kommentarer og 1 løsning
Assembler
Jeg har et stykke kode i Delphi der virker ok, men jeg vil gerne have at det skal gaa endnu hurtigere! Den samme stykke kode oversat til C++ gaar nemlig meget hurtigere i en C kompiler. Saa jeg taenkte at maaske kunne det loses med noget Assembler kode der bliver implementeret i Delphi. Hvad tror I? og er der en assembler-haj der kan hjaelpe mig med at oversaette koden? Her er koden:
type TNewContext = record dc: hdc; rc: hglrc; end;
function SetupOpenGL(dc : hdc; rc : hglrc; form : Tform; zNear, zFar : single) : TNewContext; var pfd: TPixelFormatDescriptor; i : integer; begin fillchar(pfd,SizeOf(pfd),0); with pfd do begin nsize := sizeof(pfd); nversion := 1; dwflags := pfd_support_opengl or pfd_draw_to_window or pfd_doublebuffer; ipixeltype := pfd_type_rgba; ccolorbits := 24; cdepthbits := 32; cstencilbits := 0; ilayertype := pfd_main_plane; end; dc := getdc(form.handle); i := choosepixelformat(dc,@pfd); if i = 0 then exit; if not setpixelformat(dc,i,@pfd) then exit; rc := wglcreatecontext(dc); if rc = 0 then exit; if not wglmakecurrent(dc,rc) then exit; glMatrixMode(gl_Projection); with form do glFrustum(-1.0, +1.0, -(clientheight/clientwidth), clientheight/clientwidth, zNear, zFar); result.dc := dc; result.rc := rc; end;
du får _intet_ udaf at optimere det ovenstående (c) kode. du skulle hellere optimere renderings koden.. - selvf. forudsat at du bruger initialiseringen af opengl til noget :-)
Det lyder ikke rigtigt, at din C kode skulle køre hurtigere en din Delphi kode - ikke iflg. det du har postet. Der er intet i den kode, der vil kunne give større hastighed, hvis det blev håndkodet i asm.
Flaskehalsen må ligge i en af de rutiner du kalder..
Men det gor den altsaa!!! Jeg tror at det haenger sammen med den maade at Delphi kompiler sin kode paa! Saa, hvis man kunne lave sin egen Assembler kode (mere direkte rutine), saa tror jeg at det vil kunne lykkes!!! I virkligheden tror jeg at det er fordi at Delphi er en High-Level sprog og C er en mere Low-Level sprog (maaske er jeg helt forkert paa den, saa ret mig venligst hvis jeg total har misforstaaet noget) Jeg har selvfolgelig ogsaa taenkt paa at "Flaskehalsen" maaske ligger omkring ved selve renderings rutinen. Men jeg har dog stadig den teori at jo hurtigere (fleksible) en RenderContext er jo hurtigere vil det vaere for glClearColor(), glClear() og glSwapBuffers() osv. at blive anvendt!!!
både delphi/pascal og c/c++ er high-level sprog (3. generation) assembler er 2. generation mikro kode er 1. generation
mit gæt er du har et bug et eller andet sted i din kode - et sted du ikke forventer det. hvad med at prøve at smide nogle MEssageBoxes ind strategiske steder, og på den måde finde udaf hvilken linie der giver problemet, altså mellem hvilke 2 messageboxes tager det lang tid. altså: .. MessageBox("Lige før wgl_cc"); rc := wglcreatecontext(dc); if rc = 0 then exit;
MessageBox("Lige før wgl_mc"); if not wglmakecurrent(dc,rc) then exit; ..
Hmm... Maaske du misforstaar mig lidt. Jeg har arbejdet med OpenGL i et stykke tid og altid har det hojeste FPS vaeret paa omkring 74 paa en WinNT (250 paa en Win32). Hvor imod, hvis man bruger C/C++ skulle kunne opnaa 250 FPS uanset, hvilken Windows platform man benytter. Jeg er glad for at faa rettet min opfattelse og faa vide at Delph og C++ begge er high-level sprog, men jeg er dog stadig bange for at det maaske er Delphi's kompiler der er aarsagen. Er der en der vil gore mig den tjenste, at bruge begge stykke koder (C++ og Delphi) og smide et ekstra stykke kode ind der viser FPS i formens caption og kompile dem derefter sende exe filen til info@opengl-delphi.dk ....
Når jeg koder i OpenGL bruger jeg følgende kode, skal dog ikke kunne sige om den kører hurtigere i NT, eller sågar i win32, end den du bruger, har ikke NT så kan ikke teste, men kan da tænkes :
// Settings for the OpenGL window with pfd do begin nSize := SizeOf(TPIXELFORMATDESCRIPTOR); // Size Of This Pixel Format Descriptor nVersion := 1; // The version of this data structure dwFlags := PFD_DRAW_TO_WINDOW // Buffer supports drawing to window or PFD_SUPPORT_OPENGL // Buffer supports OpenGL drawing or PFD_DOUBLEBUFFER; // Supports double buffering iPixelType := PFD_TYPE_RGBA; // RGBA color format cColorBits := PixelDepth; // OpenGL color depth cRedBits := 0; // Number of red bitplanes cRedShift := 0; // Shift count for red bitplanes cGreenBits := 0; // Number of green bitplanes cGreenShift := 0; // Shift count for green bitplanes cBlueBits := 0; // Number of blue bitplanes cBlueShift := 0; // Shift count for blue bitplanes cAlphaBits := 0; // Not supported cAlphaShift := 0; // Not supported cAccumBits := 0; // No accumulation buffer cAccumRedBits := 0; // Number of red bits in a-buffer cAccumGreenBits := 0; // Number of green bits in a-buffer cAccumBlueBits := 0; // Number of blue bits in a-buffer cAccumAlphaBits := 0; // Number of alpha bits in a-buffer cDepthBits := 16; // Specifies the depth of the depth buffer cStencilBits := 0; // Turn off stencil buffer cAuxBuffers := 0; // Not supported iLayerType := PFD_MAIN_PLANE; // Ignored bReserved := 0; // Number of overlay and underlay planes dwLayerMask := 0; // Ignored dwVisibleMask := 0; // Transparent color of underlay plane dwDamageMask := 0; // Ignored end;
// Attempts to find the pixel format supported by a device context that is the best match to a given pixel format specification. PixelFormat := ChoosePixelFormat(h_DC, @pfd); if (PixelFormat = 0) then begin glKillWnd(Fullscreen); MessageBox(0, 'Unable to find a suitable pixel format', 'Error', MB_OK or MB_ICONERROR); Result := False; Exit; end;
// Sets the specified device context's pixel format to the format specified by the PixelFormat. if (not SetPixelFormat(h_DC, PixelFormat, @pfd)) then begin glKillWnd(Fullscreen); MessageBox(0, 'Unable to set the pixel format', 'Error', MB_OK or MB_ICONERROR); Result := False; Exit; end;
// Create a OpenGL rendering context h_RC := wglCreateContext(h_DC); if (h_RC = 0) then begin glKillWnd(Fullscreen); MessageBox(0, 'Unable to create an OpenGL rendering context', 'Error', MB_OK or MB_ICONERROR); Result := False; Exit; end;
// Makes the specified OpenGL rendering context the calling thread's current rendering context if (not wglMakeCurrent(h_DC, h_RC)) then begin glKillWnd(Fullscreen); MessageBox(0, 'Unable to activate OpenGL rendering context', 'Error', MB_OK or MB_ICONERROR); Result := False; Exit; end;
skal lige siges jeg ikke selv har skrevet, har kun selv hugget det fra Sulaco... Men du har self. link til på din side, så mon ikke du egentlig har set koden før...
Det er vist på tide at jeg får lukket her!!! Jeg har ikke rigtigt fået et endeligt svar, så jeg tager pointsene tilbage. Håber ikke at det giver sure miner!
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.