Laden...

Forenbeiträge von marcom Ingesamt 123 Beiträge

27.05.2013 - 11:23 Uhr

Hallo zusammen,

ich habe eine Touch-Fähige Applikation in WPF und möchte ein altes UserControl hinzufügen.
Dabei möchte ich, dass die Touch-Gesten, die auf dem UserControl ausgeführt werden, innerhalb von WPF mittels OnManipulationStarted etc abgearbeitet werden.

Leider scheinen diese Events nicht gefeuert zu werden, wenn diese auf dem UserControl ausgeführt werden. Hat jemand eine Idee, wie ich das realisieren könnte?

Vielen Dank

Mark

27.10.2010 - 16:52 Uhr

Kleines Codebeispiel:


public interface IMy
{
    Int32 TestVar { get; }
    int Test();
}

public struct MyStruct : IMy
{
    public Int32 TestVar { get; private set; }

    #region IMy Members

    public int Test()
    {
        ++this.TestVar;
        return this.TestVar;
    }

    #endregion
}

static void Main()
{
    MyStruct m1 = new MyStruct();
    var val = m1.Test(); //val = 1
    Blub(m1);
    var val2 = m1.TestVar; //val2 = 1 (das hätte ich auch erwartet)

    IMy m2 = new MyStruct();
    val = m2.Test(); //val = 1
    Blub(m2);
    val2 = m2.TestVar; //val2 = 2 (!!)
}

static void Blub(IMy imy)
{
    var val = imy.Test();
}

Und noch was Interessantes (man achte auf den Unterschied bei der Variablendefinition von ms bzw. m1!)


MyStruct ms = new MyStruct();
IMy temp = ms;

var v1 = ms.Test(); //v1 = 1
var v2 = temp.Test(); //v2 = 1

IMy m1 = new MyStruct();
temp = m1;

v1 = m1.Test(); //v1 = 1
v2 = temp.Test(); //v2 = 2 (!!)

Hättet ihr damit gerechnet?

27.10.2010 - 16:33 Uhr

Hallo zusammen,

bis jetzt habe ich immer gedacht, dass structs nur "ByValue" übergeben werden, d.h. eine Kopie von dem Objekt bei jeder Methodenübergabe erstellt wird (es sei denn, man nutzt ref oder out, wovon ich aber erstmal nicht ausgehe).

Dann habe ich gelesen, dass structs auch Interfaces implementieren können und mich gefragt, was passiert, wenn ich in einer Methode, die nur das Interface kennt, das struct-Objekt erneut an eine andere Methode übergebe, die ebenfalls nur das Interface kennt. Und siehe da, plötzlich wurde nicht mehr eine Kopie des Structs übergeben, sondern die Referenz - d.h. es wurde keine Kopie von dem Objekt erstellt und alle Änderungen wurden auf dem Referenzobjekt ausgeführt!

Vielleicht wusstet ihr das, aber ich war doch sehr überrascht! Andererseits, woher sollte die Methode, die nur das Interface kennt, auch wissen, ob es sich um ein Ref- oder ValueType handelt...

(Deswegen hätte ich auch nicht direkt geglaubt, dass Structs Interfaces implementieren dürfen)

In diesem Sinne keine Frage von mir, nur eine Feststellung 😃

07.10.2010 - 10:37 Uhr

B747-400 oder B757/B767? 😉

28.09.2010 - 15:18 Uhr

Hallo Leute!

Erstmal vielen Dank für die zahlreichen Antworten!

Ich habe das Problem mit Action<T> gelöst, wie von Peter und cat vorgeschlagen. Damit ist die Implementierung am einfachsten Erweiterbar, falls neue Methoden (bzw. Events) hinzukommen, was wahrscheinlich ist.

Das ist auch der Grund, weshalb ich den Prototypen für die delegates vermeiden wollte, da ich für jede neue Methode einen neuen delegate erstellen muss, was hierbei entfällt (bzw. automatisch gemacht wird?!)

28.09.2010 - 11:27 Uhr

Hi Peter,

das Problem ist nicht das Aufrufen des Delegates (das würde ich auch über DynamicInvoke machen), sondern das einfache Speichern des "Funktionzeigers".
Dafür hab ich in Deinem Post auch keinen Ansatz gesehen.

