PDA

View Full Version : MSAA using glFramebufferTexture2D?



rexguo
01-17-2010, 11:51 PM
Is it possible to get an MSAA FBO using
glFramebufferTexture2D to supply the colour
buffers? No luck for me so far on a GL3.0 +
Linux machine as it keeps saying GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE.

The example code I've found online on setting
up MSAA FBOs all use:
glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, GL_RGBA8, width, height);

so I'm wondering if using Texture2D is possible
too, assuming the depth+stencil buffers are
setup using glRenderbufferStorageMultisample.

Brolingstanz
01-18-2010, 01:54 AM
I think it should work.

After calling FramebufferTexture* on the current fbo you might try a few glGetIntegervís to verify basic goodness, like

SAMPLE_BUFFERS
SAMPLE_COVERAGE
SAMPLE_COVERAGE_VALUE
SAMPLE_MASK
SAMPLE_MASK_VALUE
SAMPLES
SAMPLE_POSITION

and what have you.

I'm using textures for depth too so dunno first hand what works and doesn't work renderbuffer-wise on current os/hw/driver combos so ymmv.

Ilian Dinev
01-18-2010, 02:47 AM
This is for 3.2 :


ILFBO ilCreateFBO_MSAA(int wid,int hei,int NumTextures,IL_TEX_FORMAT* formats,IL_TEX_FORMAT depthFormat,int NumSamples){
if(NumSamples<=1)return ilCreateFBO(wid,hei,NumTextures,formats,depthForma t);

ILFBO f = new ILI_FBO;
f->wid = wid;
f->hei = hei;
f->NumTextures = NumTextures;
for(int i=0;i<8;i++)f->Textures[i]=0;
f->DepthTex = 0;
f->glFBO = 0;
f->msaaType = ILMSAA_MSAA;


bool IsComplete = false;

glGenFramebuffers(1, &amp;f->glFBO);
glBindFramebuffer(GL_FRAMEBUFFER, f->glFBO);

for(int i=0;i<NumTextures;i++){
f->Textures[i] = ilCreateMSAATexture2D(wid,hei,formats[i],NumSamples);
f->IsTexExtern[i]=false;
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+i, f->Textures[i]->glTexHandle, 0);
}

f->DepthTex = ilCreateMSAATexture2D(wid,hei,depthFormat,NumSampl es);
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, f->DepthTex->glTexHandle, 0);



GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if(status == GL_FRAMEBUFFER_COMPLETE) {
IsComplete = true;
}else{
printh(status);
}
glBindFramebuffer(GL_FRAMEBUFFER,0);
_RegisterObject(f,(DELPROC)ilDeleteFBO);

if(!IsComplete){
prints("Incomplete MSAA FBO");
ilDeleteFBO(f); ilGetError(); return 0;
}
return f;

}

