JLI Spieleprogrammierung Foren-Übersicht JLI Spieleprogrammierung

 
 FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen 
 medals.phpMedaillen   RegistrierenRegistrieren   ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin 

Direct3D: Würfel mit Index und Vertex Buffer erzeugen

 
Neues Thema eröffnen   Neue Antwort erstellen    JLI Spieleprogrammierung Foren-Übersicht -> DirectX, OpenGL
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
Jonathan_Klein
Living Legend


Alter: 37
Anmeldedatum: 17.02.2003
Beiträge: 3433
Wohnort: Siegerland
Medaillen: Keine

BeitragVerfasst am: 01.05.2004, 13:33    Titel: Direct3D: Würfel mit Index und Vertex Buffer erzeugen Antworten mit Zitat

Ich hab mich nun endlich mal an die 3D Programmierung gewagt. Nachdem ich mir dei Akpitel druchgelesen habe, hab ich beschlossen, als kleines Testprgramm einen 3Dimensinalen Würfel mit Hilfe von Vertex und Index Buffer zu erzeugen:
Code:

//Cube.cpp

#pragma once

#include "Cube.h"

CCube::CCube()
{
   m_lpD3DDevice=NULL;
   m_lpVB=NULL;
   m_lpIB=NULL;
}

CCube::~CCube()
{
   if(NULL!=m_lpIB)
   {
      m_lpIB->Release();
      m_lpIB=NULL;
   }
   if(NULL!=m_lpVB)
   {
      m_lpVB->Release();
      m_lpVB=NULL;
   }
}

void CCube::Init(LPDIRECT3DDEVICE9 lpD3DDevice)
{
   m_lpD3DDevice=lpD3DDevice;

   CubeVertex Vertex[]= //Das wird mal der Inhalt des Vertex-Buffers
   {
      //Das Quadrat der vorderseite des Würfels
      0.0f, 0.0f, 0.0f, 0xffffffff, // 0
      1.0f, 0.0f, 0.0f, 0xffffffff, // 1
      0.0f, -1.0f, 0.0f, 0xffffffff,// 2
      1.0f, -1.0f, 0.0f, 0xffffffff,// 3

      //Das Quadrat der Rückseite des Würfels
      0.0f, 0.0f, 1.0f, 0xffffffff, // 4
      1.0f, 0.0f, 1.0f, 0xffffffff, // 5
      0.0f, -1.0f, 1.0f, 0xffffffff,// 6
      1.0f, -1.0f, 1.0f, 0xffffffff,// 7
   };

   short Indices[]= //Das wird mal der Inhalt des Index-Buffers
   {
      0, 1, 2,//Die Vorderseite
      1, 3, 2,

      4, 0, 6,//die linke Seite
      0, 2, 6,
   };

   //Vertex Buffer erstellen und füllen
   m_lpD3DDevice->CreateVertexBuffer(sizeof(Vertex), D3DUSAGE_WRITEONLY, D3DFVF_CUBEVERTEX, D3DPOOL_DEFAULT, &m_lpVB, NULL);
   void* pVertices=NULL;

   m_lpVB->Lock(0, 0, &pVertices, 0);//VertexBuffer locken und den Inhalt in ihn kopieren
   memcpy(pVertices, Vertex, sizeof(Vertex));
   m_lpVB->Unlock();


   //IndexBuffer erstellen und füllen
   m_lpD3DDevice->CreateIndexBuffer(4*3*2, 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &m_lpIB, NULL);//*0 für D3DFMT_INDEX16, *3 weil jedes Dreieck 3 Vertices hat
   void* pIndices=NULL;

   m_lpIB->Lock(0, 0, &pIndices, 0);
   memcpy(pIndices, Indices, sizeof(Indices));
   m_lpIB->Unlock();


   //Jetzt muss noch die Kamera positioniert werden, und einiges anderes geklärt werden

   //Kameraposition und richtung setzten
   D3DXMatrixLookAtLH(&m_ViewMatrix, &D3DXVECTOR3(0.0f, 0.0f, -10.0f), &D3DXVECTOR3(0.0f, 0.0f, 0.0f), &D3DXVECTOR3(0.0f, 1.0f, 0.0f));
   m_lpD3DDevice->SetTransform(D3DTS_VIEW, &m_ViewMatrix);

   //Sichtfeld setzen
   D3DXMatrixPerspectiveFovLH(&m_ProjMatrix, D3DX_PI/4, (float)SCR_WIDTH/(float)SCR_HEIGHT, 1.0f, 100.0f);
   m_lpD3DDevice->SetTransform(D3DTS_PROJECTION, &m_ProjMatrix);

   //Lichtberechnung ausschalten
   m_lpD3DDevice->SetRenderState(D3DRS_LIGHTING, false);
}

