C# Managed DirectX - load Mesh

Sheeep

Lt. Junior Grade
Registriert
Juli 2007
Beiträge
272
Hi,

ich hab ein problem mit c# und directX.


also, ich hab mit blender ein .x file (directX mesh) erzeugt (funktioniert in dx-viewer). diese file würde ich gerne einlesen. das funktioniert auch noch.

das materialeinlesen scheint nach dem debugger auch zu funktionieren.

wenn ich jetzt dem device das material des meshs übergebe, dann stehen auch die meshdaten richtig im device drin.

aber trotzdem bleibt das mesh weiß (lichquelle stimmt, sonst wäre es schwarz). ich hab keine ahnung warum. weiß einer von euch woran das liegen könnte?

Hiermit lese ich das mesh ein:
Code:
mesh = Mesh.FromFile("test1.x", MeshFlags.Managed, m_Device, out apt, out hmaterial);

                if ((mesh.VertexFormat & VertexFormats.Normal) != VertexFormats.Normal)
                {
                    Mesh temp = mesh.Clone(mesh.Options.Value, apt ,m_Device);
                    mesh.Dispose();
                    mesh = temp;
                }
               // mesh.GenerateAdjacency(0.001f, );
                this.mesh.OptimizeInPlace(MeshFlags.OptimizeAttributeSort, apt);
                apt.Dispose();
                this.material = new Material[mesh.NumberAttributes];
                this.texture = new Texture[mesh.NumberAttributes];
                for (int i = 0; i < mesh.NumberAttributes; i++)
                {
                    this.material[i] = hmaterial[i].Material3D;
                    this.material[i].AmbientColor = material[i].DiffuseColor;
                    if (this.hmaterial[i].TextureFilename != null && this.hmaterial[i].TextureFilename.Length > 0)
                    {
                        this.texture[i] = TextureLoader.FromFile(m_Device, this.hmaterial[i].TextureFilename);
                    }
                    else
                    {

                        this.texture[i] = null;
                    }
                }


und das ist meine draw- funktion:
Code:
 m_Device.Clear(ClearFlags.Target, Color.Blue, 0.0f, 0);

            //RenderMode
            m_Device.RenderState.FillMode = FillMode.Solid;
            m_Device.RenderState.CullMode = Cull.CounterClockwise;
            
           
            m_Device.BeginScene();
            m_Device.VertexFormat = mesh.VertexFormat;
            for (int i = 0; i < mesh.NumberAttributes; i++)
            {
                m_Device.Material = material[i];
                m_Device.SetTexture(0, texture[i]);
                mesh.DrawSubset(i);
            }
            m_Device.EndScene();
            m_Device.Present();


ich hab mal dar komplette c# project angehängt (vs 2010)...
 

Anhänge

Zuletzt bearbeitet:
Es liegt an deinem *.x File - da du die Datei als ASCII Exportiert hast, kannst du diese einfach in einem Editor ansehen. Dort gibt es beim Material keinen Eintrag für die Textur. Ich hab mal schnell ein *.x File aus alten Tagen ausgegraben und an dein Programm übergeben und siehe da, es funktioniert:

Untitled.png
 
Hi, danke für deine Antwort...

hast du das mit meinem programm geöffnet?

da sind jetzt texturen drauf, ich hatte in meinem x-file keine texturen, sondern nur ne farbe (bzw. Material)...
macht das einen unterschied?

wie muss ich denn das x-flie aus blender exportieren, damit es korrekt eingelesen wird (mit / ohne Texture)?
kannst du mir dein x-File mal anhängen?

was mich jetzt noch wundert, mit dem directX-Viewer kann ich das x-file korrekt öffnen...
 
Zuletzt bearbeitet:
Ich dachte du wolltest eine Textur drauf haben - falsch verstanden. Die Farben werden erst durch die Beleuchtung sichtbar, wenn du kein Licht definiert hast so kannst du auch einfach das Ambient-Light aktivieren:

