2017-10-03 4 views
0

Je cherchais des tutoriels OpenGL Multi Sample Anti Aliasing et j'en ai trouvé beaucoup mais j'en prends 2.OpenGL MSAA de 2 manières différentes. Quelles sont les différences?

Ils utilisent cette méthode différemment. J'ai testé les deux façons et les deux fonctionnent pour mon projet afin que je puisse utiliser l'un d'eux. Je l'utilise pour rendre ma scène de moteur de jeu à une texture.

C'est la 1ère façon:

Créer l'OIR avec MSAA

// create a texture object 
glGenTextures(1, &textureId); 
glBindTexture(GL_TEXTURE_2D, textureId); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); 
glBindTexture(GL_TEXTURE_2D, 0); 

// create a MSAA framebuffer object 
// NOTE: All attachment images must have the same # of samples. 
// Ohterwise, the framebuffer status will not be completed. 
glGenFramebuffers(1, &fboMsaaId); 
glBindFramebuffer(GL_FRAMEBUFFER, fboMsaaId); 

// create a MSAA renderbuffer object to store color info 
glGenRenderbuffers(1, &rboColorId); 
glBindRenderbuffer(GL_RENDERBUFFER, rboColorId); 
glRenderbufferStorageMultisample(GL_RENDERBUFFER, MSAA_level, GL_RGB8, width, height); 
glBindRenderbuffer(GL_RENDERBUFFER, 0); 

// create a MSAA renderbuffer object to store depth info 
// NOTE: A depth renderable image should be attached the FBO for depth test. 
// If we don't attach a depth renderable image to the FBO, then 
// the rendering output will be corrupted because of missing depth test. 
// If you also need stencil test for your rendering, then you must 
// attach additional image to the stencil attachement point, too. 
glGenRenderbuffers(1, &rboDepthId); 
glBindRenderbuffer(GL_RENDERBUFFER, rboDepthId); 
glRenderbufferStorageMultisample(GL_RENDERBUFFER, MSAA_level, GL_DEPTH_COMPONENT, width, height); 
glBindRenderbuffer(GL_RENDERBUFFER, 0); 

// attach msaa RBOs to FBO attachment points 
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rboColorId); 
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rboDepthId); 


// create a normal (no MSAA) FBO to hold a render-to-texture 
glGenFramebuffers(1, &fboId); 
glBindFramebuffer(GL_FRAMEBUFFER, fboId); 

glGenRenderbuffers(1, &rboId); 
glBindRenderbuffer(GL_RENDERBUFFER, rboId); 
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height); 
glBindRenderbuffer(GL_RENDERBUFFER, 0); 

// attach a texture to FBO color attachement point 
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureId, 0); 

// attach a rbo to FBO depth attachement point 
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rboId); 

//@@ disable color buffer if you don't attach any color buffer image, 
//@@ for example, rendering the depth buffer only to a texture. 
//@@ Otherwise, glCheckFramebufferStatus will not be complete. 
//glDrawBuffer(GL_NONE); 
//glReadBuffer(GL_NONE); 

// check FBO status 
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) 
    return false; 

glBindFramebuffer(GL_FRAMEBUFFER, 0); 

Et quand je dois dessiner la scène

glBindFramebuffer(GL_FRAMEBUFFER, fboMsaaId); 
glViewport(0, 0, width, height); 
glClearColor(0.1f, 0.1f, 0.1f, 1.0f); 
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

DrawScene(); 

glBindFramebuffer(GL_READ_FRAMEBUFFER, fboMsaaId); 
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fboId); 
glBlitFramebuffer(0, 0, width, height, // src rect 
    0, 0, width, height, // dst rect 
    GL_COLOR_BUFFER_BIT, // buffer mask 
    GL_LINEAR); // scale filter 

glBindFramebuffer(GL_FRAMEBUFFER, 0); 
glViewport(0, 0, App->window->GetWidth(), App->window->GetHeight()); 

La 2ème façon:

Créer l'OIR avec MSAA

unsigned int framebuffer; 
glGenFramebuffers(1, &framebuffer); 
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); 

