Du bist nicht angemeldet.

Werbeanzeige

stef

Treue Seele

  • »stef« ist der Autor dieses Themas

Beiträge: 241

Wohnort: Kassel

Beruf: Softwareentwickler

  • Private Nachricht senden

1

31.08.2012, 23:34

(Instanced Rendering) Kann ein VAO Daten von 2 VBO enthalten?

Hallo Forum

Ich will Instanced Rendering ausprobieren indem ich ein Model n-mal (mit n mal MV-Matrix und n mal Normal-Matrix) rendere.
Meine Geometriedaten (Position, Normal und Texture) befinden sich in einem VBO hintereinander.
Meine n mal MV-Matrix und n mal Normal-Matrix befinden sich in einem zweiten VBO ebenfalls hintereinander.

Frage: Kann ich die Daten aus den beiden VBO in einem VAO unterbrigen oder speichert ein VAO nur States bezogen auf einen VBO ?

Etwas genauer gesagt ich möchte mit einem Bind auf ein VAO, VertexAttribArray 0 bis 4 enablen, wobei 0 - 2 Daten aus VBO 1 enthalten (Position, Normal und Texture)
und 3 und 4 MV- und Normal-Matrix aus VBO 2 enthalten.
"In C++ it's harder to shoot yourself in the foot, but when you do, you blow off your whole leg." — Bjarne Stroustrup.

Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »stef« (07.09.2012, 22:55)


dot

Supermoderator

Beiträge: 9 833

Wohnort: Graz

  • Private Nachricht senden

2

31.08.2012, 23:34

Ja ;)

stef

Treue Seele

  • »stef« ist der Autor dieses Themas

Beiträge: 241

Wohnort: Kassel

Beruf: Softwareentwickler

  • Private Nachricht senden

3

31.08.2012, 23:46

Ja


Das ist schön ^^
Aber was mache ich falsch ??? :(

Ich mixe z.B. auch GL_STATIC_DRAW (VBO 1 mit Geometriedaten) und GL_DYNAMIC_DRAW (VBO 2 mit MV- un N-Matrizzen (die ändern sich ja von Instance zu Instance) ).

Immer noch 'Ja' ???
"In C++ it's harder to shoot yourself in the foot, but when you do, you blow off your whole leg." — Bjarne Stroustrup.

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »stef« (01.09.2012, 00:16)


dot

Supermoderator

Beiträge: 9 833

Wohnort: Graz

  • Private Nachricht senden

4

01.09.2012, 00:14

Definitiv Ja. Was du falsch machst, kann ich nicht sagen, ohne gesehen zu haben, was du machst... ;)

stef

Treue Seele

  • »stef« ist der Autor dieses Themas

Beiträge: 241

Wohnort: Kassel

Beruf: Softwareentwickler

  • Private Nachricht senden

5

01.09.2012, 00:30

Definitiv Ja. Was du falsch machst, kann ich nicht sagen, ohne gesehen zu haben, was du machst...


also erst mal die Geo-Daten ...

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
void CFigure::CopyBufferData()
{
    // transform data before copy to GPU RAM
    Transform();

    GL::glBindVertexArray(m_unVAO);
    {
        // first bind buffer via handle handle
        GL::glBindBuffer(GL_ARRAY_BUFFER, m_unVBO);

        // call glBufferData with correct size and NULL-Pointer to allocate memory for the following calls of glBufferSubData
        GL::glBufferData(GL_ARRAY_BUFFER, sizeof(CVector3)*m_sNumberOfVertices + sizeof(CVector3)*m_sNumberOfVertices + sizeof(CVector2)*m_sNumberOfVertices, NULL, GL_STATIC_DRAW);


        // call glBufferSubData to actualy fill the buffers
        GL::glBufferSubData(GL_ARRAY_BUFFER, 0                                                                          , sizeof(CVector3)*m_sNumberOfVertices, &m_v3Position[0]);
        GL::glBufferSubData(GL_ARRAY_BUFFER, sizeof(CVector3)*m_sNumberOfVertices                                       , sizeof(CVector3)*m_sNumberOfVertices, &m_v3Normal[0]);
        GL::glBufferSubData(GL_ARRAY_BUFFER, sizeof(CVector3)*m_sNumberOfVertices + sizeof(CVector3)*m_sNumberOfVertices, sizeof(CVector2)*m_sNumberOfVertices, &m_v2Texture[0]);

        // buffer has three sections for position, normals and texture coordinates
        GL::glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0);
        GL::glEnableVertexAttribArray(0);
        GL::glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)(sizeof(CVector3)*m_sNumberOfVertices));
        GL::glEnableVertexAttribArray(1);
        GL::glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid*)(sizeof(CVector3)*m_sNumberOfVertices + sizeof(CVector3)*m_sNumberOfVertices));
        GL::glDisableVertexAttribArray(2); // only enabled if texture is set
    }
    GL::glBindVertexArray(0); // unbind VAO to avoid unwanted changes 
}