mit Action oder Func ginge das auch nicht, da man hier den genauen Typen vorgeben muss, was ich eben vermeiden will.

28.09.2010 - 10:40 Uhr

Hallo Peter,

danke für die Antwort.

Leider ist die Signatur aber nicht immer gleich. Kurzes Beispiel:



class ContainerClass
{
   public Object[] Params{get;set;}
   public Delegate Func{get;set;}
}

class SomeClass
{
   private List<ContainerClass> list = new List<...>();

   private void Init()
   {
      var obj1 = new ObjektMitEvents();

      obj1.Event1 += MyFunc1;
      obj1.Event2 += MyFunc2;
      ...
   }

   private void MyFunc1(Object a, int b, int c)
   {
      //Compilerfehler
      this.list.Add(new ContainerClass{Params = new Object[] {a,b,c}, Func = AsyncFunc1});
   }

   private void MyFunc2(double x, String s)
   {
      //Compilerfehler
      this.list.Add(new ContainerClass{Params = new Object[] {x,s}, Func = AsyncFunc2});
   }

   private void AsyncFunc1(Object a, int b, int c)
   {
   }

   private void AsyncFunc2(double x, String s)
   {
   }

...
}

Ich hoffe, das veranschaulicht mein Problem etwas besser.

28.09.2010 - 10:23 Uhr

Hallo zusammen,

ich habe ein Objekt, dass mehrere Events bereitstellt, die ich abonniere. Die Parameter sind dabei immer unterschiedlich. Ich möchte diese Parameter zwischenspeichern und später, aus einem anderen Thread heraus, eine bestimmte Methode aufrufen. Ich hatte nun überlegt, eine Containerklasse zu erstellen, wo ich sowolhl die Parameter als auch die Methode, die später aufgerufen werden soll, speichere (also z.B. einAnderesObjekt.Methode) Ich möchte diese Methode so generisch wie möglich speichern, deswegen hatte ich überlegt, der Containerklasse ein Delegate zu übergeben. Doch sobald ich diesem Delegate die Methode zuweisen möchte, bekomme ich die Fehlermeldung "cannot convert from method group to delegate". Gibt es eine Möglichkeit, das irgendwie zu realisieren, ohne unbedingt auf Reflection und Strings umsteigen zu müssen?

Danke & Gruß

Mark

06.09.2010 - 19:43 Uhr

Hallo Arithmetika,

danke für den Hinweis! Bist Du Dir sicher mit DirectInput? Ich habe mal in der Doku geschaut aber dort steht

The DirectInput API is used to process data from a joystick, or other game controller. The use of DirectInput for keyboard and mouse input is not recommended, Windows messages should be used instead

also nichts mit Audio.

Ich habe mir DirectSound mal angeschaut, aber dort kann ich nur die "Recording Devices" als Eingabe auswählen - also nichts mit redirection.

Mir würde auch schon der erste Schritt reichen - nämlich die Ausgabe von Rechner B an Rechner A zu schicken und es dort auszugeben.

Irgendwie muss das auch möglich sein, schließlich funktioniert es auch mit der Remote Desktop Verbindung...

Grüße

Mark

06.09.2010 - 14:09 Uhr

Hallo zusammen,

was für Möglichkeiten seht ihr, um das folgende Probleme zu lösen:
zwei Rechner (A und B)
Rechner A hat ne sound-anlage und ein Mikrofon. Rechner B hat nur eine Soundkarte, sonst nichts.
Ich möchte, dass der Sound, der auf Rechner B entsteht, auf Rechner A ausgegeben wird. Parallel möchte ich, dass wenn ich ins Mikrofon spreche (der mit A verbunden ist), dieser Sound auf Rechner B als <Eingabequelle> verwendet wird - also falls Rechner B mit Skype verbunden ist, kann ich meine Hardware von Rechner A verwenden.

Ich glaub, ich müsste einen virtuellen Soundtreiber schreiben, oder? Hat sowas jemand schon mal gemacht?

Gibts evtl. eine alternative Lösung, die sogar mit .NET gelöst werden könnte?

Danke!

31.03.2010 - 14:33 Uhr

Super, genau sowas suchte ich 👍

31.03.2010 - 11:54 Uhr

Gibt es eine Möglichkeit, z.B. mit Linq, einer Methode den Namen einer Eigenschaft zu übergeben, wobei der Name nicht als String übergeben werden soll?