Code:
m_Device.RenderState.Lighting = true;
m_Device.RenderState.Ambient = Color.White;

Damit bleibt der Mesh aber einfarbig:
AmbientLight.png

Erst wenn durch die richtige Beleuchtung (z.B. Directional Light) bekommst du Farbverläufe. Ein Directional Light kannst du z.B. so aktivieren
Code:
m_Device.RenderState.Lighting = true;
m_Device.RenderState.Ambient = Color.Black;
m_Device.Lights[0].Direction = new Vector3(-2.5f, -3, 5);
m_Device.Lights[0].Diffuse = Color.White;
m_Device.Lights[0].Enabled = true;

Das Ergebnis sieht dann ungefähr so aus:
DirectionalLight.png
 
Zuletzt bearbeitet:
Super, danke du bist meine Rettung!
:schluck:
 
Hi,

ich versuch grad über ein Polygon (Viereck) eine Videotexture zu legen.
Ich hab mal gegooglt, wie das geht...

Grundsätzlich funktioniert das auch. Nur ruckelt die video Textur, da sie wohl nicht richtig mit der framerate des draw-Funktion synchronisiert ist. nur, wie mache ich das?


ich lade die texture, indem ich zunächst ein video erstelle:
Code:
  //VideoTexture
                this.video = Video.FromFile("Sintel_Trailer1.480p.DivX_Plus_HD.mkv.MPG");
                this.video.TextureReadyToRender += new TextureRenderEventHandler(video_TextureReadyToRender);
                this.video.Ending += new EventHandler(OnMovieEnding);
                this.video.RenderToTexture(m_Device);
                this.video.Play();


und verwende folgenden event-handler:

Code:
        private void video_TextureReadyToRender(Object sender, TextureRenderEventArgs e)
        {
            if (e.Texture == null)
            {
                return;
            }
            SurfaceDescription ds = e.Texture.GetLevelDescription(0);

            if (ds.Pool == Pool.Default)
            {
                sysSurf = m_Device.CreateOffscreenPlainSurface(ds.Width, ds.Height,
                ds.Format, Pool.SystemMemory);
            }
            using (Surface vidSurf = e.Texture.GetSurfaceLevel(0))
            {
                if (this.texture1 == null)
                {
                    texture1 = new Texture(m_Device, ds.Width, ds.Height,
                    1, Usage.Dynamic, ds.Format, ds.Pool);
                }
           
                using (Surface texSurf = this.texture1.GetSurfaceLevel(0))
                {
                    SurfaceLoader.FromSurface(texSurf, vidSurf, Filter.Linear, unchecked((int)0xffffffff));
                }
            }
        }

weiß jemand wie ich in managed directX eine texture flüssig darstellen kann?

MFG
Sheeep

P.S.
ich kann das visual studio projekt leider nicht mehr anhängen, weil es wegen dem video zu groß für das forum ist.
hab es mal auf rapidshare gepackt.
http://rapidshare.com/files/425480753/DirecXCSharp.rar


Edit:
Die Videotexture wird auch nicht richtig geschlossen. Das Programm muss momentan im Tastmanager beendet werden... auch da weiß ich nicht warum... bitte um Hilfe ;)

Sheeep
 
Zuletzt bearbeitet:
Wirklich sauber scheint das mit Managed DirectX nicht zu funktionieren - siehe z.B. hier, die haben eigentlich wirklich Ahnung aber dennoch keine saubere Lösung. Die Hoffnung auf einen Bugfix in Managed DirectX gibt es auch nicht, da Managed DirectX seit Jahren tot ist. Was bei mir einigermaßen stabil funktioniert ist das Umschalten der Renderschleife direkt in den Event-Handler - eine Garantie übernehme ich hierfür jedoch nicht.

