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

the[V]oid

Alter Hase

  • »the[V]oid« ist der Autor dieses Themas

Beiträge: 775

Wohnort: Aachen

  • Private Nachricht senden

1

24.12.2009, 03:03

GL: Vertex Buffer Problem [solved]

Hallo

Ich habe eine kleine Klasse geschrieben, um das VBO zu wrappen.
Leider funktioniert es nicht wie erwartet und ich finde den Fehler einfach nicht.
Ich rendere einige viele GL_POINTS, die im Immediate Mode gerendert korrekt dargestellt werden.
Mit Vertex Buffer aber nur einige von ihnen, viele (nicht alle) schwirren durch die Gegend.
Um es mal zu verdeutlichen, ein Screenshot:


(Link)


Eigentlich sollten alle Punkte in einem Ring liegen, aber wie man sieht, bilden einige (undzwar nicht wenige) anderweitige geometrische Formen.
Wie schon gesagt, ohne Vertex Buffer wird alles richtig gerendert, ergo liegt der Fehler nicht bei den Berechnungen.
Auch wenn ich alle Punkte in den Ursprung setze, lassen sich immernoch irgendwelche Linien erkennen!
Das ist mir völlig rätselhaft. Bin mal mit valgrind drüber gegangen, nichts auffälligen bemerkt.
OpenGL-Fehler treten auch keine auf.

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
#include <GL/glew.h>
#include "vertexbuffer.hpp"

using namespace std;

class VertexBufferImplData
{

public:

    VertexBufferImplData() : nDataLength( 0 ) { }

    GLuint id;
    void* pMappedBufferPtr;
    unsigned int nDataLength;
    GLenum vertexformat;
    unsigned int nVertexSize;

}; // class VertexBufferImplData




VertexBuffer::VertexBuffer()
    : m_pImplData( new VertexBufferImplData() ), m_bDynamic( false )
{
    glGenBuffers( 1, &( m_pImplData->id ) );
}


VertexBuffer::~VertexBuffer()
{
    glDeleteBuffers( 1, &( m_pImplData->id ) );
    delete m_pImplData;
}


void VertexBuffer::update( const void* pvData, unsigned int size, GLenum vertexformat, unsigned char vertexsize, bool bDynamic )
{
    glBindBuffer( GL_ARRAY_BUFFER, m_pImplData -> id );
    glEnableClientState( GL_VERTEX_ARRAY );
    glBufferData( GL_ARRAY_BUFFER, size, pvData, bDynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW );
    m_bDynamic = bDynamic;
    m_pImplData -> nDataLength = size;
    m_pImplData -> vertexformat = vertexformat;
    m_pImplData -> nVertexSize  = vertexsize;
}


void VertexBuffer::draw( GLenum mode, unsigned int offset, unsigned int datalength ) const
{
    if( datalength == 0 )
    {
        datalength = m_pImplData -> nDataLength;
    }
    glBindBuffer( GL_ARRAY_BUFFER, m_pImplData -> id );
    glInterleavedArrays( m_pImplData -> vertexformat, m_pImplData -> nVertexSize, NULL );
    glDrawArrays( mode, offset, datalength );
}


Das verwendete Vertex-Format ist wie folgt definiert:

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
struct C3F_V3F
    : public VertexC3F,
      public VertexV3F,
      public VertexBaseType
{   unsigned char size() const   { return sizeof( VertexC3F ) +
                                          sizeof( VertexV3F ); }
    GLenum        format() const { return GL_C3F_V3F; }
} __attribute__((packed));

struct VertexBaseType
{
public:
    virtual ~VertexBaseType() { }
    virtual unsigned char size() const = 0;
    virtual GLenum format() const = 0;
protected:
    VertexBaseType() { }
}
__attribute__((packed));

struct VertexV3F
{
    Vector3f position;
}
__attribute__((packed));

struct VertexC3F
{
    Color3f color;
}
__attribute__((packed));


Bin für jeden Hinweis dankbar!
<< an dieser Stelle ist eine Signatur verstorben >>

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

2

24.12.2009, 09:57

Das Problem sind die virtuellen Methoden. Die Größe eines Vertex ist nämlich nicht sizeof(VertexC3F) + sizeof(VertexV3F), solcherlei Berechnungen sind generell eher nicht zu empfehlen da nur in bestimmten Ausnahmefällen korrekt (warum nicht einfach sizeof(C3F_V3F)?)
Durch die virtuellen Methoden (wofür brauchst du die eigentlich?) bekommt jeder Vertex noch einen versteckten Pointer auf eine vtable und damit stimmt die Größe nichtmehr und bei jedem xten Vertex kommt wohl dieser Pointer auf der Stelle einer Koordinate der Vertexposition zu liegen weswegen sich vermutlich genau diese 3 "Achsen" bilden.

Gotbread

Alter Hase

Beiträge: 421

Beruf: Student (Etechnik) + Hiwi

  • Private Nachricht senden