Also z.B. eine Methode wie

private Object GetValue(Object o, String propName)
{
Type t = o.GetType();
return t.GetProperty(propName).GetValue(o, null);
}


nur möchte ich diese Methode nicht so aufrufen:

int? a = 5;
GetValue(a, "Value");

sondern irgendwie so:

int? a = 5;
GetValue(a, a.Value);

Das Beispiel ist jetzt natürlich extrem vereinfacht und macht hier keinen Sinn, aber es geht ums Prinzip ob es sowas wie einen selector gibt mit dem man sowas machen kann?

Danke!

28.12.2009 - 18:53 Uhr

Hallo zusammen,

ich möchte ein "Fadenkreuz" malen, dass immer dort ist, wo meine Maus. In etwa wie ein eigener Cursor.
Am einfachsten ist es, die Paintmethode zu benutzen und beim MouseMove-Event per Refresh das Control neu zu zeichnen - das ist allerdings relativ langsam (hängt davon ab wie komplex das Control ist).

Alternativ habe ich ein eigenen Cursor erstellt, das funktioniert aber leider nicht auf jedem Rechner. Schließlich ist die Bitmap, die als Hintergrund für den Cursor dient, relativ groß (der Fadenkreuz soll die Breite/Höhe des Desktops haben - bei FullHD entsprechend > 1 Megapixel.)

Meine Frage: kann man eigene Overlays irgendwie zeichnen? Z.B. direkt auf den Desktop malen? Das Fadenkreuz soll möglichst schnell gezeichnet werden und ohne dass die Controls im Hintergrund beeinflusst werden.

Geht das irgendwie mit GDI+?

Danke & Gruß

Mark

14.12.2009 - 11:30 Uhr

Diese Frage hat jetzt weniger mit dem Programmieren tun, mich würde aber interessieren, wer WCF professionell einsätzt und was die Erfahrungen sind bzgl. Akzeptanz in der Industrie?

Habt ihr evtl. auch Quellen dafür?

Danke!

03.12.2009 - 15:05 Uhr

Du arbeitest mit einem 64 Bit System und das Managed DirectX unterstützt das nicht.
Ändere unter Project-Properties bei Build die Platform Target auf x86 (Release nicht vergessen!) und kompilier erneut.

16.11.2009 - 14:38 Uhr

Hallo Jelly,

der Server ist nicht in der Domäne. Im Prinzip sollte es so simpel wie ein FTP Server sein...

16.11.2009 - 13:03 Uhr

Hallo zusammen,

ich möchte bei einem WCF Server, das als Binding das NetTcpBinding benutzt, den SecurityMode auf SecurityMode.Message und den ClientCredentialType = MessageCredentialType.UserName setzen.
Dazu setz ich noch folgende Attribute vom ServiceHost:


host.Credentials.UserNameAuthentication.UserNamePasswordValidationMode = System.ServiceModel.Security.UserNamePasswordValidationMode.Custom;
host.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator = new MyValidator();

Versuche ich den Server zu starten, bekomme ich eine InvalidOperationException weil ich kein Zertifikat gesetzt habe. In einigen Foren habe ich gelesen, dass dies z.B. durch


host.Credentials.ServiceCertificate.SetCertificate(StoreLocation.LocalMachine, StoreName.My, X509FindType.FindBySubjectName, "localhost");

gelöst werden kann - aber bei mir läuft das schief weil er kein Zertifikat findet. Wozu brauch ich eigentlich ein Zertifikat? Also was wird damit gemacht? Gibt es Alternativen? In Grunde möchte ich nicht viel mehr, als dass jede Nachricht verschlüsselt wird und dass der Client den UserName / das Passwort eingeben muss...

Danke!

01.10.2009 - 18:33 Uhr

Ich seh keinen Sinn darin, hier weiter zu diskutieren.
Ich finde, ich habe den beobachteten Effekt hoffentlich einigermaßen erklären können und habe auch ein Beispiel genannt, wo dieser Effekt auftreten kann. Ich hoffe, damit dem Threadersteller geholfen zu haben.
gfoidl scheint meine Motivation hinter diesem Posting nicht verstehen zu wollen, aber das zu rechtfertigen muss nicht sein.

Insofern, schönen Feierabend 👍

01.10.2009 - 18:04 Uhr

