 |
JLI Spieleprogrammierung
|
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
|
Verfasst am: 01.05.2004, 13:33 Titel: Direct3D: Würfel mit Index und Vertex Buffer erzeugen |
|
|
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:
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 |
|
 |
Chewie Super JLI'ler
Anmeldedatum: 17.07.2003 Beiträge: 382
Medaillen: Keine
|
Verfasst am: 01.05.2004, 16:42 Titel: |
|
|
die vertizen und indizes müssten eigentlich passen, soweit ich das seh...
probier mal bei CreateIndexBuffer() sizeof(Indices) als 1. param anzugeben. |
|
Nach oben |
|
 |
Jonathan_Klein Living Legend

Alter: 37 Anmeldedatum: 17.02.2003 Beiträge: 3433 Wohnort: Siegerland Medaillen: Keine
|
Verfasst am: 01.05.2004, 17:38 Titel: |
|
|
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 |
|
 |
Jonathan_Klein Living Legend

Alter: 37 Anmeldedatum: 17.02.2003 Beiträge: 3433 Wohnort: Siegerland Medaillen: Keine
|
Verfasst am: 01.05.2004, 17:49 Titel: |
|
|
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 |
|
 |
Chewie Super JLI'ler
Anmeldedatum: 17.07.2003 Beiträge: 382
Medaillen: Keine
|
Verfasst am: 01.05.2004, 18:19 Titel: |
|
|
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 |
|
 |
Jonathan_Klein Living Legend

Alter: 37 Anmeldedatum: 17.02.2003 Beiträge: 3433 Wohnort: Siegerland Medaillen: Keine
|
Verfasst am: 02.05.2004, 10:54 Titel: |
|
|
Code: |
#define D3DFVF_CUBEVERTEX (D3DFVF_XYZ | D3DFVF_DIFFUSE)
struct CubeVertex
{
float x, y, z;
D3DCOLOR Color;
};
|
_________________ https://jonathank.de/games/ |
|
Nach oben |
|
 |
Chewie Super JLI'ler
Anmeldedatum: 17.07.2003 Beiträge: 382
Medaillen: Keine
|
Verfasst am: 02.05.2004, 16:29 Titel: |
|
|
schick mir mal das projekt: mcdonut@gmx.net |
|
Nach oben |
|
 |
Jonathan_Klein Living Legend

Alter: 37 Anmeldedatum: 17.02.2003 Beiträge: 3433 Wohnort: Siegerland Medaillen: Keine
|
Verfasst am: 02.05.2004, 18:54 Titel: |
|
|
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 |
|
 |
Fallen JLI MVP


Alter: 40 Anmeldedatum: 08.03.2003 Beiträge: 2860 Wohnort: Münster Medaillen: 1 (mehr...)
|
Verfasst am: 02.05.2004, 19:02 Titel: |
|
|
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 |
|
 |
Jonathan_Klein Living Legend

Alter: 37 Anmeldedatum: 17.02.2003 Beiträge: 3433 Wohnort: Siegerland Medaillen: Keine
|
Verfasst am: 03.05.2004, 17:07 Titel: |
|
|
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 |
|
 |
Fallen JLI MVP


Alter: 40 Anmeldedatum: 08.03.2003 Beiträge: 2860 Wohnort: Münster Medaillen: 1 (mehr...)
|
Verfasst am: 03.05.2004, 17:43 Titel: |
|
|
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 |
|
 |
Chewie Super JLI'ler
Anmeldedatum: 17.07.2003 Beiträge: 382
Medaillen: Keine
|
Verfasst am: 03.05.2004, 17:47 Titel: |
|
|
IBs bringens bei einem würfel natürlich noch nicht wirklich...außer du hast 10.000 würfel
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 |
|
 |
Jonathan_Klein Living Legend

Alter: 37 Anmeldedatum: 17.02.2003 Beiträge: 3433 Wohnort: Siegerland Medaillen: Keine
|
Verfasst am: 03.05.2004, 18:59 Titel: |
|
|
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 |
|
 |
Chewie Super JLI'ler
Anmeldedatum: 17.07.2003 Beiträge: 382
Medaillen: Keine
|
Verfasst am: 03.05.2004, 19:21 Titel: |
|
|
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 |
|
 |
Hazel JLI MVP


Alter: 40 Anmeldedatum: 19.07.2002 Beiträge: 1761
Medaillen: Keine
|
Verfasst am: 03.05.2004, 19:28 Titel: |
|
|
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 |
|
 |
|
|
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
|