dann die Matrizzen aus VBO 2 mit rein und rendern ...

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
void CFigure_Torus::DrawInstanced(GLsizei primcount, GLuint unVBO, vector& v_m44MVM, vector& v_m33NM)
{
    // draw torus
    int i;

    GL::glBindVertexArray(m_unVAO);
    {

        GL::glBindBuffer(GL_ARRAY_BUFFER, unVBO);
        GL::glBufferData   (GL_ARRAY_BUFFER, sizeof(CMatrix44) + sizeof(CMatrix33) * primcount, NULL, GL_DYNAMIC_DRAW);
        GL::glBufferSubData(GL_ARRAY_BUFFER,                             0, sizeof(CMatrix44) * primcount, &v_m44MVM[0]);
        GL::glBufferSubData(GL_ARRAY_BUFFER, sizeof(CMatrix44) * primcount, sizeof(CMatrix33) * primcount, &v_m33NM[0]);
        GL::glVertexAttribPointer(3, 16, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0);
        GL::glEnableVertexAttribArray(3);
        GL::glVertexAttribDivisor(3, 1);
        GL::glVertexAttribPointer(4,  9, GL_FLOAT, GL_FALSE, 0, (GLvoid*)(sizeof(CMatrix44) * primcount));
        GL::glEnableVertexAttribArray(4);
        GL::glVertexAttribDivisor(4, 1);

        if(m_unTexture2D)
            glBindTexture(GL_TEXTURE_2D, m_unTexture2D);
        if(m_unTextureCube)
            glBindTexture(GL_TEXTURE_CUBE_MAP, m_unTextureCube);

        //glCullFace(GL_FRONT);
        //for(i=0; i<m_snumberofsegments; i++)="" 
        //  glDrawArrays(GL_TRIANGLE_STRIP, i*(m_sNumberOfSegments*2+2) , m_sNumberOfSegments*2+2);
        glCullFace(GL_BACK);
        for(i=0; i<m_snumberofsegments; i++)="" 
            GL::glDrawArraysInstanced(GL_TRIANGLE_STRIP, i*(m_sNumberOfSegments*2+2) , m_sNumberOfSegments*2+2, primcount);

        if(m_unTexture2D)
            glBindTexture(GL_TEXTURE_2D, 0);
        if(m_unTextureCube)
            glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
    }
    GL::glBindVertexArray(0);
}


... dann krachts beim glDrawArraysInstanced !

Hier noch der Vertex-Shader

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
#version 330
precision highp float;
precision highp int;

// already transformed by view matrix !!!
uniform vec3 u_v3LightPos; 
uniform mat4 u_m4PM;

layout (location = 0) in vec3 _v3Vertex;
layout (location = 1) in vec3 _v3Normal;
layout (location = 2) in vec2 _v2Texture;

layout (location = 3) in mat4 u_m4MVM;
layout (location = 4) in mat3 u_m3NM;

out vec3 v3Vertex_;
out vec3 v3Normal_;
out vec2 v2Texture_;
out vec3 v3VertexToLight_;
out vec4 v4SecondaryColor_;

void main (void)
{
    vec3 v3HalfWay;
    vec4 v4Temp;
    float fNdotL;
    float fNdotH;

    // position
    v4Temp.xyz = _v3Vertex;
    v4Temp.w = 1.0;     
    v4Temp = u_m4MVM * v4Temp;
    v3Vertex_ = v4Temp.xyz;
    v4Temp.xyz = v3Vertex_;
    v4Temp.w = 1.0;
    gl_Position = u_m4PM * v4Temp;

    // normals
    v3Normal_ = normalize(u_m3NM * _v3Normal);

    // calculate and normalized vertex to light vector
    v3VertexToLight_ = normalize(u_v3LightPos - v3Vertex_);

    // calculate normals dot vertex to light vector
    fNdotL = max(0.0, dot(v3Normal_, v3VertexToLight_));

    // calculate half way for specular light
    v3HalfWay = normalize( normalize(vec3(0.0, 0.0, 0.0) - v3Vertex_) + normalize(u_v3LightPos - v3Vertex_) );
    fNdotH = max(0.0, dot(v3Normal_, v3HalfWay));

    // specular light
    v4SecondaryColor_ = (fNdotL > 0.0) ? vec4(pow(fNdotH, 128.0)) : vec4(0.0);

    // set texture unchanged
    v2Texture_ = _v2Texture;    
}
"In C++ it's harder to shoot yourself in the foot, but when you do, you blow off your whole leg." — Bjarne Stroustrup.

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »stef« (03.09.2012, 11:05)


stef

Treue Seele

  • »stef« ist der Autor dieses Themas

Beiträge: 241

Wohnort: Kassel

Beruf: Softwareentwickler

  • Private Nachricht senden

6

01.09.2012, 00:31

Sorry wegen dem Format, aber auch mit dem dritten Browser klappt das einfach nicht !

EDIT: Habs doch noch schön bekommen :)
"In C++ it's harder to shoot yourself in the foot, but when you do, you blow off your whole leg." — Bjarne Stroustrup.

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »stef« (03.09.2012, 11:06)


dot

Supermoderator

Beiträge: 9 833

Wohnort: Graz

  • Private Nachricht senden

7

01.09.2012, 00:57

Nun, nach schnellem drüberschauen würd ich erstmal sagen, dass du hier

C-/C++-Quelltext

1
GL::glBufferData   (GL_ARRAY_BUFFER, sizeof(CMatrix44) + sizeof(CMatrix33) * primcount, NULL, GL_DYNAMIC_DRAW);

deinen Buffer wohl zu klein machst... ;)

stef

Treue Seele

  • »stef« ist der Autor dieses Themas

Beiträge: 241

Wohnort: Kassel

Beruf: Softwareentwickler

  • Private Nachricht senden

8

01.09.2012, 14:51

Nicht schlecht ! Leider passiert das auch wenn ich die beiden sizeof klammere.
Wende ich glVertexAttributeDevisor richtig an ?
"In C++ it's harder to shoot yourself in the foot, but when you do, you blow off your whole leg." — Bjarne Stroustrup.

dot

Supermoderator

Beiträge: 9 833

Wohnort: Graz

  • Private Nachricht senden

9

01.09.2012, 15:44

Also der Doku nach würde ich mal sagen ja. Ich muss aber gestehen, dass ich Instancing bisher immer nur in Direct3D Anwendungen gebraucht hab. Du kannst ja mal schauen, ob es ohne Instancing funktioniert...

stef

Treue Seele

  • »stef« ist der Autor dieses Themas

Beiträge: 241

Wohnort: Kassel

Beruf: Softwareentwickler

  • Private Nachricht senden

10

01.09.2012, 17:26

Ich klincke mich erst mal bis morgen abend aus.
bin gerade Zelten an der Ostsee und kann hier mit meinem Smart Phone
nix ausprobieren.
"In C++ it's harder to shoot yourself in the foot, but when you do, you blow off your whole leg." — Bjarne Stroustrup.

Werbeanzeige