Danke für den Crashkurs, aber ich glaube nach 4 Semestern Mathe bin ich da halbwegs fit 👍

Du hast Recht - wenn f' = 0 ist es nicht zwingend ein Wendepunkt. Allerdings fällt mir keine (sinnvolle!) Funktion ein, wo für ein Punkt f' = 0 gilt, der Punkt kein Extrempunkt ist und dabei auch kein Wendepunkt ist.
(
) f(x) = const ist zwar so eine Funktion, aber wer Newton bei so einer Funktion ansetzt, ist selbst schuld 😁

Und dennoch:

Die eigentliche Aussage meines Posts ist und bleibt, dass Newton eben dann scheitert, wenn die erste Ableitung null wird. Dies ist immer dann der Fall, wenn es sich um einen Extrempunkt handelt und manchmal eben auch dann, wenn es nur ein Wendepunkt ist Als Beispiel: f(x) = (x-2)^3 + 8 ). Legt man dort "versehentlich" mit x=2 los, scheitert das Verfahren, obwohl es keine Extremstelle ist (nur ein Wendepunkt) und die Funktion tatsächlich auch eine Nullstelle besitzt.

01.10.2009 - 16:03 Uhr

OK, wobei es nicht zwingend ein Extremum sein muss, damit Newton schief läuft. (wenn f' = 0 ist der Punkt zumindest ein Wendepunkt, evtl. aber auch ein Extrempunkt.)

01.10.2009 - 15:48 Uhr

Ich glaube, hier liegt ein anderes Problem vor:
Du versuchst Newton anzuwenden, wo man Newton vermutlich nicht anwenden sollte 🙂
Die hohe Zahl wird vermutlich durch eine Division durch (fast) 0 erreicht. Da helfen dir 999999999 Nachkommastellen auch nicht, denn irgendwann wird der Wertebereich gesprengt.
Das passiert nämlich dann, wenn die Funktion, für die Du eine Nullstelle suchst, einen Wendepunkt oder Extremwert an der Stelle hat. Dann wird f ' (x) nämlich 0 und zack, funktioniert der Algorithmus nicht mehr.
Versuchs mit dem Bisektionsverfahren - sobald das Intervall klein genug ist, kannst Du erneut Newton anwenden, da Newton wesentlich schneller konvergiert (aber gefährlich sein kann). Du wirst sehen, dass double mehr als ausreicht.

02.09.2009 - 16:04 Uhr

Hallo zusammen,

ich arbeite schon relativ lange mit C# und würde von mir behaupten, dass ich mich einigermaßen mit Multithreading auskenne. Allerdings habe ich bis heute nie wirklich den Unterschied zwischen MTA und STA verstanden. Geht es dabei allgemein um Multithreading unter .NET oder gehts nur um COM?
Wenn ich diesen Artikel richtig verstehe http://www.developer.com/net/cplus/print.php/2202491, dann wird bei STA nur ein Thread gleichzeitig ausgeführt. Aber alle WinForm Applikationen (die standardmäßig STA sind) die ich mit ≥ 2 Threads ausgestattet habe, konnten bei 2 Kernrechnern problemlos 100% CPU-Last verursachen. Also werde ich das doch falsch verstanden haben!?

Hat hier jemand eine bessere Erklärung zu diesem Thema?

Vielen Dank!

Viele Grüße

Mark

10.07.2009 - 16:45 Uhr

Wenn ich ein kleines Tool dass sagen wir mal vier Monate lang entwickelt wurde und für 39,99€ verkauft wird, mit dem 170€ teuren .NET Reactor "obfusziere" ist das die eine Sache. Bei einem größeren Projekt dass dementsprechend teurer ist, ist es wohl eine Andere.

Wir sind bereit ~1000€ zu investieren. Wenn jetzt der .NET Reactor natürlich alles kann, was die teurere Software auch kann, dann kaufen wir naütlirch lieber den Reactor. Aber nur wenn der "genauso" sicher ist...

Wir suchen quasi das beste Preis/Obfuscation-verhältnis.

Ja, den Thread hatte ich gelesen...

10.07.2009 - 16:25 Uhr

.NET Reactor hört sich in der Tat nicht schlecht an.
Auf die Vergleichstabelle der Firma lege ich nicht soo viel Wert, ist doch klar dass das eigene Produkt viel besser ist 🙂

Hat das Tool jemand im Einsatz? Ist es "hinreichend sicher" bei einem Projekt mit mehreren Mannjahren Entwicklungszeit?

10.07.2009 - 15:49 Uhr

Hallo,

ja die Suche habe ich schon bemüht. Zugegeben, ich hab mir nicht alle Seiten angeschaut aber schon 10-12 links und die meisten Anfragen waren eher auf freeware / einfache Programme basiert. Und wiegesagt, ich bräuchte eine Bewertung von den Programmen - und das hab ich bis jetzt nirdendwo gefunden.

10.07.2009 - 15:21 Uhr

Hallo zusammen,

ich versuche eine Übersicht über die gängigen kommerziellen Obfuscatorversionen zu verschaffen. Im Moment betrachte ich:
Dotfuscator Pro, {smartassembly} Pro und Skater .NET Ultimate.

Wir wollen eines von den Produkten für ein kommerzielles Programm einsetzen, haben aber noch nicht wirklich eine Entscheidung treffen können, welches von denen wir nehmen sollten (oder evtl. eine ganz andere Version?)

Während {smartassembly} und Skater in einer ähnlichen Preiskategorie spielen, ist Dotfuscator wesentlich teurer. Einen Grund dafür hab ich bis jetzt auch nicht wirklich gesehen.

Ich habe die Evaluationversionen von allen drei getestet und sie haben bei unserem Produkt mit ein paar Einstellungen funktioniert.

Hat einer von euch Erfahrungen mit einem von diesen Programmen oder eine allgemeine Empfehlung?

Danke!

Gruß

Mark

03.07.2009 - 16:22 Uhr

Jupp, was ich auch geschrieben hatte.
Nur, wenn man es gerade sowieso zum ersten Mal implementiert, wieso nicht gleich richtig?

Ob man jetzt

distance = acos(sin(la1)*sin(la2)+cos(la1)*cos(la2)*cos(lo1-lo2))

oder

distance = 2*asin(sqrt((sin((la1-la2)/2))^2 + cos(la1)cos(la2)(sin((lo1-lo2)/2))^2))

implementiert, ist doch von der Komplexität her egal, nur ist erstere Formel eben genauer. Das war auch der Kern meiner Aussage 😉

03.07.2009 - 16:02 Uhr

Das ist aber relativ ungenau (für kurze Distanzen halbwegs ok, aber du betrachtest die Erde als flach).

Besser geeignet sind diese Formeln http://williams.best.vwh.net/avform.htm

Die werden u.A. für die Luftfahrt angewendet und sind dementsprechend genauer (dort ist die Erde eine Kugel, also auch nicht 100% genau)

01.07.2009 - 08:52 Uhr

Hallo zusammen,

weiß jemand zufällig wie ich die Temperatur eines Intel CPUs (z.B. T9400) auslesen kann? (Es muss nicht unbedingt mit C# realisierbar sein).

WMI ist keine Option da die Daten bei meinem Notebook einfach nicht vorhanden sind.

Ich habe bereits gelesen, dass die Daten in einem MSR gespeichert sind und dass man einen "Kernel Mode" Treiber dafür schreiben muss...

Allerdings gibts ja auch einfache .exe's da draussen die, soweit ich das erkennen kann, keinen Treiber installieren und trotzdem die richtige Temperatur auslesen können.

Ich wäre über jegliche Tipps sehr dankbar!

Danke

Mark

22.06.2009 - 22:45 Uhr

Hallo zusammen,

ich steuer mit C# ein LED Display an womit ich hübsche Sachen anzeigen kann 8)
Das ganze erfolgt aus einem C# Programm, das keine GUI hat - es läuft im Hintergrund bis Windows beendet wird.

Jetzt möchte ich erreichen, dass ich unter bestimmten Bedingungen auch etwas in die Anzeige eingeben kann. Ich möchte also im Prinzip eine TextBox simulieren nur wie kann ich den Focus der Tastatur bekommen? Ich habe schon überlegt das mit 'nem Window Hook zu machen allerdings finde ich die Lösung suboptimal da das recht low level wird. So tief in das System möchte ich ungern eingreifen. Hat jemand eine Idee wie ich das lösen könnte? Evtl. mit einer Message Loop? Aber das löst das Problem mit dem Fokus noch nicht - wenn z.B. Word offen ist und die Bedingungen für die Eingabe für das LED Display gegeben ist, soll der Text nicht mehr in Word angezeigt werden...

Danke für eure Hinweise!

Viele Grüße

Mark

18.06.2009 - 10:10 Uhr

Danke aber das hatte ich auch schon geposted 😉

18.06.2009 - 07:25 Uhr

So einfach ist das nicht, da der zugehörige Buchstabe vom Tastaturlayout abhängt.
Shift+7 ist im deutschen eine '/' während bei der englischen Tastatur '&' rauskommt...

17.06.2009 - 18:52 Uhr

Lol ja so schlau bin ich auch 😉

Habs jetzt jedenfalls mit good ole' P/Invoke hingekriegt (falls es jemanden Interessiert: schaut euch GetKeyboardState() und ToUnicode() bzw. ToAscii() an)

Geht vermutlich auch mit .NET allerdings keine Ahnung wie...

17.06.2009 - 17:41 Uhr

Dann ist die Frage, wie man ein KeyEventArgs in ein KeyPressEventArgs konvertieren kann 😉
Die Quelle meines Args ist ein KeyboardHook und da bekomme ich eben die VirtualKeys sowie die zu dem Zeitpunkt Modifiers und eventuell noch den Scancode aber ich glaube das ist noch ferner von meinem Ziel als der VK.

17.06.2009 - 16:42 Uhr

Hallo zusammen,

ich programmiere meine eigene Eingabe und reagiere auf einen "globalen" KeyDown Event worüber ich ein KeyEventArgs bekomme (genauso wie bei Forms).
Jetzt möchte ich wissen, welches character sich dahinter versteckt und zwar mit Berücksichtigung sämtlicher Modifier.
Also wenn ich z.B. bei einer deutschen Tastatur SHIFT+7 (nicht aufm Numpad!) drücke, dann möchte ich '/' bekommen und nicht die Zahl 7...
Im KeyCode bzw. KeyData fließt die Information über der Shift Taste nur als Flag rein aber ich kriege nicht raus, welchem Buchstaben das gerade entspricht.

Any Tips?

Danke & Gruß

Mark

12.03.2009 - 10:16 Uhr

Das hab ich gar nicht bedacht, gutes Beispiel!
Ich hab's eben ausprobiert und der Designer gibt das Schema für den ersten Eintrag in der SQL definition an (ohne es auszuführen) - auch wenn der Defaultwert den 2. Eintrag in der IF/ELSE Kaskadierung auswählen würde...! Das dürfte also zu einer Exception führen wenn man die SP mit einem anderen Wert ausführt.

12.03.2009 - 09:42 Uhr

Hmm, das müsste doch auch anders gehen, denn

a) soweit ich weiß werden SP's vorkompiliert, d.h. der Server müsste wissen was das Schema des Rückgabewertes ist

b) wenn ich im DataSet Designer von VS2008 eine Stored Procedure importiere, zeigt er mir auch ein DataTable dafür an. Und ich glaube nicht, dass er die Stored Procedure dafür ausführt...

