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

Alyx

Treue Seele

Beiträge: 236

Wohnort: Hannover

Beruf: Head Of Software Development

  • Private Nachricht senden

11

30.04.2010, 12:33

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

mfg CBenni::O
Nein, erzielt nicht das selbe Ergebnis. Funktion, die Inline Funktion aufruft, die Inline Funktion aufruft, die Inline Funktion aufruft -> 3 Calls insgesamt. Funktion, die Makro aufruft, das Makro aufruft, das Makro aufruft -> 1 Call. Hinzu kommt, dass der Compiler das spätere Ergebnis deutlich besser optimieren kann. Ist ein Schnipsel aus unserem Software-Renderer und was der auf einem handelsüblichen Quadcore-Xeon pro Sekunde im 2D-Bereich an dynamischen Linien und Flächen durch die Schaltkreise prügelt, lässt jede Grafikkarte erblassen. Die Wartbarkeit hält sich so natürlich arg in Grenzen, aber seit Jahren in unseren Navigationssystemen und Servern im Einsatz und auch wenn Makros generell ja "Pfui" sind, heiligt Erfolg in Fällen wie diesen halt die Mittel. Und glaub mir, den gesamten Quelltext willst du nicht sehen, dass mit dem Makro -> Makro -> Makro war noch sehr stark untertrieben, von den rekursiven Includes ganz zu schweigen. :-)

LG
Alyx

CBenni::O

1x Contest-Sieger

Beiträge: 1 145

Wohnort: Stuttgart

  • Private Nachricht senden

12

30.04.2010, 14:18

Okay, hatte mich nur gewundert :D

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

13

30.04.2010, 20:42

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

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


:D Ja hatte das mit 1995 gesehen, aber was damals funktioniert hat, funktioniert auch heute noch. War ja auch nur eine Anlehnung. 8) Mein Code ist fast genau so wie der, den du gepostet hast. Nun ja so ganz zufrieden bin ich noch nicht. Habe für meine Bitmap eine RGBA Struktur angelegt, das Funktioniert auch, nur der alpha Teil wird von OpenGL nicht berührt und behält immer den gleichen wert. Ist das normal, oder kann man da noch Tricksen. ??? Das nachträgliche bearbeiten, sprich aller Hintergrundpixel einen Alpha von 0 und dem eigentlichem Rendering 255 zuzufügen ist doch ziemlich teuer, da ich ja jedes Pixel dafür prüfen muss. Danke nochmals


Alyx

Treue Seele

Beiträge: 236

Wohnort: Hannover

Beruf: Head Of Software Development

  • Private Nachricht senden

14

30.04.2010, 23:51

Wie gesagt, ich denke nicht, dass es teuer ist die Transparenzfarbe durch einen sinnvollen Alpha-Wert zu tauschen, das ist eine lächerliche Vorschleife von 1024x1024 oder welche Auflösung deine Zeichnung auch immer hat, ich sehe da derzeit nicht das Problem :-). Ansonsten kannst du es machen wie David bereits vorgeschlagen hat, Framebuffer mit RGBA initialisieren, bei glClearColor mit Alpha 0 füllen und dann ganz normal zeichnen, dann sollte der A-Wert richtig gefüllt sein, wenn du nur untransparente Dreiecke bzw. welche mit Alpha-Testing darstellst.

LG
Alyx

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

15

01.05.2010, 09:33

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
Das füllen des Framebuffers mit Alphawerten läuft normalerweise über die Vertexfarben/Texelfarben. Damit kann der Framebuffer selbstverständlich mit allen möglichen Alphawerte gefüllt werden.
Was du mit "sinnvoll miteinander kombinieren" meinst ist mir etwas schleierhaft. Es gibt zig. Blendfunktionen/Combiners die allerhand Kombinationen erlauben. Oder man macht das selbst im Shader (das wär ohnehin der konforme Weg).

Übrigens, eine Frage zu deinem Code: Wenn du so viel Wert auf Geschwindigkeit legst. Wieso dann die vielen Divisionen (ich meine nicht die die sowieso optimiert werden)?
@D13_Dreinig

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »David_pb« (01.05.2010, 11:12)


Alyx

Treue Seele

Beiträge: 236

Wohnort: Hannover

Beruf: Head Of Software Development

  • Private Nachricht senden

16

01.05.2010, 15:39

Bzgl. der Divisionen: Ich weiß nicht genau, worauf du dich da beziehst. Wenn du meinst, wieso wir anstatt dessen nicht geshifted haben: Weil es auf ARM-Prozessoren langsamer war und dafür war das Ganze ursprünglich konzipiert.
Generell mussten wir wegen dem Windows CE-Compiler diverse Konstrukte bauen, wo auf den ersten Blick jeder sagen würde: Wie kann das schneller sein? Ein ganz gutes Beispiel dafür ist das

Zitat