3

24.12.2009, 15:11

sowas hatte ich auchmal, lag an nem kleinen pitch am ende einer reihe
(R2VB). diese achsen sind typisch dafür.

sieht trotzdem nice aus :)
Mfg Goti
www.gotbread.bplaced.net
viele tolle spiele kostenlos, viele hardware-basteleien :)

"Es ist nicht undicht, es läuft über" - Homer Simpson

the[V]oid

Alter Hase

  • »the[V]oid« ist der Autor dieses Themas

Beiträge: 775

Wohnort: Aachen

  • Private Nachricht senden

4

24.12.2009, 15:22

@dot: Danke für den Hinweis, werd ich mal ausprobieren.
@Gotbread: Was meinst du mit Pitch?
<< an dieser Stelle ist eine Signatur verstorben >>

the[V]oid

Alter Hase

  • »the[V]oid« ist der Autor dieses Themas

Beiträge: 775

Wohnort: Aachen

  • Private Nachricht senden

5

25.12.2009, 15:38

Also nur an den virtuals lags nicht. Die hab ich jetzt rausgenommen.
Dannach hab ich es auf zwei Rechnern getestet.
Bei dem mit dem Intel GMA Grafikchip klappt es zwar.
Auf dem mit der nVidia GeForce FX Go 5200 besteht der Fehler aber weiterhin.
Was kanns noch sein? Was meinte Godbread mit diesem Pitch?
[/b]
<< an dieser Stelle ist eine Signatur verstorben >>

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

6

25.12.2009, 16:09

Wie sieht denn dein Code jetzt aus?

Gotbread

Alter Hase

Beiträge: 421

Beruf: Student (Etechnik) + Hiwi

  • Private Nachricht senden

7

25.12.2009, 16:15

der pitch kam von einer textur, da die nächste reihe nicht bündig
hinter der ersten lag, sondern ein paar bytes dazuwischen hatte.
(Render to vertex buffer, dabei wird eine textur als vbuffer genommen,
interessante technick ;) ).

teste mal mit sizeof() wiegroß das teil wirklich ist, und ob du auch
den richtigen wert angibst. unter directx ist es so, dass man die
größe eines vertex manuell angeben kann, und die muss auch nicht
zwingend die vertexgröße sein.
Mfg Goti
www.gotbread.bplaced.net
viele tolle spiele kostenlos, viele hardware-basteleien :)

"Es ist nicht undicht, es läuft über" - Homer Simpson

the[V]oid

Alter Hase

  • »the[V]oid« ist der Autor dieses Themas

Beiträge: 775

Wohnort: Aachen

  • Private Nachricht senden

8

26.12.2009, 13:55

So, mal der aktuelle Code. Falls Ihr der Meinung seid, er sähe gut aus, werd ich mal den Code pasten, der zur Verwendung dient.

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
#include <GL/glew.h>
#include "vertexbuffer.hpp"

using namespace std;
using namespace vertexformats;

const GLenum    V3F             ::format   = GL_V3F;
const GLenum    T2F_C3F_V3F     ::format   = GL_T2F_C3F_V3F;
const GLenum    T2F_C4F_N3F_V3F ::format   = GL_T2F_C4F_N3F_V3F;
const GLenum    T2F_C4UB_V3F    ::format   = GL_T2F_C4UB_V3F;
const GLenum    T2F_N3F_V3F     ::format   = GL_T2F_N3F_V3F;
const GLenum    T2F_V3F         ::format   = GL_T2F_V3F;
const GLenum    N3F_V3F         ::format   = GL_N3F_V3F;
const GLenum    C3F_V3F         ::format   = GL_C3F_V3F;
const GLenum    C4F_N3F_V3F     ::format   = GL_C4F_N3F_V3F;
const GLenum    C4UB_V3F        ::format   = GL_C4UB_V3F;


class VertexBufferImplData
{

public:

    VertexBufferImplData() : nDataLength( 0 ) { }

    GLuint id;
    void* pMappedBufferPtr;
    unsigned int nDataLength;
    GLenum vertexformat;
    unsigned int nVertexSize;

}; // class VertexBufferImplData



VertexBuffer::VertexBuffer()
    : m_pImplData( new VertexBufferImplData() ), m_bDynamic( false )
{
    CHECK_GL_ERRORS;
    glGenBuffers( 1, &( m_pImplData->id ) );
    CHECK_GL_ERRORS;
}


VertexBuffer::~VertexBuffer()
{
    CHECK_GL_ERRORS;
    glDeleteBuffers( 1, &( m_pImplData->id ) );
    CHECK_GL_ERRORS;
    delete m_pImplData;
}


