<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Spiele-&#x2F;Grafikprogrammierung]]></title><description><![CDATA[3D-Shooter, Animationen, schnelle Grafik... wer träumt nicht davon? DirectX, Direct3D, OpenGL, SDL, Strategien und Grafik. Hier könnt Ihr Euch austoben.]]></description><link>https://www.c-plusplus.net/forum/category/53</link><generator>RSS for Node</generator><lastBuildDate>Mon, 07 Sep 2026 15:53:32 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/category/53.rss" rel="self" type="application/rss+xml"/><pubDate>Sat, 11 Apr 2020 10:11:40 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Raytracing &#x2F; Pathtracing &#x2F; Photon Mapping - Tutorial]]></title><description><![CDATA[Da ich heute mal etwas Zeit habe, habe ich jetzt noch ein Pathtracer mit Next Event Estimation hinzugefügt. Dieser ist meiner Meinung nach der effektivste Algorithmus, wenn man neben dem Bildrauschen auch noch die Quellcode-Anzahl mit in Betracht zieht. Obwohl der Algorithmus nur so klein ist, erzeugt er trotzdem weitaus bessere Ergebnisse als der normale Pathtracer.
Grundidee ist hier: Man erzeugt zufällige Pfade zwischen Camera und Lichtquelle, indem man einerseits das normale Pathtracing verwendet und anderseits verwendet man LightSource-Sampling, welches auch schon beim Berechnen des Direkten Lichtes beim Photonmapping verwendet wurde. Nur dieses mal nimmt man das LightSourcesampling nicht nur für den ersten Punkt, den die Kamera sieht sondern für alle Punkte, den der Pathtracer erzeugt.
Ich habe also zwei Sampler zur Berechnung eines Farbwertes für ein Pixel: Brdf-Sampling und Lightsource-Sampling. Jeder Sampler erzeugt ein zufälligen Schätzwert für die Lichtmenge, die ein Pixel empfängt.
Ich bezeichne die beiden Farbwerte, welche mit die beiden Sampler für ein Pixel erzeugen jetzt mal mit f1 und f2. Die endgültige Pixel-Farbe könnte ich nun z.B: so berechnen:
f = (f1 + f2)/2.
Das wäre einfach nur der Durchschnittswert von Beiden. Dieses Idee würde zwar funktionieren aber sie erzeugt unnötig hohes Bildrauschen.
Eine bessere Idee ist der Einsatz von Multiple Importance Sampling. Dort gibt erzeugt man ein MIS-Faktor, welcher als Gewicht dient. Dieser Gewichtsfaktor ist eine Zahl zwischen 0 und 1 und gibt an, zu wie viel Prozent man das ein oder das andere Sampling-Verfahren in die Summe einfließen läßt. Unsere Formel sieht nun so aus:
f = (1-MIS) * f1 + MIS * f2
Dieser MIS-Faktor wird dadurch berechnet, indem man die Wahrscheinlichkeitsdichte im Bezug zum Flächenmaß (Pdf with Respect to Surface Area = PdfA) verwendet. Dieses PdfA ist eine Funktion, welche für einen konkret gesampelten Pfad P angibt, wie hoch die Wahrscheinlichkeit ist, dass genau dieser Pfad erzeugt wurde. Ich verwende hier Brdf- und LightSource-Sampling. Also habe ich für jedes dieser beiden Sampling-Verfahren auch eine zugehörige PdfA-Funktion:
Brdf-PdfA(P)
LightSampling-PdfA(P)
Diese Funktionen bekommen ein Pfad (Menge von Punkten) als Input und sagen dann: Wie groß ist die Wahrscheinlichkeit, dass ich den Pfad P mit Brdf/Light-Sampling erzeuge?
Ich verwende nun also zwei Sampler und jeder dieser Sampler erzeugt mir jeweils ein Pfad. Brdf-Sampling erzeugt mir den Pfad P1 und LightSourceSampling den Pfad P2.
Der Farbwert(Radiance) für die Pfade wird PathContribution genannt und wird über die PathContribution-Funktion berechnet. Also Contribut(P1) und Contribut(P2).
Jeder dieser beiden PathContribution-Werte muss nun mit den MIS-Factor gewichtet werden:
PixelColor = MIS1 * Contribut(P1) / Brdf-PdfA(P1) + MIS2 * Contribut(P2) / LightSampling-PdfA(P2)
Ich berechne MIS1 nun über folgende Formel, wenn ich davon ausgehe, dass P1 mit BrdfSampling erzeugt wurde:
MIS1 = Brdf-PdfA(P1) / (Brdf-PdfA(P1) + LightSampling-PdfA(P1))
Bei MIS2 gehe ich davon aus, dass P2 mit LightSampling erzeugt wurde.
MIS2 =  LightSampling-PdfA(P2) / (Brdf-PdfA(P2) + LightSampling-PdfA(P2))
Die Idee von Multiple Importance Sampling ist also, dass man den Sampling-Verfahren mehr Gewicht verleiht, welche eine größere PdfA haben da großer PdfA-Wert wenig Rauschen bedeutet.
Diese Formel (PixelColor=...), wo die Mis-Gewichtet Summe von mehreren Verfahren gebildet wird, nennt sich Secondary-Estimator.
Der Primary-Estimator ist dann die Durchschnittswert von N Secondary-Estimator-Werten. Dieser Wert ist es dann, welcher am Ende in die Bilddatei geschrieben wird.
Der Quelltext für dieses Pathtracing, wo Brdf-Sampling mit Lightsource-Sampling via Multipe Importance Sampling (MIS) vereint, gezeigt wird, habe ich hier:
https://github.com/XMAMan/RaytracingTutorials/blob/master/08_PathtracingNextEventEstimation/RaytracingTutorials/PathtracingNEE.cs
Hinweis: Wenn die PathContribution-Funktion den Wert 0 liefert, dann mache ich mir garnicht erst die Mühe das zugewhörige MIS-Gewicht zu bilden.
Ausgabebild:
https://github.com/XMAMan/RaytracingTutorials/blob/master/08_PathtracingNextEventEstimation/Images/PathtracingWithNextEventEstimation.png
Um das ganze besser zu verstehen, wäre ein Blick in die Dissertation von Eric Veach hilfreich. Er setzt aber vorraus, dass man den Begriff 'Wahrscheinlichkeitsdichte im Bezug zu ein Maß' kennt. Ich denke, dass wäre mal ein eigenes Thema, was ich mal gesondert erklären müsste, wenn Bedarf besteht^^
]]></description><link>https://www.c-plusplus.net/forum/topic/344769/raytracing-pathtracing-photon-mapping-tutorial</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/topic/344769/raytracing-pathtracing-photon-mapping-tutorial</guid><dc:creator><![CDATA[XMAMan]]></dc:creator><pubDate>Sat, 11 Apr 2020 10:11:40 GMT</pubDate></item><item><title><![CDATA[Screenshot Thread - Eine gute Idee?]]></title><description><![CDATA[Game of Life Explorer
https://ibb.co/hJDjcjkR
https://ibb.co/v6YxmWRY
]]></description><link>https://www.c-plusplus.net/forum/topic/191889/screenshot-thread-eine-gute-idee</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/topic/191889/screenshot-thread-eine-gute-idee</guid><dc:creator><![CDATA[zeropage]]></dc:creator><pubDate>Fri, 04 Apr 2025 18:30:42 GMT</pubDate></item><item><title><![CDATA[Grafik- und Enginedemos]]></title><description><![CDATA[Nachdem die Grafikengine nun fertig ist versuche ich es mit Physiksimulation. Ich habe ein Editor geschrieben, womit man 2D-Scenen erstellen kann und dann soll sich das physikalisch verhalten. Man kann damit Personen, Fahrzeuge und alles, was aus halbwegs festen Material ist bauen. Flüssigkeiten und Gase gehen damit aber nicht. (Das ist ein anders Level^^)
https://youtu.be/fzUmWzMWWlk
Update am 30.1.2024:
Hier ist nun mein erstes Spiel. Die Sounds erzeuge ich mit mein Synthesizer und das Intro-Bild habe ich in Paint gemalt. Was sagt ihr dazu?
https://www.youtube.com/watch?v=icQ82OEPH34
Update 4.2.2024:
Hier ist nun das zweite Spiel: SkiJumper
https://www.youtube.com/watch?v=o-AgsZpFues
Ich habe die Spiele auch auf Github, wenn das jemand selber mal spielen will: https://github.com/XMAMan/PhysicGames/archive/refs/heads/main.zip
Update 16.2.2024:
Spiel Nummer Drei ist fertig: Elma (Motorradspiel)
Die Level können nun auch bewegliche Objekte enthalten und man kann auch das Motorrad/die Level im Editor, der Teil des Spiels ist, verändern.
https://www.youtube.com/watch?v=PCDX6M82iZ0
Update 23.3.2024:
Spiel Nummer 4 ist fertig: Astroids. Ich habe die Idee von zeropage von hier: https://www.c-plusplus.net/forum/topic/191889/screenshot-thread-eine-gute-idee/199
https://www.youtube.com/watch?v=iDk9u26xils
Bei diesen Spiel war die Schwierigkeit, dass ich die Objekte, welche durch den Weltraum fliegen mit der Impulskanonse zerstören kann. Letztendlich habe ich dafür aber Voronoi und Partikelexplosion verwendet.
Update 16.5.2024:
Spiel Nummer 5 ist fertig: Bridge Builder. Ich habe das Spiel vor 20 Jahren gesehen und habe mir nun gedacht, dass ich es nachbauen möchte, da das auch ein schönes Physikspiel ist.
https://www.youtube.com/watch?v=1R_ws6d83EE
Update 20.6.2024:
Ich habe versucht mit möglichst wenig Zeilen/Komplexität eine 2D-Physikengine zu erstellen. Damit will ich zeigen, dass der eigentliche Kern von so einer Physikengine nicht groß ist und ich möchte damit andere ermuntern auch in dieses Thema einzusteigen^^
https://github.com/XMAMan/SmallSI
Update 24.7.2024:
Ich habe beim SmallSI-Projekt nun eine etwas kleinere Dokumentation eingefügt und beim Hauptprojekt nun eine große Dokumentation: https://github.com/XMAMan/RigidBodyPhysics/blob/master/Dokumentation/Dokumentation.pdf
Damit habe ich nun die Grafik-, Sound- und Physik-Engine fertig. Jetzt fehlt nur noch KI und dann kann ich anfangen mein erstes kleines Spiel zu schreiben^^
]]></description><link>https://www.c-plusplus.net/forum/topic/191653/grafik-und-enginedemos</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/topic/191653/grafik-und-enginedemos</guid><dc:creator><![CDATA[XMAMan]]></dc:creator><pubDate>Wed, 20 Dec 2023 16:17:53 GMT</pubDate></item><item><title><![CDATA[SDL 3 Kompilierungsfehler]]></title><description><![CDATA[@DocShoe
Danke für die Antwort.
Wenn ich als Snake Beispiel aus
Link Text anschaue, dann fehlt dies.
Leider bin ich bezpglich SDL(3) Anfänger.
Wie muss &quot;SDL_AppInit&quot;? in der main aufgerufen werden?
Vielen Dank im voraus!
]]></description><link>https://www.c-plusplus.net/forum/topic/355487/sdl-3-kompilierungsfehler</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/topic/355487/sdl-3-kompilierungsfehler</guid><dc:creator><![CDATA[no_name1991]]></dc:creator><pubDate>Tue, 25 Aug 2026 06:16:59 GMT</pubDate></item><item><title><![CDATA[RayLib für Einsteiger]]></title><description><![CDATA[Ich hatte ein Boilerplate, das funktionierte und das Prinzip verdeutlichte... Aber die Betonung liegt auf &quot;hatte&quot; (Plusquamperfekt), das heißt, ich kann das Sample leider nicht wiederfinden.
Aber wäre es nicht ratsamer, hierbei zuerst eine KI zu fragen? Jene sollte auch die build-Schritte erklären können.
]]></description><link>https://www.c-plusplus.net/forum/topic/355466/raylib-für-einsteiger</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/topic/355466/raylib-für-einsteiger</guid><dc:creator><![CDATA[Anon-81275]]></dc:creator><pubDate>Fri, 24 Jul 2026 21:21:10 GMT</pubDate></item><item><title><![CDATA[Spieleprogrammierung - welches Tool?]]></title><description><![CDATA[Wie sind die Erfahrungen mit Raylib-cs, z.B. in Kombination mit C#?
]]></description><link>https://www.c-plusplus.net/forum/topic/355052/spieleprogrammierung-welches-tool</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/topic/355052/spieleprogrammierung-welches-tool</guid><dc:creator><![CDATA[Erhard Henkes]]></dc:creator><pubDate>Fri, 27 Feb 2026 21:47:30 GMT</pubDate></item><item><title><![CDATA[Kennt sich jemand mit OpenAL (oder mit Soundprogrammierung) aus?]]></title><description><![CDATA[Vielen Dank erst einmal.
@Lupus-SLE sagte in Kennt sich jemand mit OpenAL (oder mit Soundprogrammierung) aus?:

@Peter-Viehweger
Die wichtigsten Audioformate sind heutzutage AAC, MP3, FLAC. Auch, wenn diese lossy sind (bis auf FLAC), hört man doch keinen Unterschied.

Danke für die Information. Leider muss ich mir dann erst einmal eine Bibliothek laden, um die Daten auf PCM umzuwandeln. .wav hat den Vorteil, dass dieses (meistens) PCM enthält, sodass man dann einfach den Datenblock an OpenAL übergeben kann.  Außerdem wird im User Manual .wav in Verbindung mit einer Funktion namens LoadWAV (oder so) verwendet, wobei ich es nicht geschafft habe, alut (was laut Google KI auch nicht mehr verwendet werden soll) zu erstellen bzw. einzubinden, sodass ich die Datei dann von Hand einlesen musste. Es geht auch nicht darum, Musik zu hören, dann könnte ich ja einfach den VLC mit exec oder CreateProcess im Hintergrund starten, sondern um die Verwendung von OpenAL. Also nur so zur Info, falls du das noch liest.
@Th69 sagte in Kennt sich jemand mit OpenAL (oder mit Soundprogrammierung) aus?:

Woher kommt denn die WAV-Datei? Hast du diese selbst erzeugt?
Das Knacken kommt, wenn diese WAV-Datei auf einem hohen Wert endet und dann abrupt beendet wird (wir hören es dann als Klick bzw. Knacken).

Ich habe mir sowohl einfach eine Datei aus dem Internet geladen und dann eine Menge über das Dateiformat gelernt, als auch einen Sinuston mit 0 und PI/2.0 als Offset erstellt, wobei Ersterer nicht knackte, Zweiterer dagegen schon.

Für 16-bit PCM gibt mir ChatGPT folgenden Code zum Fade-Out:
[...]
(also die eingeladene WAV-Datei ändern, bevor sie abgespielt wird)

Das habe ich in ähnlicher Weise versucht. Ich habe einfach den letzten Wert, z.B. 12345, ausgelesen und dann 12345 weitere Werte; 12344, 12343, ..., 1, 0; angehängt, was meine ich nichts geändert hat. Ich probiere es einmal aus, die letzten Werte wie gezeigt einfach gegen 0 zu faktorisieren.
@Lupus-SLE sagte in Kennt sich jemand mit OpenAL (oder mit Soundprogrammierung) aus?:

Die Werte gehen von 0 bis 255.
Dies ist der Standard (CD-Qualität). Die Werte gehen von -32.768 bis +32.767.

Ich erinnere mich dunkel daran, mit 16-Bit unsigned gearbeitet zu haben.
]]></description><link>https://www.c-plusplus.net/forum/topic/355442/kennt-sich-jemand-mit-openal-oder-mit-soundprogrammierung-aus</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/topic/355442/kennt-sich-jemand-mit-openal-oder-mit-soundprogrammierung-aus</guid><dc:creator><![CDATA[Peter Viehweger]]></dc:creator><pubDate>Fri, 20 Feb 2026 08:48:06 GMT</pubDate></item><item><title><![CDATA[SDL2 Rendert 10x image classe ..Aber nicht hintereinander]]></title><description><![CDATA[So, habe es jetzt mal anders &quot;zusammen gegoogelt&quot;  TUTs 
Hier:

#include &lt;SDL2/SDL.h&gt; 

#include &lt;stdio.h&gt;  
#include &lt;stdlib.h&gt; 


#define hWnd_Button_height 48
#define hWnd_Button_width  42

 SDL_Surface* image = NULL;
 SDL_Texture* texture_image = NULL;
 

SDL_Rect dstrect;
SDL_Rect rects[19][25];

//________________

SDL_Rect newSDL_Rect(int xs, int ys, int widths, int heights)
{
    SDL_Rect rectangular;
    rectangular.x = xs;
    rectangular.y = ys;
    rectangular.w = widths;
    rectangular.h = heights;
    return rectangular;
}

//_________MAIN ____________

int main( int argc, char *argv[] )
{
	
  SDL_Event event; 
  SDL_Init(SDL_INIT_EVERYTHING);
 
  SDL_Window *window =  
  SDL_CreateWindow(&quot;SDL2 clone a surface &quot;, 0, 0, 1024, 768, SDL_WINDOW_SHOWN);
  
  SDL_Renderer *renderer = 
  SDL_CreateRenderer(window, -1, 0);

//-------------------------------------------------

 image =  SDL_LoadBMP(&quot;hwnd_blank_up.bmp&quot;);
  
 texture_image =  
 SDL_CreateTextureFromSurface(renderer,image);

//----------------

  SDL_Surface *hWnd_down = 
  SDL_LoadBMP(&quot;hwnd_blank_down.bmp&quot;);
  
  SDL_Texture *texture_hWnd_down = 
  SDL_CreateTextureFromSurface(renderer,hWnd_down);
  

//-------------------------------------------------

  int quit = 1;
  int system_var = 2;
  
while(quit == 1) // prgramm loop
{
 
 while (SDL_PollEvent(&amp;event))
 {
  switch (event.type)
  {
   case SDL_QUIT:
   quit = 0;
   break;	
   }
  }
 
 //---------------
 
 
 for (int i = 0; i &lt; 18; i++)
  for (int j = 0; j &lt; 24; j++)
   {
    rects[i][j] = newSDL_Rect(20 + i*42, 20 + j*42, 40, 40);
    
   SDL_SetRenderDrawColor(renderer, 255, 102, 0, 255);
   
  SDL_RenderFillRect(renderer, &amp;rects[i][j]);
    }

  
 SDL_RenderPresent(renderer);
} // end of program loop
  
//-------------------------------------------------

  SDL_DestroyTexture(texture_image);
  SDL_FreeSurface(image);
  
  SDL_DestroyTexture(texture_hWnd_down);
  SDL_FreeSurface(hWnd_down);
    
  SDL_DestroyRenderer(renderer);
  SDL_DestroyWindow(window);
  
 SDL_Quit();
 return 0;
}


]]></description><link>https://www.c-plusplus.net/forum/topic/355218/sdl2-rendert-10x-image-classe-aber-nicht-hintereinander</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/topic/355218/sdl2-rendert-10x-image-classe-aber-nicht-hintereinander</guid><dc:creator><![CDATA[Ratz]]></dc:creator><pubDate>Tue, 08 Apr 2025 20:43:21 GMT</pubDate></item><item><title><![CDATA[GPU-Programmierung]]></title><description><![CDATA[Es kommt drauf an, mit welcher CUDA-Version entwickelt werden soll, s.a. CUDA: Unterstützte GPUs.
]]></description><link>https://www.c-plusplus.net/forum/topic/355100/gpu-programmierung</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/topic/355100/gpu-programmierung</guid><dc:creator><![CDATA[Th69]]></dc:creator><pubDate>Thu, 10 Oct 2024 15:09:49 GMT</pubDate></item><item><title><![CDATA[Pong - ein Klassiker in C# und WinForms]]></title><description><![CDATA[https://www.henkessoft.de/Windows Forms/Windows Forms Csharp - 1.htm#Pong
Pong ist der Klassiker überhaupt, daher ein MUSS.
]]></description><link>https://www.c-plusplus.net/forum/topic/355055/pong-ein-klassiker-in-c-und-winforms</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/topic/355055/pong-ein-klassiker-in-c-und-winforms</guid><dc:creator><![CDATA[Erhard Henkes]]></dc:creator><pubDate>Tue, 27 Aug 2024 13:59:47 GMT</pubDate></item><item><title><![CDATA[Snake - ein Klassiker]]></title><description><![CDATA[Snake ist ein Klassiker. Hier beschreibe ich zunächst die Programmierung einer Basisversion für dieses immer hektischer werdende Spiel.
https://www.henkessoft.de/Windows Forms/Windows Forms Csharp - 1.htm#Snake
]]></description><link>https://www.c-plusplus.net/forum/topic/355051/snake-ein-klassiker</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/topic/355051/snake-ein-klassiker</guid><dc:creator><![CDATA[Erhard Henkes]]></dc:creator><pubDate>Sun, 25 Aug 2024 22:54:41 GMT</pubDate></item><item><title><![CDATA[Pixel Maze Challenge]]></title><description><![CDATA[https://www.henkessoft.de/Windows Forms/Windows Forms Csharp - 1.htm#Pixel_Maze_Challenge
Vielleicht eine neue Spielidee. Auf jeden Fall eine interessante Basisversion. Der Spieler muss Schätze einsammeln und wird durch bewegliche Hindernisse herausgefordert. Steuerung über Pfeil-Tasten.
]]></description><link>https://www.c-plusplus.net/forum/topic/355049/pixel-maze-challenge</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/topic/355049/pixel-maze-challenge</guid><dc:creator><![CDATA[Erhard Henkes]]></dc:creator><pubDate>Sat, 24 Aug 2024 19:47:46 GMT</pubDate></item><item><title><![CDATA[Mastermind]]></title><description><![CDATA[Ein Mastermind Game in C# mit WinForms:
https://www.henkessoft.de/Windows Forms/Windows Forms Csharp - 1.htm#Mastermind
]]></description><link>https://www.c-plusplus.net/forum/topic/355047/mastermind</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/topic/355047/mastermind</guid><dc:creator><![CDATA[Erhard Henkes]]></dc:creator><pubDate>Sat, 24 Aug 2024 13:33:59 GMT</pubDate></item><item><title><![CDATA[Schiffe versenken (Battleship)]]></title><description><![CDATA[Ich habe in einem C# / WinForms Tutorial ein Beispiel mit dem Thema Schiffe versenken (Battleship).
https://www.henkessoft.de/Windows Forms/Windows Forms Csharp - 1.htm#Jetzt_spielen_wir_Schiffe_versenken_gegen_einen_KI-Gegner0
Der KI-Gegner wehrt sich bereits raffiniert. Vielleicht interessant für Leute, die mit C# / WinForms einfache 2D Spiele basteln wollen.
Der Link auf den  gesamten Code (incl. exe) steht im Tutorial ganz unten.
]]></description><link>https://www.c-plusplus.net/forum/topic/355038/schiffe-versenken-battleship</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/topic/355038/schiffe-versenken-battleship</guid><dc:creator><![CDATA[Erhard Henkes]]></dc:creator><pubDate>Wed, 21 Aug 2024 20:31:19 GMT</pubDate></item><item><title><![CDATA[Firefox&#x27; Leistenprobleme]]></title><description><![CDATA[Hab's ...

about:config, dann browser.compactmode.show suchen und auf true schalten.
FF schließen und neu öffnen (vorsichtshalber...).
Rechtsklick neben den Tabbereich und auf &quot;Symbolleisten anpassen...&quot; klicken,
dann erscheint unten ein Optionsfeld &quot;Dichte v&quot;, da drauf klicken und &quot;Kompakt (nicht verfügbar)&quot; wählen:

https://i.postimg.cc/MTNGQQL4/grafik.png
Danke, Thema schon gelöst.
]]></description><link>https://www.c-plusplus.net/forum/topic/354574/firefox-leistenprobleme</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/topic/354574/firefox-leistenprobleme</guid><dc:creator><![CDATA[omggg]]></dc:creator><pubDate>Sun, 03 Mar 2024 19:58:16 GMT</pubDate></item><item><title><![CDATA[Eine &#x27;cameraLookAt&#x27; Matrix erstellen]]></title><description><![CDATA[ich habe da ein buch &quot;computergrafik&quot; von alfred nischwitz, in dem das alles wunderbar erklärt wird und bei meinem private project sieht die funktion für die berechnung der matrix dann so aus:
int Viewing(float *viewingmatrix, float *eyevector, float *lookvector, float *upvector)
{
	float nvector[VECTORSIZE];
	float uvector[VECTORSIZE];
	float vvector[VECTORSIZE];

	SubtractVectors(nvector, eyevector, lookvector);
	CrossProduct(uvector, upvector, nvector);
	CrossProduct(vvector, nvector, uvector);

	NormalizeVector(nvector);
	NormalizeVector(uvector);
	NormalizeVector(vvector);

	viewingmatrix[0] = uvector[0];
	viewingmatrix[1] = uvector[1];
	viewingmatrix[2] = uvector[2];
	viewingmatrix[3] = uvector[0] * -eyevector[0] + uvector[1] * -eyevector[1] + uvector[2] * -eyevector[2];

	viewingmatrix[4] = vvector[0];
	viewingmatrix[5] = vvector[1];
	viewingmatrix[6] = vvector[2];
	viewingmatrix[7] = vvector[0] * -eyevector[0] + vvector[1] * -eyevector[1] + vvector[2] * -eyevector[2];

	viewingmatrix[8] = nvector[0];
	viewingmatrix[9] = nvector[1];
	viewingmatrix[10] = nvector[2];
	viewingmatrix[11] = nvector[0] * -eyevector[0] + nvector[1] * -eyevector[1] + nvector[2] * -eyevector[2];

	viewingmatrix[12] = 0.0f;
	viewingmatrix[13] = 0.0f;
	viewingmatrix[14] = 0.0f;
	viewingmatrix[15] = 1.0f;

	return 0;
}

wobei
eyevector: position der kamera
lookvector: zielpunkt der kamera
upvector: da wo &quot;oben&quot; ist
]]></description><link>https://www.c-plusplus.net/forum/topic/354479/eine-cameralookat-matrix-erstellen</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/topic/354479/eine-cameralookat-matrix-erstellen</guid><dc:creator><![CDATA[Peter Viehweger]]></dc:creator><pubDate>Tue, 30 Jan 2024 02:46:31 GMT</pubDate></item><item><title><![CDATA[Einfaches Textfeld in sfml für Eingabe&#x2F;Ausgabe]]></title><description><![CDATA[Für C&amp;P mußt du wohl das Key-Handling (s. sf::Event: KeyPressed) selber behandeln und dann entsprechend die Funktionen aus der sf::Clipboard-Klasse aufrufen.
]]></description><link>https://www.c-plusplus.net/forum/topic/354499/einfaches-textfeld-in-sfml-für-eingabe-ausgabe</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/topic/354499/einfaches-textfeld-in-sfml-für-eingabe-ausgabe</guid><dc:creator><![CDATA[Th69]]></dc:creator><pubDate>Tue, 23 Jan 2024 09:08:45 GMT</pubDate></item><item><title><![CDATA[CAD STEP-format]]></title><description><![CDATA[@SoIntMan sagte in CAD STEP-format:

Was meinst du zu DWG format?

Das DWG Format wird vermutlich dein Problem nicht verbessern, da wie oben besprochen Höhen in verschiedenen Weisen angegeben werden können. Ferner ist dieses Format nach meinem Kenntnisstand nicht offen.
]]></description><link>https://www.c-plusplus.net/forum/topic/354471/cad-step-format</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/topic/354471/cad-step-format</guid><dc:creator><![CDATA[Quiche Lorraine]]></dc:creator><pubDate>Sun, 14 Jan 2024 19:05:57 GMT</pubDate></item><item><title><![CDATA[3D Projektion (Code) *entfernt*]]></title><description><![CDATA[Ich hab das mal zur Sicherheit entfernt. Da waren im Nachhinein noch soviel Fehler drin, das konnte ich nicht mehr stehen lassen. Sorry 
]]></description><link>https://www.c-plusplus.net/forum/topic/354411/3d-projektion-code-entfernt</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/topic/354411/3d-projektion-code-entfernt</guid><dc:creator><![CDATA[zeropage]]></dc:creator><pubDate>Fri, 24 Nov 2023 18:44:26 GMT</pubDate></item><item><title><![CDATA[Asteroids Example (Code)]]></title><description><![CDATA[@Jockelx sagte in Asteroids Example (Code):

Willst du feedback?

Hallo, das ist eine gute Frage, weshalb ich das Bedürfnis habe, Code zeigen zu wollen. Denn wenn ich meine Codes vor 5 Jahren sehe, schäme ich mich in Grund und Boden. Was müssen die Leute wohl gedacht haben, als ich sie gezeigt habe?
Trotzdem will man sich nicht so ganz alleine damit beschäftigen.
Auf jeden Fall habe ich jetzt Eure Anregungen und Verbesserungen umgesetzt, wie es mir möglich ist. Ich wollte noch jeden hardcodierten Wert in eine Variable überführen, aber das wurde mir zu kleinteilig, und ob das wirklich zur Übersichtlichkeit beiträgt?
Die Namen der User, dessen Vorschläge ich umgesetzt habe, habe ich an den betreffenden Stellen kommentiert.
#pragma once
#include &quot;zpEngine.h&quot;
#include &quot;TransformVector_T.h&quot;

namespace game
{
	struct SpaceObject
	{
		zp::VectorShape2D&lt;float&gt; Shape, Source;
		zp::TransformVector&lt;float&gt; Transform;

		zp::Vector2D&lt;float&gt; Position, Velocity;
		float Size = 0;
		float Heading = 0;
		float Rotate = 0;
	};

	// @Hustbaer
	// to do: load or switch in onUserCreate
	struct DisplaySettings
	{
		zp::ColorDot ScreenColor;
		zp::ColorDot AsteroidColor;
		zp::ColorDot ShipColor;
		zp::ColorDot BulletColor;

		zp::zpFont ScoreFont;
	};

	// dito
	struct GameSettings
	{
		zp::TriangleShape2D&lt;float&gt; Ship;
		zp::Vector2D&lt;float&gt; ShipStartPosition;
		float ShipSpeed = 0;
		float ShipSteerSpeed = 0;

		float BulletSpeed = 0;

		int NumOfAsteroids = 0;
		zp::Vector2D&lt;float&gt; AsteroidsStartPosition;
		float AsteroidsRadius = 0;
		float AsteroidsSpeed = 0;
		float AsteroidsDeltaSpeed = 0;
		float AsteroidsRotateSpeed = 0;
		
		int StageTime = 0;
		float StageDeltaTime = 0;
	};

	// to do: autosave every 5 GameStages, load on user input in onUserCreate
	struct PlayerState
	{
		float AsteroidsSpeed = 0;

		int GameScore = 0;
		int GameStage = 0;
		float StageTime = 0;

		bool Dead = false;
		bool Won = false;
	};

	// @Hustbaer
	static const bool checkCollision(const SpaceObject&amp; lhs, const SpaceObject&amp; rhs)
	{
		auto predicate = [&amp;](const zp::Vector2D&lt;float&gt;&amp; point)
		{
			return zp::utils::isPointInsideCircle(lhs.Shape.center(), lhs.Size, point);
		};

		const auto pos = std::find_if(std::begin(rhs.Shape.vertices()), std::end(rhs.Shape.vertices()), predicate);
		return pos != std::end(rhs.Shape.vertices());
	}

	static const bool checkCollision(const SpaceObject&amp; obj, const zp::Vector2D&lt;float&gt;&amp; point)
	{
		return zp::utils::isPointInsideCircle(obj.Shape.center(), obj.Size, point);
	}

	static zp::Vector2D&lt;float&gt; offscreenPos() 
	{ 
		return { -1, -1 }; 
	}

	static void removeOffscreen(std::vector&lt;SpaceObject&gt;&amp; objects)
	{
		auto predicate = [](const SpaceObject&amp; obj)
		{
			return obj.Position.x &lt; 0 || obj.Position.y &lt; 0;
		};

		const auto pos = std::remove_if(std::begin(objects), std::end(objects), predicate);
		objects.erase(pos, std::end(objects));
	}

	static void wrapCoordinates(zp::Vector2D&lt;float&gt;&amp; pos, const zp::Vector2D&lt;float&gt;&amp; boundary)
	{
		const zp::Vector2D&lt;float&gt; posIn = pos;

		if (posIn.x &lt; 0.f)         pos.x = posIn.x + boundary.x;
		if (posIn.x &gt;= boundary.x) pos.x = posIn.x - boundary.x;
		if (posIn.y &lt; 0.f)         pos.y = posIn.y + boundary.y;
		if (posIn.y &gt;= boundary.y) pos.y = posIn.y - boundary.y;
	}

	static zp::Vector2D&lt;float&gt; wrapCoordinates(const zp::Vector2D&lt;float&gt;&amp; pos, const zp::Vector2D&lt;float&gt;&amp; boundary)
	{
		zp::Vector2D&lt;float&gt; wrappedPos = pos;

		if (pos.x &lt; 0.f)         wrappedPos.x = pos.x + boundary.x;
		if (pos.x &gt;= boundary.x) wrappedPos.x = pos.x - boundary.x;
		if (pos.y &lt; 0.f)         wrappedPos.y = pos.y + boundary.y;
		if (pos.y &gt;= boundary.y) wrappedPos.y = pos.y - boundary.y;

		return wrappedPos;
	}
}

class AsteroidsGame : public zpEngine
{
	// variables

	game::DisplaySettings Display;
	game::GameSettings Game;
	game::PlayerState Player;

	game::SpaceObject Ship;
	std::vector&lt;game::SpaceObject&gt; Asteroids;
	std::vector&lt;game::SpaceObject&gt; Bullets;
	
	// methodes

	void createDisplay(); 
	void createGame();
	void createPlayerState();

	void createShip();
	void createStartAsteroids();
	void createAsteroids(
		const int N, 
		const float radius, 
		const zp::Vector2D&lt;float&gt;&amp; position, 
		std::vector&lt;game::SpaceObject&gt;&amp; asteroids);

	void updateShip(const float elapsedTime);
	void updateAsteroids(const float elapsedTime);
	void updateBullets(const float elapsedTime);
	void updatePlayerState(const float elapsedTime);

	void drawShip();
	void drawAsteroid(const game::SpaceObject&amp; asteroid);
	void drawBullet(const game::SpaceObject&amp; bullet);
	void drawScore();

	void stopObject(game::SpaceObject&amp; obj) const;
	void stopObjects();

	void stageDone();
	void gameOver();
	void resetShip();
	void resetGame();

	// overwritten methodes

	virtual bool onUserCreate() override;
	virtual bool onUserUpdate(float elapsedTime) override;
	virtual bool handleInput(const float elapsedTime) override;
	virtual void setDot(const int32_t x, const int32_t y, const zp::ColorDot&amp; color) override;

public:
	AsteroidsGame(const std::string&amp; appName = {});
};


#include &quot;AsteroidsGame.h&quot;

using namespace game;

AsteroidsGame::AsteroidsGame(const std::string&amp; appName) { setAppName(appName); };

void AsteroidsGame::createDisplay()
{
	Display.ScreenColor = zp::ColorDot::Default();
	Display.AsteroidColor = zp::ColorDot::YELLOW();
	Display.ShipColor = zp::ColorDot::DGREY();
	Display.BulletColor = zp::ColorDot::BLUE();

	Display.ScoreFont.font = canvas().text.font;
	Display.ScoreFont.color = zp::ColorDot::DRED();

	canvas().color = Display.ScreenColor;
	canvas().text.color = Display.ScoreFont.color;
}

void AsteroidsGame::createGame()
{
	Game.Ship = { { -5, 0 }, { 5, 0 }, { 0, -15 } };
	Game.ShipStartPosition = canvas().size.center();
	Game.ShipSpeed = 35.f;
	Game.ShipSteerSpeed = 2.2f;

	Game.BulletSpeed = 50.f;

	Game.NumOfAsteroids = 3;
	Game.AsteroidsStartPosition = { 50, 50 };
	Game.AsteroidsRadius = 25.f;
	Game.AsteroidsSpeed = 20.f;
	Game.AsteroidsDeltaSpeed = 5.f;
	Game.AsteroidsRotateSpeed = 0.5f;

	Game.StageTime = 500;
	Game.StageDeltaTime = 15.f;
}

void AsteroidsGame::createPlayerState()
{
	Player.GameStage = 1;
	Player.GameScore = 0;
	Player.StageTime = static_cast&lt;float&gt;(Game.StageTime);
	Player.AsteroidsSpeed = Game.AsteroidsSpeed;
}

void AsteroidsGame::createShip()
{
	Ship.Source = Game.Ship;
	Ship.Position = Game.ShipStartPosition;
}

void AsteroidsGame::createAsteroids(const int N, const float size, const zp::Vector2D&lt;float&gt;&amp; position, std::vector&lt;SpaceObject&gt;&amp; asteroids)
{
	asteroids.clear();
	constexpr auto V = 20; // vertices of asteroid
	for (auto i = 0; i &lt; N; ++i)
	{
		std::vector&lt;zp::Vector2D&lt;float&gt;&gt; vertices;
		for (auto i = 0; i &lt; V; ++i)
		{
			const float radius = random().uniformReal&lt;float&gt;(0.9f, 1.1f) * size;
			const float angle = (i * 1.f) / (V * 1.f) * zp::math::PI_2&lt;float&gt;;
			vertices.push_back(zp::math::toCartesian&lt;float&gt;(radius, angle));
		}
		SpaceObject asteroid;
		asteroid.Source = zp::PolygonShape2D(vertices);
		asteroid.Position = random().uniformReal&lt;float&gt;(0.7f, 1.3f) * position;
		asteroid.Size = size;
		asteroid.Heading = random().uniformReal&lt;float&gt;(0, zp::math::PI_2&lt;float&gt;);
		asteroid.Velocity =
			random().uniformReal&lt;float&gt;(0.7f, 1.3f)
			* zp::vector::getDirectionVector2D&lt;float&gt;(asteroid.Heading)
			* Player.AsteroidsSpeed;

		asteroids.push_back(asteroid);
	}
}

void AsteroidsGame::createStartAsteroids()
{
	createAsteroids(Game.NumOfAsteroids, Game.AsteroidsRadius, Game.AsteroidsStartPosition, Asteroids);
}

bool AsteroidsGame::onUserCreate()
{
	// @Schlangenmensch
	createDisplay();
	createGame();
	createPlayerState();

	createShip();
	createStartAsteroids();

	return true;
}

void AsteroidsGame::updateShip(const float elapsedTime)
{
	Ship.Shape = Ship.Source;
	Ship.Position += Ship.Velocity * elapsedTime;
	Ship.Transform.translate(Ship.Position); // thrust 
	Ship.Transform.rotateRelative(Ship.Shape.center(), Ship.Heading); // steer

	Ship.Transform.transform(Ship.Shape);
	wrapCoordinates(Ship.Position, screen().size.right()); // keep in space
	drawShip();
}

void AsteroidsGame::updateAsteroids(const float elapsedTime)
{
	for (auto&amp; asteroid : Asteroids)
	{
		asteroid.Shape = asteroid.Source;
		asteroid.Position += asteroid.Velocity * elapsedTime;
		asteroid.Transform.translate(asteroid.Position); // move 
		asteroid.Transform.rotate(asteroid.Rotate += Game.AsteroidsRotateSpeed * elapsedTime); // rotate 
		if (asteroid.Rotate &gt; zp::math::PI_2&lt;float&gt;) asteroid.Rotate = asteroid.Rotate - zp::math::PI_2&lt;float&gt;;

		asteroid.Transform.transform(asteroid.Shape);
		wrapCoordinates(asteroid.Position, screen().size.right()); // keep in space
		drawAsteroid(asteroid);
	}
}

void AsteroidsGame::updateBullets(const float elapsedTime)
{
	std::vector&lt;SpaceObject&gt; childAsteroids; // prepare child asteroids
	for (auto&amp; bullet : Bullets)
	{
		bullet.Position += bullet.Velocity * elapsedTime; // move 
		if (bullet.Position.x &gt;= screen().size.right().x || bullet.Position.y &gt;= screen().size.right().y)
			bullet.Position = offscreenPos(); // move offscreen

		// check collision with asteroids
		const float childAsteroidSize = Game.AsteroidsRadius / 2.f;
		for (auto&amp; asteroid : Asteroids)
		{
			if (checkCollision(asteroid, bullet.Position))
			{
				// asteroid hit
				bullet.Position = offscreenPos(); // move offscreen
				if (asteroid.Size &gt; childAsteroidSize)
				{
					// create 2 child asteroids
					createAsteroids(2, childAsteroidSize, asteroid.Shape.center(), childAsteroids);
				}
				asteroid.Position = offscreenPos(); // move offscreen
				Player.GameScore += 100;
			}
		}
		drawBullet(bullet);
	}
	// append child asteroids to existing vector
	Asteroids.insert(Asteroids.end(), childAsteroids.begin(), childAsteroids.end()); // @JockelX
}

void AsteroidsGame::updatePlayerState(const float elapsedTime)
{
	// check stage time
	if (!Player.Dead &amp;&amp; !Player.Won)
	{
		Player.StageTime -= Game.StageDeltaTime * elapsedTime;
	}

	if (Player.StageTime &lt; 0)
	{
		Player.Dead = true;
	}

	// check ship collision with asteroids
	for (const auto&amp; asteroid : Asteroids)
	{
		if (checkCollision(asteroid, Ship))
		{
			Player.Dead = true;
		}
	}

	// player won?
	if (Asteroids.empty())
	{
		Player.Won = true;
	}
}

bool AsteroidsGame::onUserUpdate(float elapsedTime)
{
	// @Schlangenmensch
	updateShip(elapsedTime);
	updateAsteroids(elapsedTime);
	updateBullets(elapsedTime);
	
	removeOffscreen(Bullets);
	removeOffscreen(Asteroids);

	updatePlayerState(elapsedTime);
	drawScore();

	return true;
}

bool AsteroidsGame::handleInput(const float elapsedTime)
{
	if (getKey(VK_ESCAPE).pressed) // exit game
		return false;

	if (Player.Won)
	{
		stageDone();
	}

	if (Player.Dead)
	{
		gameOver();
	}

	if (getKey(VK_BACK).pressed) // reset game
	{
		resetGame();
	}

	// steer ship
	if (getKey(VK_RIGHT).held)
	{
		Ship.Heading -= Game.ShipSteerSpeed * elapsedTime;
	}
	if (getKey(VK_LEFT).held)
	{
		Ship.Heading += Game.ShipSteerSpeed * elapsedTime;
	}

	// thrust ship
	if (getKey(VK_UP).held)
	{	
		Ship.Velocity += zp::vector::getDirectionVector2D&lt;float&gt;(-Ship.Heading) * Game.ShipSpeed * elapsedTime;
	}
	if (getKey(VK_DOWN).held)
	{
		Ship.Velocity -= zp::vector::getDirectionVector2D&lt;float&gt;(-Ship.Heading) * Game.ShipSpeed * elapsedTime;
	}

	// fire bullet
	if (getKey(VK_SPACE).released)
	{
		SpaceObject bullet;
		bullet.Position = Ship.Shape.vertices()[2];
		bullet.Heading = Ship.Heading;
		bullet.Velocity = Ship.Velocity + zp::vector::getDirectionVector2D&lt;float&gt;(-bullet.Heading) * Game.BulletSpeed;
		
		Bullets.push_back(bullet);
	}

	return true;
}

void AsteroidsGame::setDot(const int32_t x, const int32_t y, const zp::ColorDot&amp; color)
{
	const zp::Vector2D&lt;float&gt; wrappedPos = wrapCoordinates(zp::utils::castPointToVector2D&lt;float&gt;({ x, y }), screen().size.right());
	zpConsoleEngine::setDot(zp::math::toInt&lt;int32_t&gt;(wrappedPos.x), zp::math::toInt&lt;int32_t&gt;(wrappedPos.y), color);
}

void AsteroidsGame::drawShip()
{
	drawVectorShape(Ship.Shape, Display.ShipColor);
}

void AsteroidsGame::drawAsteroid(const SpaceObject&amp; asteroid)
{
	drawVectorShape(asteroid.Shape, Display.AsteroidColor);
}

void AsteroidsGame::drawBullet(const SpaceObject&amp; bullet)
{
	drawPoint(bullet.Position, Display.BulletColor);
}

void AsteroidsGame::drawScore()
{
	drawString(
		Display.ScoreFont.font, 0, 1,
		  &quot;  Score &quot; + std::to_string(Player.GameScore)
		+ &quot;  Stage &quot; + std::to_string(Player.GameStage)
		+ &quot;  Time &quot;  + std::to_string(zp::math::toInt&lt;int&gt;(Player.StageTime)),
		screen().text.color);
}

void AsteroidsGame::stageDone()
{
	stopObjects();
}

void AsteroidsGame::gameOver()
{
	stopObjects();
	fillScreen(zp::ColorDot::RED());
	screen().text.color = zp::ColorDot::BLACK();
}

void AsteroidsGame::resetGame()
{
	fillScreen(Display.ScreenColor);
	screen().text.color = Display.ScoreFont.color;

	if (Player.Dead)
	{
		Player.GameStage = 1;
		Player.GameScore = 0;
		Player.AsteroidsSpeed = Game.AsteroidsSpeed;
		Player.Dead = false;
	}
	else if (Player.Won)
	{
		Player.GameScore += 300 * Player.GameStage;
		Player.GameScore += zp::math::toInt&lt;int&gt;(Player.StageTime) * 2;
		Player.GameStage ++;
		Player.AsteroidsSpeed += Game.AsteroidsDeltaSpeed;
		Player.Won = false;
	}

	resetShip();
	Bullets.clear();
	Player.StageTime = static_cast&lt;float&gt;(Game.StageTime);
	createAsteroids(Game.NumOfAsteroids, Game.AsteroidsRadius, Game.AsteroidsStartPosition, Asteroids);
}

void AsteroidsGame::stopObject(SpaceObject&amp; obj) const
{
	obj.Velocity.clear();
}

void AsteroidsGame::stopObjects()
{
	stopObject(Ship);
	for (auto&amp; asteroid : Asteroids)
		stopObject(asteroid);
	for (auto&amp; bullet : Bullets)
		stopObject(bullet);
}

void AsteroidsGame::resetShip()
{
	Ship.Position = Game.ShipStartPosition;
	Ship.Velocity.clear();
	Ship.Heading = 0;
}


Danke fürs lesen 
Edit: Beim selber rüberschauen sind mir ein paar Ungereimtheiten aufgefallen, die habe ich editiert, also nicht wundern, wenn sich Kleinigkeiten geändert haben.
]]></description><link>https://www.c-plusplus.net/forum/topic/354166/asteroids-example-code</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/topic/354166/asteroids-example-code</guid><dc:creator><![CDATA[zeropage]]></dc:creator><pubDate>Thu, 06 Jul 2023 15:43:58 GMT</pubDate></item><item><title><![CDATA[Cheats für Spiele, Aimbot, Wallhack]]></title><description><![CDATA[Hast du echt 13 Jahre für 87 Zeilen Code gebraucht? Das sind 6.69 Zeilen pro Jahr, 0.56 Zeilen pro Monat und etwa 0.018 Zeilen pro Tag. Ich hoffe, du hast dich nicht überanstrengt bei der ganzen Tipperei.
]]></description><link>https://www.c-plusplus.net/forum/topic/283981/cheats-für-spiele-aimbot-wallhack</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/topic/283981/cheats-für-spiele-aimbot-wallhack</guid><dc:creator><![CDATA[DocShoe]]></dc:creator><pubDate>Mon, 12 Jun 2023 14:35:51 GMT</pubDate></item><item><title><![CDATA[Animation Spritesheet FLTK]]></title><description><![CDATA[@sirEgbert Ne, Bilder Hochladen geht hier nicht. Gibt aber genug Image Hoster, bei denen man Bilder hochladen und anschließend den Link hier posten kann.
]]></description><link>https://www.c-plusplus.net/forum/topic/354116/animation-spritesheet-fltk</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/topic/354116/animation-spritesheet-fltk</guid><dc:creator><![CDATA[Schlangenmensch]]></dc:creator><pubDate>Mon, 29 May 2023 11:15:14 GMT</pubDate></item><item><title><![CDATA[Performance (PC games)]]></title><description><![CDATA[Bei Spielszenen, wo viele Objekte zu sehen sind müssen mehr Grafikoperationen ausgeführt werden. Kollidieren die Objekte, dann muss mehr Physik-Berechnung gemacht werden.
Daten die noch nicht im Cache liegen müssen während des Spiels dann nachgeladen werden was Zeit kostet. Ist der Cache voll und es fallen Daten raus, die später dann doch wieder gebraucht werden, kostet das auch Zeit.
Speicherlecks bringen das Spiel über lang zum Absturz aber schon vorher wird das Spiel langsamer werden.
Ich denke das sind erstmal Faktoren, die dafür sorgen, dass ein Spiel mal kurzzeitig langsamer geht.
Ansonsten können halt Prozesse im Hintergrund dann noch für Zufall in der CPU/RAM-Auslastung sorgen, welche dann auch im Spiel als Ruckler auftreten.
]]></description><link>https://www.c-plusplus.net/forum/topic/354001/performance-pc-games</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/topic/354001/performance-pc-games</guid><dc:creator><![CDATA[XMAMan]]></dc:creator><pubDate>Fri, 31 Mar 2023 15:59:27 GMT</pubDate></item><item><title><![CDATA[Computergrafikonzepte bei richtig benannt und verstanden?]]></title><description><![CDATA[Eine Kette von Transformationen wird ausgeführt, um 3D-Welt-Koordinaten in 2D-Pixel-Koordinaten zu bekommen.
Das nennt man Rasterung oder auf Englisch &quot;Rasterization&quot;.
Ich habe mal jetzt mir überlegt, so eine nummerierte Liste von matheartigen Funktionen zu definieren.
Jede dieser Funktionen hat eine Eingabe und eine Ausgabe.
Man denke an Funktion(Eingabe) -&gt; Ausgabe.
0. Model() -&gt; 3D object coordinates
1. World(3D object coordinates) -&gt; 3D world coordinates
2. Light(3D world coordinates) -&gt; light intensity value
3. View(3D world coordinates) -&gt; 3D camera coordinates
4. Projection(3D camera coordinates) -&gt; 2D world coordinates `(e.g., matching a point on a near/projection plane)`
5. Painter's algorithm(projected 2D world coordinates `(e.g., matching a point on a near/projection plane)`) -&gt; projected 2D world coordinates `(e.g., matching a point on a near/projection plane)`
6. Clip(projected 2D world coordinates `(e.g., matching a point on a near/projection plane)`) -&gt; projected 2D world coordinates `(e.g., matching a point on a near/projection plane)`
7. Viewport(projected 2D world coordinates `(e.g., matching a point on a near/projection plane)`) -&gt; 2D pre-fragment coordinates
8. Rasterization(2D pre-fragment coordinates) -&gt; 2D fragment coordinates.
9. Fragment shading/processing(2D fragment coordinates) -&gt; 2D pixel coordinates
10. Draw pixel(2D pixel coordinate) -&gt; pixel (on screen)

Kommentare dazu:


Man fängt bei Schritt 0 an (modelliert seine OBJ-Datei zum Beispiel in Blender).


Dann macht man aus den OBJ-Objektkoordinaten 3D-Weltkoordinaten (durch Skalierung, Rotation und Translation).


Zwischendurch berechnet man die Lichtintensitäten, indem man die transformierten Weltkoordinaten nimmt und dann verrechnet, mit einem sogenannten Beleuchtungsmodell.
Zum Beispiel kann ich ein Lambertsche Beleuchtungsmodell nehmen, dass diffuses Licht imitierten soll (also &lt;N, L&gt; = Lichtintensität).
Dann habe ich die Lichtintensitäten pro Dreiecksoberflächennormale (für einfache Schattierung oder &quot;Flat Shading&quot;) oder Dreieckseckpunktnormale (für Gouraud-Shattierung).


Die inverse der Kamera-Transformation (ganz normale Skalierung, Rotation und Translation), wird zum Kamera-Sichtvolumen.


Jetzt nimmt man diese Kamera-Koordinaten und dividiert sie durch den z-Wert (dann hat man eine schwache Projektion ohne Normalisierung der XYZ-Werte nach [-1; 1] bzw. [0, 1]).
Das entspricht einem Schnappschuss mit der Foto-Kamera.
Nach der Projektion (der Division mit z) hat man die 2D-Welt-Koordinaten projiziert auf der Projektionsebene.
Also: x* := H * x / d und y* := H * y / d (H ist der Z-Abstand zum Projektionspunkt).
H war in diesem Fall 1.


Jetzt nimmt man diese projizierten Punkte in 2D-Welt-Koordinaten und sortiert sie alle, indem man den Durchschnitt der Z-Werte von den Dreieckseckpunkten bildet und dann absteigend von hinten (Z-Wert = 1000) bis vorne (Z-Wert = 1) sortiert.
Die Punkte sind immer noch in 2D auf der Projektionsebene in Weltkoordinaten.


Jetzt schneidet man alle vom Sichtvolumen &quot;raus guckenden&quot; Dreiecke ab.
Wir sind immer noch in 2D-Welt-Koordinaten in der Projektionsebene.
Aber man behält die 3D-Sichtvolumenkoordinaten aus Schritt 3.


Nun wollen wir die Projektionsebene verlassen und konvertieren alle diese 2D-Welt-Koordinaten von der Projektionsebene in &quot;Pre-Fragment-Koordinaten&quot;.


Der Die Rasterungsroutine macht dann aus den &quot;Pre-Fragmenten&quot;, Fragmente.
Wir haben also Fragmentkoordinaten (die fast Pixel sind, aber noch &quot;gefärbt&quot; werden müssen durch Interpolation der Texturkoordinaten zum Beispiel.)


Jetzt werden die Fragmente final gefärbt.
Hierzu nimmt man beispielsweise die Texturkoordinaten der Dreiecke und berechnet zunächst die Pixelposition bzw. Texelposition der Textur.
Mit der Texelposition wird dann die Farbe in der Textur ermittelt.
Dann wird diese Farbe genommen und mit einer vorhandenen Farbe zusammen vermischt.


Jetzt hat man ein Pixel, dass man darstellen kann auf seinem Bildschirm.