__BA = __OA; \
__BA = (__BA*__AntiAlpha)/255 + __Alpha;
Sollte man meinen, dass __BA = (__OA*__AntiAlpha)/255 + __Alpha; hier ja definitiv schneller sein müsste als es erst der Variable zuzuweisen, um sie dann direkt danach mit einem neuen Wert wieder zu überschreiben. Ist es in dem Fall aber nicht, da er das andere Konstrukt besser optimieren kann. Sprich wir haben tagelang an einzelnen Formen wie diesen solange hin und hergestellt und am Ende die genommen, die die beste Leistung lieferte (auf dem ARM). Auf dem x86 könnte man bestimmt noch ein gutes Stück mehr rauskitzeln, wenn man es drauf anlegen würde, aber da die Leistung mehr als nur zufriedenstellend war, haben wir uns die Mühe nicht mehr gemacht. Das RGBA8-Beispiel ist in der Praxis aber generell auch eher ein Exot, hatte es nur der Formel halber mal rausgesucht :-).

Aber mal zurück zum eigentlichen Thema:
Folgendes Szenario: Du zeichnest auf die selbe Stelle 10x ein Rechteck mit einem Alpha-Wert von 0.1 und möchtest am Ende eine Textur haben, die sich, wenn man sie anschließend in einen anderen FB ausgibt, so verhält, dass der andere FB am Ende genau so aussieht, als hätte man diese 10 Rechtecke direkt in diesen gezeichnet. Ohne Shader ist das soweit ich weiß nicht möglich, zumindest fiele mir auf anhieb keine sinnvolle Konfiguration für BlendFunc und Equation ein, mit der man diesen Effekt erzielen könnte. Via Shader könnte man das ganze eventuell realisieren, wenn man nicht in den Haupt-FB zeichnet, sondern via RenderToTexture und dann dem FS gleichzeitig den Ziel-FB, also der der Textur in diesem Fall, als Textur zur Verfügung stellt, so dass ihm dann alle Werte zur Verfügung ständen, die er für die Berechnung benötigt.

LG
Alyx

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

17

01.05.2010, 15:58

Zitat

Ich weiß nicht genau, worauf du dich da beziehst. Wenn du meinst, wieso wir anstatt dessen nicht geshifted haben: Weil es auf ARM-Prozessoren langsamer war und dafür war das Ganze ursprünglich konzipiert.
Nein, ich bezog mich hauptsächlich auf folgende Stelle

C-/C++-Quelltext

1
*cgOffsetVar = cgCombColorA(((cgTarComp(2)*__Scale+__NewR*__Alpha)/__BA),((cgTarComp(1)*__Scale+__NewG*__Alpha)/__BA),((cgTarComp(0)*__Scale+__NewB*__Alpha)/__BA),__BA);   \


Selbst auf dem ARM sollten Multiplikationen schneller sein als Divisionen. Bei der von dir angesprochenen Stelle sollte der Compiler ohnehin optimieren.

Zitat

Folgendes Szenario: Du zeichnest auf die selbe Stelle 10x ein Rechteck mit einem Alpha-Wert von 0.1 und möchtest am Ende eine Textur haben, die sich, wenn man sie anschließend in einen anderen FB ausgibt, so verhält, dass der andere FB am Ende genau so aussieht, als hätte man diese 10 Rechtecke direkt in diesen gezeichnet. Ohne Shader ist das soweit ich weiß nicht möglich, zumindest fiele mir auf anhieb keine sinnvolle Konfiguration für BlendFunc und Equation ein, mit der man diesen Effekt erzielen könnte. Via Shader könnte man das ganze eventuell realisieren, wenn man nicht in den Haupt-FB zeichnet, sondern via RenderToTexture und dann dem FS gleichzeitig den Ziel-FB, also der der Textur in diesem Fall, als Textur zur Verfügung stellt, so dass ihm dann alle Werte zur Verfügung ständen, die er für die Berechnung benötigt.
Wieso sollte man so etwas tun wollen? War das die Anforderung des Threaderstellers?
@D13_Dreinig

Alyx

Treue Seele

Beiträge: 236

Wohnort: Hannover

Beruf: Head Of Software Development

  • Private Nachricht senden

18

01.05.2010, 16:10

Bäume mit alpha-transparenten Texturen in Imposter umwandeln ist hier denke ich ein gutes Beispiel, für das man so etwas bräuchte.
Und ja, für mich klang die Frage des Threaderstellers so, als wollte er am Ende die Szene Mit-Ohne-Hintergrund :-).

LG
Alyx

19

02.05.2010, 07:36

Hier ist ja eine Richtige Diskussion entstanden. Freut mich. Ich hab es so realisiert wie du es vorgeschlagen hast Alyx und habe mir ein Paar Gedanken darüber gemacht wie man die Farbe möglichste effizient filtert. Performance reicht so völlig aus. Ich werde den Ansatz mit dem Framebuffer evtl. mal aufgreifen, aber im Moment bin ich zufrieden. :thumbup: Danke

Werbeanzeige