Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

29.04.2010, 10:48

OpenGL auf Bild + Alpha

Hallo Liebe Spiele Programmierer,

ich würde gern eine Opengl Szene auf einem Bild (Offscreen auf bmp, PNG etc.) erstellen. Dabei würde ich gern einen Alpha Kanal benutzen der die Szene (Hintergrund) durchsichtig macht. Lässt sich so was Realisieren, oder soll ich gleich aufhören mich damit zu beschäftigen. Meine bisherigen Recherchen haben nicht viel gebracht. Vielleicht ginge was mit glClearColor, der besitzt ja einen Alpha Wert?! Danke für eure mühe.

Gruß

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »juniorProgrammer« (29.04.2010, 10:58)


Alyx

Treue Seele

Beiträge: 236

Wohnort: Hannover

Beruf: Head Of Software Development

  • Private Nachricht senden

2

29.04.2010, 11:29

Je nachdem was du unter durchsichtig verstehst :-). Wenn die Szene nur transparent und nicht alpha-transparent sein soll, ist es überhaupt kein Problem, Antialiasing aus, Backbuffer mit fiktiver Farbe wie 255,0,255 füllen, rendern, auslesen, Transparenzfarbe rausfiltern, speichern, fertig. Mit Alpha-Transparenz kenne ich den aktuellen Stand der Dinge nicht, da es für mich nie interessant war, aber vor einigen Jahren musste man sich auf jeden Fall noch drumrum tricksen, um zumindest nahekommende Ergebnisse zu erhalten.

LG
Alyx

ernest7

Frischling

Beiträge: 20

Wohnort: Dresden

Beruf: Student

  • Private Nachricht senden

3

29.04.2010, 15:32

Ich denke das größte Problem stellt vor allem das zu erstellende Dateiformat dar. Bmp unterstützt soweit ich weiß ja überhaupt keine Transparenz und das PNG-format ist nicht gerade das simpelste.
Ich würde also erstmal daran gehen überhaupt mal eine funktionierende PNG-Datei mit einem Alphakanal zu erstellen (möglicherweise findest du dazu irgendwelche libs, sonst viel Spass mit der Formatspezifikation ;)).
Deine OpenGL-Szene dann in Texturbuffer (alpha-werte vermutlich in extra buffer) zu rendern und in die Datei übertragen sollte eigentlich machbar sein.

Ich weiß ja nicht was dein Ziel ist, aber wenn es nur um ein paar Bilder geht würde ich warscheinlich die Renderergebnisse lieber per Hand im Grafikprogramm zu einem PNG zusammensetzen.
*Werbung* Der Welt bestes Android-Metronom: Metronomerous *Werbung*

Alyx

Treue Seele

Beiträge: 236

Wohnort: Hannover

Beruf: Head Of Software Development

  • Private Nachricht senden

4

29.04.2010, 16:15

Wenn man gewährleisten kann, dass das Fenster mit dessen HDC der Context erstellt wurde, nicht überdeckt wird, muss man sich nicht einmal einen seperaten Framebuffer erstellen, sondern kann direkt den Standard-Framebuffer verwenden. Das Problem ist allerdings, dass OpenGL so "schlau" ist zu erkennen, welcher Teil vom Fenster verdeckt wird und diesen dann auch gleich im Backbuffer mit wegcullt, was natürlich bei dem Anwendungsfall fatal ist.

Bzgl. PNG kann ich bei Bedarf gerne Quelltext mit einer entschlackten Version von CxImage zur Verfügung stellen, der BMP/PNG/JPG und GIF lädt und speichert. Haben wir auf unseren Servern, Desktop, Windows CE bis hin zum iPhone seit Jahren überall im Einsatz und läuft 100%ig zuverlässig ohne Probleme überall.
Ansonsten kannst du dir natürlich auch die neuesten Version von http://www.xdp.it/cximage.htm ziehen und den überflüssigen Kram einfach selbst entfernen.

LG
Alyx

5

29.04.2010, 22:23

Danke schon mal für eure Tipps. Ihr seid echt zu gut. :) Also ein Fenster soll es nicht geben. Im Moment ist mein Rendering in einem Speicher Kontext. Habe mich hieran orientiert: Rendering on DIBs http://msdn.microsoft.com/en-us/library/ms970768.aspx
Das Funktioniert auch, nur wäre es schön den Hintergrund direkt Transparent zu haben, da ein nachträgliches herausfiltern des Hintergrundes ziemlich langsam ist. Als Datei brauch ich das Rendering nicht, sondern das Bild im Arbeitss. um damit arbeiten zu können. Also wenn das Möglich ist würde ich mich in die entsprechenden Themen einlesen, da ich nicht so mit den Tiefen der Opengl vertraut bin, wie ihr ^^

Gruß

Alyx

Treue Seele

Beiträge: 236

Wohnort: Hannover

Beruf: Head Of Software Development

  • Private Nachricht senden

6

29.04.2010, 23:07

Zitat


OpenGL VI: Rendering on DIBs with PFD_DRAW_TO_BITMAP Dale Rogerson
Microsoft Developer Network Technology Group
April 18, 1995
Hattest du mal auf das Datum geschaut? :-) Hier mit OpenGL-Code von 1995 anzufangen ist ungefähr so als würdest in der Fahrschule den Lehrer nach Peitsche und Zügeln fragen ;-). Das ist sowas von deprecated, dass es mich wundert, dass sich Visual Studio nicht weigert, dass überhaupt noch zu compilieren.
Hardware-Beschleunigung hast du damit auf jeden Fall keine, wenn dir Software-Rendering reicht, kannst du das so natürlich trotzdem gerne verwenden.

