2010-06-10 10:33:34 -04:00
|
|
|
/*
|
|
|
|
* Cogl
|
|
|
|
*
|
|
|
|
* An object oriented GL/GLES Abstraction/Utility Layer
|
|
|
|
*
|
|
|
|
* Copyright (C) 2010 Intel Corporation.
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* Authors:
|
|
|
|
* Neil Roberts <neil@linux.intel.com>
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include "config.h"
|
|
|
|
#endif
|
|
|
|
|
2012-02-13 18:02:04 -05:00
|
|
|
#include "cogl-private.h"
|
2010-06-10 10:33:34 -04:00
|
|
|
#include "cogl-util.h"
|
|
|
|
#include "cogl-texture-private.h"
|
|
|
|
#include "cogl-texture-rectangle-private.h"
|
|
|
|
#include "cogl-texture-driver.h"
|
2010-11-04 18:25:52 -04:00
|
|
|
#include "cogl-context-private.h"
|
2010-06-10 10:33:34 -04:00
|
|
|
#include "cogl-handle.h"
|
|
|
|
#include "cogl-journal-private.h"
|
2010-10-27 13:54:57 -04:00
|
|
|
#include "cogl-pipeline-opengl-private.h"
|
2010-06-10 10:33:34 -04:00
|
|
|
|
|
|
|
#include <string.h>
|
|
|
|
#include <math.h>
|
|
|
|
|
|
|
|
/* These aren't defined under GLES */
|
|
|
|
#ifndef GL_TEXTURE_RECTANGLE_ARB
|
|
|
|
#define GL_TEXTURE_RECTANGLE_ARB 0x84F5
|
|
|
|
#endif
|
|
|
|
#ifndef GL_CLAMP
|
|
|
|
#define GL_CLAMP 0x2900
|
|
|
|
#endif
|
|
|
|
#ifndef GL_CLAMP_TO_BORDER
|
|
|
|
#define GL_CLAMP_TO_BORDER 0x812D
|
|
|
|
#endif
|
|
|
|
|
|
|
|
static void _cogl_texture_rectangle_free (CoglTextureRectangle *tex_rect);
|
|
|
|
|
2011-10-14 04:25:12 -04:00
|
|
|
COGL_TEXTURE_DEFINE (TextureRectangle, texture_rectangle);
|
2010-06-10 10:33:34 -04:00
|
|
|
|
|
|
|
static const CoglTextureVtable cogl_texture_rectangle_vtable;
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
can_use_wrap_mode (GLenum wrap_mode)
|
|
|
|
{
|
|
|
|
return (wrap_mode == GL_CLAMP ||
|
|
|
|
wrap_mode == GL_CLAMP_TO_EDGE ||
|
|
|
|
wrap_mode == GL_CLAMP_TO_BORDER);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_cogl_texture_rectangle_set_wrap_mode_parameters (CoglTexture *tex,
|
|
|
|
GLenum wrap_mode_s,
|
|
|
|
GLenum wrap_mode_t,
|
2010-07-12 12:01:32 -04:00
|
|
|
GLenum wrap_mode_p)
|
2010-06-10 10:33:34 -04:00
|
|
|
{
|
|
|
|
CoglTextureRectangle *tex_rect = COGL_TEXTURE_RECTANGLE (tex);
|
|
|
|
|
2011-07-06 16:51:00 -04:00
|
|
|
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
|
|
|
|
2010-06-10 10:33:34 -04:00
|
|
|
/* Only set the wrap mode if it's different from the current value
|
|
|
|
to avoid too many GL calls. Texture rectangle doesn't make use of
|
|
|
|
the r coordinate so we can ignore its wrap mode */
|
|
|
|
if (tex_rect->wrap_mode_s != wrap_mode_s ||
|
|
|
|
tex_rect->wrap_mode_t != wrap_mode_t)
|
|
|
|
{
|
|
|
|
g_assert (can_use_wrap_mode (wrap_mode_s));
|
|
|
|
g_assert (can_use_wrap_mode (wrap_mode_t));
|
|
|
|
|
2011-07-06 16:51:00 -04:00
|
|
|
_cogl_bind_gl_texture_transient (GL_TEXTURE_RECTANGLE_ARB,
|
|
|
|
tex_rect->gl_texture,
|
|
|
|
tex_rect->is_foreign);
|
|
|
|
GE( ctx, glTexParameteri (GL_TEXTURE_RECTANGLE_ARB,
|
|
|
|
GL_TEXTURE_WRAP_S, wrap_mode_s) );
|
|
|
|
GE( ctx, glTexParameteri (GL_TEXTURE_RECTANGLE_ARB,
|
|
|
|
GL_TEXTURE_WRAP_T, wrap_mode_t) );
|
2010-06-10 10:33:34 -04:00
|
|
|
|
|
|
|
tex_rect->wrap_mode_s = wrap_mode_s;
|
|
|
|
tex_rect->wrap_mode_t = wrap_mode_t;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_cogl_texture_rectangle_free (CoglTextureRectangle *tex_rect)
|
|
|
|
{
|
2010-10-04 10:27:38 -04:00
|
|
|
if (!tex_rect->is_foreign)
|
|
|
|
_cogl_delete_gl_texture (tex_rect->gl_texture);
|
2010-06-10 10:33:34 -04:00
|
|
|
|
|
|
|
/* Chain up */
|
|
|
|
_cogl_texture_free (COGL_TEXTURE (tex_rect));
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
_cogl_texture_rectangle_can_create (unsigned int width,
|
|
|
|
unsigned int height,
|
2011-10-14 04:25:12 -04:00
|
|
|
CoglPixelFormat internal_format,
|
|
|
|
GError **error)
|
2010-06-10 10:33:34 -04:00
|
|
|
{
|
|
|
|
GLenum gl_intformat;
|
|
|
|
GLenum gl_type;
|
|
|
|
|
2011-07-07 07:48:24 -04:00
|
|
|
_COGL_GET_CONTEXT (ctx, FALSE);
|
|
|
|
|
2011-10-12 17:31:12 -04:00
|
|
|
if (!cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_RECTANGLE))
|
2011-10-14 04:25:12 -04:00
|
|
|
{
|
|
|
|
g_set_error (error,
|
|
|
|
COGL_TEXTURE_ERROR,
|
|
|
|
COGL_TEXTURE_ERROR_TYPE,
|
|
|
|
"The CoglTextureRectangle feature isn't available");
|
|
|
|
return FALSE;
|
|
|
|
}
|
2010-06-10 10:33:34 -04:00
|
|
|
|
2012-03-22 12:32:56 -04:00
|
|
|
ctx->driver_vtable->pixel_format_to_gl (ctx,
|
|
|
|
internal_format,
|
|
|
|
&gl_intformat,
|
|
|
|
NULL,
|
|
|
|
&gl_type);
|
2010-06-10 10:33:34 -04:00
|
|
|
|
|
|
|
/* Check that the driver can create a texture with that size */
|
2012-03-22 13:04:47 -04:00
|
|
|
if (!ctx->texture_driver->size_supported (ctx,
|
|
|
|
GL_TEXTURE_RECTANGLE_ARB,
|
2010-06-10 10:33:34 -04:00
|
|
|
gl_intformat,
|
|
|
|
gl_type,
|
|
|
|
width,
|
|
|
|
height))
|
2011-10-14 04:25:12 -04:00
|
|
|
{
|
|
|
|
g_set_error (error,
|
|
|
|
COGL_TEXTURE_ERROR,
|
|
|
|
COGL_TEXTURE_ERROR_SIZE,
|
|
|
|
"The requested texture size + format is unsupported");
|
|
|
|
return FALSE;
|
|
|
|
}
|
2010-06-10 10:33:34 -04:00
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static CoglTextureRectangle *
|
|
|
|
_cogl_texture_rectangle_create_base (unsigned int width,
|
|
|
|
unsigned int height,
|
|
|
|
CoglPixelFormat internal_format)
|
|
|
|
{
|
|
|
|
CoglTextureRectangle *tex_rect = g_new (CoglTextureRectangle, 1);
|
|
|
|
CoglTexture *tex = COGL_TEXTURE (tex_rect);
|
|
|
|
|
2011-01-06 08:25:45 -05:00
|
|
|
_cogl_texture_init (tex, &cogl_texture_rectangle_vtable);
|
2010-06-10 10:33:34 -04:00
|
|
|
|
|
|
|
tex_rect->width = width;
|
|
|
|
tex_rect->height = height;
|
|
|
|
|
|
|
|
/* We default to GL_LINEAR for both filters */
|
|
|
|
tex_rect->min_filter = GL_LINEAR;
|
|
|
|
tex_rect->mag_filter = GL_LINEAR;
|
|
|
|
|
|
|
|
/* Wrap mode not yet set */
|
|
|
|
tex_rect->wrap_mode_s = GL_FALSE;
|
|
|
|
tex_rect->wrap_mode_t = GL_FALSE;
|
|
|
|
|
|
|
|
tex_rect->format = internal_format;
|
|
|
|
|
|
|
|
return tex_rect;
|
|
|
|
}
|
|
|
|
|
2011-10-14 04:25:12 -04:00
|
|
|
CoglTextureRectangle *
|
|
|
|
cogl_texture_rectangle_new_with_size (CoglContext *ctx,
|
|
|
|
int width,
|
|
|
|
int height,
|
|
|
|
CoglPixelFormat internal_format,
|
|
|
|
GError **error)
|
2010-06-10 10:33:34 -04:00
|
|
|
{
|
|
|
|
CoglTextureRectangle *tex_rect;
|
|
|
|
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;
|
|
|
|
|
2011-10-14 04:25:12 -04:00
|
|
|
if (!_cogl_texture_rectangle_can_create (width, height,
|
|
|
|
internal_format, error))
|
|
|
|
return NULL;
|
2010-06-10 10:33:34 -04:00
|
|
|
|
2012-03-22 12:32:56 -04:00
|
|
|
internal_format = ctx->driver_vtable->pixel_format_to_gl (ctx,
|
|
|
|
internal_format,
|
|
|
|
&gl_intformat,
|
|
|
|
&gl_format,
|
|
|
|
&gl_type);
|
2010-06-10 10:33:34 -04:00
|
|
|
|
2011-10-14 04:25:12 -04:00
|
|
|
tex_rect = _cogl_texture_rectangle_create_base (width, height,
|
2010-06-10 10:33:34 -04:00
|
|
|
internal_format);
|
|
|
|
|
2012-03-22 13:04:47 -04:00
|
|
|
ctx->texture_driver->gen (ctx,
|
|
|
|
GL_TEXTURE_RECTANGLE_ARB,
|
|
|
|
1, /* num textures */
|
|
|
|
&tex_rect->gl_texture);
|
2011-07-06 16:51:00 -04:00
|
|
|
_cogl_bind_gl_texture_transient (GL_TEXTURE_RECTANGLE_ARB,
|
|
|
|
tex_rect->gl_texture,
|
|
|
|
tex_rect->is_foreign);
|
|
|
|
GE( ctx, glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, gl_intformat,
|
|
|
|
width, height, 0, gl_format, gl_type, NULL) );
|
2010-06-10 10:33:34 -04:00
|
|
|
|
2011-10-14 04:25:12 -04:00
|
|
|
return _cogl_texture_rectangle_object_new (tex_rect);
|
2010-06-10 10:33:34 -04:00
|
|
|
}
|
|
|
|
|
2011-10-14 04:25:12 -04:00
|
|
|
CoglTextureRectangle *
|
2010-07-07 13:44:16 -04:00
|
|
|
_cogl_texture_rectangle_new_from_bitmap (CoglBitmap *bmp,
|
2010-06-10 10:33:34 -04:00
|
|
|
CoglTextureFlags flags,
|
|
|
|
CoglPixelFormat internal_format)
|
|
|
|
{
|
|
|
|
CoglTextureRectangle *tex_rect;
|
2010-07-07 13:44:16 -04:00
|
|
|
CoglBitmap *dst_bmp;
|
2010-06-10 10:33:34 -04:00
|
|
|
GLenum gl_intformat;
|
|
|
|
GLenum gl_format;
|
|
|
|
GLenum gl_type;
|
|
|
|
|
2011-10-14 04:25:12 -04:00
|
|
|
_COGL_GET_CONTEXT (ctx, NULL);
|
2011-07-07 07:48:24 -04:00
|
|
|
|
2011-10-14 04:25:12 -04:00
|
|
|
_COGL_RETURN_VAL_IF_FAIL (cogl_is_bitmap (bmp), NULL);
|
2010-06-10 10:33:34 -04:00
|
|
|
|
2010-07-07 13:44:16 -04:00
|
|
|
internal_format =
|
2012-02-25 15:18:05 -05:00
|
|
|
_cogl_texture_determine_internal_format (cogl_bitmap_get_format (bmp),
|
2010-07-07 13:44:16 -04:00
|
|
|
internal_format);
|
2010-06-10 10:33:34 -04:00
|
|
|
|
2012-02-25 15:18:05 -05:00
|
|
|
if (!_cogl_texture_rectangle_can_create (cogl_bitmap_get_width (bmp),
|
|
|
|
cogl_bitmap_get_height (bmp),
|
2011-10-14 04:25:12 -04:00
|
|
|
internal_format,
|
|
|
|
NULL))
|
|
|
|
return NULL;
|
2010-06-10 10:33:34 -04:00
|
|
|
|
2010-07-07 13:44:16 -04:00
|
|
|
dst_bmp = _cogl_texture_prepare_for_upload (bmp,
|
|
|
|
internal_format,
|
|
|
|
&internal_format,
|
|
|
|
&gl_intformat,
|
|
|
|
&gl_format,
|
|
|
|
&gl_type);
|
|
|
|
|
|
|
|
if (dst_bmp == NULL)
|
2011-10-14 04:25:12 -04:00
|
|
|
return NULL;
|
2010-06-10 10:33:34 -04:00
|
|
|
|
2012-02-25 15:18:05 -05:00
|
|
|
tex_rect = _cogl_texture_rectangle_create_base (cogl_bitmap_get_width (bmp),
|
|
|
|
cogl_bitmap_get_height (bmp),
|
2010-06-10 10:33:34 -04:00
|
|
|
internal_format);
|
|
|
|
|
2012-03-22 13:04:47 -04:00
|
|
|
ctx->texture_driver->gen (ctx,
|
|
|
|
GL_TEXTURE_RECTANGLE_ARB,
|
|
|
|
1, /* num textures */
|
|
|
|
&tex_rect->gl_texture);
|
|
|
|
ctx->texture_driver->upload_to_gl (ctx,
|
|
|
|
GL_TEXTURE_RECTANGLE_ARB,
|
2010-06-10 10:33:34 -04:00
|
|
|
tex_rect->gl_texture,
|
|
|
|
FALSE,
|
2010-07-07 13:44:16 -04:00
|
|
|
dst_bmp,
|
2010-06-10 10:33:34 -04:00
|
|
|
gl_intformat,
|
|
|
|
gl_format,
|
|
|
|
gl_type);
|
|
|
|
|
|
|
|
tex_rect->gl_format = gl_intformat;
|
|
|
|
|
2010-07-07 13:44:16 -04:00
|
|
|
cogl_object_unref (dst_bmp);
|
2010-06-10 10:33:34 -04:00
|
|
|
|
2011-10-14 04:25:12 -04:00
|
|
|
return _cogl_texture_rectangle_object_new (tex_rect);
|
2010-06-10 10:33:34 -04:00
|
|
|
}
|
|
|
|
|
2011-10-14 04:25:12 -04:00
|
|
|
CoglTextureRectangle *
|
2010-10-04 10:27:38 -04:00
|
|
|
_cogl_texture_rectangle_new_from_foreign (GLuint gl_handle,
|
|
|
|
GLuint width,
|
|
|
|
GLuint height,
|
|
|
|
CoglPixelFormat format)
|
|
|
|
{
|
|
|
|
/* NOTE: width, height and internal format are not queriable
|
|
|
|
* in GLES, hence such a function prototype.
|
|
|
|
*/
|
|
|
|
|
|
|
|
GLenum gl_error = 0;
|
|
|
|
GLint gl_compressed = GL_FALSE;
|
|
|
|
GLenum gl_int_format = 0;
|
|
|
|
CoglTextureRectangle *tex_rect;
|
|
|
|
|
2011-10-14 04:25:12 -04:00
|
|
|
_COGL_GET_CONTEXT (ctx, NULL);
|
2011-07-06 16:51:00 -04:00
|
|
|
|
2012-03-22 13:04:47 -04:00
|
|
|
if (!ctx->texture_driver->allows_foreign_gl_target (ctx,
|
|
|
|
GL_TEXTURE_RECTANGLE_ARB))
|
2011-10-14 04:25:12 -04:00
|
|
|
return NULL;
|
2010-10-04 10:27:38 -04:00
|
|
|
|
|
|
|
/* Make sure it is a valid GL texture object */
|
2011-07-06 16:51:00 -04:00
|
|
|
if (!ctx->glIsTexture (gl_handle))
|
2011-10-14 04:25:12 -04:00
|
|
|
return NULL;
|
2010-10-04 10:27:38 -04:00
|
|
|
|
|
|
|
/* Make sure binding succeeds */
|
2011-07-06 16:51:00 -04:00
|
|
|
while ((gl_error = ctx->glGetError ()) != GL_NO_ERROR)
|
2010-10-04 10:27:38 -04:00
|
|
|
;
|
|
|
|
|
|
|
|
_cogl_bind_gl_texture_transient (GL_TEXTURE_RECTANGLE_ARB, gl_handle, TRUE);
|
2011-07-06 16:51:00 -04:00
|
|
|
if (ctx->glGetError () != GL_NO_ERROR)
|
2011-10-14 04:25:12 -04:00
|
|
|
return NULL;
|
2010-10-04 10:27:38 -04:00
|
|
|
|
|
|
|
/* Obtain texture parameters */
|
|
|
|
|
|
|
|
#if HAVE_COGL_GL
|
2011-07-07 15:44:56 -04:00
|
|
|
if (ctx->driver == COGL_DRIVER_GL)
|
|
|
|
{
|
|
|
|
GLint val;
|
2010-10-04 10:27:38 -04:00
|
|
|
|
2011-07-07 15:44:56 -04:00
|
|
|
GE( ctx, glGetTexLevelParameteriv (GL_TEXTURE_RECTANGLE_ARB, 0,
|
|
|
|
GL_TEXTURE_COMPRESSED,
|
|
|
|
&gl_compressed) );
|
2010-10-04 10:27:38 -04:00
|
|
|
|
2011-07-07 15:44:56 -04:00
|
|
|
GE( ctx, glGetTexLevelParameteriv (GL_TEXTURE_RECTANGLE_ARB, 0,
|
|
|
|
GL_TEXTURE_INTERNAL_FORMAT,
|
|
|
|
&val) );
|
2010-10-04 10:27:38 -04:00
|
|
|
|
2011-07-07 15:44:56 -04:00
|
|
|
gl_int_format = val;
|
2010-10-04 10:27:38 -04:00
|
|
|
|
2011-07-07 15:44:56 -04:00
|
|
|
/* If we can query GL for the actual pixel format then we'll ignore
|
|
|
|
the passed in format and use that. */
|
2012-03-22 12:32:56 -04:00
|
|
|
if (!ctx->driver_vtable->pixel_format_from_gl_internal (ctx,
|
|
|
|
gl_int_format,
|
|
|
|
&format))
|
2011-10-14 04:25:12 -04:00
|
|
|
return NULL;
|
2011-07-07 15:44:56 -04:00
|
|
|
}
|
|
|
|
else
|
2010-10-04 10:27:38 -04:00
|
|
|
#endif
|
2011-07-07 15:44:56 -04:00
|
|
|
{
|
|
|
|
/* Otherwise we'll assume we can derive the GL format from the
|
|
|
|
passed in format */
|
2012-03-22 12:32:56 -04:00
|
|
|
ctx->driver_vtable->pixel_format_to_gl (ctx,
|
|
|
|
format,
|
|
|
|
&gl_int_format,
|
|
|
|
NULL,
|
|
|
|
NULL);
|
2011-07-07 15:44:56 -04:00
|
|
|
}
|
2010-10-04 10:27:38 -04:00
|
|
|
|
|
|
|
/* Note: We always trust the given width and height without querying
|
|
|
|
* the texture object because the user may be creating a Cogl
|
|
|
|
* texture for a texture_from_pixmap object where glTexImage2D may
|
|
|
|
* not have been called and the texture_from_pixmap spec doesn't
|
|
|
|
* clarify that it is reliable to query back the size from OpenGL.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* Validate width and height */
|
|
|
|
if (width <= 0 || height <= 0)
|
2011-10-14 04:25:12 -04:00
|
|
|
return NULL;
|
2010-10-04 10:27:38 -04:00
|
|
|
|
|
|
|
/* Compressed texture images not supported */
|
|
|
|
if (gl_compressed == GL_TRUE)
|
2011-10-14 04:25:12 -04:00
|
|
|
return NULL;
|
2010-10-04 10:27:38 -04:00
|
|
|
|
|
|
|
/* Create new texture */
|
2011-10-14 04:25:12 -04:00
|
|
|
tex_rect = _cogl_texture_rectangle_create_base (width, height, format);
|
2010-10-04 10:27:38 -04:00
|
|
|
|
|
|
|
/* Setup bitmap info */
|
|
|
|
tex_rect->is_foreign = TRUE;
|
|
|
|
|
|
|
|
tex_rect->format = format;
|
|
|
|
|
|
|
|
tex_rect->gl_texture = gl_handle;
|
|
|
|
tex_rect->gl_format = gl_int_format;
|
|
|
|
|
|
|
|
/* Unknown filter */
|
|
|
|
tex_rect->min_filter = GL_FALSE;
|
|
|
|
tex_rect->mag_filter = GL_FALSE;
|
|
|
|
|
|
|
|
return _cogl_texture_rectangle_handle_new (tex_rect);
|
|
|
|
}
|
|
|
|
|
2010-06-10 10:33:34 -04:00
|
|
|
static int
|
|
|
|
_cogl_texture_rectangle_get_max_waste (CoglTexture *tex)
|
|
|
|
{
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
_cogl_texture_rectangle_is_sliced (CoglTexture *tex)
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
_cogl_texture_rectangle_can_hardware_repeat (CoglTexture *tex)
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_cogl_texture_rectangle_transform_coords_to_gl (CoglTexture *tex,
|
|
|
|
float *s,
|
|
|
|
float *t)
|
|
|
|
{
|
|
|
|
CoglTextureRectangle *tex_rect = COGL_TEXTURE_RECTANGLE (tex);
|
|
|
|
|
|
|
|
*s *= tex_rect->width;
|
|
|
|
*t *= tex_rect->height;
|
|
|
|
}
|
|
|
|
|
|
|
|
static CoglTransformResult
|
|
|
|
_cogl_texture_rectangle_transform_quad_coords_to_gl (CoglTexture *tex,
|
|
|
|
float *coords)
|
|
|
|
{
|
|
|
|
CoglTextureRectangle *tex_rect = COGL_TEXTURE_RECTANGLE (tex);
|
|
|
|
gboolean need_repeat = FALSE;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < 4; i++)
|
|
|
|
{
|
|
|
|
if (coords[i] < 0.0f || coords[i] > 1.0f)
|
|
|
|
need_repeat = TRUE;
|
|
|
|
coords[i] *= (i & 1) ? tex_rect->height : tex_rect->width;
|
|
|
|
}
|
|
|
|
|
|
|
|
return (need_repeat ? COGL_TRANSFORM_SOFTWARE_REPEAT
|
|
|
|
: COGL_TRANSFORM_NO_REPEAT);
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
_cogl_texture_rectangle_get_gl_texture (CoglTexture *tex,
|
|
|
|
GLuint *out_gl_handle,
|
|
|
|
GLenum *out_gl_target)
|
|
|
|
{
|
|
|
|
CoglTextureRectangle *tex_rect = COGL_TEXTURE_RECTANGLE (tex);
|
|
|
|
|
|
|
|
if (out_gl_handle)
|
|
|
|
*out_gl_handle = tex_rect->gl_texture;
|
|
|
|
|
|
|
|
if (out_gl_target)
|
|
|
|
*out_gl_target = GL_TEXTURE_RECTANGLE_ARB;
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_cogl_texture_rectangle_set_filters (CoglTexture *tex,
|
|
|
|
GLenum min_filter,
|
|
|
|
GLenum mag_filter)
|
|
|
|
{
|
|
|
|
CoglTextureRectangle *tex_rect = COGL_TEXTURE_RECTANGLE (tex);
|
|
|
|
|
2011-07-06 16:51:00 -04:00
|
|
|
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
|
|
|
|
2010-06-10 10:33:34 -04:00
|
|
|
if (min_filter == tex_rect->min_filter
|
|
|
|
&& mag_filter == tex_rect->mag_filter)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* Rectangle textures don't support mipmapping */
|
|
|
|
g_assert (min_filter == GL_LINEAR || min_filter == GL_NEAREST);
|
|
|
|
|
|
|
|
/* Store new values */
|
|
|
|
tex_rect->min_filter = min_filter;
|
|
|
|
tex_rect->mag_filter = mag_filter;
|
|
|
|
|
|
|
|
/* Apply new filters to the texture */
|
2011-07-06 16:51:00 -04:00
|
|
|
_cogl_bind_gl_texture_transient (GL_TEXTURE_RECTANGLE_ARB,
|
|
|
|
tex_rect->gl_texture,
|
|
|
|
tex_rect->is_foreign);
|
|
|
|
GE( ctx, glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER,
|
|
|
|
mag_filter) );
|
|
|
|
GE( ctx, glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER,
|
|
|
|
min_filter) );
|
2010-06-10 10:33:34 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_cogl_texture_rectangle_pre_paint (CoglTexture *tex,
|
|
|
|
CoglTexturePrePaintFlags flags)
|
|
|
|
{
|
|
|
|
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
|
|
|
|
|
|
|
/* Rectangle textures don't support mipmaps */
|
|
|
|
g_assert ((flags & COGL_TEXTURE_NEEDS_MIPMAP) == 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_cogl_texture_rectangle_ensure_non_quad_rendering (CoglTexture *tex)
|
|
|
|
{
|
|
|
|
/* Nothing needs to be done */
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
_cogl_texture_rectangle_set_region (CoglTexture *tex,
|
|
|
|
int src_x,
|
|
|
|
int src_y,
|
|
|
|
int dst_x,
|
|
|
|
int dst_y,
|
|
|
|
unsigned int dst_width,
|
|
|
|
unsigned int dst_height,
|
2010-07-08 10:15:22 -04:00
|
|
|
CoglBitmap *bmp)
|
2010-06-10 10:33:34 -04:00
|
|
|
{
|
2010-07-08 10:15:22 -04:00
|
|
|
CoglTextureRectangle *tex_rect = COGL_TEXTURE_RECTANGLE (tex);
|
|
|
|
GLenum gl_format;
|
|
|
|
GLenum gl_type;
|
2010-06-10 10:33:34 -04:00
|
|
|
|
2011-07-07 07:48:24 -04:00
|
|
|
_COGL_GET_CONTEXT (ctx, FALSE);
|
|
|
|
|
2011-08-31 12:22:20 -04:00
|
|
|
bmp = _cogl_texture_prepare_for_upload (bmp,
|
|
|
|
cogl_texture_get_format (tex),
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
&gl_format,
|
|
|
|
&gl_type);
|
2010-06-10 10:33:34 -04:00
|
|
|
|
|
|
|
/* Send data to GL */
|
2012-03-22 13:04:47 -04:00
|
|
|
ctx->texture_driver->upload_subregion_to_gl (ctx,
|
|
|
|
GL_TEXTURE_RECTANGLE_ARB,
|
2010-06-10 10:33:34 -04:00
|
|
|
tex_rect->gl_texture,
|
|
|
|
FALSE,
|
|
|
|
src_x, src_y,
|
|
|
|
dst_x, dst_y,
|
|
|
|
dst_width, dst_height,
|
2010-07-08 10:15:22 -04:00
|
|
|
bmp,
|
|
|
|
gl_format,
|
|
|
|
gl_type);
|
2010-06-10 10:33:34 -04:00
|
|
|
|
2011-08-31 12:22:20 -04:00
|
|
|
cogl_object_unref (bmp);
|
|
|
|
|
2010-06-10 10:33:34 -04:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2010-07-08 08:54:37 -04:00
|
|
|
static gboolean
|
2010-06-10 10:33:34 -04:00
|
|
|
_cogl_texture_rectangle_get_data (CoglTexture *tex,
|
|
|
|
CoglPixelFormat format,
|
|
|
|
unsigned int rowstride,
|
|
|
|
guint8 *data)
|
|
|
|
{
|
2010-07-08 08:54:37 -04:00
|
|
|
CoglTextureRectangle *tex_rect = COGL_TEXTURE_RECTANGLE (tex);
|
|
|
|
int bpp;
|
|
|
|
GLenum gl_format;
|
|
|
|
GLenum gl_type;
|
2010-06-10 10:33:34 -04:00
|
|
|
|
2011-07-06 16:51:00 -04:00
|
|
|
_COGL_GET_CONTEXT (ctx, FALSE);
|
|
|
|
|
2012-02-13 18:02:04 -05:00
|
|
|
bpp = _cogl_pixel_format_get_bytes_per_pixel (format);
|
2010-06-10 10:33:34 -04:00
|
|
|
|
2012-03-22 12:32:56 -04:00
|
|
|
ctx->driver_vtable->pixel_format_to_gl (ctx,
|
|
|
|
format,
|
|
|
|
NULL, /* internal format */
|
|
|
|
&gl_format,
|
|
|
|
&gl_type);
|
2010-06-10 10:33:34 -04:00
|
|
|
|
2012-03-22 13:04:47 -04:00
|
|
|
ctx->texture_driver->prep_gl_for_pixels_download (ctx, rowstride, bpp);
|
2010-06-10 10:33:34 -04:00
|
|
|
|
2011-07-06 16:51:00 -04:00
|
|
|
_cogl_bind_gl_texture_transient (GL_TEXTURE_RECTANGLE_ARB,
|
|
|
|
tex_rect->gl_texture,
|
|
|
|
tex_rect->is_foreign);
|
2012-03-22 13:04:47 -04:00
|
|
|
return ctx->texture_driver->gl_get_tex_image (ctx,
|
|
|
|
GL_TEXTURE_RECTANGLE_ARB,
|
2010-07-08 08:54:37 -04:00
|
|
|
gl_format,
|
|
|
|
gl_type,
|
|
|
|
data);
|
2010-06-10 10:33:34 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
static CoglPixelFormat
|
|
|
|
_cogl_texture_rectangle_get_format (CoglTexture *tex)
|
|
|
|
{
|
|
|
|
return COGL_TEXTURE_RECTANGLE (tex)->format;
|
|
|
|
}
|
|
|
|
|
|
|
|
static GLenum
|
|
|
|
_cogl_texture_rectangle_get_gl_format (CoglTexture *tex)
|
|
|
|
{
|
|
|
|
return COGL_TEXTURE_RECTANGLE (tex)->gl_format;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
_cogl_texture_rectangle_get_width (CoglTexture *tex)
|
|
|
|
{
|
|
|
|
return COGL_TEXTURE_RECTANGLE (tex)->width;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
_cogl_texture_rectangle_get_height (CoglTexture *tex)
|
|
|
|
{
|
|
|
|
return COGL_TEXTURE_RECTANGLE (tex)->height;
|
|
|
|
}
|
|
|
|
|
2010-10-04 10:27:38 -04:00
|
|
|
static gboolean
|
|
|
|
_cogl_texture_rectangle_is_foreign (CoglTexture *tex)
|
|
|
|
{
|
|
|
|
return COGL_TEXTURE_RECTANGLE (tex)->is_foreign;
|
|
|
|
}
|
|
|
|
|
2012-02-09 06:19:04 -05:00
|
|
|
static CoglTextureType
|
|
|
|
_cogl_texture_rectangle_get_type (CoglTexture *tex)
|
|
|
|
{
|
|
|
|
return COGL_TEXTURE_TYPE_RECTANGLE;
|
|
|
|
}
|
|
|
|
|
2010-06-10 10:33:34 -04:00
|
|
|
static const CoglTextureVtable
|
|
|
|
cogl_texture_rectangle_vtable =
|
|
|
|
{
|
|
|
|
_cogl_texture_rectangle_set_region,
|
|
|
|
_cogl_texture_rectangle_get_data,
|
2011-10-08 09:13:03 -04:00
|
|
|
NULL, /* foreach_sub_texture_in_region */
|
2010-06-10 10:33:34 -04:00
|
|
|
_cogl_texture_rectangle_get_max_waste,
|
|
|
|
_cogl_texture_rectangle_is_sliced,
|
|
|
|
_cogl_texture_rectangle_can_hardware_repeat,
|
|
|
|
_cogl_texture_rectangle_transform_coords_to_gl,
|
|
|
|
_cogl_texture_rectangle_transform_quad_coords_to_gl,
|
|
|
|
_cogl_texture_rectangle_get_gl_texture,
|
|
|
|
_cogl_texture_rectangle_set_filters,
|
|
|
|
_cogl_texture_rectangle_pre_paint,
|
|
|
|
_cogl_texture_rectangle_ensure_non_quad_rendering,
|
|
|
|
_cogl_texture_rectangle_set_wrap_mode_parameters,
|
|
|
|
_cogl_texture_rectangle_get_format,
|
|
|
|
_cogl_texture_rectangle_get_gl_format,
|
|
|
|
_cogl_texture_rectangle_get_width,
|
|
|
|
_cogl_texture_rectangle_get_height,
|
2012-02-09 06:19:04 -05:00
|
|
|
_cogl_texture_rectangle_get_type,
|
2010-10-04 10:27:38 -04:00
|
|
|
_cogl_texture_rectangle_is_foreign
|
2010-06-10 10:33:34 -04:00
|
|
|
};
|