11.03.2009 - 09:37 Uhr

verwendetes Datenbanksystem: MS SQL Server 2005/2008

Bei einer function ist es mit exec sp_help 'funcname' möglich, das Schema des Rückgabewertes zu ermitteln (z.B. bei Table-Valued-Functions kriegt man das Schema der Tabelle). Das gleiche funktioniert einem Stored Procedure leider nicht.
Wie kann man das anders lösen (z.B. wenn die SP nur ein select ausführt).

Danke & Gruß

Mark

02.02.2009 - 19:19 Uhr

Hallo,

interessanter Ansatz. Ganz im Allgemeinen: bist Du Dir sicher, dass so viele Multiplikationen schneller sind als eine einfache Matrixmultiplikation?

In meinem Fall hilft das nicht viel, da alleine der Aufruf DrawUser() bzw. ohne User in der Schleife langsam ist (wiegesagt, ich habe ca. 380.000 Objekte).

Bis jetzt ist die Lösung, alles in einem Array zu speichern und einfach die World Matrix zu bewegen, die um über Faktor 10 schnellste (90 fps <-> 7-5 fps)

30.01.2009 - 22:56 Uhr

So, ich habe jetzt ein paar Tests durchgeführt:

De facto habe ich um die 320.000 Objekte, die gezeichnet werden müssen.

