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

LukasBanana

Alter Hase

  • »LukasBanana« ist der Autor dieses Themas

Beiträge: 1 097

Beruf: Shader Tools Programmer

  • Private Nachricht senden

1

04.11.2011, 13:40

OpenGL FBO + MRT + MS

Hi, ich möchte mit OpenGL MultiSampled (MS) FrameBufferObjects (FBO) als MultiRenderTargets (MRT) verwenden. MRTs habe ich bereits mit den FBOs gemacht aber noch nicht in verbindung mit MultiSampled RenderTargets.
Kann mir einer die Vorgehensweise erklären? Wenn ich jetzt meine MultiSampled FBOs verwende wird im Shader nur gl_FragData[0] berücksichtigt aber nicht die anderen Indizes (also gl_FragData[1] usw.).

Bei MRTs mit FBOs nutze ich natürlich die Funktion "glDrawBuffers" und dann eben die jeweiligen Color-Attachments. Da man aber bei MultiSampling mit der "glBlitFramebuffer" Funktion arbeiten muss, sieht das ja eh etwas anders aus.
Ich hoffe einer von euch hat sowas schon mal mit OpenGL gemacht und kann mir weiter helfen :)

LukasBanana

Alter Hase

  • »LukasBanana« ist der Autor dieses Themas

Beiträge: 1 097

Beruf: Shader Tools Programmer

  • Private Nachricht senden

3

06.11.2011, 00:33

Ok darauf wäre ich jetzt kaum selbst gekommen :thumbdown:
Allerdings habe ich das Problem mitlerweile selbst können. Das mit den MultiRenderTargets funktioniert bei MultiSampled FBOs ähnlich zu den normalen FBOs.
Dabei müssen allerdings alle RenderTargets separat mit "glBlitFramebuffer..." ge-'blittet' werden und diese müssen jeweil per "glRenderBuffer..." an das MultiSampled FBO angehängt werden.
Genau bekomme ich das jetzt auch nicht mehr auswenig zusammen, aber so in etwa habe ich das jetzt gelöst.
Gruß,
Lukas

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

4

06.11.2011, 00:36

Mit glBlitFramebuffer tust du aber was völlig andres, nämlich den Inhalt von einem Framebuffer in einen andren kopieren...

LukasBanana

Alter Hase

  • »LukasBanana« ist der Autor dieses Themas

Beiträge: 1 097

Beruf: Shader Tools Programmer

  • Private Nachricht senden

5

06.11.2011, 12:27

Bei multisampled FBOs ist das aber anscheinend notwendig. Das habe ich jetzt schon in mehreren Beispielen gelesen. Man rendert in den multisampled Buffer und muss dann mit "glBlit..." den Kram in den finalen framebuffer packen, wo er dann auf die jeweilige Texture übertragen wird (bzw. auf die jeweiligen Color Attachments).

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

6

08.11.2011, 02:36

Ja, wenn deine Zieltextur nicht multisampled sein soll, dann musst du das. Ansonsten kannst du auch einfach in eine Multisampled Texture rendern und dann z.B. im nächsten Shader resolven. Das erfodert aber D3D10+ Hardware.

7

07.02.2012, 07:10

Moinsen,

ich versuche schon seit Tagen MRT+FBO+Multisampling zum laufen zu bekommen, ohne Erfolg. Ich hab danach immer nur irgendwelchen Restmüll im ZielFBO. Wie genau hast du die FBOs erstellt und geblittet? Ich hab versucht mehrere ColorBuffers für den MS-FBO zu erstellen und diese dann mit dem jeweiligen Attachment gebunden.

Hier mal mein relevanter Delphi code:

Quellcode

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
procedure TMultiSampleFBO.Bind;
begin
  inherited;
  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, Container);
   glPushAttrib(GL_VIEWPORT_BIT);
   glViewport(0,0,Width,Height);

   glClearColor(1,0,0,1);
   glClear(GL_COLOR_BUFFER_BIT Or GL_DEPTH_BUFFER_BIT);

end;

function TMultiSampleFBO.Generate(Attachments: Integer; const MRTcount,
  Texis32BitIdx: Integer): Boolean;
var
  I: Integer;
    FBOState: TuInt32;
begin
setLength(tex, Attachments);
setLength(ColorBuffers, Attachments);


// Attach them
glGenFramebuffersEXT(1, @Container);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, Container);

// Multi sample colorbuffer
for I := 0 to high(tex) do
 begin
  glGenRenderbuffersEXT(1, @colorBuffers[i]);
  glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, colorBuffers[i]);
  glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, GL_RGBA, width, height);
  glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT+i, GL_RENDERBUFFER_EXT, colorBuffers[i]);
 end;

// Multi sample depth buffer
glGenRenderbuffersEXT(1, @depthBufferID);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depthBufferID);
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, GL_DEPTH_COMPONENT, width, height);




glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depthBufferID);



    FBOState:= glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
    If FBOState = GL_FRAMEBUFFER_COMPLETE_EXT
    Then Result:= TRUE
    Else Result:= FALSE;

    if result = false then
    ShowmessagE('FBO Incomplete');


//Final FBO
 glGenFramebuffersEXT(1, @finalFBO);
 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FinalFBO);



// Final framebuffer color buffer
 for I := 0 to high(tex)  do
  begin
   glGenTextures(1, @tex[i]);
   glBindTexture(GL_TEXTURE_2D, tex[i]);
   glTexImage2D(GL_TEXTURE_2D, 0,       // Set properties
        GL_RGBA, Width, Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NIL);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

   glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT + i, GL_TEXTURE_2D, tex[0], 0);
  end;


    FBOState:= glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
    If FBOState = GL_FRAMEBUFFER_COMPLETE_EXT
    Then Result:= TRUE
    Else Result:= FALSE;

    if result = false then
    ShowmessagE('FBO Incomplete');


 glBindTexture(GL_TEXTURE_2D, 0);



end;

procedure TMultiSampleFBO.Unbind;
var
  I: Integer;
begin
 for I := 0 to high(tex) do
  begin
   glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, Container);
   glReadBuffer(GL_COLOR_ATTACHMENT0_EXT + i);

   glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, finalFBO);
   glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT + i);
  glBlitFramebufferEXT(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
 end;

 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
 glBindFramebufferEXT( GL_READ_FRAMEBUFFER_EXT, 0 );
 glBindFramebufferEXT( GL_DRAW_FRAMEBUFFER_EXT, 0 );

   glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );


    inherited;
  glPopAttrib;

end;

LukasBanana

Alter Hase

  • »LukasBanana« ist der Autor dieses Themas

Beiträge: 1 097

Beruf: Shader Tools Programmer

  • Private Nachricht senden

8

07.02.2012, 20:08

Auswendig weiß ich das jetzt auch nicht mehr, müsste ich mich auch erst wieder rein arbeiten.
Allerdings meine ich mich zu erinnern, dass der große Unterschied zwischen Multisampled-RTs die Color-Attachments jeweils einen eigenen Render-Buffer brauchen wohin gegen man ohne Multisampling für die Color-Attachments nur einen Frame-Buffer braucht.

Hier ist der Teil-Code dazu aus meiner Engine, ansonsten kannst du dir die ja mal zum reingucken runterladen und in die Datei "sources/RenderSystem/OpenGL/spOpenGLFramebufferObject.cpp" schauen ;)

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
void GLFramebufferObject::createFramebufferMultisample(
    GLuint TexID, const dim::size2di &Size, GLenum GLDimension, GLenum GLInternalFormat,
    s32 Samples, const std::vector<Texture*> &MultiRenderTargets, const EPixelFormats Format,
    const ETextureDimensions DimensionType, const ECubeMapDirections CubeMapFace, GLuint DepthBufferSourceID)
{
    if (!__spVideoDriver->RenderQuery_[RenderSystem::RENDERQUERY_RENDERTARGET] ||
        !__spVideoDriver->RenderQuery_[RenderSystem::RENDERQUERY_MULTISAMPLE_RENDERTARGET] || !TexID || Samples < 0)
    {
        return;
    }
    
    MSColorBufferID_.resize(MultiRenderTargets.size() + 1);
    
    math::Clamp(Samples, 0, GL_MAX_SAMPLES);
    
    /* Create multi-sample color buffer */
    if (!MSColorBufferID_.empty())
    {
        glGenRenderbuffersEXT(MSColorBufferID_.size(), &MSColorBufferID_[0]);
        
        for (s32 i = 0; i < MSColorBufferID_.size(); ++i)
        {
            if (i)
                GLInternalFormat = static_cast<GLTextureBase*>(MultiRenderTargets[i - 1])->GLInternalFormat_;
            
            glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, MSColorBufferID_[i]);
            glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, Samples, GLInternalFormat, Size.Width, Size.Height);
        }
    }
    
    /* Create multi-sample depth buffer */
    if (!DepthBufferSourceID)
    {
        glGenRenderbuffersEXT(1, &DepthBufferID_);
        glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, DepthBufferID_);
        glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, Samples, GL_DEPTH_COMPONENT24, Size.Width, Size.Height);
    }
    
    /* Create multi-sample frame buffer */
    glGenFramebuffersEXT(1, &MSFrameBufferID_);
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, MSFrameBufferID_);
    
    /* Bind color- and depth buffers */
    GLenum Attachment = GL_COLOR_ATTACHMENT0_EXT;
    foreach (GLuint Id, MSColorBufferID_)
        glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, Attachment++, GL_RENDERBUFFER_EXT, Id);
    
    glFramebufferRenderbufferEXT(
        GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT,
        DepthBufferSourceID ? DepthBufferSourceID : DepthBufferID_
    );
    
    /* Create frame buffer */
    glGenFramebuffersEXT(1, &FrameBufferID_);
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FrameBufferID_);
    
    /* Attach frame buffer texture */
    attachFramebufferTexture(TexID, GLDimension, Format, DimensionType, CubeMapFace);
}