/*


ILFBO ilCreateFBO_CSAA(int wid,int hei,IL_TEX_FORMAT format,int NumCoverageSamples,int NumColorSamples){
if(NumCoverageSamples==0 || NumColorSamples==0){
return ilCreateFBO(wid,hei,format,1,ILTEXFMT_DEPTH24);
}
if(!glRenderbufferStorageMultisampleCoverageNV)ret urn 0;
ILFBO prevFBO = gil_CurRenderTarget; gil_CurRenderTarget=0;
ILFBO f = new ILI_FBO;
f->wid = wid;
f->hei = hei;
f->NumTextures = 1;
f->IsTexExtern[0]=false;
f->DepthTex = 0;
f->msaaType = ILMSAA_CSAA;
f->glFBO = 0;
f->glNativeDepth=0;

bool IsComplete = false;


//=============[ create multisampled FBO ]=======================================[
// Create a multisampled color buffer.
GLuint msaa_color;
GLuint msaa_depth;
GLuint msaa_fbo;
glGenFramebuffers(1, &amp;msaa_fbo);
glBindFramebuffer(GL_FRAMEBUFFER, msaa_fbo);

glGenRenderbuffers(1, &amp;msaa_color);
glBindRenderbuffer(GL_RENDERBUFFER, msaa_color);
glRenderbufferStorageMultisampleCoverageNV(GL_REND ERBUFFER,NumCoverageSamples,NumColorSamples,TEX_FO RMATS[format].iformat, wid, hei);
//int query;
//glGetRenderbufferParameteriv( GL_RENDERBUFFER, GL_RENDERBUFFER_COVERAGE_SAMPLES_NV, &amp;query); print(query);
//glGetRenderbufferParameteriv( GL_RENDERBUFFER, GL_RENDERBUFFER_COLOR_SAMPLES_NV, &amp;query); print(query);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,GL_RENDERBUFFER, msaa_color);


// Create a multisampled depth buffer
glGenRenderbuffers(1, &amp;msaa_depth);
glBindRenderbuffer(GL_RENDERBUFFER, msaa_depth);
glRenderbufferStorageMultisampleCoverageNV(GL_REND ERBUFFER,NumCoverageSamples,NumColorSamples,GL_DEP TH_COMPONENT24,wid,hei);
//glGetRenderbufferParameteriv( GL_RENDERBUFFER, GL_RENDERBUFFER_COVERAGE_SAMPLES_NV, &amp;query); print(query);
//glGetRenderbufferParameteriv( GL_RENDERBUFFER, GL_RENDERBUFFER_COLOR_SAMPLES_NV, &amp;query); print(query);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,GL_RENDERBUFFER, msaa_depth);

f->gl_msaaColor[0] = msaa_color;
f->gl_msaaDepth = msaa_depth;
f->gl_msaaFBO = msaa_fbo;

if(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE) {
IsComplete = true; // gets complete only if the two FBOs are complete
}
//================================================== =============================/

//===========[ create singlesampled FBO ]==================================[
// Create an fbo for blitting the multisampled fbo to a texture.
f->Textures[0] = ilCreateTexture2D(wid,hei,format); ilUploadTex2D_LOD(f->Textures[0],0,0);
f->IsTexExtern[0]=false;
f->DepthTex = ilCreateTexture2D(wid,hei,ILTEXFMT_DEPTH24);ilUplo adTex2D_LOD(f->DepthTex,0,0);


GLuint fbo;
glGenFramebuffers(1, &amp;fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
f->glFBO = fbo;

// Draw into the texture.
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D, f->Textures[0]->glTexHandle, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
GL_TEXTURE_2D, f->DepthTex->glTexHandle, 0);
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE) {
IsComplete &amp;= true;
}
//================================================== =======================/




ilSetRenderTarget(prevFBO);
_RegisterObject(f,(DELPROC)ilDeleteFBO);

if(!IsComplete){ilDeleteFBO(f); ilGetError(); return 0;}
return f;
}
*/



The CSAA version has not been updated, I'm yet to experiment on it. (on somehow using it for custom-HDR AA resolve via texture2DMS or renderBufferMS)


Ah, the ilCreateMSAATexture2D() basically only calls:


glGenTextures( 1, &amp;glTexHandle);
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE,glTexHandl e);
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, NumSamples, TEX_FORMATS[format].iformat, wid, hei, false);

rexguo
01-18-2010, 04:03 AM
Hey thanks guys!

Now I know the part I missed was this:
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, NumSamples, TEX_FORMATS[format].iformat, wid, hei, false);

I kept feeding my FBO code with the texture object
from my texture class, which was using glTexImage2D
all along and it completely slipped my mind.

Many thanks again!

rexguo
01-18-2010, 05:52 AM
BTW, what is the advantage of glTexImage2DMultisample
over MSAA renderbuffers? Can you bind and render MSAA
textures directly? Or is it used for custom resolves?

Alfonse Reinheart
01-18-2010, 10:31 AM
BTW, what is the advantage of glTexImage2DMultisample
over MSAA renderbuffers?

Renderbuffers can only be used as render targets. Textures can be used as both render targets and textures.

Pierre Boudier
01-18-2010, 10:40 AM
if you are never going to use a surface as a texture, we recommend that you use render buffer. this allows the implementation to make better optimizations for those surfaces (compression or hiz for depth, compression for msaa surface)