[Directx] Eigenes 3D Format
-
Sry doppelpost is keine absicht
-
Kann ich denn Sachen zu aus einem Buffer wieder in ein Array zurück wandeln? Bzw kann ich die einzelenen sachen aus dem Buffer verändern? z.b. für Bewegung?
-
Du kannst den Buffer locken und mit neuen Daten ueberschreiben oder die dafuer notwendigen Berechnungen im Vertex-Shader ausfuehren.
Aus einem Vertexbuffer zu lesen kann um ein Vielfaches langsamer sein.
-
Naja es geht grad nur um den Editor den ich mir zurechtschreibe um das ganze ein Wenig zu testen.
Ich wöde den Buffer dann immer wenn was hinzugefügt wird größer machen wollen und müsste dazu die alten Daten erstmal in den Neuen kopiern geht sowas? (Performant muss das an der stelle nicht sein).Bei Bewegungen wödest du dann den ganzen Buffer neu schreiben oder kann man nur bestimmte stellen des Buffers überschreiben?
mfg nils
-
bei einem editor waere es nicht schlimm wenn du die daten auch local im speicher haettest, du kommst frueher oder spaeter auf die idee damit noch was anderes anzustellen (z.b. picking) und dann musst du oefter drauf zugreifen, was nicht smart waere bei nem vertexbuffer von d3d
zudem, wenn es nur ein 'editor' ist, kannst du dir eventuell immer noch ein wenig 'puffer' hintern dran allokieren, sodass, falls noch ein paar mehr vertices dazu kommen, du keinen neuen buffer allokieren musst. ab und zu musst du das dann vielleicht wieder, aber das sollte bei einem editor absolut kein performance problem darstellen. (niemand wird sich beschweren wenn es einen ruckler geben sollte
)
-
rapso schrieb:
(niemand wird sich beschweren wenn es einen ruckler geben sollte
)
Stimm da das wie gesagt alles dem Spaß dient werde wahrscheinlich nur ich das ganze einsetzen und das auch nur zum testen
Ich finde grade keine Funktion um die Vertex und Index Buffer wieder zu "löschen", gibt es da keine Funktion? Und ich erstell den neuen einfach "Über" dem alten?
mfg nils
-
->Release(), wie bei allen resourcen.
und nein, du erstellst keinen drueber, danaben oder daruntern, du hast nur CreateVertexbuffer und der treiber sucht sich aus ws er damit macht.
-
Jau danke dann werd ich da heut Abend mal weiter dran rumspielen muss ja jetzt doch nen bisschen was umnstellen. Melde mich wieder wenns noch Probleme/Fragen gibt.
Erstmal ein riesen danke an die wunderbare hilfe die ihr mir gegeben habt.
mfg nils
-
Es hat sich da jetzt doch gleich eine neue Frage aufgedrängt. Und zwar immoment haben meine Gegenstände ja alle nur Farben wie mach ich das denn dann das die verschiedene Texturen haben können?
Bekommt die Vertex Struktur dann anstatt D3DCOLOR_XRGB ein enstprechendes Textur Objekt?
Und es ist dann auch richtig das ich den Buffer jedesmal neu erstellen muss wenn sich ein Objekt bewegt oder?
mfg nils
-
Bekommt die Vertex Struktur dann ein Textur Objekt?
Das wuerde keinen Sinn machen weil ja sonst fuer die jeweiligen Eckpunkte eines Polygons unterschiedliche Texturen definiert sein koennten.
Stattdessen weisst man jedem Polygon eine Material-ID (das Material beinhaltet neben anderen Parametern auch die Textur(en)).
Um nicht jedes Polygon einzelnd zeichnen und staendig Renderstates aendern zu muessen kannst Du fuer das Mesh zb eine Liste von verwendeten Materialien halten und fuer jedes Material eine Liste von Polygonen (oder dessen Indices) die es verwenden.
-
Hmm aber wie funktioniert das Rendern denn dann?
Mal angenommen ich möchte für meinen Test Editor erstmal nur die ansicht mit Farben und dann irgendwann eine mit Texturen dann soll man da aber trozdem noch umschalten können.Ist sowas möglich wie teile ich Direct x dann mit wie er rendern soll?
mfg nils
-
Definiere bitte etwas genauer was "die ansicht mit Farben" und "eine mit Texturen" darstellen sollen und in wie fern sich diese unterscheiden.
Daraus muesste sich auch schon ergeben was Du unternehmen musst um zwischen beiden umzuschalten.
Allgemein koenntest Du zb ein "internes" Material definieren, dass im Falle einer gewaehlten Darstellungsoption das Rendering uebernimmt.
Du solltest Dir auch mal die Beispiele vom DirectX-SDK angucken.
-
hellihjb schrieb:
Definiere bitte etwas genauer was "die ansicht mit Farben" und "eine mit Texturen" darstellen sollen und in wie fern sich diese unterscheiden.
Daraus muesste sich auch schon ergeben was Du unternehmen musst um zwischen beiden umzuschalten.
Allgemein koenntest Du zb ein "internes" Material definieren, dass im Falle einer gewaehlten Darstellungsoption das Rendering uebernimmt.
Du solltest Dir auch mal die Beispiele vom DirectX-SDK angucken.Lassen wir das mal vorerst. Habe jetzt mal nen großen Teil neugeschrieben.
Die Mesh klasse ist rausgeflogen.
Die Objects Klasse:Objects::Objects() : ClassVertexBuffer(&MapObjects), ClassIndexBuffer(&MapObjects) { AddTriangle(120.0, 400.0, 200.0, 350.0); //AddQuad(120.0, 400.0, 200.0, 350.0); } void Objects::AddTriangle(float x, float y, float Width, float Height) { list<Vertex> Vertices; Vertices.push_back(Vertex(x, y, 0.5f, 1.0f, D3DCOLOR_XRGB(0, 0, 255))); Vertices.push_back(Vertex(x + Width, y + Height, 0.5f, 1.0f, D3DCOLOR_XRGB(0, 255, 0))); Vertices.push_back(Vertex(x - Width, y + Height, 0.5f, 1.0f, D3DCOLOR_XRGB(255, 0, 0))); list<WORD> Indices; Indices.push_back(ClassIndexBuffer.GetNumIndices() + 0); Indices.push_back(ClassIndexBuffer.GetNumIndices() + 1); Indices.push_back(ClassIndexBuffer.GetNumIndices() + 2); MapObjects.push_back(Object(Vertices, sizeof(Vertices), Indices, 3, 3, 1)); ClassVertexBuffer.GenerateNew(); ClassIndexBuffer.GenerateNew(); } void Objects::Render3D(const RenderType RenderType) { MyDirectx->Device->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE); cout<<"Get Buffer Pointer: "<<ClassVertexBuffer.GetBuffer()<<endl; if(FAILED(MyDirectx->Device->SetStreamSource(0, ClassVertexBuffer.GetBuffer(), 0, sizeof(Vertex)))) { cout<<"Error"<<endl; } if(FAILED(MyDirectx->Device->SetIndices(ClassIndexBuffer.GetBuffer()))) { cout<<"Error"<<endl; } if(FAILED(MyDirectx->Device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, ClassVertexBuffer.GetNumVertices(), 0, ClassVertexBuffer.GetNumTriangles()))) { cout<<"Error"<<endl; } cout<<ClassVertexBuffer.GetNumVertices()<<" "<<ClassVertexBuffer.GetNumTriangles()<<endl; MyDirectx->DrawText("Finished Rendering", 20, 420); }
Die Object Klasse Merkt sich dann alles für ein Object (Nur Der header):
class Object { private: unsigned int VerticesSize, NumVertices, NumIndices, NumTriangles; std::list<Vertex> Vertices; std::list<WORD> Indices; protected: public: /* Methods */ Object(std::list<Vertex> Vertices, unsigned int VerticesSize, std::list<WORD> Indices, unsigned int NumIndices, unsigned int NumVertices, unsigned int NumTriangles); unsigned int GetVerticesSize(); unsigned int GetNumVertices(); unsigned int GetNumIndices(); unsigned int GetNumTriangles(); std::list<Vertex> GetVertices(); std::list<WORD> GetIndices(); };
So dann hab ich eine Klasse IndexBuffer:
IndexBuffer::IndexBuffer(std::list<Object> *ObjectList) { Init = false; this->ObjectList = ObjectList; GenerateNew(); Init = true; } unsigned int IndexBuffer::GetNumIndices() { unsigned int NumIndices = 0; for(list<Object>::iterator it = ObjectList->begin(); it != ObjectList->end(); it++) { NumIndices += it->GetNumIndices(); } return NumIndices; } void IndexBuffer::GenerateNew() { Clear(); unsigned int NumIndices = GetNumIndices(); MyDirectx->Device->CreateIndexBuffer(NumIndices * sizeof(WORD), D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_MANAGED, &Buffer, NULL); WORD *Indices = NULL; if(NumIndices > 0) { Buffer->Lock( 0, 0, (void**)&Indices, 0 ); unsigned int i = 0; for(list<Object>::iterator it = ObjectList->begin(); it != ObjectList->end(); it++) { list<WORD> IndicesList = it->GetIndices(); for(list<WORD>::iterator it = IndicesList.begin(); it != IndicesList.end(); it++) { Indices[i] = (*it); i++; } } Buffer->Unlock(); cout<<"List Größe: "<<NumIndices<<endl; for(unsigned int i = 0; i < 3; i++) { cout<<"Indices "<<i<<" : "<<Indices[i]<<endl; } }else{ cout<<"No Indices"<<endl; } } void IndexBuffer::Clear() { if(Init) { //Buffer->Release(); <--- Da segfault es wohl iwie deswegen auskommentiert } }
Und noch eine für Vertexe:
VertexBuffer::VertexBuffer(std::list<Object> *ObjectList) { Init = false; this->ObjectList = ObjectList; GenerateNew(); Init = true; } unsigned int VertexBuffer::GetNumTriangles() { unsigned int NumTriangles = 0; for(list<Object>::iterator it = ObjectList->begin(); it != ObjectList->end(); it++) { NumTriangles += it->GetNumTriangles(); } return NumTriangles; } unsigned int VertexBuffer::GetNumVertices() { unsigned int NumVertices = 0; for(list<Object>::iterator it = ObjectList->begin(); it != ObjectList->end(); it++) { NumVertices += it->GetNumVertices(); } return NumVertices; } unsigned int VertexBuffer::GetVerticesSize() { unsigned int VerticesSize = 0; if(!ObjectList->empty()) { for(list<Object>::iterator it = ObjectList->begin(); it != ObjectList->end(); it++) { VerticesSize += it->GetVerticesSize(); } } return VerticesSize; } void VertexBuffer::GenerateNew() { Clear(); unsigned int VerticesSize = GetVerticesSize(), NumVertices = GetNumVertices(); Vertex *Vertices = new Vertex[NumVertices]; unsigned int i = 0; for(list<Object>::iterator it = ObjectList->begin(); it != ObjectList->end(); it++) { list<Vertex> VerticesList = it->GetVertices(); for(list<Vertex>::iterator it = VerticesList.begin(); it != VerticesList.end(); it++) { Vertices[i] = (*it); i++; } } MyDirectx->Device->CreateVertexBuffer(VerticesSize * sizeof(Vertex), 0, D3DFVF_XYZRHW | D3DFVF_DIFFUSE, D3DPOOL_MANAGED, &Buffer, NULL); if(NumVertices > 0) { void *pVoid; Buffer->Lock(0, 0, (void**)&pVoid, 0); memcpy(pVoid, Vertices, VerticesSize); Buffer->Unlock(); cout<<"List Size: "<<VerticesSize<<endl; for(unsigned int i = 0; i < 3; i++) { cout<<"Vertexe "<<i<<" : x: "<<Vertices[i].x<<" y: "<<Vertices[i].y<<endl; } } delete [] Vertices; cout<<"Buffer pointer: "<<Buffer<<endl; } void VertexBuffer::Clear() { if(Init) { //Buffer->Release(); <-- Ebenfalls Segfault } }
Achja und Vertex:
class Vertex { public: int a; float x, y, z, rwh; DWORD Color; inline Vertex(float x, float y, float z, float rwh, DWORD Color) { this->x = x; this->y = y; this->z = z; this->rwh = rwh; this->Color = Color; } inline Vertex() { this->x = 0; this->y = 0; this->z = 0; this->rwh = 0; this->Color = 0; } };
Leider wird mir so Rein garnichts angezeigt (also kein Dreieck das Finished Rendering schon) es wird nirgends error Ausgegben und die Debug ausgeben (sie screenshot) sehen auch gut aus.
Und wieso segfaulten die Release() ?http://www.imgwelt.de/show.php?code=AI2147L9Y2W
mfg nils
-
Was soll das "int a" in "Vertex" ?
-
Ok danke das ist von einem Test über geblieben behebt aber leider nicht das Problem.
-
Jetzt wirds ganz komisch wenn ich noch folgendes mache:
Und ein Quad genau über dem Dreieck erstelle sehe ich das Dreieck?!
Objects::Objects() : ClassVertexBuffer(&MapObjects), ClassIndexBuffer(&MapObjects) { AddTriangle(120.0, 400.0, 200.0, 350.0); AddQuad(120.0, 400.0, 200.0, 350.0); }
void Objects::AddQuad(float x, float y, float Width, float Height) { list<Vertex> Vertices; Vertices.push_back(Vertex(x, y, 0.5f, 1.0f, D3DCOLOR_XRGB(0, 0, 255))); Vertices.push_back(Vertex(x + Width, y, 0.5f, 1.0f, D3DCOLOR_XRGB(0, 0, 255))); Vertices.push_back(Vertex(x, y + Height, 0.5f, 1.0f, D3DCOLOR_XRGB(0, 0, 255))); Vertices.push_back(Vertex(x + Width, y + Height, 0.5f, 1.0f, D3DCOLOR_XRGB(0, 0, 255))); list<WORD> Indices; Indices.push_back(ClassIndexBuffer.GetNumIndices() + 0); Indices.push_back(ClassIndexBuffer.GetNumIndices() + 3); Indices.push_back(ClassIndexBuffer.GetNumIndices() + 2); Indices.push_back(ClassIndexBuffer.GetNumIndices() + 0); Indices.push_back(ClassIndexBuffer.GetNumIndices() + 1); Indices.push_back(ClassIndexBuffer.GetNumIndices() + 3); MapObjects.push_back(Object(Vertices, sizeof(Vertices), Indices, 6, 4, 2)); ClassVertexBuffer.GenerateNew(); ClassIndexBuffer.GenerateNew(); }
Irgend was ist da noch nicht so richtig...
-
Ok es klappt wenn ich irgend wo noch etwas hinzeichne. Ihm scheint der Letzte Vertex zu fehlen (konnte ich über die farbe ermitteln)
Aber wieso?
mfg nils
-
Ok hab alle Probleme gelöst
troztdem danke