a) Baller ich alle in ein riesen Vertices-array, dauert die Rendermethode ca. 15 ms.

b) Wähle ich nun ein mini Array, in dem die lokalen Positionen meines Dreiecks gespeichert sind, und setze die View Matrix für jede Stadt neu, dauert meine Rendermethode 250-300 ms. Und dabei benutze ich schon ein VertexBuffer das im Video RAM gespeichert ist (verbraucht ja schließlich ein paar bytes). Dafür sehen die Symbole aber schick aus wenn ich sie skaliere...

Was gibts noch für Möglichkeiten? Kann ich meine Vertices nicht einmalig auf eine temporäre Fläche malen und diese dann immer wieder neu anzeigen? Und nur wenn meine Skalierung oder meine Translation sich ändert muss die Fläche neu aufgebaut werden? Oder ein völlig anderer Ansatz? 320.000 * 3 Vertices dürften für ne Moderne Graka ja ein Kinderspiel sein (wie Beispiel a) zeigt) - was mache ich bei Ansatz b) falsch?

30.01.2009 - 12:18 Uhr

Leidet die Performance nicht erheblich, wenn ich für jede Stadt einmal die View neu setzen muss und die Stadt einzeln malen muss?

Ich habe ca. 80.000 Städte im Moment, und die Vertices für die Symbole (ich arbeite nicht mit Texturen) sind in einem einzelnen Array der Länge 80.000 * 3. Lasse ich dieses Array malen, dauert das ca. 10-14 ms.