Bzgl. dem Konvertieren, wenn du dein DiB so initialisierst, hast du direkten Zugriff auf die Pixel-Daten, das Filtern der Farbwerte sollte dann in 1<ms möglich sein:

C-/C++-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
// Create OS canvas
void CreateGDICanvas(int Width, int Height)
{
    FreeDC();

    if( Width%4 ) Width += 4-(Width%4);
    if( Height%4 ) Height += 4-(Height%4);

    BITMAPINFO Info;
    memset(&Info,0,sizeof(Info));

    Info.bmiHeader.biSize       = sizeof(BITMAPINFOHEADER);
    Info.bmiHeader.biBitCount   = 24;
    Info.bmiHeader.biWidth      = Width;
    Info.bmiHeader.biHeight     = Height;
    Info.bmiHeader.biPlanes     = 1;

    gCurWidth   = Width;
    gCurHeight  = Height;

    gDC         = CreateCompatibleDC(0);
    gDIB        = CreateDIBSection(gDC,&Info,DIB_RGB_COLORS,(void**)&gPixelData,0,0);
    SelectObject(gDC,gDIB); 
}


LG
Alyx

Alyx

Treue Seele

Beiträge: 236

Wohnort: Hannover

Beruf: Head Of Software Development

  • Private Nachricht senden

7

29.04.2010, 23:53

Hab mir das gerade noch mal in Ruhe durchgelesen auf der Microsoft-Seite... die nutzen noch Windows 3.1 und diskutieren über Problemlösungen für die 256-Farben-Farbpalette... eieieiei, wie geil ist das denn :-).... ich sag nur

C-/C++-Quelltext

1
2
mov ax,13h
int 10h
;-).

LG
Alyx

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

8

30.04.2010, 07:50

OpenGL kann in einen 32 Bit Pixelbuffer rendern der über einen Alphakanal verfügt. Die Bilddaten können direkt ausgelesen werden und nahezu unverändert (ggf müssen R-B Channels getauscht werden) im Bitmapformat gespeichert werden (Bitmaps unterstützen 32 Bit).

Grüße
@D13_Dreinig

Alyx

Treue Seele

Beiträge: 236

Wohnort: Hannover

Beruf: Head Of Software Development

  • Private Nachricht senden

9

30.04.2010, 11:43

Also mein letzter Stand der Dinge war hier, dass du zwar sehr wohl RGBA-Framebuffer erstellen kannst, diese aber nur gezielt durch tricksten überhaupt sinnvoll gefüllt werden können und weder die gerenderten Fragmente mit dem bereits enthaltenen Inhalt noch die Alpha-Werte sinnvoll miteinander kombiniert werden. Sprich wenn man zwei mal mit A 0.5 über die selbe Stelle zeichnet enthält der FB anschließend 0.5 und nicht 0.75 wie es sein müsste. Sie machen also nur Sinn, um rein gealphatesteten Objekten einen Alphakanal sinnvoll füllen zu lassen, nämlich mit 0.0 oder 1.0, ihen eigentlich darüber hinaus erwünschten Sinn z. Bsp. zur Erzeugung von Impostern mit alphatransparenten Texturen oder generell halbtransparenten Flächen jedoch leider nicht.
Korrigier mich bitte, wenn du da einen sinnvollen Weg kennst, würde mich auch sehr interessieren, wenn so etwas irgendwie ginge... mir fehlte da bisher immer der Framebuffer-Shader. In Software sieht das Ganze bei mir so aus:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#ifdef TAR_RGB_8888
    //! Stores a color with given alpha and anti alpha and combines it with current RGBA content
    #define cgSetCurPixelMixedEx(__Alpha,__AntiAlpha,__NewR,__NewG,__NewB)  \
    {   \
        if( !__AntiAlpha || cgTarComp(3)==0x00 )    \
        {   \
            *cgOffsetVar = cgCombColorA(__NewR,__NewG,__NewB,__Alpha);  \
        }   \
        else    \
        {   \
            int __OA  = cgTarComp(3),   \
                __BA  = __OA;   \
            __BA = (__BA*__AntiAlpha)/255 + __Alpha;    \
            if( __BA )  \
            {   \
                int __Scale = __OA*__AntiAlpha/255; \
                *cgOffsetVar = cgCombColorA(((cgTarComp(2)*__Scale+__NewR*__Alpha)/__BA),((cgTarComp(1)*__Scale+__NewG*__Alpha)/__BA),((cgTarComp(0)*__Scale+__NewB*__Alpha)/__BA),__BA);   \
            }   \
        }   \
    }
#else
...



LG
Alyx

CBenni::O

1x Contest-Sieger

Beiträge: 1 145

Wohnort: Stuttgart

  • Private Nachricht senden

10

30.04.2010, 12:08

Wieso erstellst du ein Makro? Sollte eine inline-Funktion nicht das selbe Ergebnis erzielen?

mfg CBenni::O
Ein Mitglied der VEGeiCoUndGraSonMaWiGeS Bewegung.
42!
Aufräumen kann jeder, nur das Genie überblickt das Chaos!
Metal will never die!
1. Sppro Gamecontest - mein Beitrag

Werbeanzeige