Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

TrommlBomml

Community-Fossil

  • »TrommlBomml« ist der Autor dieses Themas

Beiträge: 2 117

Wohnort: Berlin

Beruf: Software-Entwickler

  • Private Nachricht senden

1

30.01.2008, 16:54

DrawPrimitiveUp vs Dynamische VertexBuffer

Mich würde mal folgendes interessiern: was ist schneller? DrawPrimitiveUp oder per dynamische VB und dann DrawPrimitive (dieselben Primitives sollen natürlich gezeichnet werden).

da das ganze denke ich auch noch abhängig ist von der situation, will ich gleich mal den beuzg erklärn: ich will eine Schriftklasse entwickeln für meine 2D-Engine. Und da würde ich gern ein Bitmapfont nutzen (als textur laden) und die einzelnen Buchstaben die angezeigt werden sollen auf Quads packen mit entsprechenden texturkoordinaten.

und nu überlege ich, ob das mit dynamischen vertexbuffern sinnvoller ist oda mit DrawPrimitiveUp.

dynmaische vertexbuffer sind ja allgemein langsamer als die statischen, und man muss sie dauernd sperren /freigen und wenn man das einfach per ...Up macht, dannn spart man sich das ganze. wobei aber die renderingprozesse denke ich mehr für die vertexbuffer optimiert sind. und ich weiss nicht wie ich das gewichten soll. was meint ihr?

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

2

30.01.2008, 16:57

Carmack meinte mal zu mir, auf so ziemlich genau diese Frage, er würde Vertexpuffer empfehlen!
@D13_Dreinig

drakon

Supermoderator

Beiträge: 6 513

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

3

30.01.2008, 17:28

Ich habe es auch mit einem dynamischen VB gemacht. Geht ganz fix.

Allerdings solltest du dann aber undebingt Batching einsetzen.. sonst wirds auch so nichts.. ;-)

TrommlBomml

Community-Fossil

  • »TrommlBomml« ist der Autor dieses Themas

Beiträge: 2 117

Wohnort: Berlin

Beruf: Software-Entwickler

  • Private Nachricht senden

4

30.01.2008, 18:39

Zitat von »"David_pb"«

Carmack meinte mal zu mir, auf so ziemlich genau diese Frage, er würde Vertexpuffer empfehlen!


wie jetz zu dir?! haste den ma getroffen oda so?

Zitat von »"drakon"«

Allerdings solltest du dann aber undebingt Batching einsetzen.. sonst wirds auch so nichts.. ;)


hm jo das hatte ich sowieso vor, egal ob DrawPrimitiveUp oder VB, trotzdem danke nochma für den hinweis :)

muss ich mich nochma mit dynamsichen vertexbuffern auseinandersetzen, das geht ja ein bisschen anders als mit statischen, und ich hab die dynamsichen nie verwendet, ma schauen.

drakon

Supermoderator

Beiträge: 6 513

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

5

30.01.2008, 18:51

Hehe, Ok. War mir nicht sicher. ;-)

Hmm, soo anderst sind die nicht.

Ein anderes Flag und das wars. :D

TrommlBomml

Community-Fossil

  • »TrommlBomml« ist der Autor dieses Themas

Beiträge: 2 117

Wohnort: Berlin

Beruf: Software-Entwickler

  • Private Nachricht senden

6

30.01.2008, 19:38

jo ich hab mal nen bissle recherchiert in der zwischenzeit.

muss man aber dennoch den belegten speicher beachten gell? wenn man für 20 vertices reserviert, darf man den nicht überschreiten, soweit geht der spass mit den dynamischen nicht. nur ist jetzt der zugriff flexibler, dass neuer speicher belegt wird, wenn man den buffer sperrt, damit das alte unabhängig gerendert werden kann.

drakon

Supermoderator

Beiträge: 6 513

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

7

30.01.2008, 19:46

Zitat von »"TrommlBomml"«


muss man aber dennoch den belegten speicher beachten gell? wenn man für 20 vertices reserviert, darf man den nicht überschreiten, soweit geht der spass mit den dynamischen nicht.


Was meinst du jetzt damit? - Ich dachte du willst ja einen dynamischen VB
erzeugen.

TrommlBomml

Community-Fossil

  • »TrommlBomml« ist der Autor dieses Themas

Beiträge: 2 117

Wohnort: Berlin

Beruf: Software-Entwickler

  • Private Nachricht senden

8

30.01.2008, 19:59

na am besten beispiel, drück mich vllt doof aus wie oftmals:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
struct SVertex
{
    D3DXVECTOR4 vPosRHW;
    DWORD iColor;
    D3DXVECTOR2 vTexCoord;
};

const DWORD FVF_CUSTOMVERTEX = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1;

m_lpDevice->CreateVertexBuffer(sizoef(SVertex)*20,D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY,FVF_CUSTOMVERTEX,D3DPOOL_DEFAULT,&m_lpVertexBuffer,NULL);