void CCube::Render()
{
   //Das VertexFormat festlegen
   m_lpD3DDevice->SetFVF(D3DFVF_CUBEVERTEX);
   
   //VertexBuffer angeben:
   m_lpD3DDevice->SetStreamSource(0, m_lpVB, 0, sizeof(D3DFVF_CUBEVERTEX));

   
   //IndexBuffer angeben:
   m_lpD3DDevice->SetIndices(m_lpIB);

   m_lpD3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 8, 0, 4);

}


Soweit ich es verstanden habe definiert man also erst ie Vertices aus denen der Würfel besteht. Im Indexbuffer bastelt man dann aus immer 3 Vertices ein Dreieck zusammen. Wie man sieht hab ich erstmal nur 2 Seiten des Würfels gemacht, links und vorne.
Wenn ich das Programm jetzt starte, sihet man aber nur ein Trapez am Bildschirm:
Code:

\   \
  \   \
    \   \
      \__\

Es ist weiß (oh wunder, sollte es ja auch) und geht von der Mitte des Bildschirmes bis zum oberen Rand. Ich schätze, das da irgendwie die Werte durcheinander gekommen sind, hab aber keine Ahnung, wo mein Fehler liegt.
Als ich im Desturkto noch nicht getestet hab, ob die Zeiger gleich NULL sind, erzeugte das Programm beim Beenden immer eine Fehlermeldung. Das müsste ja theoretisch bedeuten, das der entsprechende Buffer nicht erzeugt werden konnte.
_________________
https://jonathank.de/games/
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
Chewie
Super JLI'ler



Anmeldedatum: 17.07.2003
Beiträge: 382

Medaillen: Keine

BeitragVerfasst am: 01.05.2004, 16:42    Titel: Antworten mit Zitat

die vertizen und indizes müssten eigentlich passen, soweit ich das seh...
probier mal bei CreateIndexBuffer() sizeof(Indices) als 1. param anzugeben.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Jonathan_Klein
Living Legend


Alter: 37
Anmeldedatum: 17.02.2003
Beiträge: 3433
Wohnort: Siegerland
Medaillen: Keine

BeitragVerfasst am: 01.05.2004, 17:38    Titel: Antworten mit Zitat

Hab ich probiert, aber es ändert sich nix.
Aber laut Buch müsste 4*3*2 ja auch richtig sein, weil es ja 12 (4*3) Punkte sind und ich den Indexbuffer mit D3DFMT_INDEX16 benutze.

Ich hab auch mal testweise alle Dreiecke anzeigen lassen (mit SetRendeState(D3D_CULLMODE, D3DCULL_NON)), und in den WIREFRAME Modus geschaltet. Dann sieht man die umrisse des Trapez, mehr aber auch nicht.
_________________
https://jonathank.de/games/
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
Jonathan_Klein
Living Legend


Alter: 37
Anmeldedatum: 17.02.2003
Beiträge: 3433
Wohnort: Siegerland
Medaillen: Keine

BeitragVerfasst am: 01.05.2004, 17:49    Titel: Antworten mit Zitat

Seltsam: Wenn ich an den Farbwerten rumspiel, ändern sich manchmal die Liniendie angezeigt werden.
Code:

\
 \
  \
    \___
     |    |
     |    |
     |    |
     |    |
     |    |

Ich denke mal, das es deshalb irgendwie am Format liegen muss. den die Farbe sol ja die Farbe der Linien/Fläche verändern und nicht deren Position/existenz. Also denke ich mal das es einen Feheler beim füllen des Buffers gibt.
_________________
https://jonathank.de/games/
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
Chewie
Super JLI'ler



Anmeldedatum: 17.07.2003
Beiträge: 382

Medaillen: Keine

BeitragVerfasst am: 01.05.2004, 18:19    Titel: Antworten mit Zitat

stimmt schon, dass es mit 4*3*2 eigentlich auch funzen sollte..ich dachte nen versuch wärs wert. wenn du schon dabei bist, kannst du das auch mal probieren:
CreateVB(8 * sizeof(CubeVertex), ..);
CreateIB(12 * sizeof(WORD), ...);
und bei memcpy dasselbe. so mach ich es immer.

zeig mal dein FVF, vielleicht hast du zuwenig daten per vertex im VB, das könnte erklären warum sich die form bei veränderung der farbangaben ändert.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Jonathan_Klein
Living Legend


Alter: 37
Anmeldedatum: 17.02.2003
Beiträge: 3433
Wohnort: Siegerland
Medaillen: Keine

BeitragVerfasst am: 02.05.2004, 10:54    Titel: Antworten mit Zitat

Code:

#define D3DFVF_CUBEVERTEX (D3DFVF_XYZ | D3DFVF_DIFFUSE)

struct CubeVertex
{
   float x, y, z;
   D3DCOLOR Color;
};

_________________
https://jonathank.de/games/
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
Chewie
Super JLI'ler



Anmeldedatum: 17.07.2003
Beiträge: 382

Medaillen: Keine

BeitragVerfasst am: 02.05.2004, 16:29    Titel: Antworten mit Zitat

schick mir mal das projekt: mcdonut@gmx.net
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Jonathan_Klein
Living Legend


Alter: 37
Anmeldedatum: 17.02.2003
Beiträge: 3433
Wohnort: Siegerland
Medaillen: Keine

BeitragVerfasst am: 02.05.2004, 18:54    Titel: Antworten mit Zitat

Ich hab ein bischen Rumexperimentiert und einige 3D Objekte ohne Index Buffer erzeugt. Funktioniert auch ganz toll, hab einen einfachen Baum gemacht (Zylinder mit Kegel). Er besteht aus insgesamt 32 Dreiecken. Im Moment läuft ja noch alle flüssig, ab welcher Menge sollte man aber einen Indexbuffer benutzen?
Ich meine, bracuh ich den eigentlich? Oder spielt das erst ab 10.000 Dreiecken (wie bei der Landschaft) einen entscheidente Rolle?
_________________
https://jonathank.de/games/
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
Fallen
JLI MVP
JLI MVP


Alter: 40
Anmeldedatum: 08.03.2003
Beiträge: 2860
Wohnort: Münster
Medaillen: 1 (mehr...)

BeitragVerfasst am: 02.05.2004, 19:02    Titel: Antworten mit Zitat

Son Indexbuffer nutze ich für alle Objekte, und es macht auch Sinn bei Objekten mit wenigen Polygonen. Ausserdem machen sich Indexbuffer gut wenn man Verdeckte Flächen entfernen möchte,...
_________________
"I have a Core2Quad at 3.2GHz, 4GB of RAM at 1066 and an Nvidia 8800 GTS 512 on Vista64 and this game runs like ass whereas everything else I own runs like melted butter over a smokin' hot 18 year old catholic schoolgirl's arse."
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
Jonathan_Klein
Living Legend


Alter: 37
Anmeldedatum: 17.02.2003
Beiträge: 3433
Wohnort: Siegerland
Medaillen: Keine

BeitragVerfasst am: 03.05.2004, 17:07    Titel: Antworten mit Zitat

OK das mit den verdeckten Flächen versteht ich nicht. Keine Ahnung was du damit meinst. Aber ich hab auch noch ne andere Frage:
Wenn man Licht benutzen will, muss man ja Normalvektoren für jedes Vertex angeben. Bei dem Würfel war das dann immer die Richtung, in die die Oberfläche die aus den Vertices besthet zeigt. Also haben alle 3 Vertices der Oberfläche den selben Normalvektor.
Aber wenn ich jetzt 2 seiten die aneinanderliegen habe also ein Kante wie beim Würfel, muss es doch zu einen Konflik zwischen den Normalvektoren kommen, jedenfalls wenn ich den Indexbuffer benutze. Was muss ich den dann für Normalvektoren angeben?Wäre es nicht theoretisch viel sinvoller, wenn die normalvekotren auch im Indexbuffer stehen würden? Denn mit dem Indexbufer baut man ja quasi aus Vertices Dreiecke zusammen. Und dann müsste man pro Dreieck nur einmal und nicht 3 mal den Normalvektor berechnen.
Und den Normalvektor muss man ja auch anhand der 3 Eckpunkte des Dreieckes berechnen können. Den er ist doch im Prinzip nichts anderes als eine Senkrechte zur Ebene des Dreiecks. Warum muss man ihn dann noch angeben und kann ihn nicht von DirectX berechnen lassen?

Das da oben ist jetzt die Theorie, soweit ich sie verstanden hab. Wenn ich mich irgendwo irren sollte, dann sagt es mir bitte.
_________________
https://jonathank.de/games/
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
Fallen
JLI MVP
JLI MVP


Alter: 40
Anmeldedatum: 08.03.2003
Beiträge: 2860
Wohnort: Münster
Medaillen: 1 (mehr...)

BeitragVerfasst am: 03.05.2004, 17:43    Titel: Antworten mit Zitat

Weil man im Grunde einen Vektor rausbekommen könnte der nach innen zeigt und so würde man die Flächen nicht mehr sehen die nach aussen zeigen, so werden übrigens Skyboxen dargestellt.
_________________
"I have a Core2Quad at 3.2GHz, 4GB of RAM at 1066 and an Nvidia 8800 GTS 512 on Vista64 and this game runs like ass whereas everything else I own runs like melted butter over a smokin' hot 18 year old catholic schoolgirl's arse."
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
Chewie
Super JLI'ler