Ich habe schon einen anderen Ansatz ausprobiert, wo jede Stadt seine zu malende Vertices gespeichert hat und eine Paint Methode hatte (wo nichts berechnet wurde, nur DrawUserPrimitives aufgerufen wurde) und ich in der Haupt-Rendermethode nur eine Schleife hatte wo ich die PaintMethode von jeder Stadt aufgerufen habe. Das führte zum Ergebnis, dass die Gesamtdauer auf ca. 450 ms gestiegen ist.

Wenn ich mir überlege, dass ich in der Schleife auch noch mal die View Matrix neu berechnen muss, wird es vermutlich auf knapp über 500 ms steigen (jedenfalls ≥ 450 ms), oder?

Ich bin schon auf eine flüssige Darstellung angewiesen, also so 50-30 fps sollten es schon sein.

29.01.2009 - 23:48 Uhr

Hmm so ganz glücklich bin ich noch nicht:

meine Städte bzw. deren Symbole (also die Dreiecke) sind alle in einem Vertex Array gespeichert und zwar mit absoluten Positionen. Nehme ich den Ansatz, so funktioniert das einzoomen (also das skalieren) und auch der neue Mittelpunkt wird richtig gesetzt (via Translation) aber die Symbole werden ebenfalls mitskaliert. Mein Ziel ist es, zwar nur einen Ausschnitt von der Erde darzustellen aber gleichzeitig die Symbole nicht mit-zu-skalieren. Vielleicht ist ja auch mein Ansatz nicht so ideal?

29.01.2009 - 19:51 Uhr

Die rotation Matrix, wie wird sie initialisiert? Als Einheitsmatrix?

Vector3 point=...
point.Transform(Matrix.Scalation(scalation,scalation,scalation) * rotation * Matrix.Translation(translation))

Das heißt doch, dass ich doch jeden Punkt anfassen muss und im Endeffekt neu berechnen muss sobald ich den Zoommodus verändere, oder? Also wird es nicht wirklich schneller?

29.01.2009 - 18:34 Uhr

Hallo Christian,

Kannst Du dafür mal ein Beispiel geben?
Also ich geh so vor:
Am Anfang setz ich das hier:

this.device.Transform.Projection = Matrix.OrthoOffCenterLH(-180, 180, -90, 90, 0, 10);

womit die ganze Erde sichtbar ist. Meine Vertices fallen eben in dieses Intervall. Will ich auf eine Stadt einzoomen, die sagen wir mal bei 10,10 liegt, führe ich aus:

this.device.Transform.Projection = Matrix.OrthoOffCenterLH(8, 12, 9, 11, 0, 10);

Nur wird dadurch die Stadt viel größer dargestellt.
Wie meinst Du das mit der Viewmatrix? Außer die Projection setze ich keine Matrix.