dieser dynamische Vertexbuffer ist für 20 vertices reserviert. d. h., wenn dieser voll ist muss ich den erst rendern und danach neu füllen. meinte jetzt, dass es nicht geht z. b. jetz 30 elemte auf einmal zu speichern in dem buffer, dass soweit dynamische vertexbuffer nicht zu verstehen sind.

das mit dem extra speicher usw. macht direct3d ja intern (laut directx-doku)

drakon

Supermoderator

Beiträge: 6 513

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

9

30.01.2008, 20:10

Ja, das ist so.

Aber du kannst ja genügend Speicher reservieren. Zum Beispiel für 1000 Vertices und dann zählen, wie viel wirklich drin sind und das dann beim rendern angeben. Falls das dein Verständnissproblem war.

TrommlBomml

Community-Fossil

  • »TrommlBomml« ist der Autor dieses Themas

Beiträge: 2 117

Wohnort: Berlin

Beruf: Software-Entwickler

  • Private Nachricht senden

10

01.02.2008, 12:47

jo genau mehr nich^^. hab das ganze mal implementiert. so richtig klappen will es aber trotzdem nicht! erzeigt immer blos die häfte der schriftzeichen an. ich poste den ganzen code, es wird alles richtig berechnet (auch die texturkoordinaten). auch ist genügend speicher für den veretxbuffer reserviert. es werden auch eigl alle vertexdaten richtig eingetragen, hab das mal durchgespielt. trotzdem nur die häfte angezeigt. wär nett wenn du ma guggn magst. denke es liegt irgendwie an den Vertexbufferoperationen.

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#pragma once

//vertex des Fontbuffers

struct SFontVertex
{
    D3DXVECTOR4   vPosRHW; //Transformierte Vertexpos

    DWORD          iColor; //Texturfarbe

    D3DXVECTOR2 vTexCoord; //Texturkoordinaten

};

//Vertexformat

const DWORD FVF_FONT = D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1;

//Anzahl an Zeichen, bis gerendert wird, erstmal auf 256 beschränken

const DWORD MAX_VERTICES = 1024;

class AICE_API CFont
{
private:

    LPDIRECT3DTEXTURE9           m_lpTexture; //Bitmapfont

    LPDIRECT3DVERTEXBUFFER9 m_lpVertexBuffer; //Dynamischer Vertexbuffer

    FLOAT                   m_fCoord[256][4]; //Texturkoordinaten

    int             m_iTexWidth,m_iTexHeight; //Texturbreite /höhe

    
public:

    //Konstruktor/Destruktor

    CFont();
    ~CFont();

    //Schrift erzeugen anhand Bitmapfont + byte.dat

    BOOL Init(const char* sFontFile,char* sFontDesc,DWORD iColorKey);

    //Schrift ausgeben

    void Draw(int x,int y,const char *sText,DWORD iColor);
};


C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
#include <aice.h>

//--------------------------------------------------------------------------------------------

//Konstruktor: Setzt startwerte

//--------------------------------------------------------------------------------------------

CFont::CFont()
{
    m_lpTexture = 0;
    m_lpVertexBuffer = 0;
}

//--------------------------------------------------------------------------------------------

//Destruktor: Gibt alles frei!

//--------------------------------------------------------------------------------------------

CFont::~CFont()
{
    if (m_lpTexture) m_lpTexture->Release();
    if (m_lpVertexBuffer) m_lpVertexBuffer->Release();
}

//--------------------------------------------------------------------------------------------

//Funktion: erzeugt die Schriftart

//--------------------------------------------------------------------------------------------