void VertexBuffer::update( const void* pvData, unsigned int size, GLenum vertexformat, unsigned char vertexsize, bool bDynamic )
{
    CHECK_GL_ERRORS;
    glBindBuffer( GL_ARRAY_BUFFER, m_pImplData -> id );
    glEnableClientState( GL_VERTEX_ARRAY );
    glBufferData( GL_ARRAY_BUFFER, size, pvData, bDynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW );
    m_bDynamic = bDynamic;
    m_pImplData -> nDataLength = size;
    m_pImplData -> vertexformat = vertexformat;
    m_pImplData -> nVertexSize  = vertexsize;
    CHECK_GL_ERRORS;
}


void VertexBuffer::draw( GLenum mode, unsigned int offset, unsigned int datalength ) const
{
    CHECK_GL_ERRORS;
    if( datalength == 0 )
    {
        datalength = m_pImplData -> nDataLength;
    }
    glBindBuffer( GL_ARRAY_BUFFER, m_pImplData -> id );
    glInterleavedArrays( m_pImplData -> vertexformat, m_pImplData -> nVertexSize, NULL );
    glDrawArrays( mode, offset, datalength );
    CHECK_GL_ERRORS;
}


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
template<typename T>
struct PackedVector2
{
    union { T x; T r; };
    union { T y; T g; };
    PackedVector2<T>& operator=( const Vector2f& v )
    {
        x = v.x;
        y = v.y;
        return *this;
    }
}
__attribute__((packed));

template<typename T>
struct PackedVector3
{
    union { T x; T r; };
    union { T y; T g; };
    union { T z; T b; };
    PackedVector3<T>& operator=( const Vector3f& v )
    {
        x = v.x;
        y = v.y;
        z = v.z;
        return *this;
    }
}
__attribute__((packed));

template<typename T>
struct PackedVector4
{
    union { T x; T r; };
    union { T y; T g; };
    union { T z; T b; };
    union { T w; T a; };
    PackedVector4<T>& operator=( const Vector4f& v )
    {
        x = v.x;
        y = v.y;
        z = v.z;
        w = v.w;
        return *this;
    }
}
__attribute__((packed));

typedef PackedVector2<float>         PackedVector2f;
typedef PackedVector3<float>         PackedVector3f;
typedef PackedVector4<float>         PackedVector4f;
typedef PackedVector4<unsigned char> PackedVector4ub;

struct VertexV3F
{
    PackedVector3f position;
}
__attribute__((packed));

struct VertexN3F
{
    PackedVector3f normals;
}
__attribute__((packed));

struct VertexC3F
{
    PackedVector3f color;
}
__attribute__((packed));

struct VertexT2F
{
    PackedVector2f texture;
}
__attribute__((packed));

struct VertexC4F
{
    PackedVector4f color;
}
__attribute__((packed));

struct VertexC4UB
{
    PackedVector4ub color;
}
__attribute__((packed));


namespace vertexformats
{

struct V3F
    : public VertexV3F
{   const static GLenum format;
} __attribute__((packed));

struct T2F_C3F_V3F
    : public VertexT2F,
      public VertexC3F,
      public VertexV3F
{   const static GLenum format;
} __attribute__((packed));

struct T2F_C4F_N3F_V3F
    : public VertexT2F,
      public VertexC4F,
      public VertexN3F,
      public VertexV3F
{   const static GLenum format;
} __attribute__((packed));

struct T2F_C4UB_V3F
    : public VertexT2F,
      public VertexC4UB,
      public VertexV3F
{   const static GLenum format;
} __attribute__((packed));

struct T2F_N3F_V3F
    : public VertexT2F,
      public VertexN3F,
      public VertexV3F
{   const static GLenum format;
} __attribute__((packed));

struct T2F_V3F
    : public VertexT2F,
      public VertexV3F
{   const static GLenum format;
} __attribute__((packed));

struct N3F_V3F
    : public VertexN3F,
      public VertexV3F
{   const static GLenum format;
} __attribute__((packed));

struct C3F_V3F
    : public VertexC3F,
      public VertexV3F
{   const static GLenum format;
} __attribute__((packed));

struct C4F_N3F_V3F
    : public VertexC4F,
      public VertexN3F,
      public VertexV3F
{   const static GLenum format;
} __attribute__((packed));

struct C4UB_V3F
    : public VertexC4UB,
      public VertexV3F
{   const static GLenum format;
} __attribute__((packed));

}  // namespace vertexformats



@ Gotbread:

Die sizeof Werte sind korrekt, im Falle von C3F_V3F, was ich verwende, 24 Bytes.
<< an dieser Stelle ist eine Signatur verstorben >>

the[V]oid

Alter Hase

  • »the[V]oid« ist der Autor dieses Themas

Beiträge: 775

Wohnort: Aachen

  • Private Nachricht senden

9

28.12.2009, 13:40

Hat denn sonst niemand eine Idee? Oo
<< an dieser Stelle ist eine Signatur verstorben >>

10

28.12.2009, 13:42

gibts den sowas inder art von glComputeVertexSizeFromFormat. Damit könntest ja prüfen, ob die sizeof werte so sind wie sie sollen.

Werbeanzeige