Renderbuffer::Obj::Obj( int aWidth, int aHeight, GLenum internalFormat, int msaaSamples, int coverageSamples ) : mWidth( aWidth ), mHeight( aHeight ), mInternalFormat( internalFormat ), mSamples( msaaSamples ), mCoverageSamples( coverageSamples ) { #if defined( CINDER_MSW ) static bool csaaSupported = ( GLEE_NV_framebuffer_multisample_coverage != 0 ); #else static bool csaaSupported = false; #endif GL_SUFFIX(glGenRenderbuffers)( 1, &mId ); if( mSamples > Fbo::getMaxSamples() ) mSamples = Fbo::getMaxSamples(); if( ! csaaSupported ) mCoverageSamples = 0; GL_SUFFIX(glBindRenderbuffer)( GL_SUFFIX(GL_RENDERBUFFER_), mId ); #if ! defined( CINDER_GLES ) #if defined( CINDER_MSW ) if( mCoverageSamples ) // create a CSAA buffer glRenderbufferStorageMultisampleCoverageNV( GL_RENDERBUFFER_EXT, mCoverageSamples, mSamples, mInternalFormat, mWidth, mHeight ); else #endif if( mSamples ) // create a regular MSAA buffer glRenderbufferStorageMultisampleEXT( GL_RENDERBUFFER_EXT, mSamples, mInternalFormat, mWidth, mHeight ); else #endif GL_SUFFIX(glRenderbufferStorage)( GL_SUFFIX(GL_RENDERBUFFER_), mInternalFormat, mWidth, mHeight ); }
bool CFrameBufferObject::createCSAA( GLuint width, GLuint height, fboConfig *p_config, fboData *p_data ) { GLint query; bool ret = false; // Step #1 { glGenRenderbuffersEXT( 1, &p_data->depthRB); glGenRenderbuffersEXT( 1, &p_data->colorRB); glGenFramebuffersEXT( 1, &p_data->resolveFB); p_data->depthTex = 0; //no resolve of depth buffer for now //multisample, so we need to resolve from the FBO, bind the texture to the resolve FBO glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, p_data->resolveFB); glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, m_eGLTarget, p_data->colorTex, 0); ret &= checkStatus(__FILE__, __LINE__, true); //now handle the rendering FBO glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, p_data->fb); // initialize color renderbuffer glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, p_data->colorRB); } // Step #2 { glRenderbufferStorageMultisampleCoverageNV( GL_RENDERBUFFER_EXT, p_config->coverageSamples, p_config->depthSamples, p_config->colorFormat, width, height); glGetRenderbufferParameterivEXT( GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_COVERAGE_SAMPLES_NV, &query); if ( query < p_config->coverageSamples) { ret = false; } else if ( query > p_config->coverageSamples) { // report back the actual number p_config->coverageSamples = query; } glGetRenderbufferParameterivEXT( GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_COLOR_SAMPLES_NV, &query); if ( query < p_config->depthSamples) { ret = false; } else if ( query > p_config->depthSamples) { // report back the actual number p_config->depthSamples = query; } } // Step #3 { // attach the multisampled color buffer glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, p_data->colorRB); ret &= checkStatus(__FILE__, __LINE__, true); // bind the multisampled depth buffer glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, p_data->depthRB); } // Step #4 create the multisampled depth buffer (with coverage sampling) { // create a coverage sampled MSAA depth buffer glRenderbufferStorageMultisampleCoverageNV( GL_RENDERBUFFER_EXT, p_config->coverageSamples, p_config->depthSamples, p_config->depthFormat, width, height); // check the number of coverage samples glGetRenderbufferParameterivEXT( GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_COVERAGE_SAMPLES_NV, &query); if ( query < p_config->coverageSamples) { ret = false; } else if ( query > p_config->coverageSamples) { // set the coverage samples value to return the actual value p_config->coverageSamples = query; } // cehck the number of stored color samples (same as depth samples) glGetRenderbufferParameterivEXT( GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_COLOR_SAMPLES_NV, &query); if ( query < p_config->depthSamples) { ret = false; } else if ( query > p_config->depthSamples) { // set the depth samples value to return the actual value p_config->depthSamples = query; } } return ret; }
FramebufferManager::FramebufferManager(int targetWidth, int targetHeight, int msaaSamples, int msaaCoverageSamples) { m_efbFramebuffer = 0; m_efbColor = 0; m_efbDepth = 0; m_resolvedFramebuffer = 0; m_resolvedColorTexture = 0; m_resolvedDepthTexture = 0; m_xfbFramebuffer = 0; m_targetWidth = targetWidth; m_targetHeight = targetHeight; m_msaaSamples = msaaSamples; m_msaaCoverageSamples = msaaCoverageSamples; // The EFB can be set to different pixel formats by the game through the // BPMEM_ZCOMPARE register (which should probably have a different name). // They are: // - 24-bit RGB (8-bit components) with 24-bit Z // - 24-bit RGBA (6-bit components) with 24-bit Z // - Multisampled 16-bit RGB (5-6-5 format) with 16-bit Z // We only use one EFB format here: 32-bit ARGB with 24-bit Z. // Multisampling depends on user settings. // The distinction becomes important for certain operations, i.e. the // alpha channel should be ignored if the EFB does not have one. // Create EFB target. glGenFramebuffersEXT(1, &m_efbFramebuffer); if (m_msaaSamples <= 1) { // EFB targets will be textures in non-MSAA mode. GLuint glObj[2]; glGenTextures(2, glObj); m_efbColor = glObj[0]; m_efbDepth = glObj[1]; glBindTexture(GL_TEXTURE_RECTANGLE_ARB, m_efbColor); glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, m_targetWidth, m_targetHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, m_efbDepth); glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_DEPTH_COMPONENT24, m_targetWidth, m_targetHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0); // Bind target textures to the EFB framebuffer. glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_efbFramebuffer); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, m_efbColor, 0); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_RECTANGLE_ARB, m_efbDepth, 0); GL_REPORT_FBO_ERROR(); } else { // EFB targets will be renderbuffers in MSAA mode (required by OpenGL). // Resolve targets will be created to transfer EFB to RAM textures. // XFB framebuffer will be created to transfer EFB to XFB texture. // Create EFB target renderbuffers. GLuint glObj[2]; glGenRenderbuffersEXT(2, glObj); m_efbColor = glObj[0]; m_efbDepth = glObj[1]; glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_efbColor); if (m_msaaCoverageSamples) glRenderbufferStorageMultisampleCoverageNV(GL_RENDERBUFFER_EXT, m_msaaCoverageSamples, m_msaaSamples, GL_RGBA8, m_targetWidth, m_targetHeight); else glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, m_msaaSamples, GL_RGBA8, m_targetWidth, m_targetHeight); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_efbDepth); if (m_msaaCoverageSamples) glRenderbufferStorageMultisampleCoverageNV(GL_RENDERBUFFER_EXT, m_msaaCoverageSamples, m_msaaSamples, GL_DEPTH_COMPONENT24, m_targetWidth, m_targetHeight); else glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, m_msaaSamples, GL_DEPTH_COMPONENT24, m_targetWidth, m_targetHeight); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); // Bind target renderbuffers to EFB framebuffer. glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_efbFramebuffer); glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, m_efbColor); glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_efbDepth); GL_REPORT_FBO_ERROR(); // Create resolved targets for transferring multisampled EFB to texture. glGenFramebuffersEXT(1, &m_resolvedFramebuffer); glGenTextures(2, glObj); m_resolvedColorTexture = glObj[0]; m_resolvedDepthTexture = glObj[1]; glBindTexture(GL_TEXTURE_RECTANGLE_ARB, m_resolvedColorTexture); glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, m_targetWidth, m_targetHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, m_resolvedDepthTexture); glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_DEPTH_COMPONENT24, m_targetWidth, m_targetHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0); // Bind resolved textures to resolved framebuffer. glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_resolvedFramebuffer); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, m_resolvedColorTexture, 0); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_RECTANGLE_ARB, m_resolvedDepthTexture, 0); GL_REPORT_FBO_ERROR(); // Return to EFB framebuffer. glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_efbFramebuffer); } // Create XFB framebuffer; targets will be created elsewhere. glGenFramebuffersEXT(1, &m_xfbFramebuffer); // EFB framebuffer is currently bound, make sure to clear its alpha value to 1.f glViewport(0, 0, m_targetWidth, m_targetHeight); glScissor(0, 0, m_targetWidth, m_targetHeight); glClearColor(0.f, 0.f, 0.f, 1.f); glClearDepth(1.0); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); }
void Renderbuffer::resizeCSAA() { glRenderbufferStorageMultisampleCoverageNV( GL_RENDERBUFFER_EXT, m_coverageSamples, m_colorSamples, m_internalFormat, m_width, m_height ); }
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_NVFramebufferMultisampleCoverage_nglRenderbufferStorageMultisampleCoverageNV(JNIEnv *env, jclass clazz, jint target, jint coverageSamples, jint colorSamples, jint internalformat, jint width, jint height, jlong function_pointer) { glRenderbufferStorageMultisampleCoverageNVPROC glRenderbufferStorageMultisampleCoverageNV = (glRenderbufferStorageMultisampleCoverageNVPROC)((intptr_t)function_pointer); glRenderbufferStorageMultisampleCoverageNV(target, coverageSamples, colorSamples, internalformat, width, height); }
rtt::fbo* rtt::add_buffer(const unsigned int width_, const unsigned int height_, const GLenum* target, const TEXTURE_FILTERING* filtering, const TEXTURE_ANTI_ALIASING* taa, const GLint* wrap_s, const GLint* wrap_t, const GLint* internal_format, const GLenum* format, const GLenum* type, const unsigned int attachment_count, const rtt::DEPTH_TYPE depth_type, const rtt::STENCIL_TYPE stencil_type) { unsigned int width = width_; unsigned int height = height_; rtt::fbo* buffer = new rtt::fbo(attachment_count); buffers.push_back(buffer); buffer->width = width; buffer->height = height; buffer->draw_width = width; buffer->draw_height = height; buffer->depth_type = depth_type; buffer->stencil_type = stencil_type; buffer->samples = 0; // const size_t max_tex_size = exts->get_max_texture_size(); const float fmax_tex_size = max_tex_size; size2 orig_resolution = size2(width, height); float ssaa = 0.0f; for(unsigned int i = 0; i < buffer->attachment_count; i++) { buffer->anti_aliasing[i] = taa[i]; float ssaa_factor = get_anti_aliasing_scale(buffer->anti_aliasing[i]); if(ssaa_factor <= 1.0f) continue; // // try lower ssaa setting float cur_ssaa_factor = ssaa_factor; while(cur_ssaa_factor >= 2.0f) { if(float(orig_resolution.x) * ssaa_factor > fmax_tex_size || float(orig_resolution.y) * ssaa_factor > fmax_tex_size) { cur_ssaa_factor -= 2.0f; continue; } else break; } if(cur_ssaa_factor <= 0.0f) { log_error("couldn't create a SSAA%u buffer (nor using a smaller SSAA setting)!", ssaa_factor); break; // break, since this won't work with any setting } if(cur_ssaa_factor < ssaa_factor) { log_error("couldn't create a SSAA%u buffer - using SSAA%u instead!", ssaa_factor, cur_ssaa_factor); } ssaa = std::max(ssaa, cur_ssaa_factor); } // apply ssaa if(ssaa > 0.0f) { const float2 ssaa_res = get_resolution_for_scale(ssaa, size2(width, height)); width = (unsigned int)ssaa_res.x; height = (unsigned int)ssaa_res.y; buffer->width = width; buffer->height = height; buffer->draw_width = width; buffer->draw_height = height; } // glGenFramebuffers(1, &buffer->fbo_id); glBindFramebuffer(GL_FRAMEBUFFER, buffer->fbo_id); glGenTextures((GLsizei)attachment_count, &buffer->tex[0]); for(unsigned int i = 0; i < buffer->attachment_count; i++) { #if defined(FLOOR_IOS) && !defined(PLATFORM_X64) if(i > 0) { log_error("too many FBO attachments - only one is allowed on iOS!"); break; } #endif buffer->target[i] = target[i]; glBindTexture(buffer->target[i], buffer->tex[i]); glTexParameteri(buffer->target[i], GL_TEXTURE_MAG_FILTER, (filtering[i] == TEXTURE_FILTERING::POINT ? GL_NEAREST : GL_LINEAR)); glTexParameteri(buffer->target[i], GL_TEXTURE_MIN_FILTER, texman::select_filter(filtering[i])); glTexParameteri(buffer->target[i], GL_TEXTURE_WRAP_S, wrap_s[i]); glTexParameteri(buffer->target[i], GL_TEXTURE_WRAP_T, wrap_t[i]); if(exts->is_anisotropic_filtering_support() && filtering[i] >= TEXTURE_FILTERING::BILINEAR) { glTexParameteri(buffer->target[i], GL_TEXTURE_MAX_ANISOTROPY_EXT, (GLint)exts->get_max_anisotropic_filtering()); } switch(buffer->target[i]) { #if !defined(FLOOR_IOS) case GL_TEXTURE_1D: glTexImage1D(buffer->target[i], 0, texman::convert_internal_format(internal_format[i]), (GLsizei)width, 0, format[i], type[i], nullptr); break; #endif case GL_TEXTURE_2D: glTexImage2D(buffer->target[i], 0, texman::convert_internal_format(internal_format[i]), (GLsizei)width, (GLsizei)height, 0, format[i], type[i], nullptr); break; #if !defined(FLOOR_IOS) case GL_TEXTURE_2D_MULTISAMPLE: glTexImage2DMultisample(buffer->target[i], (GLsizei)get_sample_count(buffer->anti_aliasing[0]), texman::convert_internal_format(internal_format[i]), (GLsizei)width, (GLsizei)height, false); break; #endif default: glTexImage2D(buffer->target[i], 0, texman::convert_internal_format(internal_format[i]), (GLsizei)width, (GLsizei)height, 0, format[i], type[i], nullptr); break; } if(filtering[i] > TEXTURE_FILTERING::LINEAR) { buffer->auto_mipmap[i] = true; //glGenerateMipmap(buffer->target[i]); } else buffer->auto_mipmap[i] = false; glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+i, buffer->target[i], buffer->tex[i], 0); #if !defined(FLOOR_IOS) #if defined(A2E_DEBUG) // TODO: fbo/texture checking GLint check_internal_format = 0, check_type = 0, check_size = 0; glGetTexLevelParameteriv(buffer->target[i], 0, GL_TEXTURE_INTERNAL_FORMAT, &check_internal_format); glGetTexLevelParameteriv(buffer->target[i], 0, GL_TEXTURE_RED_TYPE, &check_type); glGetTexLevelParameteriv(buffer->target[i], 0, GL_TEXTURE_RED_SIZE, &check_size); //log_debug("FBO: iformat: %X, type: %X, size: %d", check_internal_format, check_type, check_size); #endif #endif } current_buffer = buffer; check_fbo(current_buffer); // check if a depth attachment should be created if(depth_type != DEPTH_TYPE::NONE) { // apparently opencl/opengl depth texture sharing only works with a float format #if !defined(A2E_INFERRED_RENDERING_CL) GLenum depth_internel_format = GL_DEPTH_COMPONENT24; GLenum depth_storage_type = GL_UNSIGNED_INT; #else GLenum depth_internel_format = GL_DEPTH_COMPONENT32F; GLenum depth_storage_type = GL_FLOAT; #endif GLenum depth_format = GL_DEPTH_COMPONENT; GLenum depth_attachment_type = GL_DEPTH_ATTACHMENT; if(stencil_type == STENCIL_TYPE::STENCIL_8) { #if !defined(A2E_INFERRED_RENDERING_CL) depth_internel_format = GL_DEPTH24_STENCIL8; depth_storage_type = GL_UNSIGNED_INT_24_8; #else depth_internel_format = GL_DEPTH32F_STENCIL8; depth_storage_type = GL_FLOAT_32_UNSIGNED_INT_24_8_REV; #endif depth_format = GL_DEPTH_STENCIL; depth_attachment_type = GL_DEPTH_STENCIL_ATTACHMENT; } buffer->depth_attachment_type = depth_attachment_type; switch(buffer->anti_aliasing[0]) { case TEXTURE_ANTI_ALIASING::NONE: case TEXTURE_ANTI_ALIASING::SSAA_2: case TEXTURE_ANTI_ALIASING::SSAA_4: case TEXTURE_ANTI_ALIASING::FXAA: case TEXTURE_ANTI_ALIASING::SSAA_4_3_FXAA: case TEXTURE_ANTI_ALIASING::SSAA_2_FXAA: if(depth_type == DEPTH_TYPE::RENDERBUFFER) { glGenRenderbuffers(1, &buffer->depth_buffer); glBindRenderbuffer(GL_RENDERBUFFER, buffer->depth_buffer); glRenderbufferStorage(GL_RENDERBUFFER, depth_internel_format, (GLsizei)width, (GLsizei)height); } else if(depth_type == DEPTH_TYPE::TEXTURE_2D) { glGenTextures(1, &buffer->depth_buffer); glBindTexture(GL_TEXTURE_2D, buffer->depth_buffer); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_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); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE); glTexImage2D(GL_TEXTURE_2D, 0, texman::convert_internal_format((GLint)depth_internel_format), (GLsizei)width, (GLsizei)height, 0, depth_format, depth_storage_type, nullptr); glFramebufferTexture2D(GL_FRAMEBUFFER, depth_attachment_type, GL_TEXTURE_2D, buffer->depth_buffer, 0); } check_fbo(current_buffer); break; case TEXTURE_ANTI_ALIASING::MSAA_2: case TEXTURE_ANTI_ALIASING::MSAA_4: case TEXTURE_ANTI_ALIASING::MSAA_8: case TEXTURE_ANTI_ALIASING::MSAA_16: case TEXTURE_ANTI_ALIASING::MSAA_32: case TEXTURE_ANTI_ALIASING::MSAA_64: { buffer->samples = get_sample_count(buffer->anti_aliasing[0]); glGenFramebuffers((GLsizei)attachment_count, &buffer->resolve_buffer[0]); for(size_t i = 0; i < attachment_count; i++) { glBindFramebuffer(GL_FRAMEBUFFER, buffer->resolve_buffer[i]); glFramebufferTexture2D(GL_FRAMEBUFFER, (GLenum)(GL_COLOR_ATTACHMENT0+i), target[i], buffer->tex[i], 0); } check_fbo(current_buffer); glBindFramebuffer(GL_FRAMEBUFFER, buffer->fbo_id); glGenRenderbuffers(1, &buffer->color_buffer); glBindRenderbuffer(GL_RENDERBUFFER, buffer->color_buffer); glRenderbufferStorageMultisample(GL_RENDERBUFFER, (GLsizei)buffer->samples, (GLenum)internal_format[0], (GLsizei)buffer->width, (GLsizei)buffer->height); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, buffer->color_buffer); check_fbo(current_buffer); if(depth_type == DEPTH_TYPE::RENDERBUFFER) { glGenRenderbuffers(1, &buffer->depth_buffer); glBindRenderbuffer(GL_RENDERBUFFER, buffer->depth_buffer); glRenderbufferStorageMultisample(GL_RENDERBUFFER, (GLsizei)buffer->samples, depth_internel_format, (GLsizei)buffer->width, (GLsizei)buffer->height); glFramebufferRenderbuffer(GL_FRAMEBUFFER, depth_attachment_type, GL_RENDERBUFFER, buffer->depth_buffer); } #if !defined(FLOOR_IOS) else if(depth_type == DEPTH_TYPE::TEXTURE_2D) { glGenTextures(1, &buffer->depth_buffer); glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, buffer->depth_buffer); glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, (GLsizei)buffer->samples, texman::convert_internal_format((GLint)depth_internel_format), (GLsizei)width, (GLsizei)height, false); glFramebufferTexture2D(GL_FRAMEBUFFER, depth_attachment_type, GL_TEXTURE_2D_MULTISAMPLE, buffer->depth_buffer, 0); } #endif check_fbo(current_buffer); } break; #if !defined(FLOOR_IOS) && 0 // TODO: fix or remove this case TEXTURE_ANTI_ALIASING::CSAA_8: case TEXTURE_ANTI_ALIASING::CSAA_8Q: case TEXTURE_ANTI_ALIASING::CSAA_16: case TEXTURE_ANTI_ALIASING::CSAA_16Q: case TEXTURE_ANTI_ALIASING::CSAA_32: case TEXTURE_ANTI_ALIASING::CSAA_32Q: { int color_samples, coverage_samples; switch(buffer->anti_aliasing[0]) { case TEXTURE_ANTI_ALIASING::CSAA_8: color_samples = 4; coverage_samples = 8; break; case TEXTURE_ANTI_ALIASING::CSAA_8Q: color_samples = 8; coverage_samples = 8; break; case TEXTURE_ANTI_ALIASING::CSAA_16: color_samples = 4; coverage_samples = 16; break; case TEXTURE_ANTI_ALIASING::CSAA_16Q: color_samples = 8; coverage_samples = 16; break; case TEXTURE_ANTI_ALIASING::CSAA_32: // TODO: ratio? case TEXTURE_ANTI_ALIASING::CSAA_32Q: // TODO: ratio? default: color_samples = 4; coverage_samples = 8; break; } glGenRenderbuffers(1, &buffer->depth_buffer); glGenRenderbuffers(1, &buffer->color_buffer); glGenFramebuffers(1, &buffer->resolve_buffer[0]); glBindFramebuffer(GL_FRAMEBUFFER, buffer->resolve_buffer[0]); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, buffer->tex[0], 0); check_fbo(current_buffer); glBindFramebuffer(GL_FRAMEBUFFER, buffer->fbo_id); glBindRenderbuffer(GL_RENDERBUFFER, buffer->color_buffer); glRenderbufferStorageMultisampleCoverageNV(GL_RENDERBUFFER, coverage_samples, color_samples, (GLenum)internal_format[0], (GLsizei)buffer->width, (GLsizei)buffer->height); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, buffer->color_buffer); check_fbo(current_buffer); glBindRenderbuffer(GL_RENDERBUFFER, buffer->depth_buffer); glRenderbufferStorageMultisampleCoverageNV(GL_RENDERBUFFER, coverage_samples, color_samples, depth_internel_format, (GLsizei)buffer->width, (GLsizei)buffer->height); glFramebufferRenderbuffer(GL_FRAMEBUFFER, depth_attachment_type, GL_RENDERBUFFER, buffer->depth_buffer); check_fbo(current_buffer); } break; #else case TEXTURE_ANTI_ALIASING::CSAA_8: case TEXTURE_ANTI_ALIASING::CSAA_8Q: case TEXTURE_ANTI_ALIASING::CSAA_16: case TEXTURE_ANTI_ALIASING::CSAA_16Q: case TEXTURE_ANTI_ALIASING::CSAA_32: case TEXTURE_ANTI_ALIASING::CSAA_32Q: log_error("CSAA not supported right now"); break; #endif } } glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindRenderbuffer(GL_RENDERBUFFER, 0); return buffer; }