// create a multisampled color attachment texture 
unsigned int textureColorBufferMultiSampled; 
glGenTextures(1, &textureColorBufferMultiSampled); 
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, textureColorBufferMultiSampled); 
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGB, SCR_WIDTH, SCR_HEIGHT, GL_TRUE); 
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0); 
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, textureColorBufferMultiSampled, 0); 

// create a (also multisampled) renderbuffer object for depth and stencil attachments 
unsigned int rbo; 
glGenRenderbuffers(1, &rbo); 
glBindRenderbuffer(GL_RENDERBUFFER, rbo); 
glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_DEPTH24_STENCIL8, SCR_WIDTH, SCR_HEIGHT); 
glBindRenderbuffer(GL_RENDERBUFFER, 0); 
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo); 

if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) 
    cout << "ERROR::FRAMEBUFFER:: Framebuffer is not complete!" << endl; 
glBindFramebuffer(GL_FRAMEBUFFER, 0); 

// configure second post-processing framebuffer 
unsigned int intermediateFBO; 
glGenFramebuffers(1, &intermediateFBO); 
glBindFramebuffer(GL_FRAMEBUFFER, intermediateFBO); 

// create a color attachment texture 
unsigned int screenTexture; 
glGenTextures(1, &screenTexture); 
glBindTexture(GL_TEXTURE_2D, screenTexture); 
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, SCR_WIDTH, SCR_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, screenTexture, 0); // we only need a color buffer 

if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) 
    cout << "ERROR::FRAMEBUFFER:: Intermediate framebuffer is not complete!" << endl; 
glBindFramebuffer(GL_FRAMEBUFFER, 0); 

Et quand je dois dessiner la scène:

glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); 
glViewport(0, 0, width, height); 
glClearColor(0.1f, 0.1f, 0.1f, 1.0f); 
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

DrawScene(); 

    glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer); 
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, intermediateFBO); 
    glBlitFramebuffer(0, 0, SCR_WIDTH, SCR_HEIGHT, 0, 0, SCR_WIDTH, SCR_HEIGHT, GL_COLOR_BUFFER_BIT, GL_LINEAR); 

    glBindFramebuffer(GL_FRAMEBUFFER, 0); 
    glViewport(0, 0, App->window->GetWidth(), App->window->GetHeight()); 

Résumer: 1er chemin: Créer OIR, créer RBO pour la couleur et RBO pour la profondeur et de l'utilisation glRenderbufferStorageMultisample(...) pour spécifier le niveau MSAA. Ensuite, créez d'autres FBO avec la texture pour la couleur et RBO pour la profondeur.

2ème manière: créer FBO, créer une texture pour la couleur et RBO pour la profondeur et utiliser glTexImage2DMultisample(...) pour le niveau MSAA dans la texture. Puis créez d'autres FBO et une texture.

Quelles sont les différences d'utilisation dans un sens ou dans l'autre? Est-ce que l'un est meilleur que l'autre?

+1

Votre question se résume-t-elle à "Quelle est la différence entre l'utilisation d'une texture et d'un renderbuffer comme attachement fbo?" – BDL

+0

@BDL Oui mais lors de l'utilisation de MSAA. Les différences et si une façon est meilleure que l'autre. –

+1

Les différences sont les mêmes avec ou sans MSAA. Vous pouvez lire [this] (https://www.opengl.org/discussion_boards/showthread.php/175962-FBO-Renderbuffer-vs-Texture) – BDL

Répondre

0

La configuration MSAA dans votre exemple est en fait la même dans les deux cas. La seule différence entre les deux méthodes que vous avez décrites est le type de pièce jointe FBO. En général, vous voudrez joindre une texture et ne pas rendre le tampon lorsque vous aurez besoin d'utiliser les informations de cette FBO pour d'autres passes de rendu. Dans un tel cas, vous devez brancher le rendu précédent passer la pièce jointe de texture de FBO dans l'unité de texture, et en faire un échantillon dans le prochain programme de shader de passe. Shadow mapping est l'un de ces cas.