Nargil Opublikowano 13 Października 2005 Zgłoś Opublikowano 13 Października 2005 (edytowane) Po dlugim czasie znow powrocilem do 3d, ale chyba mijam sie tu z powolaniem bo z tego co mi wychodzi to stwierdzam ze brak mi talentu :) No ale nie bede sie poddawal tylko zaloze lamerski topic Laduje model podloza z pliku ase ( tak wiem ze tam jest XZY i Z*(-1) ) i laduje to vertex buffora, ale to co pojawia sie na scenie to hmmmm HEREZJE :D Sa dziury ( brakuje faces ) w podlozu, a faces polozone w oddali przyblizaja i oddalaja sie szybciej od tych polozonych blisko kamery. Ja naprawde nie wiem co tu sie dzieje. Zarys wczytanego obiektu jest mniej wiecej ok wiec to raczej nie wina zlego uzycia TriangleList vs TriangleStrip itp. Program wymaga: net framework 2.0 beta 2 - http://www.microsoft.com/downloads/details...&displaylang=en managed d3d - http://www.microsoft.com/downloads/details...&displaylang=en oto program: http://demon.hell.org.pl/darq/Release.rar poki co jest takze mirror na: http://rainbow.mimuw.edu.pl/~ks209502/darq/Release.rar , ale tu moze zniknac w przeciagu kilku dni. a oto kod: engine.cs using System;using System.Collections;using System.Collections.Generic;using System.Data;using System.Data.Common;using System.Drawing;using System.Windows.Forms;using Microsoft.DirectX;using Microsoft.DirectX.Direct3D;using Microsoft.DirectX.DirectInput;namespace NRG_3D_CS{ /// <summary> /// Summary description for Form1. /// </summary> /// public class NRG_3D : System.Windows.Forms.Form { private Microsoft.DirectX.DirectInput.Device keyb; private float piover180 = (float)Math.PI / 180.0f; private const int nargil_width = 1024; private const int nargil_height = 768; private Microsoft.DirectX.Direct3D.Device device = null;//urządzenie private bool paused = false; private _model teren = new _model(); private bool devicelost = false; private kamera cam = new kamera(); private long t1, t2; private float delta; public void InitializeKeyboard() { keyb = new Microsoft.DirectX.DirectInput.Device(SystemGuid.Keyboard); keyb.SetCooperativeLevel(this, CooperativeLevelFlags.Background | CooperativeLevelFlags.NonExclusive); keyb.Acquire(); } public NRG_3D() { InitializeDevice(); } #region inicjalizacja i obsluga urzadzenia //zininjowanie urzadzenia public void InitializeDevice() { //standardowe ustawienie dla okna ClientSize = new System.Drawing.Size(nargil_width, nargil_height); Name = "Nargil"; Text = "Nargil's c# d3d 9.0"; FormBorderStyle = FormBorderStyle.FixedDialog; Format current = Microsoft.DirectX.Direct3D.Manager.Adapters[0].CurrentDisplayMode.Format; PresentParameters pp = new PresentParameters(); pp.Windowed = true;//uruchamiamy w trybie okienkowym //pp.Windowed = false; pp.BackBufferFormat = current; pp.BackBufferCount = 1; pp.BackBufferWidth = nargil_width; pp.BackBufferHeight = nargil_height; pp.SwapEffect = SwapEffect.Discard;//troche wieksza wydajnosc pp.EnableAutoDepthStencil = true; pp.AutoDepthStencilFormat = DepthFormat.D16; //utworzenie urzadzenia device = new Microsoft.DirectX.Direct3D.Device(0, Microsoft.DirectX.Direct3D.DeviceType.Hardware, this, CreateFlags.HardwareVertexProcessing, pp); device.DeviceReset += new EventHandler(OnResetDevice); OnResetDevice(device, null); paused = false; } public void OnResetDevice(object sender, EventArgs e) { Microsoft.DirectX.Direct3D.Device d = (Microsoft.DirectX.Direct3D.Device)sender; d.RenderState.ZBufferEnable = true; d.RenderState.CullMode = Cull.None;//ukrywanie scian niewidocznych d.RenderState.Lighting = true;//nie ma oswietlena d.RenderState.FogEnable = false; d.RenderState.FogColor = Color.DarkGray; d.RenderState.FogStart = 0.0f; d.RenderState.FogEnd = 1200.0f; d.RenderState.FogTableMode = FogMode.Linear; d.RenderState.FogVertexMode = FogMode.Linear; } #endregion #region obsluga okna protected override void OnPaint(PaintEventArgs e) { Render(); } protected override void OnResize(System.EventArgs e) {//sprawdzenie stanu okna i aktualizacja zmiennej paused paused = ((WindowState == FormWindowState.Minimized) || !Visible); } #endregion #region transformacje //resetowanie kamery private void resetcamera() { cam.pos = new Vector3(0.0f, 36.0f, 5.0f); cam.lookat = new Vector3(0.0f, 36.0f, 0.0f); cam.lh = new Vector3(0.0f, 1.0f, 0.0f); } //ustawienie macierzy private void SetupLights() { System.Drawing.Color col = System.Drawing.Color.White; //Set up a material. The material here just has the diffuse and ambient //colors set to yellow. Note that only one material can be used at a time. Material mtrl = new Material(); mtrl.Diffuse = col; mtrl.Ambient = col; device.Material = mtrl; //Set up a white, directional light, with an oscillating direction. //Note that many lights may be active at a time (but each one slows down //the rendering of our scene). However, here we are just using one. Also, //we need to set the D3DRS_LIGHTING renderstate to enable lighting device.Lights[0].Type = LightType.Point; device.Lights[0].Diffuse = System.Drawing.Color.White; device.Lights[0].Position = cam.pos; device.Lights[0].YPosition += 100.0f; device.Lights[0].Attenuation0 = 5.001f; device.Lights[0].Range = 2000.0f; device.Lights[0].Enabled = true;//turn it on //Finally, turn on some ambient light. //Ambient light is light that scatters and lights all objects evenly device.RenderState.Ambient = Color.FromArgb(0x505020); } private void Matrices() { cam.lookat.X = cam.pos.X + (float)Math.Sin(cam.rot.Y); cam.lookat.Z = cam.pos.Z + (float)Math.Cos(cam.rot.Y); device.Transform.View = Matrix.LookAtLH( //trnasformacja do przestrzeni 'kamery' cam.pos,//pozycja kamery cam.lookat, //kierunek patrzenia cam.lh );//gdzie jest gora device.Transform.Projection = Matrix.PerspectiveFovLH( (float)Math.PI / 4, //pole widzenia 1.0f, //wspolczynnik proporcji (szerokosc/wysokosc) 1.0f, //najblizsze z 1000.0f );//najdalsze z } #endregion #region rendering //wyswietlenie sceny public void Render() { if(device == null || paused == true) return;//nie ma gdzie wyswietlac //wyczysc ekran do koloru czarnego device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.SkyBlue, 1.0f, 0); //po skasowaniu komentarzy mozna zobaczyc jak dziala wzirniki //trojkat bedzie renderowany tylko na czesci ekranu, reszte pozostawiajac na np. //interface uzytkownka Viewport vp = new Viewport(); vp.X = vp.Y = 0; vp.Width = nargil_width; vp.Height = nargil_height; device.Viewport =vp; //poczatek sceny device.BeginScene(); Matrices();//przeksztalcenia teren.render(device); device.EndScene(); try { device.Present(); } catch (DeviceLostException) { devicelost = true; } } #endregion static void Main() { NRG_3D app = null; try { app = new NRG_3D(); } catch(DirectXException) { return; } app.Show(); //wczytujemy app.SetupLights(); app.teren.loadase("t.ASE"); app.teren.SortToQuad(); app.teren.FillVB(app.device); // ustawienia kamery app.resetcamera(); //glowna petla programu app.t1 = Environment.TickCount; app.InitializeKeyboard(); while(app.Created) { app.gra(); Application.DoEvents(); } } private void ReadKeyboard() { KeyboardState keys = keyb.GetCurrentKeyboardState(); if (keys[Key.D]) { cam.rot.Y += 45.0f * piover180 * delta; } if (keys[Key.A]) { cam.rot.Y -= 45.0f * piover180 * delta; } if (keys[Key.W]) { cam.pos.Z += 160.0f * delta * (float)Math.Cos(cam.rot.Y); cam.pos.X += 160.0f * delta * (float)Math.Sin(cam.rot.Y); } if (keys[Key.S]) { cam.pos.Z -= 160.0f * delta * (float)Math.Cos(cam.rot.Y); cam.pos.X -= 160.0f * delta * (float)Math.Sin(cam.rot.Y); } } private void gra() { t2 = Environment.TickCount; delta = (float)(t2 - t1)/1000; t1 = t2; ReadKeyboard(); Render(); } }} model.cs using System;using System.IO;using System.Drawing;using System.Text;using System.Collections;using System.Collections.Generic;using System.Data;using System.Data.Common;using System.Windows.Forms;using Microsoft.DirectX;using Microsoft.DirectX.Direct3D;namespace NRG_3D_CS{ public class quadtreeheader { public treenode4 first = null, tmp = null; public float min_x, max_x, min_z, max_z; public int max_lvl; } public class treenode4 { public treenode4 [] n = new treenode4[4]; public float min_x, max_x, min_z, max_z; public List<_face> faces = new List<_face>(); } public class _material { public string diffuse_map; public Color diffuse_color; public string bump_map; } public class _vertex { public Vector3 pos = new Vector3(); public Vector3 normal = new Vector3(); public float tv, tu = new float(); }; public class _face { public _vertex a; public _vertex b; public _vertex c; public int mat_id; }; public class _model { //private private int v_count; private int f_count; private int m_count; private _vertex[] vertex; private _face[] face; private _material[] material; private VertexBuffer vbuf; private quadtreeheader quadtree = new quadtreeheader(); //public public Vector3 pos; public _model() { pos.X = 0.0f; pos.Y = 0.0f; pos.Z = 0.0f; v_count = 0; f_count = 0; m_count = 0; } private long przesun(long i, string[] atmp) { i++; while (atmp[i].Equals(" ")) i++; while (atmp[i].Equals("")) i++; while (atmp[i].Equals("\t")) i++; return i; } public void loadase(string plik) { System.Globalization.NumberFormatInfo ni; System.Globalization.CultureInfo ci = System.Globalization.CultureInfo.InstalledUICulture; ni = (System.Globalization.NumberFormatInfo) ci.NumberFormat.Clone(); ni.NumberDecimalSeparator = "."; v_count = 0; f_count = 0; m_count = 0; StreamReader fp; string ftmp; fp = File.OpenText(plik); ftmp = fp.ReadToEnd(); fp.Close(); char[] split = " \n\t\r".ToCharArray(); string[] atmp = ftmp.Split(split); long ltmp = 0; for (long i = 0; i < atmp.Length; i++) { if (atmp[i].Equals("")) continue; else if (atmp[i].Equals(" ")) continue; else if (atmp[i].Equals("*MATERIAL_COUNT")) { i = przesun(i, atmp); m_count = Int32.Parse(atmp[i]); material = new _material[m_count]; } else if (atmp[i].Equals("*MESH_NUMVERTEX")) { i = przesun(i, atmp); v_count = Int32.Parse(atmp[i]); vertex = new _vertex[v_count]; for (int j = 0; j < v_count; j++) vertex[j] = new _vertex(); } else if (atmp[i].Equals("*MESH_NUMFACES")) { i = przesun(i, atmp); f_count = Int32.Parse(atmp[i]); face = new _face[f_count]; for (int j = 0; j < f_count; j++) face[j] = new _face(); } else if (atmp[i].Equals("*MESH_VERTEX")) { i = przesun(i, atmp); ltmp=Int32.Parse(atmp[i]); i = przesun(i, atmp); vertex[ltmp].pos.X = float.Parse(atmp[i],ni); i = przesun(i, atmp); vertex[ltmp].pos.Z = -1.0f * float.Parse(atmp[i],ni); i = przesun(i, atmp); vertex[ltmp].pos.Y = float.Parse(atmp[i],ni); } else if (atmp[i].Equals("*MESH_FACE")) { i = przesun(i, atmp); atmp[i] = atmp[i].Remove(atmp[i].Length-1); ltmp = Int32.Parse(atmp[i]); i = przesun(i, atmp); i = przesun(i, atmp); face[ltmp].a = vertex[Int32.Parse(atmp[i])]; i = przesun(i, atmp); i = przesun(i, atmp); face[ltmp].b = vertex[Int32.Parse(atmp[i])]; i = przesun(i, atmp); i = przesun(i, atmp); face[ltmp].c = vertex[Int32.Parse(atmp[i])]; while (!atmp[i].Equals("*MESH_MTLID")) i = przesun(i, atmp); i = przesun(i, atmp); face[ltmp].mat_id = Int32.Parse(atmp[i]); } else if (atmp[i].Equals("*MESH_VERTEXNORMAL")) { i = przesun(i, atmp); ltmp = Int32.Parse(atmp[i]); i = przesun(i, atmp); vertex[ltmp].normal.X = float.Parse(atmp[i], ni); i = przesun(i, atmp); vertex[ltmp].normal.Z = -1.0f * float.Parse(atmp[i], ni); i = przesun(i, atmp); vertex[ltmp].normal.Y = float.Parse(atmp[i], ni); } else if (atmp[i].Equals("*MESH_TVERT")) { i = przesun(i, atmp); ltmp = Int32.Parse(atmp[i]); i = przesun(i, atmp); vertex[ltmp].tu = float.Parse(atmp[i], ni); i = przesun(i, atmp); vertex[ltmp].tv = float.Parse(atmp[i], ni); } else if (atmp[i].Equals("*MATERIAL_LIST")) { i = przesun(i, atmp); i = przesun(i, atmp); i = przesun(i, atmp); m_count = Int32.Parse(atmp[i]); material = new _material[m_count]; for (int j = 0; j < m_count; j++) material[j] = new _material(); } else if (atmp[i].Equals("*MATERIAL")) { i = przesun(i, atmp); ltmp = Int32.Parse(atmp[i]); while (!atmp[i].Equals("*MATERIAL_DIFFUSE") && !atmp[i].Equals("}")) i = przesun(i, atmp); int r, b, g, a; a = (char)255; i = przesun(i, atmp); r = (int)(255 * float.Parse(atmp[i], ni)); i = przesun(i, atmp); g = (int)(255 * float.Parse(atmp[i], ni)); i = przesun(i, atmp); b = (int)(255 * float.Parse(atmp[i], ni)); material[ltmp].diffuse_color = Color.FromArgb(a, r, g, b); } else if (atmp[i].Equals("*MAP_DIFFUSE")) { while (!atmp[i].Equals("*BITMAP")) i = przesun(i, atmp); i = przesun(i, atmp); material[ltmp].diffuse_map = atmp[i]; material[ltmp].diffuse_map = material[ltmp].diffuse_map.TrimStart("\"".ToCharArray()); material[ltmp].diffuse_map = material[ltmp].diffuse_map.TrimEnd("\"".ToCharArray()); } else if (atmp[i].Equals("*MAP_BUMP")) { while (!atmp[i].Equals("*BITMAP")) i = przesun(i, atmp); i = przesun(i, atmp); material[ltmp].bump_map = atmp[i]; material[ltmp].bump_map = material[ltmp].bump_map.TrimStart("\"".ToCharArray()); material[ltmp].bump_map = material[ltmp].bump_map.TrimEnd("\"".ToCharArray()); } } } private void dividequad(treenode4 node, int poziom) { if ((poziom > quadtree.max_lvl) || (node.faces.Count==0)) return; for (int i = 0; i < 4; i++) { node.n[i] = new treenode4(); } for (int i = 0; i < 2; ++i) { for (int j = 0; j < 2; ++j) { //przypisujemy galeziom ich zakresy node.n[2 * i + j].min_x = node.min_x + i * ((node.max_x - node.min_x) / 2); node.n[2 * i + j].max_x = node.min_x + (i + 1) * ((node.max_x - node.min_x) / 2); node.n[2 * i + j].min_z = node.min_z + j * ((node.max_z - node.min_z) / 2); node.n[2 * i + j].max_z = node.min_z + (j + 1) * ((node.max_z - node.min_z) / 2); } } for (int j = 0; j < 4; j++) { for (int i = 0; i < node.faces.Count; i++) { if ((node.faces[i].a.pos.X > node.n[j].min_x && node.faces[i].a.pos.X < node.n[j].max_x) && (node.faces[i].a.pos.Z > node.n[j].min_z && node.faces[i].a.pos.Z < node.n[j].max_z)) node.n[j].faces.Add(node.faces[i]); else if ((node.faces[i].b.pos.X > node.n[j].min_x && node.faces[i].b.pos.X < node.n[j].max_x) && (node.faces[i].b.pos.Z > node.n[j].min_z && node.faces[i].b.pos.Z < node.n[j].max_z)) node.n[j].faces.Add(node.faces[i]); else if ((node.faces[i].c.pos.X > node.n[j].min_x && node.faces[i].c.pos.X < node.n[j].max_x) && (node.faces[i].c.pos.Z > node.n[j].min_z && node.faces[i].c.pos.Z < node.n[j].max_z)) node.n[j].faces.Add(node.faces[i]); } dividequad(node.n[j], poziom + 1); } } public void SortToQuad() { quadtree.max_lvl = 5; quadtree.first = new treenode4(); quadtree.tmp = quadtree.first; int poziom = 0; //szukanie wymiarow obiektu quadtree.min_x = vertex[0].pos.X; quadtree.max_x = vertex[0].pos.X; quadtree.min_z = vertex[0].pos.Z; quadtree.max_z = vertex[0].pos.Z; for (long i = 1; i < v_count; i++) { if (vertex[i].pos.X < quadtree.min_x) quadtree.min_x = vertex[i].pos.X; else if (vertex[i].pos.X > quadtree.max_x) quadtree.min_x = vertex[i].pos.X; if (vertex[i].pos.Z < quadtree.min_z) quadtree.min_z = vertex[i].pos.Z; else if (vertex[i].pos.Z > quadtree.max_z) quadtree.min_z = vertex[i].pos.Z; } quadtree.first.max_x = quadtree.max_x; quadtree.first.min_x = quadtree.min_x; quadtree.first.max_z = quadtree.max_z; quadtree.first.min_z = quadtree.min_z; //porzadkowanie drzewa for(long i=0; i<f_count; i++) { quadtree.tmp.faces.Add(face[i]); } poziom = 1; dividequad(quadtree.tmp, poziom); } public void FillVB(Device device) { /* vbuf = new VertexBuffer(typeof(CustomVertex.PositionNormalTextured),f_count*3,device, 0,CustomVertex.PositionNormalTextured.Format,Pool.Default); CustomVertex.PositionNormalTextured[] verticles = (CustomVertex.PositionNormalTextured[])vbuf.Lock(0, 0); for (int i = 0; i < f_count; i++) { verticles[i * 3].X = face[i].a.pos.X; verticles[i * 3].Y = face[i].a.pos.Y; verticles[i * 3].Z = face[i].a.pos.Z; verticles[i * 3].Nx = face[i].a.normal.X; verticles[i * 3].Ny = face[i].a.normal.Y; verticles[i * 3].Nz = face[i].a.normal.Z; verticles[i * 3].Tu = face[i].a.tu; verticles[i * 3].Tv = face[i].a.tv; verticles[i * 3 + 1].X = face[i].b.pos.X; verticles[i * 3 + 1].Y = face[i].b.pos.Y; verticles[i * 3 + 1].Z = face[i].b.pos.Z; verticles[i * 3 + 1].Nx = face[i].b.normal.X; verticles[i * 3 + 1].Ny = face[i].b.normal.Y; verticles[i * 3 + 1].Nz = face[i].b.normal.Z; verticles[i * 3 + 1].Tu = face[i].b.tu; verticles[i * 3 + 1].Tv = face[i].b.tv; verticles[i * 3 + 2].X = face[i].c.pos.X; verticles[i * 3 + 2].Y = face[i].c.pos.Y; verticles[i * 3 + 2].Z = face[i].c.pos.Z; verticles[i * 3 + 2].Nx = face[i].c.normal.X; verticles[i * 3 + 2].Ny = face[i].c.normal.Y; verticles[i * 3 + 2].Nz = face[i].c.normal.Z; verticles[i * 3 + 2].Tu = face[i].c.tu; verticles[i * 3 + 2].Tv = face[i].c.tv; */ vbuf = new VertexBuffer(typeof(CustomVertex.PositionNormalColored), f_count * 3, device, 0, CustomVertex.PositionNormalColored.Format, Pool.Managed); CustomVertex.PositionNormalColored[] verticles = (CustomVertex.PositionNormalColored[])vbuf.Lock(0, 0); for (int i = 0; i < f_count; i++) { verticles[i * 3].X = face[i].a.pos.X; verticles[i * 3].Y = face[i].a.pos.Y; verticles[i * 3].Z = face[i].a.pos.Z; verticles[i * 3].Nx = face[i].a.normal.X; verticles[i * 3].Ny = face[i].a.normal.Y; verticles[i * 3].Nz = face[i].a.normal.Z; verticles[i * 3].Color = Color.Green.ToArgb(); verticles[i * 3 + 1].X = face[i].b.pos.X; verticles[i * 3 + 1].Y = face[i].b.pos.Y; verticles[i * 3 + 1].Z = face[i].b.pos.Z; verticles[i * 3 + 1].Nx = face[i].b.normal.X; verticles[i * 3 + 1].Ny = face[i].b.normal.Y; verticles[i * 3 + 1].Nz = face[i].b.normal.Z; verticles[i * 3 + 1].Color = Color.Green.ToArgb(); verticles[i * 3 + 2].X = face[i].c.pos.X; verticles[i * 3 + 2].Y = face[i].c.pos.Y; verticles[i * 3 + 2].Z = face[i].c.pos.Z; verticles[i * 3 + 2].Nx = face[i].c.normal.X; verticles[i * 3 + 2].Ny = face[i].c.normal.Y; verticles[i * 3 + 2].Nz = face[i].c.normal.Z; verticles[i * 3 + 2].Color = Color.Green.ToArgb(); } vbuf.Unlock(); } public void render(Device device) { device.SetStreamSource(0, vbuf, 0);//skad bedzie rendering device.VertexFormat = CustomVertex.PositionNormalColored.Format;//format wierzcholkow device.DrawPrimitives(PrimitiveType.TriangleList, 0, f_count);//narysowanie trojkata } }; } kod po czesci przepisany z jakiegos tutoriala, po czesci z sdk, po czesci samemu kombinowane :P identyczny topic zalozylem na warsztacie, ale narazie nikt tam nie byl mi w stanie pomoc, moze tu ktos zajrzy. Dodatkowo do tweakowcow mialbym prosbe o przetestowanie czy u was tez sie tak dzieje. ( nie chodzi mi o przenikanie przez obiekty bo nie mam wykrywania kolizji, ale o opisane wyzej symptomy ) Edytowane 13 Października 2005 przez Nargil Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...