Performance beim Vertexarray

Für Fragen zu Grafik APIs wie DirectX und OpenGL sowie Shaderprogrammierung.
Antworten
Tornby
Beiträge: 17
Registriert: 17.09.2010, 15:33

Performance beim Vertexarray

Beitrag von Tornby »

Hallo,

ich bräuchte mal einen Rat... Es geht um ne Optimierungsmaßnahme. Also ich zeichne einen Kreis mit meinem Grafikengine Objekt welches die Zeichenfunktionien bereithält:

Code: Alles auswählen

	int vertexCount = _steps+1;
	int primCount = vertexCount-3;
	cVertex* vertices = new cVertex[vertexCount];
	float fullCircle = cMath<float>::Pi()*2;
	
	float circle = 0;
	for (int i = 0; i < _steps;++i)
	{
		vertices[i].m_x = _x+(sin(circle)*_radius);
		vertices[i].m_y = _y+(cos(circle)*_radius);
		vertices[i].m_z = 0.0f;
		vertices[i].m_color = m_quad.GetColor(cQuad::QV_LEFT_BOTTOM); // Always take the first color, because we have more than 4 corners

		circle += (fullCircle/_steps);
	}

	ApplyTransformation();
	m_d3DDevice->SetTexture(0,NULL);
	m_d3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN,primCount,vertices,sizeof(cVertex));

	delete[] vertices;
Im Code sind die markanten stellen für mich die Allokation des Arrays im Speicher und das spätere freigeben des speichers. Geht man jetzt davon aus dass das jeden Tick geschieht finde ich das recht unperformant und mir ist die Idee gekommen vielleicht ein fixes Array mit der größe 64 oder 128 vom Typ cVector einfach in das Objekt zu legen. Also wie so ein Container der einfach da ist ohne die ständige Allokation. Die Frage ist halt ob mir das nen Performance schub bringt...

Ich frag halt nur weil ich jetzt auch ne Primitive Drawing Methode in die Engine einbaue wo ich jedes Vertex einzeln definieren kann und dafür dann immer neuen Speicher belegen und wieder freigeben und das jeden Tick...

Ratschläge? Meinungen? Tipps? :)


Viele Grüße
Tornby
Tornby
Beiträge: 17
Registriert: 17.09.2010, 15:33

Re: Performance beim Vertexarray

Beitrag von Tornby »

Also die neue Methode ist halt so das ich immer ein cVertex übergebe

//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
void cDXGraphics9::BeginPrimitive(ePrimitiveMode _mode)
{

}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
void cDXGraphics9::DrawPrimitive(cVertex _v)
{

}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
void cDXGraphics9::EndPrimitive()
{

}

Vielleicht definier ich die auch als Inline dann spar ich mir den Call weils ja eh nur ne Array belegung ist. Sicherlich könnte ich als parameter auch ein ganzes Array übergeben, aber ich finde das so GL Style mässig ganz cool außerdem spar ich mir dann das Array handling mit den Vertices an sich.
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Performance beim Vertexarray

Beitrag von Krishty »

Hi Tornby,

DrawPrimitiveUP() ist nur für Rapid Prototyping da und sollte nie in einer Produktivumgebung eingesetzt werden. Was du willst, ist gleichzeitig, womit Direct3D standardmäßig arbeitet und nennt sich Vertex Buffer – du schreibst die Vertices einmal rein, bekommst ein COM-Handle zurück und sagst der GPU vor jedem Rendern mit DrawPrimitive() per SetStreamSource(), aus welchem der nun im VRAM liegenden Puffer sie die Vertices lesen soll.

Der Performance-Schub ist dann noch bedeutend größer, weil nicht nur die Speicherallokation, sondern auch das Schieben der Daten vom RAM in den VRAM und die Synchronisierung der GPU mit der GPU entfällt. Eigentlich ist DrawPrimitiveUP so langsam, dass die Allokationen dein geringstes Problem sind.

Ist normalerweise Kapitel 2 oder 3 jedes Direct3D-Tutorials.

Gruß, Ky
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Tornby
Beiträge: 17
Registriert: 17.09.2010, 15:33

Re: Performance beim Vertexarray

Beitrag von Tornby »

Ja danke, das Ding ist derzeit aber noch eine 2D Orthogonal geschichte, heißt ich zeichne nur Vierecke. also ein Circle ist da recht selten. Ich weiß aber was du meinst. Den Vertexbuffer verwende ich auch schon aber eben nur bei komplexeren Meshes. Bei einzelnen Quads rentiert sich das nicht oder? Vor allem weil das sich dann auch die Textur ändert etc... hmm vielleicht sollte ich das aber auch mal komplett refaktoren. Das Problem ist halt, dass das Zeichnen relativ "anonym" ist. Ich sag halt nur zeichne mir Bild xy (welche Texturen in einer Liste sind) und erstelle ein Quad hau die Texture drauf mit dem jeweiligen Frame Rectangle, also Texturekoordinate (wenn es denn animiert ist)... Haben schon viele gesagt dass man das auch über Vertexbuffer lösen könnte aber ich wüsste jetzt nicht wie...
Aber du hast recht wenn ich jetzt ins richtige 3D gehe mit komplexeren Sachen sollte ich echt auf Vertexbuffer umsteigen :)
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Performance beim Vertexarray

Beitrag von Krishty »

Tornby hat geschrieben:Bei einzelnen Quads rentiert sich das nicht oder?
Doch
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Jörg
Establishment
Beiträge: 296
Registriert: 03.12.2005, 13:06
Wohnort: Trondheim
Kontaktdaten:

Re: Performance beim Vertexarray

Beitrag von Jörg »

Hast Du schonmal ueberlegt, den Kreis im Vertex-Shader zu berechnen? In verschiedenen Aufloesungsvarianten, so wie Du es jetzt ueber den '_steps'-Parameter steuerst?
Da kommst Du mit einem statischen Vertexbuffer aus. Und kannst mit den richtigen Werten sogar Kreise und Rechtecke zeichnen, ohne ihn wechseln zu muessen.

Das mit den Texturen ist dann einen andere Geschichte. Wenn Du wenig Texturen und viel Geometrie hast, dann lohnt es sich, die Geometrie nach den Texturen zu sortieren. Dann setzt Du eine Textur, zeichnest alles, was diese Textur verwendet, und faehrst dann mit der naechsten fort. Usw.
Wenn das Verhaeltnis zwischen Geometrie-Objekten und verwendeten Texturen etwa 1:1 ist, dann kannst Du gerade fuer 2D-Geschichten mit einem Texture-Atlas ziemlich was reissen.
Antworten