Code:
        private void video_TextureReadyToRender(Object sender, TextureRenderEventArgs e)
        {
            m_Device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.Blue, 1.0f, 0);

            m_Device.BeginScene();
            //draw Mesh
            m_Device.VertexFormat = mesh.VertexFormat;
            m_Device.SetTexture(0, this.texture1);
            for (int i = 0; i < mesh.NumberAttributes; i++)
            {
                m_Device.Material = material[i];
                m_Device.SetTexture(0, texture[i]);
                mesh.DrawSubset(i);
            }

            //draw user primitives
            m_Device.SetStreamSource(0, this.vertexBuffer, 0);
            m_Device.VertexFormat = CustomVertex.PositionColoredTextured.Format;
            m_Device.Material = material1;
            m_Device.SetTexture(0, e.Texture);
            Matrix world = Matrix.RotationZ(-(float)Math.PI / 2);
            world *= Matrix.Translation(0.2f, 0, -1);
            m_Device.Transform.World = world;
            m_Device.DrawPrimitives(PrimitiveType.TriangleList, 0, this.verts.Length);
            m_Device.Transform.World = Matrix.Identity;
            m_Device.EndScene();
            m_Device.Present();
        }

Außerdem "texture1" komplett entfernen und in die shutdown() Methode so umbauen:
Code:
            DisposeTextures();
            m_Device.Dispose();

Neben dem normalen Ruckeln hat aber dein Video auch einige Hänger egal in welchem Player ich es abspiele.
 
hey,
danke für die antwort. das hatte ich irgendwie befürchtet

kann ich über ein mesh eine videotexture legen? könnte das das problem lösen?

mfg
Sheeep
 
Das Problem wirst du nicht lösen, so lange du die Video Klasse von Managed DirectX verwendest. Allerdings kannst du ja meine Modifikationen mal probieren, diese laufen eigentlich recht gut.
 
hmm, ok, dann versuch ich das mal so.

aber was passiert, wenn die texture zu ende ist? dann wird die rendermethode ja nicht mehr aufgerufen?


EDIT:
ok, da herum zu programmieren war nicht schwer ;)

jetzt hab ich nur das problem, dass immer ein fehler auftritt, wenn ich das fenster schließe:

Informationen über das Aufrufen von JIT-Debuggen
anstelle dieses Dialogfelds finden Sie am Ende dieser Meldung.

************** Ausnahmetext **************
System.AccessViolationException: Es wurde versucht, im geschützten Speicher zu lesen oder zu schreiben. Dies ist häufig ein Hinweis darauf, dass anderer Speicher beschädigt ist.
bei Microsoft.DirectX.AudioVideoPlayback.Video.ReleaseObjects()
bei Microsoft.DirectX.AudioVideoPlayback.Video.Dispose()
bei Microsoft.DirectX.AudioVideoPlayback.Video.OnDeviceLost(Object sender, EventArgs e)
bei System.EventHandler.Invoke(Object sender, EventArgs e)
bei Microsoft.DirectX.Direct3D.Device.raise_DeviceLost(Object i1, EventArgs i2)
bei Microsoft.DirectX.Direct3D.Device.Dispose()
bei Microsoft.DirectX.Direct3D.Device.OnParentDisposed(Object sender, EventArgs e)
bei System.ComponentModel.Component.Dispose(Boolean disposing)
bei System.Windows.Forms.Control.Dispose(Boolean disposing)
bei System.Windows.Forms.ContainerControl.Dispose(Boolean disposing)
bei System.Windows.Forms.Form.Dispose(Boolean disposing)
bei DirectX_C_Sharp_1.Form1.Dispose(Boolean disposing) in C:\Users\BlackSheeep\Desktop\DirecXCSharp\DirecXCSharp\Form1.Designer.cs:Zeile 20.
bei System.ComponentModel.Component.Dispose()
bei System.Windows.Forms.Form.WmClose(Message& m)
bei System.Windows.Forms.Form.WndProc(Message& m)
bei System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
bei System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
bei System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

DisposeTextures() steht in shutdown() drin... die bewirkt aber den absturtz...
 
Zuletzt bearbeitet:
Zurück
Oben