void GLFramebufferObject::blitFramebufferMultisample(const dim::size2di &Size, u32 RTCount)
{
    if (!__spVideoDriver->RenderQuery_[RenderSystem::RENDERQUERY_RENDERTARGET] ||
        !__spVideoDriver->RenderQuery_[RenderSystem::RENDERQUERY_MULTISAMPLE_RENDERTARGET])
    {
        return;
    }
    
    /* Blit framebuffer */
    glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, MSFrameBufferID_);
    glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, FrameBufferID_);
    
    for (s32 i = 0; i <= RTCount; ++i)
    {
        glReadBuffer(GL_COLOR_ATTACHMENT0_EXT + i);
        glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT + i);
        glBlitFramebufferEXT(0, 0, Size.Width, Size.Height, 0, 0, Size.Width, Size.Height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
    }
    
    glReadBuffer(GL_NONE);
    glDrawBuffer(GL_NONE);
    
    /* Unbind multisample framebuffer objects */
    glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0);
    glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0);
}


Gruß,
Lukas

9

08.02.2012, 13:44

irgendwie verstehe ich das nich.. Du erstellst zuerst den MultiSampled FBO und hängst da mehrere ColorBuffer + 1x Depthbuffer rein. Soweit so gut. Doch dann erstellst du den ZielFBO mit nur einer Textur?

Dann beim binden des FBOs (updateMultiFramebuffer) machst du am ende:

Quellcode

1
2
3
4
5
6
7
8
9
10
    /* Activate draw buffers multi-render-targets */
    if (isMultiSampled())
        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, MSFrameBufferID_);
    
    if (MultiRTBuffers.empty())
        glDrawBuffer(GL_NONE);
    else
        glDrawBuffersARB(MultiRTBuffers.size(), &MultiRTBuffers[0]);
    
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);


warum bindest du dann am ende wieder keinen FBO?

Mh also bei mir kommt immernoch Müll raus wenn ich das so rendere.. Die Attachments (ich habe meinem ZielFBO auch genauso viele Texturen gebunden wie halt MRT Attachmetns da sind, und auch MS colorbuffer), sind alle mit müll aus der Graka gefüllt.

LukasBanana

Alter Hase

  • »LukasBanana« ist der Autor dieses Themas

Beiträge: 1 097

Beruf: Shader Tools Programmer

  • Private Nachricht senden

10

08.02.2012, 19:01

Ich unbinde natürlich, weil die Funktion nicht unbedingt direkt vor dem blitten kommen muss. Aber durch "glDrawBuffers" werden schon alle Draw Buffer zu dem zuvor gebundenen Framebuffer hinzugefügt.

Wie gesagt ich müsste mich dauch erst wieder einarbeiten, deshalb schreib ich ja ne Engine, damit ich sowas nur einmal machen muss ^^.
Wenn dir der Source-Code meiner Engine nicht weiter hilft, kann ich dir im Moment auch nicht weiter helfen.

Werbeanzeige