Esempio n. 1
0
Texture create_texture_from_image(const ImagePtr& the_img, bool mipmap,
                                  bool compress, GLfloat anisotropic_filter_lvl)
{
    Texture ret;
    
    if(!the_img){ return ret; }
    GLenum format = 0, internal_format = 0;
    
    switch(the_img->bytes_per_pixel)
    {
#ifdef KINSKI_GLES
        case 1:
            internal_format = format = GL_LUMINANCE;
            break;
        case 2:
            internal_format = format = GL_LUMINANCE_ALPHA;
            break;
        case 3:
            internal_format = format = GL_RGB;
            // needs precompressed image and call to glCompressedTexImage2D
            //                internal_format = compress ? GL_ETC1_RGB8_OES : GL_RGB;
            break;
        case 4:
            internal_format = format = GL_RGBA;
        default:
            break;
#else
        case 1:
            format = GL_RED;
            internal_format = compress? GL_COMPRESSED_RED_RGTC1 : GL_RGBA;
            break;
        case 2:
            format = GL_RG;
            internal_format = compress? GL_COMPRESSED_RG_RGTC2 : GL_RGBA;
            break;
        case 3:
            format = GL_RGB;
            internal_format = compress? GL_COMPRESSED_RGB_S3TC_DXT1_EXT : GL_RGBA;
            break;
        case 4:
            format = GL_RGBA;
            internal_format = compress? GL_COMPRESSED_RGBA_S3TC_DXT5_EXT : GL_RGBA;
        default:
            break;
#endif
    }
    Texture::Format fmt;
    fmt.set_internal_format(internal_format);
    
    if(mipmap)
    {
        fmt.set_mipmapping();
        fmt.set_min_filter(GL_LINEAR_MIPMAP_NEAREST);
    }
    uint8_t *data = the_img->data;
    
#if !defined(KINSKI_GLES)
    gl::Buffer pixel_buf;
    pixel_buf.set_data(the_img->data, the_img->num_bytes());
    pixel_buf.bind(GL_PIXEL_UNPACK_BUFFER);
    data = nullptr;
#endif
    ret = Texture(data, format, the_img->width, the_img->height, fmt);
    ret.set_flipped();
    KINSKI_CHECK_GL_ERRORS();
    
    ret.set_anisotropic_filter(anisotropic_filter_lvl);
    return ret;
}
Esempio n. 2
0
void Fbo::init()
{
	bool useAA = m_impl->m_format.m_num_samples > 0;

	// allocate the framebuffer itself
	glGenFramebuffers(1, &m_impl->m_id);
    glBindFramebuffer(GL_FRAMEBUFFER, m_impl->m_id);

	Texture::Format textureFormat;
	textureFormat.set_target(target());
    auto col_fmt = format().color_internal_format();
	textureFormat.set_internal_format(col_fmt);
    
#if !defined(KINSKI_GLES)
    GLint float_types[] = {GL_R32F, GL_RG32F, GL_RGB32F, GL_RGBA32F};
    GLint one_comp_types[] = {GL_RED, GL_GREEN, GL_BLUE, GL_R32F};
    if(contains(float_types, col_fmt)){ textureFormat.set_data_type(GL_FLOAT); }
#endif
	textureFormat.set_wrap(m_impl->m_format.m_wrap_s, m_impl->m_format.m_wrap_t);
	textureFormat.set_min_filter(m_impl->m_format.m_min_filter);
	textureFormat.set_mag_filter(m_impl->m_format.m_mag_filter);
	textureFormat.set_mipmapping(format().has_mipmapping());

	// allocate the color buffers
	for(int c = 0; c < m_impl->m_format.m_num_color_buffers; ++c)
    {
        auto tex = Texture(m_impl->m_width, m_impl->m_height, textureFormat);
        
#if !defined(KINSKI_GLES)
        if(contains(one_comp_types, col_fmt)){ tex.set_swizzle(GL_RED, GL_RED, GL_RED, GL_ONE); }
#endif
		m_impl->m_color_textures.push_back(tex);
	}
	
#if !defined(KINSKI_GLES)
	if(m_impl->m_format.m_num_color_buffers == 0)
    {
        // no color
		glDrawBuffer(GL_NONE);
		glReadBuffer(GL_NONE);
	}
#endif
    
    if(useAA){ useAA = init_multisample(); }
    
	if(!useAA)
    {
        // if we don't need any variety of multisampling or it failed to initialize
		// attach all the textures to the framebuffer
		vector<GLenum> drawBuffers;
		for(size_t c = 0; c < m_impl->m_color_textures.size(); ++c)
        {
			glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + c, target(),
                                   m_impl->m_color_textures[c].id(), 0);
			drawBuffers.push_back(GL_COLOR_ATTACHMENT0 + c);
		}
#if ! defined(KINSKI_GLES)
        if(!drawBuffers.empty()){ glDrawBuffers(drawBuffers.size(), &drawBuffers[0]); }
#endif

		// allocate and attach depth texture
		if(m_impl->m_format.m_depth_buffer)
        {
			if(m_impl->m_format.m_depth_buffer_texture)
            {
	#if ! defined(KINSKI_GLES)			
				GLuint depthTextureId;
				glGenTextures(1, &depthTextureId);
				glBindTexture(target(), depthTextureId);
				glTexImage2D(target(), 0, format().depth_internal_format(),
                             m_impl->m_width, m_impl->m_height, 0, GL_DEPTH_STENCIL,
                             GL_FLOAT_32_UNSIGNED_INT_24_8_REV, nullptr);
                
//                glTexImage2D(target(), 0, getFormat().getDepthInternalFormat(),
//                             m_impl->m_width, m_impl->m_height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr);
                
				glTexParameteri(target(), GL_TEXTURE_MIN_FILTER, m_impl->m_format.m_min_filter);
				glTexParameteri(target(), GL_TEXTURE_MAG_FILTER, m_impl->m_format.m_mag_filter);
				glTexParameteri(target(), GL_TEXTURE_WRAP_S, m_impl->m_format.m_wrap_s);
				glTexParameteri(target(), GL_TEXTURE_WRAP_T, m_impl->m_format.m_wrap_t);
				m_impl->m_depth_texture = Texture(target(), depthTextureId, m_impl->m_width,
                                                m_impl->m_height, false);
                
				glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, target(),
                                       m_impl->m_depth_texture.id(), 0);
                
                if(m_impl->m_format.has_stencil_buffer())
                {
                    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, target(),
                                           m_impl->m_depth_texture.id(), 0);
                }
	#endif
			}
            // implement depth buffer as RenderBuffer
			else if(m_impl->m_format.m_depth_buffer)
            {
				m_impl->m_depthRenderbuffer = Renderbuffer(m_impl->m_width, m_impl->m_height,
                                                          m_impl->m_format.depth_internal_format());
				glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
                                          m_impl->m_depthRenderbuffer.id());
                
                if(m_impl->m_format.has_stencil_buffer())
                {
                    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
                                              GL_RENDERBUFFER, m_impl->m_depthRenderbuffer.id());
                }
			}
		}

		FboExceptionInvalidSpecification exc;
        // failed creation; throw
		if(!check_status(&exc)) { throw exc; }
	}
	
	m_impl->m_needs_resolve = false;
	m_impl->m_needs_mipmap_update = false;
    
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
}