![]() |
Direkt auf Bitmap zeichnen (OpenGL)
Ich rendere meine Plugins auf das DC von meinem Window. (Das Flackert aber ohne spezielle tricks)
Jetzt möchte ich aber direkt auf ein Bitmap zeichnen wie muss ich den CreateRenderingContext erstellen damit dieser erkennt das ich auf ein Bitmap zeichnen will? Das HBitmap wird von außerhalb übergeben.
Delphi-Quellcode:
verwende ich jetzt
glDC := GetDC(WinHandle);
// Renderkontext erstellen (32 Bit Farbtiefe, // 32 Bit Tiefenpuffer, Doublebuffering) h_RC := CreateRenderingContext(glDC, [opDoubleBuffered], 24, 32, 0, 0, 0, 0);
Delphi-Quellcode:
glDC := CreateCompatiblemDC(GetDC(WinHandle));
Dann wird im CreateRenderingContext erkannt das ich ein Bitmap anstelle eines Fenster verwenden will. Aber es rendert nichts. Fehler gibt es aber auch nicht. crosspost: ![]() gruss |
AW: Direkt auf Bitmap zeichnen (OpenGL)
Emil,
mit der Menge an Information kann man schwerlich helfen. Wie machst Du den RC Current, wie wird gezeichnet......... Flush, Finish, swap buffers etc....... |
AW: Direkt auf Bitmap zeichnen (OpenGL)
CreateRenderingContext..
Delphi-Quellcode:
gezeichnet wird so..
glDC := GetDC(WinHandle);
// Renderkontext erstellen (32 Bit Farbtiefe, // 32 Bit Tiefenpuffer, Doublebuffering) h_RC := CreateRenderingContext(glDc, [opDoubleBuffered], 24, 32, 0, 0, 0, 0); // Erstellten Renderkontext aktivieren ActivateRenderingContext(glDc, h_RC, True);
Delphi-Quellcode:
Bedingt durch diese Zeile teile ich dem CreateRenderingContext mit das ich auf ein Window zeichnen will das möchte ich aber nicht.
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT); glLoadIdentity(); EnterCriticalSection(CritSect); try glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, StretchWidth, StretchHeight, GL_BGRA, GL_UNSIGNED_BYTE, VisInfo^.VisBuf); finally LeaveCriticalSection(CritSect); end; glColor4f(1, 1, 1, 1); glEnable(GL_TEXTURE_2D); if VisTexture <> 0 then glBindTexture(GL_TEXTURE_2D, VisTexture); glBegin(GL_QUADS); glTexCoord2d(0.0, 0.0); glVertex2f(0.0, 0.0); glTexCoord2d(0.0, 1.0); glVertex2f(0.0, LastHeight); glTexCoord2d(1.0, 1.0); glVertex2f(LastWidth, LastHeight); glTexCoord2d(1.0, 0.0); glVertex2f(LastWidth, 0.0); glEnd(); if length(BassSoInfo.SongTitle) > 0 then begin BassSoVis.SongRender; if SON_ShowFPS then BassSoVis.GetFramesInSec; if SON_ShowPrgBar then begin SON_Current_YPos := 20; ProgressBarRender; end else SON_Current_YPos := 5; end; glFlush; SwapBuffers(glDC); end;
Delphi-Quellcode:
glDC := GetDC(WinHandle);
also gibt es nur die Möglichkeit das DC auf andere weise zu erstellen. Über...
Delphi-Quellcode:
Sollte stimmen das Problem ist nur es rendert nicht.
glDC := CreateCompatibleDc(0);
SelectObject(glDC, MeinÜbergebenesBitmap); In der Function CreateRenderingContext wird dann abhängig von der Erstellung des DC (MemoryDC, WindowDc.. usw..) das entsprechende Flag gesetzt.
Delphi-Quellcode:
Aber wie gesagt es tut sich nichts.
if GL_LibHandle = nil then
InitOpenGL; FillChar(PFDescriptor, SizeOf(PFDescriptor), 0); with PFDescriptor do begin nSize := SizeOf(PFDescriptor); nVersion := 1; dwFlags := PFD_SUPPORT_OPENGL; AType := GetObjectType(DC); if AType = 0 then RaiseLastOSError; if AType in MemoryDCs then dwFlags := dwFlags or PFD_DRAW_TO_BITMAP else dwFlags := dwFlags or PFD_DRAW_TO_WINDOW; Im Moment mache ich es so das ich auf das DC meiner Haupt Anwendung zeichne und den Canvas auf die korrekte Position verschiebe. Logischerweise ist das Fenster nicht sichtbar, es rendert zwar aber man sieht es nicht. Deshalb wende ich einen Trick an in dem ich das darüberliegende Fenster einfach mit dem WS_EX_LAYERED Style versehe und den Alpha Kanal auf 160 einstelle. Nur dann sind die Schriften etwas verblasst, was ich umgehen möchte indem ich direkt auf das Bitmap zeichne. (siehe Pic) Direkt auf das Hauptfenster zeichnen Funktioniert nicht das Flackert extrem deshalb der Umweg über das Bitmap. (WM_ERASEBKGND) macht hier Probleme. gruss |
AW: Direkt auf Bitmap zeichnen (OpenGL)
Zitat:
![]() |
AW: Direkt auf Bitmap zeichnen (OpenGL)
Zitat:
Das ist ja mein Problem :) Was soll ich unternehmen um das DC mit dem device context zu verbinden? Das Bitmap kann nicht zerstört werden es wird von außen zugeführt und ist solange gültig wie die Anwendung läuft. Das einzige was verloren geht ist das DC.. nach jedem
Delphi-Quellcode:
Ich könnte vor glClearColor das DC neu zuweisen und selektieren.. was anderes fällt mir da jetzt nicht ein.
glFlush;
SwapBuffers(glDC);
Delphi-Quellcode:
PS:
glDC := CreateCompatibleDc(0);
SelectObject(glDC, MeinÜbergebenesBitmap); Bitmap erstellen..
Delphi-Quellcode:
Dieses wird in meiner Lib intern gespeichert und kann damit zurückgeholt werden..
if gBin.UsePlugin then
begin sFile := SpriteResPath + 'plugin.png'; if FileExists(sFile) then gSprDisplayC.GI_SetFromFile(HSprDisplayC, PWideChar(sFile)) end else gSprDisplayC.GI_SetFromFile(HSprDisplayC, gG.PhoneBackground); Mein Container und dessen Handle mit dem das Bitmap erstellt wurde. (Typ Bitmap)
Delphi-Quellcode:
gSprDisplayC.GI_GetProperty(HSprDisplayC, GI_BITMAP);
Jetzt übergeben ich das an meinen BassVis Wrapper..
Delphi-Quellcode:
mExec.Pluginfile := PAnsiChar(Filename);
mExec.SON_ConfigFile := PAnsiChar(PluginDir + 'vis.ini'); mExec.SON_UseOpenGL := true; mExec.SON_ParentHandle := HSprDisplayC; mExec.SON_ViewportWidth := 1024; mExec.SON_ViewportHeight := 800; mExec.SON_ShowPrgBar := false; mExec.SON_ShowFPS := false; mExec.SON_UseCover := false; mExec.SON_PaintHandle := gSprDisplayC.GI_GetProperty(HSprDisplayC, GI_BITMAP); // hier das Bitmap mExec.Left := 0; mExec.Top := 0; mExec.Width := Rect.Right; mExec.Height := Rect.Bottom;
Delphi-Quellcode:
In der DLL erstelle ich das DC
Base.VisHandle := BASSSoVisAPI.SONIQUEVIS_CreateVis(Param^.PluginFile,
Param^.SON_ConfigFile, Param^.Left, Param^.Top, Param^.Width, Param^.Height, Param^.SON_ParentHandle, Param^.SON_ViewportWidth, Param^.SON_ViewportHeight, Param^.SON_ShowPrgBar, Param^.SON_ShowFPS, Param^.SON_UseCover, Param^.SON_PaintHandle, Param^.SON_UseOpenGL);
Delphi-Quellcode:
nur damit ich über CreateRenderingContext die richtigen Flags bekomme.
function TBASSSoVis.IntMeinGL(WinHandle: HWND): BOOL;
var IntI, IntJ: integer; begin // OpenGL-Funtionen initialisieren Result := False; try LastWidth := 0; LastHeight := 0; if not InitOpenGL then Halt; glDC := CreateCompatibleDc(GetDC(WinHandle)); // hier mein DC Und nun beim rendern vor glClearColor..
Delphi-Quellcode:
Was wird gerendert? Nichts! ;)
if VisRenderThread.PaintHandle <> 0 then
begin glDC := CreateCompatibleDc(GetDC(VisRenderThread.ParentHandle)); SelectObject(glDC, VisRenderThread.PaintHandle); end; Nebenbei gelöscht werden darf das Bitmap in meinem Wrapper nicht der ist nicht der Eigentümer davon das ist mein Container mit dem es erstellt wurde der gibt das beim beenden wieder frei. gruss |
AW: Direkt auf Bitmap zeichnen (OpenGL)
Sorry das ich das nach 24 Stunden nochmal hoch pushe.. Hat noch jemand eine Idee?
Informationen sollten ja genug vorhanden sein ;) Das mit dem Flag "PFD_DRAW_TO_BITMAP" kann ich mir abschminken ist Software Rendering und uninteressant.. Frage mich nur warum man so etwas in einer Bibliothek noch drin lässt wenn es nichts taugt. Hmmmm gruss |
AW: Direkt auf Bitmap zeichnen (OpenGL)
So sollte es gehen:
Delphi-Quellcode:
unit glHelper;
interface uses Windows, graphics, dglOpenGl; type TGlHelper = class private function GetGlBitmap(aWidth, aHeight: integer): TBitmap; protected procedure RenderSceneGL; virtual; end; implementation function TGlHelper.GetGlBitmap(aWidth, aHeight: integer): TBitmap; type ByteArray = array [0 .. 0] of byte; pByteArray = ^ByteArray; var lDataSize: Cardinal; lFrameBufferid: GLuint; lRenderbufferId: GLuint; lActViewtexure: GLuint; lData: Pointer; Y, X, x4: integer; pSrc, pDest: pByteArray; begin result := nil; lDataSize := aWidth * aHeight * 4; if lDataSize > 0 then begin // Prepare fbo glDrawBuffer(GL_BACK); glGenFramebuffers(1, @lFrameBufferid); glBindFramebuffer(GL_FRAMEBUFFER, lFrameBufferid); glGenRenderbuffers(1, @lRenderbufferId); glBindRenderbuffer(GL_RENDERBUFFER, lRenderbufferId); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, aWidth, aHeight); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, lRenderbufferId); GLGenTextures(1, @lActViewtexure); GLBindTexture(GL_TEXTURE_2D, lActViewtexure); GLTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); GLTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); GLTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, aWidth, aHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, nil); GLFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, lActViewtexure, 0); glBindFramebuffer(GL_FRAMEBUFFER, lFrameBufferid); GLViewPort(0, 0, aWidth, aHeight); // render the scene part RenderSceneGL; GLFinish; glDrawBuffer(gl_Front); glBindRenderbuffer(GL_FRAMEBUFFER, 0); GLDeleteRenderbuffers(1, @lRenderbufferId); glBindFramebuffer(GL_FRAMEBUFFER, 0); GLDeleteFramebuffers(1, @lFrameBufferid); lData := AllocMem(lDataSize); try GLGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, lData); GLBindTexture(GL_TEXTURE_2D, 0); GLDeleteTextures(1, @lActViewtexure); // Prepare the Bitmap result := TBitmap.Create; result.PixelFormat := pf32bit; result.Width := aWidth; result.Height := aHeight; pSrc := @pByteArray(lData)[aWidth * 4 * (aHeight - 1)]; for Y := 0 to aHeight - 1 do begin pDest := result.ScanLine[Y]; for X := 0 to aWidth - 1 do begin x4 := X * 4; pDest[x4 + 0] := pSrc[x4 + 2]; pDest[x4 + 1] := pSrc[x4 + 1]; pDest[x4 + 2] := pSrc[x4 + 0]; pDest[x4 + 3] := pSrc[x4 + 3]; end; Dec(pSrc, aWidth * 4); end; finally FreeMem(lData); end; end; end; procedure TGlHelper.RenderSceneGL; begin end; end. |
AW: Direkt auf Bitmap zeichnen (OpenGL)
Hi Fritz..
Danke für deine Mühe werde es mal testen. Verstehe nur nicht wie ich das in meinen Buffer portieren soll
Delphi-Quellcode:
Ich werde mal meinen Quelltext abändern der nur den einen Plugintyp unterstützt und dir den Source davon mal schicken wenn du möchtest.
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, StretchWidth, StretchHeight, GL_BGRA,
GL_UNSIGNED_BYTE, VisInfo^.VisBuf); Ohne Beispiel mit Quelltext wird das schwierig. gruss |
AW: Direkt auf Bitmap zeichnen (OpenGL)
@Fritz.. Habe die DLL und ein Beispiel Projekt zum testen der DLL fertig..
Wenn du zeit und Lust dazu hast kann ich es gerne hochladen vielleicht kannst du mir das dann implementieren? Ich weis leider nicht wie ich das alles zusammen bringen soll. (FBO keinerlei Erfahrung.) :oops: Wir müssen dann nur ein Bitmap aus der Anwendung an die DLL schicken auf der dann gerendert werden soll.. (HBitmap also das Handle sollte doch reichen oder?) wenn du Interesse daran hast werde ich das noch implementieren so das du dich damit nicht rumschlagen must. gruss |
AW: Direkt auf Bitmap zeichnen (OpenGL)
Mache ich dir gerne, kommt im Moment etwas auf die Temperaturen an... 😄
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:12 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz