Laden...
H
hauptmann myCSharp.de - Member
Schüler Österreich/Kärnten Dabei seit 19.07.2003 704 Beiträge
Benutzerbeschreibung

Forenbeiträge von hauptmann Ingesamt 704 Beiträge

23.12.2004 - 15:52 Uhr

auch von mir Frohe Weihnachten ^^

ha, da fällt mir ein, dass ich heuer mein Weihnachtsgeschenk schon bekommen habe ^^ (neue Ski )

20.12.2004 - 17:11 Uhr

** Mehr als 2 Objekte **

Bisher hatten wir immer nur 1 Objekt auf unserem Bildschirm. Das wird sich nun ändern, da wir nun zwei Objekte rendern
werden. Wie immer baut dieses Tutorial auf den anderen auf, sowohl im Wissen, als auch im Code. Doch nun zum
vergnüglichen Teil ^^
Zuerst brauchen wir natürlich zwei Objekte, dazu nehmen wir einfach die rote Box aus dem vorgen Teil und eine Teekanne.
Lassen wir die Teekanne einfach mal grün sein.
Dazu machen wir eigentlich dasselbe, was wir mit der Box getan haben: Eine Variable vom Typ Mesh erzeugen, in ihr eine
Teekanne speichern und danach die Farbe verändern. Zuerst definieren wir die Membervariable sphere:


Mesh teapot;

Danach weisen lassen wir uns wieder durch eine statische Funktion eine Kugel vorberechnen und speichern diese in der
Variable teapot:


teapot = Mesh.Teapot(dev);

Die Mesh Klasse ist wirklich toll ^^
Nun machen wir dasselbe, was wir für die Box getan haben. Wir verändern die Farbe der Teekanne. Da wir den Code gleich
nach dem erstellen der Box einfügen, müssen wir nicht wieder extra Variablen einfügen und können so das Vertex Format von
oben verwenden:


tempBox = teapot.Clone( teapot.Options.Value, format, dev );
			teapot.Dispose();
			teapot = tempBox;

			verts = (CustomVertex.PositionNormalColored[])teapot.VertexBuffer.Lock( 0, 
				typeof( CustomVertex.PositionNormalColored ), 
				LockFlags.None, 
				teapot.NumberVertices );
		

			for(int i=0;i < verts.Length;++i)
			{
				verts[i].Color = Color.Green.ToArgb();
			}
			teapot.VertexBuffer.Unlock();

Jetzt kommen wir zum interessanten Teil. Und zwar zum Rendern. Zuerst begnügen wir uns mal, einfach beide Objekte zu
rendern, ohne sie zu rotieren o.ä.
Dazu müssen wir für jedes Objet zuerst eine World Matrix setzen und es dann damit zeichnen.
Anders ausgedrückt:
Begin Scene
Projection Matrix setzen
View Matrix setzen

World Matrix für Objekt 1 setzen
Objekt 1 rendern

World Matrix(und evtl. auch Projection und View Matrix) für Objekt 2 setzen
Objekt 2 rendern
World Matrix für Objekt 1 setzen
Objekt 1 rendern

World Matrix(und evtl. auch Projection und View Matrix) für Objekt n setzen
Objekt n rendern
End Scene

Das ist natürlich stark vereinfacht ausgedrückt, da in echten Spielen natürlich noch haufenweise andere Sachen dazukommen(
wie z.B. Kollisionsabfrage, Benutzereingabe etc.). Wir werden später noch sehen, wie man eine einfache Benutzereingabe
verwirklichen kann.
Sehen wir uns nun einmal an, wie wir das rendern verwirklichen. Zuerst setzen wir die Projection und View Matrix, für unser
Beispiel reicht eine Projection und eine View Matrix.


device.Transform.View = Matrix.LookAtLH( new Vector3( 0.0f, 3.0f,-5.0f ), new Vector3( 0.0f, 0.0f, 0.0f ), 
											new Vector3( 0.0f, 1.0f, 0.0f ) );
device.Transform.Projection = Matrix.PerspectiveFovLH( (float)Math.PI / 4, 1.0f, 1.0f, 100.0f );

Danach setzen wir die World Matrix für das erste Objekt und zeichnen es:


Matrix world;
world = Matrix.Scaling(0.5f,0.5f,1.5f);
			
world *= Matrix.Translation(-1.0f,0.0f,0.0f);
device.Transform.World = world;

box.DrawSubset(0);

Zuerst verkleinern wir das Objekt und strecken es auf der z Achse "nach hinten". Danach verschieben wir das Objekt um
eine Einheit nach links(auf der x Achse, negative Koordinaten sind hierbei nach links gerichtet). Schließlich rendern wir
es.
Nun zum zweiten Objekt. Wir setzen unsere Variable world zuerst auf die Identitätsmatrix:


world = Matrix.Identity;

Nun verkleinern wir das Objekt ein wenig und rotieren seitlich. Danach verschieben wir es um eine Einheit nach rechts.


world = Matrix.Scaling(0.5f,0.5f,1.0f);
world *= Matrix.Translation(1.0f,0.0f,0.0f);
world *= Matrix.RotationX(380);

Nun setzen wir die neue World Matrix und rendern die Teekanne:


device.Transform.World = world;
teapot.DrawSubset(0);

Und das wars schon. Was ganz wichtig ist, man darf vor dem rendern nicht vergessen, eine neue World Matrix zu setzen, denn
ansonsten wir weiterhin die Alte verwendet. Das könnt ihr ja ausprobieren. Kommentiert einfach mal den device.Transform.World =
world; vor dem teapit.DrawSubset(0); aus. Ihr werdet sehen, das die Teekanne dann auf der Box liegt. Kein schöner
Anblick(ich weis, die derzeitige Szene ist auch nicht gerade "schön", aber das muss man einfach können. Wenn wir dann
Spiele programmieren wollen, müssen wir uns auf diese Grundlagen zurückerinnern ^^)

Im nächsten Teil sehen wir uns dann eine einfache Benutzereingabe an. Wie immer gibt es den Source zum Download und seit
dem 5. Tutorial lege der zip Datei noch das Tutorial als txt File bei.

19.12.2004 - 20:45 Uhr

** Der Box eine Farbe zuweisen **

Nun, wir haben jetzt zwar eine schöne Box, jedoch ist sie noch komplett weiß. Das bringt uns natürlich nicht viel,
da wir ja mal aufregende Spiele schreiben wollen. Wie bringen wir jetzt jedoch Direct3D dazu, die Box mit einer
Farbe zu rendern? Das ist eigentlich ganz einfach: Wir verändern einfach die Vertices der Box direkt. Und dazu
kommen wir wieder auf unsere Vertex Buffer zu sprechen, aber wir brauchen diesmal keinen selber erstellen, sondern
wir holen uns die Vertex Daten einfach aus der Mesh Klasse(die diese ja speichert).
Und das ist mit ein paar Handgriffen gemacht. Zuerst müssen wir unseren Mesh "klonen" und bei diesem Vorgang das
Vertex Format ändern. Dies ändern wir so ab, dass wir die Box ganz normal transformieren können, jedoch jedem Vertex noch
eine Farbe zuweisen können. Nachdem das getan ist, holen wir uns die Vertex Daten des Mesh und schreiben einfach unsere
gewünschte Farbe hinein und geben die Vertex Daten der Mesh Klasse wieder bekannt. Und hierbei verändern wir nur die
Farbkomponente, nicht die Koordinaten der Vertices, da diese ja bereits vorberechnet wurden.
Sehen wir uns nuneinmal an, wie wir unseren Mesh klonen und ihm ein neues Vertex Format zuweisen:


VertexFormats format = VertexFormats.PositionNormal | VertexFormats.Diffuse;
Mesh tempBox = box.Clone( box.Options.Value, format, dev );
box.Dispose();
box = tempBox;

Zuerst definieren wir eine Variable vom Typ VertexFormat das unser VertexFormat enthält. Das VertexFormat für uns ist
PositionNormal(das standardmäßig verwendet wird) und dazu fügen wir Diffuse hinzu. Diffuse beschreibt die diffuse Farbe
eines Vertex. Die diffuse Farbe können wir uns derzeit einfach als jene Farbe merken, die man direkt sieht. Wir werden
später, wenn wir unsere Szene beleuchten sehen, dass es noch andere Arten von Farben gibt bzw. Lichtfarben.
Danach verwenden wir die Funktion Clone um einen vorläufigen Mesh zu erstellen. Danach löschen wir den eigentlichen Mesh
wieder und weisem unserem Mesh den Vorläufigen zu.
Nun müssen wir an die Vertex Daten kommen. Das geht ebenfalls äußerst einfach: Wie im Kapitel über Vertex Buffer locken
wir ihn einfach und kommen so an seine Daten(Lock sperrt die Daten eines Vertex Buffers für weitere Zugriffe und gibt
uns eine Referenz aus diese zurück. Die Änderungen werden übernommen und der Vertex Buffer entsperrt, wenn wir Unlock
aufrufen)
Gespeichert werden sie natürlich in einem Array vom Typ PositionNormalColored


CustomVertex.PositionNormalColored[] verts = (CustomVertex.PositionNormalColored[])box.VertexBuffer.Lock( 0, 
															typeof( CustomVertex.PositionNormalColored ), 
															LockFlags.None, 
															box.NumberVertices );

Da uns Lock nur ein System.Array zurückgibt, müssen wir dies erst explizit auf CustomVertex.PositionNormalColored casten.
Der Erste Parameter bestimmt die Menge an Daten, die wir sperren wollen. Wenn wir 0 angeben, wird der gesamte Vertex
Buffer gesperrt. Beim zweiten Parameter müssen wir bestimmen, welchen Typ die zurückgegebenen Daten haben sollen.
Der Dritte bestimmt die Lock Flags, die wir hier jedoch vernachlässigen können. Der letzte Parameter bestimmt, wie viele
Vertices zurückgegeben werden sollen. Da wir ja jeden Vertex des Mesh verändern wollen, müssen wir auch alle angeben.
Der nächste Schritt ist, die Vertex Daten zu verändern. Dazu gehen wir jeden Vertex durch und ändern seine Farbe:


for(int i=0;i < verts.Length;++i)
{
	verts[i].Color = Color.Red.ToArgb();
}

Die Variable Color ist uns bereits im Kapitel über Vertex Buffer begegnet, sie bestimmt welche Farbe der Vertex haben soll.
Als Letztes müssen wir den Vertex Buffer wieder entsperren, um die Änderungen zu übernehmen.


box.VertexBuffer.Unlock();

Nun rotieren wir unseren Mesh noch:


Matrix world;
world = Matrix.Scaling(1.0f,2.0f,1.0f);
			
int iTime = Environment.TickCount % 1000;
float fAngle = iTime * (2.0f * (float)Math.PI) / 1000.0f;
			
world *= Matrix.RotationY(fAngle);
world *= Matrix.Translation(0.0f,0.0f,0.0f);

device.Transform.World = world;
box.DrawSubset(0);

Und das wars schon. Direct3D ist einfach, wenn man weis wie's geht ^^

18.12.2004 - 11:27 Uhr

** Verschoben nach Windows Forms(Entwicklung grafischer Oberflächen für klassische Windows-Anwendungen ) **

17.12.2004 - 17:09 Uhr

** 3D Objekte **

Bisher waren unsere Programme eher langweilig. Klar gibt es heute noch 2D Spiele und und 2D war mal das Maß aller Dinge, aber die richtige Action gibt's heute mit 3D. Und deshalb werden wir uns jetzt mal ansehen, wie man einfache 3D Objekte mit Direct3D erstellt und diese anzeigt.
Zunächst jedoch ein wenig Theorie, um überhaupt zu verstehen, wie 3D Objekte gespeichert werden: Wie unschwer zu erkennen ist der Monitor vor euch eine Fläche. Dh das er 2 Koordinaten hat. Die x und die y Koordinate(wie man es beim karthesischen Koordinatensystem in der Schule lernt ^^). Durch ein Koordinatenpaar x|y können wir nun jeden beliebigen Punkt auf diesem Monitor angeben. Aber wie kann man dann 3D Objekte, wie man sie in jedem Spiel hat, abbilden? Wie ist es möglich, dass man eine 3D Szene auf ein 2D Koordinatensystem abbildet? Die Antwort ist simpel: Man führt einfach noch eine Koordinate ein(die z Koordinate), die einfach mit den beiden vorhanden Koordinaten verknüpft wird. Nun, das klingt ein wenig schwer verständlich, jedoch ist es im Endeffekt für uns Programmierer sehr einfach: Wir geben einfach bei Koordinaten eine z Koordinate zusätzlich an, die Tiefeninformationen speichert. Eine positive z Koordinate zeigt dabei an, dass wir "in den Bildschirm hinein" wollen, eine negative "aus dem Bildschirm heraus". Mathematisch ausgedrückt müssen wir nun also eine Formel finden, die uns nun aus einem Koordinaten Tripel x|y|z ein Koordinatenpaar x|y macht. Dazu können wir nun auf etwas, das wir jeden Tag erleben: Wenn wir uns von einem Haus entfernen, dann erscheint es mit zunehmender Entfernung kleiner. Nähern wir uns dem Haus, wird es größer. Dazu dividieren wir x und y einfach durch z. Die Koordinaten, die wir dadurch erhalten nennt man projezierte Koordinaten. Die Formel lautet nun:
x' (x projeziert) = x / z
y' (y projeziert) = y / z

Wir müssen uns diese Formel nicht merken und uns um diese Umrechnung auch keine Sorgen machen: Direct3D bzw. die Grafikhardware macht dies automatisch.(dazu stecken wir ja mehrere hundert € in Grafikkarten(zumindest ich ^^))

Jetzt können wir uns wieder Direct3D zuwenden. Normalerweise würde hier nun ein Beispiel kommen, in dem man einen Vertex Buffer und einen Würfel oder eine Pyramide erzeugt, jedoch will ich jetzt mal nicht diesen Weg gehen. Und zwar nutzen wir einfach eine vorgefertige Funktion, die uns bereits eine "Box" aus 3 Parametern berechnet und die wir dann leicht anzeigen können.
Zunächst deklarieren wir eine neue Variable box vom Typ Mesh. Mesh ist eine Klasse, in der man genau solche Vertex Informationen leicht speichern und anzeigen kann(bisher haben wir uns ja um die Erstellung eines Vertex Buffers gekümmert und um dessen anzeigen ...).


Mesh box;

Nun verwenden wir die statische Funktion Box der Klasse Mesh, die uns aus 3 Parametern eine Box berechnet und uns eine Variable vom Typ Mesh zurückgibt.


public void OnCreateDevice(object sender, EventArgs e)
{
			Device dev = (Device)sender;

			box = Mesh.Box(dev,2.0f,1.0f,2.0f);
}

Die Parameter sind simpel: Der Erste ist einfach das device. Der zweite beschreibt die Ausdehnung auf der x Achse. Der dritte auf der y Achse und letzte schließlich, trommelwirbel, auf der z Achse.
Diese Funktion berechnet uns nun aus diesen Parametern eine Box die wir in der der Variable box speichern. Einfach, nicht wahr?

Nun kommen wir zum anzeigen. Das geht ebenfalls entsprechend einfach. Wir springen in unsere Render Funktion und rufen die Funktion DrawSubset auf. Fertig.


box.DrawSubset(0);

Um den Parameter brauchen wir uns erstmal nicht kümmern.(erst später, wenn wir dann zB Vertex Daten von Dateien laden o.ä.)

Die Mesh Klasse bietet uns jedoch nicht nur eine Funktion, für die Erstellung einer Box, sondern wir können mir ihr auch noch Teekannen, Zylinder, Kugeln und Ringe erzeugen. Und natürlich auch beliebige 2D Polygone(ein Polygon ist einfach der Sammelbegriff für Dreiecke, Vierecke, Sechsecke usw.). Einfach mal ein wenig in der Klasse rumstöbern ^^

Einen Schönheitsfehler hat das ganze jedoch. Die Box erscheint weiß. Logisch, wir haben ja auch keine Farbe angegeben. Wie können wir der Box jetzt jedoch eine Farbe zuweisen? Nun, dazu müssen wir einfach die Vertex Daten ändern, doch dazu im nächsten Kapitel mehr.

Wie immer gibt es nun auch den Source als VS.net 2003 Projektfiles als Zip File.

17.12.2004 - 14:58 Uhr

** Verschoben nach Windows Forms(Entwicklung grafischer Oberflächen für klassische Windows-Anwendungen) **

17.12.2004 - 14:55 Uhr

naja, ich würde es für sehr schlimm halten, wenn die Sprite Klasse Device.Begin aufrufen würde. Device.Begin brauchst du immer wenn du irgendwas zeichnest(immer, einfach immer ^^).

@Matrizen:
Projektionsmatrix, Worldmatrix und Viewmatrix. Aber wenn Sprite das schon automatisch setzt ... (ich muss mir mal die Sprite Klasse ansehen)

16.12.2004 - 21:11 Uhr

mDevice.Begin und End hast du vergessen. Und hast du auch alle Matrizen gesetzt?

16.12.2004 - 17:22 Uhr

** Verschoben nach ADO.NET(Anbindung von Datenbanken) **

15.12.2004 - 20:48 Uhr

http://www2.b3ta.com/heyhey16k/

Wie viele hatten denn hier noch einen Commodore, ZX81, Armstrad und wie die alle heißen ^^

Wir hatten zu Hause mal einen, aber meine Mutter hat den leider weggeschmissen...

Aber dafür hab ich noch zwei Bücher wie man den ZX81 mit BASIC programmiert ^^

Vorallem finde ich den Vergleich zwischen früher und heute sehr interessant. Wenn man mal ein paar Spiele von http://www.the-underdogs.org/ gespielt hat und man sich vom grafischen Schock überwunden hat(he, meine ersten "richtigen" Spiele waren Sachen wie Aquanox...) merkt man doch relativ oft das alte Spiele besser sind als neue. Klar, neue Spiele haben ihre großen Reize(z.B. finde ich HL2 sehr gut, vorallem die Physik Rätsel oder Spiele wie America's Army hätte es früher nie gegeben)

Was denkt ihr so dazu? ^^

15.12.2004 - 20:31 Uhr

USD_wert = Math.Round(USD_Wert , 2);

Die Funktion Round rundet den ersten Parameter auf soviele Kommastellen, wie im zweiten angegeben(also USD_Wert wird hier auf 2 Kommastellen gerundet. Auf/Abrundung erfolgt automatisch) und gibt den gerundeten Wert zurück.

15.12.2004 - 15:54 Uhr

ich kann mich mal erinnern, in einem ATi Performance Paper gelesen zu haben, dass man VBs so groß wie möglich machen sollte...

11.12.2004 - 10:50 Uhr

naja, ist jetzt auch egal. Ich habe jetzt mit VirtualPC ein WindowsXP installiert auf dem nur der IIS läuft und dort funktionierts jetzt(ohne Performanceeinbußen wie es mich überascht ^^)

10.12.2004 - 21:20 Uhr

Original von alexander
Hast schonmal den IIS deinstalliert und nochmal sauber installiert?

ja, ich habe ihn über Windows Komponenten deinstalliert und dann wieder installiert.

10.12.2004 - 21:09 Uhr

Hi!

ich habe WinXP Pro und den IIS 5.1 installiert. Wenn ich jetzt über Systemsteuerung -> Verwaltung -> Internet-Informationsdienste -> Websites -> Standardwebsite die Standardwebsite versuche zu starten(Zustand Beendet) dann bekomme ich folgende Fehlermeldung:
Der Dienst antwortete nicht rechtzeitig auf die Start- oder Steuerungsanforderung.

Ich habe zum Test schonmal alle Dienste von Windows eingeschalten, was aber nichts gebracht hat. Auch eine Neuinstallation vom IIS bringt nichts.

Was kann ich machen? ^^

(der WebMatrix Server funktioniert ohne Probleme, aber der IIS will einfach nicht ^^)

08.12.2004 - 15:32 Uhr

da es hier jetzt um Direct3D geht, verschiebe ich das jetz mal ins DirectX Foum...

08.12.2004 - 15:29 Uhr

na, da stoße ich doch gerne an ^^

04.12.2004 - 18:18 Uhr

du sagst doch, dass geht über COM1 raus...Analysiere einfach den Verkehr von COM1 wenn das Programm mit der Melkmaschine verbunden ist

03.12.2004 - 19:20 Uhr

probier mal das hier aus:



         System.Diagnostics.Process pr = new System.Diagnostics.Process();
         pr.StartInfo.UseShellExecute = false;
         pr.StartInfo.CreateNoWindow = true;
         pr.StartInfo.RedirectStandardOutput = true;
         pr.StartInfo.FileName = "d:\\temp\\test.bat";
         pr.Start();        

pr.StartInfo.FileName musst du natürlich noch anpassen

29.11.2004 - 19:43 Uhr

Hoi!

Ich habe mal einen Thread mit Bücher- und Tutorialtipps gemacht. Der Sinn des Ganzen ist einfach, das Buchfragen/Tutorialfragen verhindert werden sollen ^^

Das Tolle dabei: Ihr braucht nur eine PM an einen Mod schicken und dieser fügt euren Tipp dann ein.

Ich hoffe mal das wir hier ein kleines Archiv von vielen guten .net Büchern aufbauen können ^^

29.11.2004 - 18:26 Uhr

Hi!

Gefällt mir gut, der Manager, jedoch gibts einige Verbesserungsvorschläge:

  • Beim Ersten Start ist ein Standardmusikordner drin, es währe besser wenn man den User beim ersten Mal starten den Musikordner gleich wählen lässt.
  • Beim Einlese meiner Musik(8.81gb) bekomme ich immer wieder "Syntaxfehler"(fehlender Operator) und da ich meine Musik auf einer eigenen Partition habe, wird die Musik nicht eingelesen, wenn das Programm zum Ordner System Volume Information kommt d.h. das ich meine Musik nicht verwalten kann.(oder zumindest nicht die, die im Root Verzeichnis ist)
  • Ogg Vorbis/WMA wird nicht unterstützt
  • Wenn ich in den Musikordne gehe, wird nichts angezeigt, sondern es wird alles auf die einzelnen Generes aufgeteilt.

Außerdem gefällt mir der MPlayer sehr gut. Cool währe noch ein Equalizer und verschiedene Skins.

28.11.2004 - 18:51 Uhr

Original von SexyEnemy
habe mal verscht aus dem dreieck ein viereck zu machen, indem ich einen weiteren punkt eingefügt habe...
ich habe auch die anzhal der punkte verändert, aber er zeichnet kein viereck..
WARUM?

gib mal den Code vom Vertex Buffer erstellen und vom Rendern. Dann ist es leichter einen Fehler auszumachen 😉

28.11.2004 - 18:44 Uhr

Dieser Thread soll dazu dienen, Buch- und Tutorialtipps bereitzustellen. Wen jemand ein Buch hier hinzufügen möchte(mit kurzer Bewertung), bitte eine PM an jemanden aus dem Team schicken.

**Bücher **

Inside C#, Microsoft Press, Tom Archer, Andrew Whitechapel
Gutes Buch das mit vielen Beispielen C# näher bringt. Grundwissen beim Programmieren wird jedoch vorausgesetzt.
[

C# IT-Tutorial](http://www.amazon.de/exec/obidos/ASIN/3826608348/mycsharpde-21) vom MITP-Verlag, Herbert Schildt
Nicht so sehr für absolute Anfänger, aber gut für Fortgeschrittene zu empfehlen (empfohlen von #ELIF)[

C# von Walter Saumweber](http://www.amazon.de/exec/obidos/ASIN/382726426X/mycsharpde-21), Markt&Technik-Verlag
Für absolute Anfänger und normale Anfänger ein gutes Buch. (empfohlen von #ELIF)

C#.NET mit Methode von Heinrich Rottmann, Vieweg
Das Buch hat ca. 800 Seiten, ist sehr einfach geschrieben (Deutsch) und beinhaltet sehr, sehr viele anschauliche Code-Beispiele. (empfohlen von norman_timo)

Visual C# . Grundlagen, Programmiertechniken, Windows-Anwendungen, Frank Eller, Michael Kofler, Addison-Wesley (empfohlen von Joltan)

Das C# Codebook, Jürgen Bayer, Addison-Wesley (empfohlen von Joltan)

**Tutorials und eBooks **

Guide To C#, Golo Haas
Gutes Tutorial für Anfänger, das für den Einstieg in C# genau richtig ist.
[

Galileo Computing Open Book: Einstieg in ASP .net von Matthias Lohrer ](http://www.galileocomputing.de/openbook/asp/)
[

Galileo Computing Open Book: C# von Eric Gunnerson ](http://www.galileocomputing.de/openbook/csharp/)

Programmierkurs C-Sharp
(empfohlen von pegasus2)

Ich hoffe mit Hilfe aus der Community wird hier bald ein gutes Bucharchiv enstehen

25.11.2004 - 17:55 Uhr

hehe, das mit dem Lehrer nicht auskennen kenn ich ^^

zu deinen Fragen:
ReadLine liest die nächste Zeile von Zeichen aus dem Eingabestream(= Console Input) ein
Read liest nur das nächste Zeichen ein

WriteLine schreibt die in den Parametern angegeben Zeichen in den Ausgabe Stream(= Console) , und fügt einen Zeilenabschluss ein('\n')
Write schreibt nur die Parameter raus, ohne Zeilenabschluss.

24.11.2004 - 19:48 Uhr

braucht man da nur den Passport oder auch einen richtige MSDN Subscription?

WEil das währe ja ganz interessant ^^

19.11.2004 - 16:01 Uhr

Original von Code-Hacker
Hi!

Achso, ich habe einen ähnliches Post bereits 2x verfasst. 1x bei der CC und im C++-Forum. 🙂
Hatte dieses Problem mal in einer C-Übung und musste mir ganz schnell was einfallen lassen, aber cool das ich auf etwas gekommen bin was schon 190 Leute vor mir kannten g

Code-Hacker

joa, is sowas wie ein Standardproblem das ^^

18.11.2004 - 21:08 Uhr

Original von Code-Hacker
Hi!

@hauptmann:
Wusstest du das oder haste das zufällig irgendwo abgeguckt? Ich kenne diese Antwort irgendwoher....flöt
😉

Code-Hacker

von hier hab ich das:
http://www.comeaucomputing.com/techtalk/#flushinput

irgendwann bin ich dann auf das getchar gekommen ^^

Aber ich hab das schon vor längerer Zeit dort gelesen 😉

17.11.2004 - 14:36 Uhr

klar, sogar einfacher als du dir denkst ^^


int x,y,z;
scanf("%d %d %d",&x,&y,&z);
printf("%d %d %d",x,y,z);

16.11.2004 - 17:20 Uhr

du musst den Eingabebuffer leeren. fflush(stdin) erzeugt ein undefinierties Verhalten:
Deshalb musst du einfach sowas machen:
while(getchar() != '\n');

Also entferne das fflush und füge an dessen stelle while(getchar() != '\n');
Dann funktionierts 😉

14.11.2004 - 20:52 Uhr

jo, ich finde viele Blogs auch sehr gut. Jedoch selber habe ich mir noch nie eins gemacht, ich wüsste nicht was ich da reinschreiben sollte ^^

13.11.2004 - 16:48 Uhr

spiel mal ein wenig mit den Parametern rum. Also z.B. das Vertex Processing mal auf Software stellen oder.

09.11.2004 - 20:56 Uhr

** Beitrag verschoben nach ADO.NET(Anbindung von Datenbanken) **

08.11.2004 - 16:52 Uhr

änder mal pParam.PresentationInterval = PresentInterval.Immediate; auf pParam.PresentationInterval = PresentInterval.Default;

Ansonsten habe ich kein Flimmern, das Schiff bewegt sich jedoch ein wenig ruckartig(es sind keine fließenden Bewegungen)

07.11.2004 - 20:40 Uhr

** Beitrag verschoben nach Integrierte Entwicklungsumgebungen(
Installation und Einsatz von Visual Studio .NET) **

07.11.2004 - 10:29 Uhr

** Die World Matrix **

Sehen wir uns nun die World Matrix einmal genauer an. Im letzten Beispiel haben wir ja das Dreieck rotiert, was ist aber, wenn wir es still stehen lassen wollen. Dann müssen wir die World Matrix auf die Identitätmatrix setzen(was mit 1 oder 0 verglichen wird. Also eine Matrix + der Identitätsmatrix ergibt wieder die Matrix selbst). Das machen wir so:


device.Transform.World = Matrix.Identity;

Damit steht unser Dreieck jetzt still. Kommen wir jetzt zum Rotieren. Wir können das Objekt um die x Achse, die y Achse und um die z Achse rotieren. Die Parameter beschreiben immer den Winkel, um den rotiert werden soll:


int  iTime  = Environment.TickCount % 1000;
float fAngle = iTime * (2.0f * (float)Math.PI) / 1000.0f;
device.Transform.World = Matrix.RotationX(fAngle);

Hier wird unser Objekt jetzt eine Rotation um die X Achse vollziehen. Es gibt noch die Funktionen Matrix.RotationY(für die Y Achse) und Matrix.RotationZ(für die Z Achse)

Nun zum Translieren oder verschieben. Erstmal ein Beisiel:


device.Transform.World = Matrix.Translation(1.0f,0.0f,0.0f);

Wie unschwer zu erkennen, haben wir hier unser Dreieck auf der x-Achse verschoben(Vektorangaben sind immer x,y,z).
Und zum Schluss das skalieren. Das skalieren bedeutet ja vergrößern oder verkleiner.


device.Transform.World = Matrix.Scaling(1.5f,1.0f,1.0f);

Auch hier können wir auf den verschiedenen Achsen skalieren. Wichtig zu wissen ist, dass der Wert 1 bedeutet, das das Objekt seine ursprüngliche Größe behalten soll. Jeder Wert kleiner 1 bedeutet eine Verkleinerung, jeder Wert größer 1(so wie hier), bedeutet eine Vergrößerung.

In einer echten Anwendung wollen wir jedoch nicht einfach nur mal rotieren und mal translieren, sondern diese Operationen auch kombinieren. Das ist eigentlich ganz einfach: Wir müssen einfach eine Matrix bilden und diese dann als World Matrix setzen. Wie wir bereits wissen, müssen wir zuerst skalieren, dann rotieren und dann translieren. Wichtig ist, das man die einzelnen Ergebnisse(Skalieren,rotieren,translieren) miteinander mulitplizieren muss.(Eine Matrix Multiplikation ist jedoch nicht assoziativ d.h. Marix M * Matrix B ist ungleich Matrix B * Matrix M)


Matrix world;
			
// skalieren
world = Matrix.Scaling(1.0f,1.0f,1.0f);
// rotieren
world *= Matrix.RotationY(1.0f);
// translieren
world *= Matrix.Translation(1.0f,0.0f,0.0f);
			
device.Transform.World = world;

07.11.2004 - 10:09 Uhr

ich würde sagen das dies die Klassen selbst übernehmen. So wie ich das immer gemacht habe war es, das ich im Spiel verschiedene Game States setzte(Intro,Game,Menu...) und diese GameStates dann in der Hauptschleife ausgewertet wurden. Wenn jetzt also der GameState Intro gesetzt wurde, renderte ich das Intro. Was ich damit sagen will, ist einfach, dass man flexibler ist, wenn z.B. die Klasse YMesh einen Mesh selbst loaded und eine Render Methode anbietet. Dann kannst du dann, als derjenige, der die Engine dann verwendet bestimmen wann etwas gerendert werden soll. Wenn du das über eine Klasse rendern lässt, musst ja wieder sowas wie eine Warteliste verwalten(um zu wissen was wann gerendert wird), was ja wieder zusätzlichen Aufwand mit sich bringt.

07.11.2004 - 01:03 Uhr

Heute geht es weiter ^^

**Transformationen **

Bisher waren unsere Programme eher langweilig. Jetzt wird sich das aber ändern, da wir jetzt Bewegung in die ganze Sache bringen. Und dazu brauchen wir jedoch ein wenig Mathematik. Wie wir bereits gesehen haben haben wir 3 Werte um einen Punkt in unserer Szene zu beschreiben. Diese sind die x Koordinate, die y Koordinate und die z Koordinate. Währe es nun nicht gut, wenn wir diese Werte zusammenfassen könnten und mit ihnen rechnen? Nun, das geht natürlich und das ganze nennt sich einen _ Vektor_. Wir verwenden einen 3D Vektor, da wir ja 3 Werte verwenden. Wie man damit rechnet will ich hier mal ausklammern, da es bereits auf Wikipedia einen ausgezeichneten Artikel zu diesem Thema gibt.
Das nächste, was wir wissen müssen, ist der Begriff der Matrix. Eine Matrix ist eine rechteckige Anordnung von Zahlen. Wir werden gleich sehen, wozu wir eine Matrix brauchen.(Für die Rechenregeln verweise ich wieder auf Wikipedia).
Nun kommen wir erstmal zu einer wichtigen Frage: Wie können wir usnere Szene nun animieren bzw. in Bewegung versetzen.
Um das zu programmieren, müssen wir erstmal verstehen, wie unsere Vertices aus unseren VertexBuffern auf der Grafikkarte behandelt werden. Und zwar wird jeder Vertex duch eine sogenannte Fixed Function Geometry Pipeline. Dort werden die Vertices(welche als Vektoren vorliegen) mit 3 verschiedenen Matrizen transformiert. Anschließend werden die Vertices geclippt(= Culling) und ihre Koordinaten werden auf den Monitor skaliert d.h. die Koordinaten werden so angepasst, das sie auf bzw. für den Monitor passen.
Für uns sind nun die ersten 3 Schritte dieser Pipeline wichtig. Diese 3 Transformationen sind: World Transformation, View Transformation und Projection Transformation.
Sehen wir uns diese 3 einmal genauer an:
World Transformation:
Normalerweise sind alle Vertices relativ zum Ursprung des Objekts(also in einem lokalen Koordinatensystem). Jedoch müssen wir, um das Objekt auch anzeigen zu können, dieses lokale Koordinatensystem zu einem sogenannten world space transformieren. Der world space ist nichts anderes, als ein Koordinatensystem, in dem alle Koordinaten relativ zu einem gemeinsamen Ursprung sind. Welche genauen mathematischen Vorgänge das nun sind, dies ist für uns eher uninteressant. Für uns ist es jetzt wichtig zu wissen, das wir mit dieser World Transformation unser Dreieck aus dem vorigen Beispiel bewegen können. Und diese World Transformation wird durch eine Matrix dargestellt, die World Matrix. Wir können nämlich auf die World Matrix 3 verschiedenen Operationen anwenden: Translieren, Rotieren und Skalieren.
Translieren bedeutet einfach ein Objekt zu verschieben. Man kann es nach oben,unten und links,rechts verschieben. Rotieren ist wohl klar. Man rotiert das Objekt entweder um die x-Achse oder um die y-Achse. Und beim Skalieren kann man ein Objekt um einen bestimmten Faktor vergrößern oder verkleinern.
Ich habe jetzt von Objekt gesprochen, nun warum rede ich hier von Objekt und nicht von Matrix? Nun, alle diese Operationen werden auf die World Matrix angewendet und diese World Matrix wird ja wiederrum auf alle Vertices eines Objektes angewendet(wir können die World Matrix während der Laufzeit jederzeit verändern). DirectX bietet uns natürlich mehrere Funktionen, damit wir uns nicht mit den genauen Rechnungen herumschlagen müssen. Wichtig ist außerdem, dass wir skalieren, translieren und rotieren nicht einfach in beliebiger Reiehenfolge durchführen dürfen(bzw, können schon, jedoch kommen dann unlogische Verschiebungen zum Vorschein...) Die richtige Reihenfolge lautet: Skalieren und danach zuerst rotieren und zum Schluss translieren. Man kann auch zuerst translieren und dann rotieren(skalieren kommt immer als erstes.). Der unterschied ist einfach der, das ja um den Koordinatenursprung rotiert wird. Wenn man nun zuerst transliert und dann rotiert, dann wird das Objekt zuerst irgendwohin in der Szene gesetzt und dann nochmal um die Rotierung verschoben. Um diesen Effekt zu vermeiden, rotieren wir zuerst und translieren erst später.
_View Transformation _
Mit der View Transformation können wir eine Kamera oder auch Viewport erzeugen. Damit ist einfach gemeint, wohin der Betrachter einer Szene schaut. Eine View Matrix wird aus 3 Vektoren gebildet. Diese sind der eye point Vektor, der look-at Vektor und der world's up Vektor. Der eye point Vektor beschreibt, wo der Augenpunkt(Also der Ausgangspunkt) des Betrachters ist. Der look-at Vektor gibt an, wohin(also zu welchem Punkt) der Betrachter schaut. Und der world's up Vektor beschreibt die Ausrichtig auf der y Achse.(Dieser Vektor ist normalerweise [ 0,1,0] außer man will die Kamera um ihre eigene z Achse drehen).
Um eine View Matrix zu bilden, bietet uns DirectX wie immer die Möglichkeit dies mit mehreren vorgefertigten Funktionen zu tun.
_Projection Transformation _
Die Projection Transformation(beschrieben durch die Projection Matrix) ist dafür verantwortlich, das wir auf dem 2D Monitor eine 3D Szene darstellen und auch sehen können. Und zwar sorgt sie dafür, dass Objekte, die weiter weg sind, kleiner sind und Objekte, die näher sind, größer sind(also wie, als wenn man aus dem Fenster schaut.)

Nun, jetzt wissen wir die Theorie, jedoch noch nicht, wie man das in der Praxis anwendet. In der Praxis ist das aber äußerst einfach: Man berechnet einfach die jeweiligen Matrizen und gibt sie dann dem Device bekannt. Alle Objekte, die wir danach rendern, werden mit den derzeit gesetzten Matrizen transformiert. Jedes Objekt wird immer nur einmal durch die Pipeline geschleust, außer man render es nochmal im selben Frame.

Aber wir müssen noch etwas bedenken. Unsere Initalisierung wird von nun an länger sein. Deshalb werden wir ab jetzt auch eine neue Struktur des Quellcodes haben(der dem aus dem Tutorial sehr ähnlich ist ^^).

Kommen wir nun endgültig zur Praxis. Jedoch vorher müssen wir noch den Typ unserer Vertices ändern. Bisher hatten wir sie vom Typ TransformedColored, dies müssen wir jetzt ändern. Das Transformed bedeutet nämlich, das wir uns nicht um die einzelnen Transformationen kümmern wollen und diese DirectX überlassen wollen(was bei statischen Objekten ja auch durchaus sinnvoll sein kann). Wir benötigen jetzt jedoch Vertices vom Typ PositionColored.

Die einzelnen Matrizen setzen wir über uns device. D.h.
device.Transform.View = View Matrix
device.Transform.World = World Matrix
device.Transform.Projection = Projection Matrix

Jetzt wird es aber ernst: Die Render Funktion. Hier setzen wir zuerst die Matrizen und rendern dann aus unseren Vertex Buffer ein Dreieck. Die Besonderheit: Es dreht sich um die y Achse. Sehen wir uns zuerst die World Matrix an:


int iTime = Environment.TickCount % 1000;
float fAngle = iTime * (2.0f * (float)Math.PI) / 1000.0f;
device.Transform.World = Matrix.RotationY(fAngle);

Zunächst berechnen wir den Winkel, in dem sich das Dreieck rotieren soll. Danach setzen wir die World Matrix einfach über die Funktion Matrix.RotationY, welche uns eine Roation um die Y Achse mit dem angegbenen Winkel(fAngle) berechnet.

Nun die View Matrix:


device.Transform.View = Matrix.LookAtLH( new Vector3( 0.0f, 3.0f,-5.0f ), new Vector3( 0.0f, 0.0f, 0.0f ), new Vector3( 0.0f, 1.0f, 0.0f ) );

Die View Matrix ist nichts besonderes. Zuerst wird der eye Point definiert, dann der look-at Vektor und dann noch world's up.


device.Transform.Projection = Matrix.PerspectiveFovLH( (float)Math.PI / 4, 1.0f, 1.0f, 100.0f );

Hier die die Projection berechnet. Ebenfalls nichts besonderes.

In den nächsten Programmen werden wie die Projections Matrix und die World Matrix eher in den Schatten stellen und uns dafür ausgiebig mit der World Matrix beschäftigen.

Etwas, das wir noch klären müssen, ist warum wir das Culling ausschalten. Wir rotieren ja das Dreieck. Und beim rotieren sind die Vertices ja einmal gegen den Uhrzeigersinn angeordnet und einmal im Uhrzeigersinn. Wenn wir jetzt das Culling einschalten würden, würden wir je nach gesetzen Wert eine Seite des Dreiecks nicht sehen(einfach mal ausprobieren).
Ansonsten gibt es nicht mehr viel zu sagen. Der Code ist halt vom Microsoft DirectX Tutorial übernommen, aber ich hoffe mal, das das kein Problem darstellt.
Der gesamte Sourcecode ist wie immer als Visual Studio .net 2003 Projekt(gepackt als zip) angehängt.

EDIT: wow, is ja schon spät geworden, als ich das letzte mal auf die Uhr schaute war erst halb 11 ^^

04.11.2004 - 19:47 Uhr

** Verschoben nach Windows Forms **

Ist da nicht noch ein 3. Parameter Color?
edit: nein, doch nicht. Das war C++ ^^

04.11.2004 - 19:45 Uhr

ja, aber eine Textur kannst du nicht einfach render.

Außerdem, wie glaubst du denn rendert denn die Sprite Klasse das intern?

04.11.2004 - 18:53 Uhr

Hast du das Direct3D SDK installiert? Dann hast du sicher auch den DirectX Application Wizard installiert. Dort kannst du dir eine Anwendung erstellen lassen die in eine Picture Box rendert.

2D Rendering ist einfach so, dass du z.B. für ein rechteckiges Bild 2 Dreiecke nimmst, diese Texturierst und dann mit World Matrix verschiebst etc. und Alpha Blending etc. darauf anwendest.

04.11.2004 - 18:28 Uhr

Danke! 🙂

Ich freue mich schon auf den 1000. User.....

02.11.2004 - 12:33 Uhr

Also, angefangen hab ich vor 3/4 Jahren so mit 11/12 mit C. Dann habe ich C++ und schließlich auch noch C# gelernt.

Ich bin derzeit(altersbedingt ^^) Hobbyprogrammierer(oder auch Schulprogrammierer, ich gehe auf eine Schule mit dem Schwerpunkt Software Engineering die jedoch mit dem Abitur/Matura(5 Jahre geht die) abschließt also nicht vergleichbar mit einer Berufsschule ist, da auf meiner Schule viel mehr gelehrt wird(so auch Mathe,Physik etc.))

Und später, naja, eigentlich will ich ja Wrestler oder (Airline)Pilot werden. Wenn das nicht klappt würde ich gerne Spieleprogrammierer werden.

01.11.2004 - 22:40 Uhr

Sofern du es nur für Windows brauchst, kannst du die Funktion GetShortPathName via Interop einbinden:


[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern int GetShortPathName(
   [MarshalAs(UnmanagedType.LPTStr)]
   string path,
   [MarshalAs(UnmanagedType.LPTStr)]
   StringBuilder shortPath,
   int shortPathLength);

Aufruf:


StringBuilder shortPath = new StringBuilder(80);
int result = GetShortPathName(
@"d:\test.jpg", shortPath, shortPath.Capacity);
string s = shortPath.ToString();

26.10.2004 - 15:33 Uhr

naja binden, das heißt wohl eher pipen oder so.

Du musst zuerst Befehlszeilenargumente hinzufügen, deshalb muss deine Main so aussehen:


static void Main(string[] args)
		{
			if(args.Length == 0)
			{
				Console.WriteLine("Usage: cat filename >> pipe");
				return;
			}

			
		}

in args[0] ist das erste Befehlszeilenargument(nicht der Programmname wie in C++) gespeichert, in args[1] das 2. und in args[2] das 3.

Jetzt musst du halt das 2. Argument ansehen und schaune was das für Dateien sind un die dann entsprechend öffnen. Und dann gibts das ins 3. Argument aus(z.B. in eine Datei schreiben, wenn eine Datei angegeben ist o.ä.)

26.10.2004 - 13:15 Uhr

** Beitrag verschoben nach Windows Forms**

26.10.2004 - 11:47 Uhr

** Beitrag verschoben nach Integrierte Entwicklungsumgebungen(
Installation und Einsatz von Visual Studio .NET, #develop, MonoDevelop und anderen integrierten Entwicklungsumgebungen ) **

25.10.2004 - 11:10 Uhr

Wobei das alles auch in der MSDN gestanden währe......

24.10.2004 - 18:53 Uhr

** Verschoben nach Sonstiges(->
Diskussionen zu allen sonstigen Themen ) **

Der MP3 Verwalter muss mal alle gängigen Formate lesen und wiedergeben und verwalten können. Dann noch zusätzliche Gimmicks wie z.B. die Symbolleiste beim WMP oder Visualtizations. Offen für Plugins und Themes sollte es auch sein. Und dann natürlich die ganzen Sachen, die Mog schon erwähnte.

24.10.2004 - 16:54 Uhr

Schau dir mal das Bootsrtapper Plugin an
http://msdn.microsoft.com/vstudio/downloads/tools/bootstrapper/

Damit kannst du das .net Framework in ein Windows Installer Projekt einfügen und installieren falls nötig.