CoglHandle _cogl_texture_2d_new_with_size (unsigned int width, unsigned int height, CoglTextureFlags flags, CoglPixelFormat internal_format) { CoglTexture2D *tex_2d; GLenum gl_intformat; GLenum gl_format; GLenum gl_type; /* Since no data, we need some internal format */ if (internal_format == COGL_PIXEL_FORMAT_ANY) internal_format = COGL_PIXEL_FORMAT_RGBA_8888_PRE; if (!_cogl_texture_2d_can_create (width, height, internal_format)) return COGL_INVALID_HANDLE; internal_format = _cogl_pixel_format_to_gl (internal_format, &gl_intformat, &gl_format, &gl_type); tex_2d = _cogl_texture_2d_create_base (width, height, flags, internal_format); _cogl_texture_driver_gen (GL_TEXTURE_2D, 1, &tex_2d->gl_texture); GE( glBindTexture (GL_TEXTURE_2D, tex_2d->gl_texture) ); GE( glTexImage2D (GL_TEXTURE_2D, 0, gl_intformat, width, height, 0, gl_format, gl_type, NULL) ); return _cogl_texture_2d_handle_new (tex_2d); }
static gboolean _cogl_texture_2d_can_create (unsigned int width, unsigned int height, CoglPixelFormat internal_format) { GLenum gl_intformat; GLenum gl_type; /* If the driver doesn't support glGenerateMipmap then we need to store a copy of the first pixels to cause an update. Instead of duplicating the code here we'll just make it fallback to CoglTexture2DSliced */ if (!cogl_features_available (COGL_FEATURE_OFFSCREEN)) return FALSE; /* If NPOT textures aren't supported then the size must be a power of two */ if (!cogl_features_available (COGL_FEATURE_TEXTURE_NPOT) && (!_cogl_texture_2d_is_pot (width) || !_cogl_texture_2d_is_pot (height))) return FALSE; _cogl_pixel_format_to_gl (internal_format, &gl_intformat, NULL, &gl_type); /* Check that the driver can create a texture with that size */ if (!_cogl_texture_driver_size_supported (GL_TEXTURE_2D, gl_intformat, gl_type, width, height)) return FALSE; return TRUE; }
CoglBitmap * _cogl_texture_prepare_for_upload (CoglBitmap *src_bmp, CoglPixelFormat dst_format, CoglPixelFormat *dst_format_out, GLenum *out_glintformat, GLenum *out_glformat, GLenum *out_gltype) { CoglPixelFormat src_format = _cogl_bitmap_get_format (src_bmp); CoglBitmap *dst_bmp; dst_format = _cogl_texture_determine_internal_format (src_format, dst_format); /* OpenGL supports specifying a different format for the internal format when uploading texture data. We should use this to convert formats because it is likely to be faster and support more types than the Cogl bitmap code. However under GLES the internal format must be the same as the bitmap format and it only supports a limited number of formats so we must convert using the Cogl bitmap code instead */ #ifdef HAVE_COGL_GL /* If the source format does not have the same premult flag as the dst format then we need to copy and convert it */ if (_cogl_texture_needs_premult_conversion (src_format, dst_format)) { dst_bmp = _cogl_bitmap_copy (src_bmp); if (!_cogl_bitmap_convert_premult_status (dst_bmp, src_format ^ COGL_PREMULT_BIT)) { cogl_object_unref (dst_bmp); return NULL; } } else dst_bmp = cogl_object_ref (src_bmp); /* Use the source format from the src bitmap type and the internal format from the dst format type so that GL can do the conversion */ _cogl_pixel_format_to_gl (src_format, NULL, /* internal format */ out_glformat, out_gltype); _cogl_pixel_format_to_gl (dst_format, out_glintformat, NULL, NULL); #else /* HAVE_COGL_GL */ { CoglPixelFormat closest_format; closest_format = _cogl_pixel_format_to_gl (dst_format, out_glintformat, out_glformat, out_gltype); if (closest_format != src_format) dst_bmp = _cogl_bitmap_convert_format_and_premult (src_bmp, closest_format); else dst_bmp = cogl_object_ref (src_bmp); } #endif /* HAVE_COGL_GL */ if (dst_format_out) *dst_format_out = dst_format; return dst_bmp; }