29.01.2009 - 17:55 Uhr

Hallo zusammen,

ich schreibe gerade ein kleines Programm, dass mir auf einer einfachen Karte Städte einzeichnet. In der Standardzoomeinstellung ist die ganze Welt sichtbar und man kann daraufhin in bestimmte Regionen hineinzoomen. Das funktioniert soweit auch nur hab ich ein Problem:
Meine Städte werden durch Dreiecke repräsentiert und sind alle in einem Vertex Array gespeichert. Wenn ich reinzoome, ändere ich lediglich die Projektionsmatrix (OrthoLH) (width/height wird kleiner) nur dadurch werden meine Städte natürlich viel größer weil das Dreieck ja mitwächst. Gelöst habe ich das nun so, dass ich für jede Stadt das Dreieck neuberechne sodass die Breite halbwegs konstant bleibt, egal wie weit ich reinzoome. Dadurch verlier ich allerdings leider etwas performance.
Kennt jemand eine Methode, wie ich das eleganter lösen könnte? Bin noch relativ neu auf dem Gebiet von 3D Programmierung.

Danke & Gruß

Mark

24.01.2009 - 11:50 Uhr

Hallo zusammen,

ich benutze Direct3D um Objekte 2 dimensional darzustellen (Z achse ist konstant). GIbt es eine Methode, um Objekte im Umkreis eines vorgegebenen Punktes zu finden, ohne manuell alle Vertices zu prüfen? Das soll dazu verwendet werden, um bei einem Mausklick das darunter liegende Objekt zu finden.

Es handelt sich um ein orthogonales World-system (device.Transform.Projection = Matrix.OrthoOffCenterLH(...) ) und ich benutze DrawUserPrimitives() um meine Vertices zu malen.

Danke für eure Hinweise!

Ein sehr frischer D3D Progger,
Mark

08.01.2009 - 15:07 Uhr

So ich glaube ich verstehe so langsam was passiert:

die Kommunikation zwischen verschiedenen AppDomains läuft bekanntlich über Remoting. Wenn man bei Remoting mit Events arbeitet, muss Objekt A Objekt B kennen und umgekehrt (die Assembly muss sowohl beim Server als auch beim Client vorliegen).
Und genau das verursacht den Fehler: die Host-AppDomain versucht das Assembly des Plugins zu laden sobald der delegate "rübergeschickt" werden soll, findet dabei die Assembly nicht -> Exception. Und mit Spooks Lösung wird die Assembly geladen, allerdings ist das Plugin dann fest in der AppDomain geladen und ich kann sie nicht mehr entladen.

Meine unschöne Lösung ist, dass ich einfach alle Events durch abstrakte Methoden ersetze (die in einer anderen Klasse implementiert sind) und rufe diese Methoden auf. Das funktioniert auch.

Unterstützt System.AddIn Events AppDomain-übergreifend? Wenn ja, wie funktioniert es dort? Kennt jemand eine bessere Lösung für mein Problem? Fragen über Fragen 8o

Viele Grüße

Mark

08.01.2009 - 11:15 Uhr

Hallo kelkes,

das ist sicherlich auch interessant - nur würde ich gerne mein Konzept zum Laufen kriegen. System.AddIn scheint mit dem ganzen drum-rum etwas viel Aufwand zu sein, zumal ich schon (hoffentlich!) "kurz davor" bin 😉

08.01.2009 - 08:35 Uhr

Hallo Spooky,

vielen Dank! Das war der Trick! 👍

Jetzt habe ich aber das Problem, dass die DLL in die AppDomain vom Host geladen wird und somit nicht mehr entladen werden kann, was mein Plugin System hinfällig macht.
Ich kann zwar die AppDomain vom Plugin entladen, aber die DLL bleibt weiterhin in der Host-AppDomain geladen und kann somit weder gelöscht noch ersetzt werden.

Interessanterweise funktionieren die Methodenraufrufe ohne die App.Config problemlos - erst das Abonnieren des Events verursacht dieses Verhalten.

Hat dafür jemand einen Tipp?

Danke!

Gruß

Mark

07.01.2009 - 12:42 Uhr

Ich habe jetzt mal eine mini-Solution erstellt, wo das Problem auftritt. Vielleicht findet sich jemand der kurz Zeit hat und mal reinschauen kann?

Danke!