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(); }
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; }
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(); } } }
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; }