Bild mit Opengl darstellen und Farbe schwarz transparent

Fragen zu Grafik- & Soundproblemen und zur Spieleprogrammierung haben hier ihren Platz.
wasser
Beiträge: 125
Registriert: 27.11.2006 21:16

Bild mit Opengl darstellen und Farbe schwarz transparent

Beitrag von wasser »

Guten abend.

Ich fange mit mit Opengl an auf Purebasic.
Habe schon einiges mit Google unternommen und viel über Opengl gelesen.

Nun die Praxis. Ich möchte mit dem unteren Openglprogramm(aus diesem Forum) ein Bild(Texture )einladen, BMP oder TGA mit Alphakanal.
Die Farbe schwarz soll tranparent werden.
Ich weiss nicht, wie ich dieses Loadprogramm in das Openglfenster intregiere.

Wer kann mir mal mit einem einfachen Beispiel unter die Arme greifen,um ein Bild darzustellen, wo die schwarzen Pixel durchsichtig sind.

Bin für die Hilfe sehr dankbar.

MFG

Code: Alles auswählen

; OpenGL Fenster
;
IncludeFile "OpenGL.pbi"

Structure GLscreen
  container.l
  hWnd.l
  hDC.l
EndStructure

Procedure OpenGLScreen(*p.GLscreen,x,y,w,h)
  If *p
    container = ContainerGadget(#PB_Any,x,y,w,h)
    If container
      hwnd = GadgetID(container)
      pfd.PIXELFORMATDESCRIPTOR
      hdc = GetDC_(hwnd)
      pfd\nSize = SizeOf(PIXELFORMATDESCRIPTOR)
      pfd\nVersion = 1
      pfd\dwFlags = #PFD_SUPPORT_OPENGL | #PFD_DOUBLEBUFFER | #PFD_DRAW_TO_WINDOW
      pfd\iLayerType = #PFD_MAIN_PLANE
      pfd\iPixelType = #PFD_TYPE_RGBA
      pfd\cColorBits = 24
      pfd\cDepthBits = 16
      pixformat = ChoosePixelFormat_(hdc, pfd)
      SetPixelFormat_(hdc, pixformat, pfd)
      hrc = wglCreateContext_(hdc)
      wglMakeCurrent_(hdc, hrc)
      SwapBuffers_(hdc)
      glClearColor_(0.0, 1.0, 0.0, 1.0)
      *p\container = container
      *p\hWnd      = GadgetID(container)
      *p\hDC       = hdc
      ProcedureReturn 1
    EndIf
  EndIf
EndProcedure

If OpenWindow(0, 0, 0, 800,600,  "TEST",#PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  CreateGadgetList(WindowID(0))
  If OpenGLScreen(screen.GLscreen,10,10,400,400)

    HideWindow(0,0)

    Repeat
      glClear_(#GL_COLOR_BUFFER_BIT | #GL_DEPTH_BUFFER_BIT)
      glClearColor_(1.0,0.0,0.0,0.0)
      
      
      
      SwapBuffers_(screen\hdc)
      Event = WaitWindowEvent()
      
    Until Event = #PB_Event_CloseWindow

    ReleaseDC_(screen\hWnd,screen\hDC)

  EndIf

EndIf

Code: Alles auswählen

Procedure LoadAlphaTexture(ID, Filename.s, TransparentColor)
  img = LoadImage(#PB_Any, Filename.s)
  Width.l=ImageWidth()
  Height.l=ImageHeight()
  Size.l=Width * Height
 
  Dim ImageData.b(Size*4)
 
  StartDrawing(ImageOutput())
  i = 0
  For Y=0 To Height-1
    For X=0 To Width-1
     
      Color = Point(X,Y)
      ImageData(i)=Red(Color)
      i+1
      ImageData(i)=Green(Color)
      i+1
      ImageData(i)=Blue(Color)
      i+1
      If Color = TransparentColor
        ImageData(i)=0
      Else
        ImageData(i)=$FF
      EndIf
      i+1
   
    Next
  Next
  StopDrawing()
 
  glGenTextures_(1, @Tex)
 
  glBindTexture_(#GL_TEXTURE_2D, Tex)
  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_RGBA, Width, Height, 0, #GL_RGBA, #GL_UNSIGNED_BYTE, @ImageData())
 
  ProcedureReturn Tex
EndProcedure


Benutzeravatar
Helle
Beiträge: 566
Registriert: 11.11.2004 16:13
Wohnort: Magdeburg

Beitrag von Helle »

Ich scheine nicht der Einzige zu sein, der mit OpenGL nicht so die rechte Erfahrung hat :) . Deshalb hier ein Beispiel ohne die GL:

Code: Alles auswählen

;- PB v4.01
Procedure DrawTransparentImage(DC, Bitmap, x, y, Width, Height, TransparentColor) 
;- Hat Fred im englischen Forum selbst gepostet! Sind auch seine Original-Kommentare!
    ; First, create some DC's. These are our gateways To associated 
    ; bitmaps in RAM 
    maskDC = CreateCompatibleDC_(DC) 
    tempDC = CreateCompatibleDC_(DC) 
    
    SourceDC = CreateCompatibleDC_(DC) 
    SelectObject_(SourceDC, Bitmap) 
 
    ; Then, we need the bitmaps. Note that we create a monochrome 
    ; bitmap here! 
    ; This is a trick we use For creating a mask fast enough. 
    hMaskBmp = CreateBitmap_(Width, Height, 1, 1, 0) 
    hTempBmp = CreateCompatibleBitmap_(DC, Width, Height) 

    ; Then we can assign the bitmaps to the DCs 
    ; 
    hMaskBmp = SelectObject_(maskDC, hMaskBmp) 
    hTempBmp = SelectObject_(tempDC, hTempBmp) 

    ; Now we can create a mask. First, we set the background color 
    ; To the transparent color; then we copy the image into the 
    ; monochrome bitmap. 
    ; When we are done, we reset the background color of the 
    ; original source. 
    TransparentColor= SetBkColor_(SourceDC, TransparentColor) 
    BitBlt_ (maskDC, 0, 0, Width, Height, SourceDC, 0, 0, #SRCCOPY) 
    SetBkColor_(SourceDC, TransparentColor) 

    ; The first we do with the mask is To MergePaint it into the 
    ; destination. 
    ; This will punch a WHITE hole in the background exactly were 
    ; we want the graphics To be painted in. 
    BitBlt_ (tempDC, 0, 0, Width, Height, maskDC, 0, 0, #SRCCOPY) 
    BitBlt_ (DC, X, Y, Width, Height, tempDC, 0, 0, #MERGEPAINT) 

    ; Now we delete the transparent part of our source image. To do 
    ; this, we must invert the mask And MergePaint it into the 
    ; source image. The transparent area will now appear as WHITE. 
    BitBlt_ (maskDC, 0, 0, Width, Height, maskDC, 0, 0, #NOTSRCCOPY) 
    BitBlt_ (tempDC, 0, 0, Width, Height, SourceDC, 0, 0, #SRCCOPY) 
    BitBlt_ (tempDC, 0, 0, Width, Height, maskDC, 0, 0, #MERGEPAINT) 

    ; Both target And source are clean. All we have To do is To And 
    ; them together! 
    BitBlt_ (DC, X, Y, Width, Height, tempDC, 0, 0, #SRCAND) 

    ; Now all we have To do is To clean up after us And free system 
    ; resources.. 
    DeleteObject_ (hMaskBmp) 
    DeleteObject_ (hTempBmp) 
    DeleteDC_ (maskDC) 
    DeleteDC_ (tempDC) 
    DeleteDC_ (SourceDC) 

EndProcedure 

;- Fenstergröße an Bitmap-Größe anpassen!
If OpenWindow(0,0,0,250,65, "Demo für DrawTransparentImage", #PB_Window_SystemMenu) = 0
   MessageRequester("Fehler!", "Hier stimmt was nicht!")
EndIf 

CreateGadgetList(WindowID(0))

;- Bmp1 ist das Bild mit schwarzem Hintergrund, Bmp2 ist z.B. irgendein Hintergrundbild
If LoadImage(1, "Bmp1.bmp") And LoadImage(2, "Bmp2.bmp") ;Pfad und Namen anpassen!
  Else 
    MessageRequester("Fehler!", "Probleme mit den Bitmaps!")
EndIf

DC = StartDrawing(ImageOutput(2)) 
DrawTransparentImage(DC, ImageID(1), 0, 0, 64, 55, 0) ;64x55 ist Bmp1-Größe (anpassen!), 0 ist Schwarz
StopDrawing()
 
ImageGadget(0, 0, 0, 0, 0, ImageID(2))

Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow

CloseWindow(0)

End
Die Prozedur stammt von Fred höchstpersönlich und funktioniert bei mir tadellos.

Gruss
Helle
wasser
Beiträge: 125
Registriert: 27.11.2006 21:16

Beitrag von wasser »

Hallo, vielen Dank für deine Hilfe.
Ist ein erster Schritt für Opengl.

MFG
Benutzeravatar
Tafkadasom2k5
Beiträge: 1578
Registriert: 13.08.2005 14:31
Kontaktdaten:

Beitrag von Tafkadasom2k5 »

...aber warum willst du unbedingt OpenGL nutzen, wenn du im Endeffekt die Plattformunabhängigkeit durch die WinAPI-Aufrufe wieder zerstörst..?

Gr33tz
Tafkadasom2k5
OpenNetworkConnection() hat geschrieben:Versucht eine Verbindung mit dem angegebenen Server aufzubauen. 'ServerName$' kann eine IP-Adresse oder ein voller Name sein (z.B.: "127.0.0.1" oder "ftp.home.net").
php-freak hat geschrieben:Ich hab die IP von google auch ned rausgefunden!
wasser
Beiträge: 125
Registriert: 27.11.2006 21:16

Beitrag von wasser »

In Opengl gibt es nur ein Fenster zur Darstellung, da kann man nicht alles reinpacken (Buttons) ohne die V-Null start negativ zu beeinflussen.

Ich möchte ein Openglfenster nur für die Opengl-Routinen und ich möchte eine Gui die das Openglfenster steuert hier ist es Windows das selbe geht auch in Linux und das selbe geht auch auf den MAC.

Ich benutze Opengl , weil ich damit mehr machen kann in Purebasic als mit dem eingebauten OGRE-Krampf. Fängt schon an mit den MeshKörper erstellen und einfärben der Baugruppen in der Mesh-Datei. Es gehen da nur Textureflächen. Andere wurden auch von OGRE abtrünnig und versuchen sich jetzt mit "Irrlicht", sind auch schon sehr weit.

Ich benutze Opengl , weil ich damit flexibler bin in der Spriteprogrammierung.

Ich bnutze Opengl, weil die Unabhängigkeit der einzelnen 3d-Teile am Körper gegeben ist.

Ich benutze Opengl, weil ich da jetzt selber eine Rouine geschrieben habe um eine Direct-x-Datei(Textformat), die mit Blender3d erstellt wurde einlesen kann mit den Farbwerten. Ist noch nicht ganz fertig. Funktioniert aber schon für ein Körperteil.

Ich freu mich, das ich es mit der Hilfe des Forums geschafft habe , in Opengl :
- Sprite erstellen kann und bewegen kann mit einer kleinen selbsterstellten
Kollisionsroutine
- das ich einen 3d-Körper einlesen kann mit einer selbsterstellten Routine
- das ich Armgelenke unabhängig von einem Körper bewegen kann
(habe ein Kranauto erstellt mit 3 Gelenkarmen, die Positionen der gedrehten Gelenkarme gehen zb mit dem Kranauto mit .

Dieses habe ich mit dem eingebauten 3D in Purebasic nicht geschafft.
(Wenn du so etwas geschafft hast, informier uns hier mal im Forum)

Opengl ist eine Tolle sache. Super.

Der Programmierer von glBasic(Opengl) hat versucht in das Openglfenster eine Gui darzustellen, ist Grottenlangsam und nicht wirklich ein Vorteil sondern nur Ballast, der das Opengl ausbremsen tut.

Fazit : das glBasic bleibt immer auf der untersten Stufe , also nur ein Openglfenster ohne schöne Optische Bedienung durch Buttons usw.
Zuletzt geändert von wasser am 05.12.2006 18:53, insgesamt 1-mal geändert.
Benutzeravatar
vonTurnundTaxis
Beiträge: 2130
Registriert: 06.10.2004 20:38
Wohnort: Bayreuth
Kontaktdaten:

Beitrag von vonTurnundTaxis »

Trotzdem ist einer der großen Vorteile von OpenGL die plattformunabhängigkeit.
Nicht durch Zorn, sondern durch Lachen tötet man
ClipGrab | Pastor - jetzt mit kurzen URLs!
wasser
Beiträge: 125
Registriert: 27.11.2006 21:16

Beitrag von wasser »

Da gebe ich dir recht.

Dieses war auch geplant von den Erfindern, eine Einheitlichkeit zu schaffen in der Grafik.
Antworten