BOOL CFont::Init(const char* sFontFile,char* sFontDesc,DWORD iColorKey)
{
    CLogData clLog;

    //Textur laden

    if(FAILED(D3DXCreateTextureFromFileEx(
        CGraphic::GetSingleton().GetDevice(),
        sFontFile,
        D3DX_DEFAULT,D3DX_DEFAULT,D3DX_DEFAULT,
        0,
        D3DFMT_A8R8G8B8,
        D3DPOOL_DEFAULT,
        D3DX_FILTER_NONE,
        D3DX_FILTER_NONE,
        iColorKey,
        NULL,NULL,
        &m_lpTexture)))
    {
        clLog.AddInformation("Konnte Textur für Schrift nicht laden: ",sFontFile,INFOTYPE_FAILED);
        return FALSE;
    }

    //Datei öfnen mit Zeichenbreiten

    std::ifstream fFile(sFontDesc,std::ios::in | std::ios::binary);

    if (fFile.bad())
    {
        clLog.AddInformation("Konnte Koordinatendatei für Schrift nicht laden",sFontDesc,INFOTYPE_FAILED);
        return FALSE;
    }

    //texturhöhe holen und daraus Höhe eines zeichens berechnen

    D3DSURFACE_DESC stDesc;
    m_lpTexture->GetLevelDesc(0,&stDesc);
    m_iTexWidth = stDesc.Width;
    m_iTexHeight = stDesc.Height;

    //Alle Werte für Textturkoordinaten eintragen

    FLOAT fFontHeight = static_cast<FLOAT>(m_iTexHeight / 16);
    FLOAT fFontWidth = static_cast<FLOAT>(m_iTexWidth / 16);
    for(int i=0;i<256;i++)
    {
        //Wert lesen - 2 Byte

        int iAbsValue=0;
        fFile.read(reinterpret_cast<char*>(&iAbsValue),2);

        //In Array werte speichern, xStart,yStart,xEnd,yEnd

        int iRow = i / 16;
        int iCol = i % 16;
        m_fCoord[i][0] = iCol * fFontWidth / m_iTexWidth;
        m_fCoord[i][1] = iRow * fFontHeight / m_iTexHeight;
        m_fCoord[i][2] = (iCol * fFontWidth + iAbsValue + 2) / m_iTexWidth;
        m_fCoord[i][3] = ((iRow+1) * fFontHeight) / m_iTexHeight;
    }

    //Datei schliessen

    fFile.close();

    //Dynamischen VertexBuffer erzeugen

    if(FAILED(CGraphic::GetSingleton().GetDevice()->CreateVertexBuffer(
            MAX_VERTICES*sizeof(SFontVertex),D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY,
            FVF_FONT,D3DPOOL_DEFAULT,&m_lpVertexBuffer,NULL)))
    {
        clLog.AddInformation("Font-Klasse: Konnte Vertexbuffer nicht erzeugen!",NULL,INFOTYPE_FAILED);
        return FALSE;
    }
    
    clLog.AddInformation("Schrift erfolgreiche Erzeugt!",NULL,INFOTYPE_SUCCESS);
    return TRUE;
}

//--------------------------------------------------------------------------------------------

//Funktion: Zeichnet die Schrift mit Quads

//--------------------------------------------------------------------------------------------

void CFont::Draw(int x,int y,const char *sText,DWORD iColor)
{
    LPDIRECT3DDEVICE9 lpDevice = CGraphic::GetSingleton().GetDevice();

    //Renderstates umschalten

    lpDevice->SetRenderState(D3DRS_ALPHATESTENABLE,TRUE);
    lpDevice->SetTexture(0,m_lpTexture);
    lpDevice->SetFVF(FVF_FONT);
    lpDevice->SetStreamSource(0,m_lpVertexBuffer,0,sizeof(SFontVertex));

    //Vertexbuffer sperren

    SFontVertex *vStart = NULL;
    m_lpVertexBuffer->Lock(0,0,(VOID**)&vStart,D3DLOCK_DISCARD);

    //Für jedes Zeichen

    int iLength = static_cast<int>(strlen(sText));
    FLOAT fX = static_cast<FLOAT>(x);
    FLOAT fY = static_cast<FLOAT>(y);
    
    for(int i=0;i<iLength;i++)
    {
        //Aktuelles zeichen raussuchen

        unsigned char cCurrentChar = sText[i];

        //Texturkoordinaten raussuchen

        FLOAT tx1 = m_fCoord[cCurrentChar][0];
        FLOAT ty1 = m_fCoord[cCurrentChar][1];
        FLOAT tx2 = m_fCoord[cCurrentChar][2];
        FLOAT ty2 = m_fCoord[cCurrentChar][3];

        //Breite und Höhe des Vierecks berechnen

        FLOAT w = (tx2-tx1) * m_iTexWidth;
        FLOAT h = (ty2-ty1) * m_iTexHeight;

        //vertices einstellen

        vStart->iColor = iColor;
        vStart->vPosRHW = D3DXVECTOR4(fX,fY+h,0.0f,1.0f);
        vStart->vTexCoord = D3DXVECTOR2(tx1,ty2);
        *vStart++;

        vStart->iColor = iColor;
        vStart->vPosRHW = D3DXVECTOR4(fX,fY,0.0f,1.0f);
        vStart->vTexCoord = D3DXVECTOR2(tx1,ty1);
        *vStart++;

        vStart->iColor = iColor;
        vStart->vPosRHW = D3DXVECTOR4(fX+w,fY+h,0.0f,1.0f);
        vStart->vTexCoord = D3DXVECTOR2(tx2,ty2);
        *vStart++;

        vStart->iColor = iColor;
        vStart->vPosRHW = D3DXVECTOR4(fX+w,fY,0.0f,1.0f);
        vStart->vTexCoord = D3DXVECTOR2(tx2,ty1);
        *vStart++;

        //anfangsmarke weiterschieben

        fX += w;
    }

    //VertexBuffer wieder aufschliessen

    m_lpVertexBuffer->Unlock();

    //Rendern allet

    lpDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP,0,iLength*2);

    //Alphablending aus

    lpDevice->SetRenderState(D3DRS_ALPHATESTENABLE,FALSE);
}

Werbeanzeige