Das war's, oder?
War das richtig?
Ich glaube, bei den Details hakt es bei mir noch.
Ich finde die Terminologien der Computergrafik verwirrend.
Angemerkt sei noch:
Schritte 1-4 kann man als Eckpunktprozessor oder &quot;Vertex-Shader&quot; verstehen, oder?
Der Fragmentprozessor (Fragmente sind im Begriff Pixel zu werden), ist im Rasterungsroutine drin, oder?
Ein ja/nein, reicht mir auch.
PS: Das habe ich mir noch in meinen Notizen geschrieben:
### 01 Fragment

Assume points in 2D or 3D space have continuous coordinates.

A rasterizer converts these continuous coordinates to discrete ones.

We call these discrete coordinates from the rasterizer &quot;fragments&quot;.

Think of  fragments as &quot;non-ready pixels&quot;, &quot;raw pixels&quot; or &quot;soon-to-be pixels&quot;, if you like.

Fragment shaders/processors compute the final pixel color (e.g., by interpolating texture coordinates).

A fragment shader resides inside a rasterizer.

Nachtrag:
Mir ist aufgefallen, dass Schritt 6 nur bei normalisierten Ansichtsvolumen möglich ist.
Das Wegschneiden (ich glaube damit ist gemeint &quot;Frustum Culling&quot; und auch &quot;Backface Culling&quot;, kann zum Beispiel nach Schritt 1 (nach der Objekt-Zu-Welt-Koordinaten-Transformation) passieren.
]]></description><link>https://www.c-plusplus.net/forum/topic/353514/computergrafikonzepte-bei-richtig-benannt-und-verstanden</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/topic/353514/computergrafikonzepte-bei-richtig-benannt-und-verstanden</guid><dc:creator><![CDATA[[[global:former_user]]]]></dc:creator><pubDate>Tue, 20 Sep 2022 15:24:21 GMT</pubDate></item><item><title><![CDATA[Interpolationen bei der Rasterung (basierend auf Ebenen-Gleichung) - Texturierung und Gouraud-Beleuchtung von Dreiecken]]></title><description><![CDATA[Hallo dozgon,
ich konnte dein Fehler mit mein Rasterizer nachstellen:
https://i.ibb.co/yRgmvqk/Dot-Lighting-Pixel-Shader-vs-Vertex-Shader.jpg
Wenn du im VertexShader die Farbe berechnest, dann beachtest du nicht, dass ja die &quot;ToLight&quot;-Richtung falsch ist.
Im VertexShader schreibe ich
 Vector3D lightPosition = new Vector3D(0, 7.5f, 3);
            Vector3D toLight = Vector3D.Normalize(lightPosition - outputVertex.Position);
            Vector3D lam = new Vector3D(1, 1, 1) * System.Math.Max(outputVertex.Normal * toLight, 0.0f);
            shaderOutput.Interpolationvariables.AddVector3D(lam, Interpolationvariables.VariableType.WithoutPerspectiveDivision);


Im PixelShader schreibe ich
 Vector3D toLight = Vector3D.Normalize(prop.Lights[0].Position - v.Position);
                        return new Vector4D(new Vector3D(1, 1, 1) * Math.Max(normalVector * toLight, 0.0f), 1);

Wenn ich im PixelShader rechne, dann bekommt ja toLight stehts den &quot;echten&quot; Wert und wenn ich im VertexShader das mache, dann interpoliere ich ja indirekt den toLight-Wert übers Dreieck (Ohne das ich dabei aber toLight oder die Normale nochmal normalisiere).
]]></description><link>https://www.c-plusplus.net/forum/topic/353438/interpolationen-bei-der-rasterung-basierend-auf-ebenen-gleichung-texturierung-und-gouraud-beleuchtung-von-dreiecken</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/topic/353438/interpolationen-bei-der-rasterung-basierend-auf-ebenen-gleichung-texturierung-und-gouraud-beleuchtung-von-dreiecken</guid><dc:creator><![CDATA[XMAMan]]></dc:creator><pubDate>Sun, 18 Sep 2022 07:00:39 GMT</pubDate></item><item><title><![CDATA[Code-Organisation bei Software-Rendererern (Ray Tracer&#x2F;Rasterizer)]]></title><description><![CDATA[Hallo Dozgon,
bei der Rasterung ist die Grundidee: Lade eine Menge von Dreiecken und Texturen in den Speicher, lege fest welche Shader verwendet werden sollen und parametrisiere die Shader und anderen Bauteile der Grafikpipeline. Dann rufe nur noch den Zeichenbefehl auf um das Dreiecksarray zu zeichnen. Dann wird das Array mit dem Painter-Algorithmus gemalt (Schleife geht über alle Dreiecke).
Beim Raytracing iteriert man nicht über eine gegebene Menge von Objekten/Fragmenten/Dreiecken/Linien sondern man iteriert über alle Pixel und bestimmt dessen Farbwert, indem man schaut, welches Objekt durch diesen Pixel betrachtet wird. Es gibt zwei Grundsätze beim Raytracing: Strahlen von der Kamera aus erzeugen und dann durch die Scene verfolgen (Pathtracing) und Strahlen von der Lichtquelle erzeugen und durch die Scene verfolgen (Lighttracing).
Vom Design her würde ich mich beim Rasterizer an der Grafikpipeline(https://de.wikipedia.org/wiki/Grafikpipeline#/media/Datei:3D-Pipeline.png / http://www.songho.ca/opengl/gl_transform.html) orientieren.
D.h. du hast erstmal Klassen zum Speichern von Texturen und Dreiecken. Mit 4*4-Matrizen (Model * Kamera * Projektion) transformierst du alle Dreiecke vom Objektspace in Clippingkoordinaten. Das macht der Vertexshader, welcher eine Callbackfunktion ist, um ihn frei austauschbar zu machen. Für das Clipping hast du dann eine eigene Klasse, um aus ein Dreieck dann eine Liste von Dreiecken zu machen. Dann die Division durch W für jeden Vertex.  Für die Viewporttransformation hast du auch eine eigene Klasse, um die Dreiecke in 2D-Dreiecke zu bringen, welche in Pixelkoordinaten vorliegen.
Dann hast du eine Triangle-Raster-Klasse, welche als Input ein 2D-Dreieck bekommt und was dann für jedes Pixel, was innerhalb vom Dreieck liegt ein Callback-Handler aufruft. Innerhalb von diesen Callbackhandler wird dann erst der PixelShader um die Farbe zu bestimmen. Dann noch das Zeichnen in den Farb- und Tiefenpuffer.
Du brauchst also mindestens die Klassen: ColorTexture, DepthTexture, Buffer (Enthält eine Farb- und Tiefentextur), TriangleRasterizer, VertexShader, PixelShader, Matrix4x4, Vertex, Vector3D, Clipping.
Beim Raytracer konvertiert man alle Dreiecke/Objekte auch erst vom Objektspace in den World- oder Kamera-Space. Man könnte das dort auch Vertexshader nennen, wenn man das will. Aber ab da kannst du es nicht mehr mit einer Grafikpipeline vergleichen. Du schickst ja keine Dreiecke durch eine Pipeline, wo am Ende dann ein Farbpuffer wartet sondern du ermittelst für jeden Pixel den Schnittpunkt mit dem ersten Dreieck.
Die Gemeinsamkeit zwischen Rasterizer und Raytracer ist also, dass beide eine Menge von Dreiecken, Lichtquellen und eine Kamera als Input bekommen und beide ein Bild erzeugen. Der Teil dazwischen muss dann unterschiedlich implementiert werden.
]]></description><link>https://www.c-plusplus.net/forum/topic/353486/code-organisation-bei-software-rendererern-ray-tracer-rasterizer</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/topic/353486/code-organisation-bei-software-rendererern-ray-tracer-rasterizer</guid><dc:creator><![CDATA[XMAMan]]></dc:creator><pubDate>Tue, 13 Sep 2022 19:05:30 GMT</pubDate></item></channel></rss>