Anmeldedatum: 17.07.2003
Beiträge: 382

Medaillen: Keine

BeitragVerfasst am: 03.05.2004, 17:47    Titel: Antworten mit Zitat

IBs bringens bei einem würfel natürlich noch nicht wirklich...außer du hast 10.000 würfel Wink
nur wirst du bald draufkommen, dass es nicht so lustig ist, sich für nen character die vertizen auszudenken und manuell zu notieren, und wenn du dann z.B. ein xfile aus einem 3d-prog exportierst, hast du fast immer gleich indizierte daten.

du mußt bei modellen zwischen harten und weichen kanten unterscheiden.
ein würfel mit harten kanten hätte 24 vertizen, wie du richtig gesagt hast, einer mit weichen wieder nur 8. die normalvektoren würden dann schräg von den ecken wegstehen, wenn dus dir irgendwie vorstellen kannst. ein würfel mit weichen kanten schaut natürlich kacke aus, man macht das z.B. bei rohren, damit sie schön rund aussehen.

drum kann man es auch nicht gscheit berechnen, außer du hast ein modell mit nur weichen/nur harten kanten. allerdings wird bei weichen kanten die berechnung wieder komplizierter, weil du ja einen mittelwert zw. den flächen haben willst, etc. abgesehen davon, dass man ja jedesmal den VB locken müßte und man lieber mehr speicher als performance hergibt, denke ich...
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Jonathan_Klein
Living Legend


Alter: 37
Anmeldedatum: 17.02.2003
Beiträge: 3433
Wohnort: Siegerland
Medaillen: Keine

BeitragVerfasst am: 03.05.2004, 18:59    Titel: Antworten mit Zitat

Also verstehe ich das jetzt richtig: Wenn man bei einer Fläche an den Vertexen verschiedene Normalvektoren angibt, beleuchtet DirectX das, wie wenn es gekrümpte Flächen wären. Also kann man damit dann recht hübsch Kugel oder Figuren beleuchten. Aber bei ungekrümten Flächen, sind alle Normalvektoren gleich.
Wenn man die Normalvektoren bei einer geraden Flcähe berechnet, dürfte das mit den Vektoren die nahc innen zeigen doch eigentlic kein Problem sein. Die Vertices werden doch extra im Uhrzeigersinn angegeben. Deshalb müsste es doch eine DirectX Funktion geben, mit deren Hilfe man den Normalvektor eines Dreiecks berechnen kann.
Ich denke mal, das ich dann für einfache Objekte den IndexBuffer nicht verwende. Wenn man ja doch wie bei dem Würfel für die verschiedenen Normalvektoren verschiedene Vertexe angeben muss, ist der Vorteil ja schon wieder nicht mehr so hoch.
Und für komplexe Modelle kann man dann ja X-Files benutzen.
_________________
https://jonathank.de/games/
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
Chewie
Super JLI'ler



Anmeldedatum: 17.07.2003
Beiträge: 382

Medaillen: Keine

BeitragVerfasst am: 03.05.2004, 19:21    Titel: Antworten mit Zitat

das mit der krümmung verstehst du richtig...es findet dann keine lichtbrechung an der kante statt.

den normalvektor eines polys kannst du z.B. so ausrechen:
D3DXPlaneFromPoints(plane, v1, v2, v3);
vNorm = VECTOR(plane.a, plane.b, plane.c);

oder auch irgendwie mim kreuzprodukt, je nach belieben.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Hazel
JLI MVP
JLI MVP


Alter: 40
Anmeldedatum: 19.07.2002
Beiträge: 1761

Medaillen: Keine

BeitragVerfasst am: 03.05.2004, 19:28    Titel: Antworten mit Zitat

Mit dem Kreuzprodukt geht das auch.

Man hat 3 Punkte eines Dreiecks: A, B und C. Dann berechnet sich der Normalenvektor wie folgt:

n = (b - a) X (c - a)

b-a und c-a sind die beiden Richtungsvektoren der Ebene die durch das Dreieck definiert wird und ihr Kreuzprodukt ist ein Vektor, der orthogonal auf ihnen steht, also ein Normalenvektor.
_________________
*click* Dabuu!?
Twitter: http://twitter.com/Ollie_R
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    JLI Spieleprogrammierung Foren-Übersicht -> DirectX, OpenGL Alle Zeiten sind GMT
Seite 1 von 1

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.


Powered by phpBB © 2001, 2005 phpBB Group
Deutsche Übersetzung von phpBB.de

Impressum