예제 #1
0
void Texture::init(const void *data, GLint dataFormat, const Format &format)
{
    m_impl->m_do_not_dispose = false;
    m_impl->m_datatype = format.m_datatype;
    
    if(!m_impl->m_texture_id)
    {
        glGenTextures(1, &m_impl->m_texture_id);
        glBindTexture(m_impl->m_target, m_impl->m_texture_id);
        glTexParameteri(m_impl->m_target, GL_TEXTURE_WRAP_S, format.m_wrap_s);
        glTexParameteri(m_impl->m_target, GL_TEXTURE_WRAP_T, format.m_wrap_t);
        glTexParameteri(m_impl->m_target, GL_TEXTURE_MIN_FILTER, format.m_min_filter);
        glTexParameteri(m_impl->m_target, GL_TEXTURE_MAG_FILTER, format.m_mag_filter);
    }
    else{ glBindTexture(m_impl->m_target, m_impl->m_texture_id); }
    
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    
//#if ! defined(KINSKI_GLES)
//    glPixelStorei(GL_UNPACK_ROW_LENGTH, unpackRowLength);
//#endif
    
    if(m_impl->m_target == GL_TEXTURE_2D)
    {
        glTexImage2D(m_impl->m_target, 0, m_impl->m_internal_format,
                     m_impl->m_width, m_impl->m_height, 0, dataFormat,
                     m_impl->m_datatype, data);
    }
#if !defined(KINSKI_GLES)
    else if (m_impl->m_target == GL_TEXTURE_3D ||
             m_impl->m_target == GL_TEXTURE_2D_ARRAY)
    {
        glTexImage3D(m_impl->m_target, 0, m_impl->m_internal_format, m_impl->m_width, m_impl->m_height,
                     m_impl->m_depth, 0, dataFormat, m_impl->m_datatype, data);
    }
#endif
    
#if ! defined(KINSKI_GLES)
    glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
#endif
    
    if(format.m_mipmapping){ glGenerateMipmap(m_impl->m_target); }
    
#ifndef KINSKI_GLES
    if(dataFormat != GL_RGB && dataFormat != GL_RGBA && dataFormat != GL_BGRA)
    {
        GLint swizzleMask[] = {(GLint)(dataFormat), (GLint)(dataFormat), (GLint)(dataFormat),
            GL_ONE};
        glTexParameteriv(m_impl->m_target, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);
    }
#endif
    
    KINSKI_CHECK_GL_ERRORS();
}
예제 #2
0
void Fbo::resolve_textures() const
{
    if(!m_impl->m_needs_resolve){ return; }

#if ! defined(KINSKI_GLES)
	// if this FBO is multisampled, resolve it, so it can be displayed
	if(m_impl->m_resolve_fbo_id)
    {
		//SaveFramebufferBinding saveFboBinding;

		glBindFramebuffer(GL_READ_FRAMEBUFFER, m_impl->m_id);
		glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_impl->m_resolve_fbo_id);
		
		for(size_t c = 0; c < m_impl->m_color_textures.size(); ++c)
        {
			glDrawBuffer(GL_COLOR_ATTACHMENT0 + c);
			glReadBuffer(GL_COLOR_ATTACHMENT0 + c);
			GLbitfield bitfield = GL_COLOR_BUFFER_BIT;
            
			if(m_impl->m_depth_texture && m_impl->m_depth_texture.id())
                bitfield |= GL_DEPTH_BUFFER_BIT;
            
			glBlitFramebuffer(0, 0, m_impl->m_width, m_impl->m_height, 0, 0, m_impl->m_width,
                              m_impl->m_height, bitfield, GL_NEAREST);
            KINSKI_CHECK_GL_ERRORS();
		}

		// restore the draw buffers to the default for the antialiased (non-resolve) framebuffer
		vector<GLenum> drawBuffers;
        
		for(size_t c = 0; c < m_impl->m_color_textures.size(); ++c)
			drawBuffers.push_back(GL_COLOR_ATTACHMENT0 + c);
        
		glBindFramebuffer(GL_FRAMEBUFFER, m_impl->m_id);
		glDrawBuffers(drawBuffers.size(), &drawBuffers[0]);
        KINSKI_CHECK_GL_ERRORS();
	}
#endif
	m_impl->m_needs_resolve = false;
}
예제 #3
0
    void Material::update_uniforms()
    {
        
#if !defined(KINSKI_GLES)
        if(!m_uniform_buffer){ m_uniform_buffer = gl::Buffer(GL_UNIFORM_BUFFER, GL_DYNAMIC_DRAW); }
        
        
        struct material_struct_std140
        {
            vec4 diffuse;
            vec4 ambient;
            vec4 specular;
            vec4 emission;
            vec4 point_vals;
            float shinyness;
            uint32_t pad[3];
        };
        
        if(m_dirty_uniform_buffer)
        {
            material_struct_std140 m;
            m.diffuse = m_diffuse;
            m.ambient = m_ambient;
            m.specular = m_specular;
            m.emission = m_emission;
            m.point_vals[0] = m_point_size;
            m.point_vals[1] = m_point_attenuation.constant;
            m.point_vals[2] = m_point_attenuation.linear;
            m.point_vals[3] = m_point_attenuation.quadratic;
            m.shinyness = m_shinyness;
            
            m_uniform_buffer.set_data(&m, sizeof(m));
            m_dirty_uniform_buffer = false;
        }
        glBindBufferBase(GL_UNIFORM_BUFFER, 0, m_uniform_buffer.id());
#else
        if(m_dirty_uniform_buffer)
        {
            m_uniforms["u_material.diffuse"] = m_diffuse;
            m_uniforms["u_material.ambient"] = m_ambient;
            m_uniforms["u_material.specular"] = m_specular;
            m_uniforms["u_material.emmission"] = m_emission;
            m_uniforms["u_material.shinyness"] = m_shinyness;
            m_uniforms["u_material.point_vals"] = vec4(m_point_size,
                                                       m_point_attenuation.constant,
                                                       m_point_attenuation.linear,
                                                       m_point_attenuation.quadratic);
            m_dirty_uniform_buffer = false;
        }
#endif
        
//        if(m_dirty_uniform_buffer)
        {
            // set all other uniform values
            for (auto it = uniforms().begin(); it != uniforms().end(); ++it)
            {
                boost::apply_visitor(InsertUniformVisitor(shader(), it->first), it->second);
                KINSKI_CHECK_GL_ERRORS();
            }
        }
    }
예제 #4
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;
}