Bug 1297 - Bring back support for GL_ARB_texture_rectangle

* clutter/cogl/gl/cogl-texture.c (cogl_texture_new_from_foreign,
	(_cogl_texture_quad_hw, cogl_texture_polygon),
	(_cogl_texture_quad_sw): Support GL_ARB_texture_rectangle textures

	* clutter/glx/clutter-glx-texture-pixmap.c: Use rectangle textures
	when NPOTs are not available or it is forced by the
	CLUTTER_PIXMAP_TEXTURE_RECTANGLE environment variable.

	* clutter/cogl/gl/cogl.c (cogl_enable): Allow enabling
	GL_TEXTURE_RECTANGLE_ARB.
This commit is contained in:
Neil Roberts 2008-12-04 17:24:33 +00:00
parent 10d7cf3273
commit 58f6aaa589
2 changed files with 83 additions and 34 deletions

View File

@ -1427,16 +1427,22 @@ cogl_texture_new_from_foreign (GLuint gl_handle,
CoglTexture *tex; CoglTexture *tex;
CoglTexSliceSpan x_span; CoglTexSliceSpan x_span;
CoglTexSliceSpan y_span; CoglTexSliceSpan y_span;
/* Allow 2-dimensional textures only */ /* GL_ARB_texture_rectangle textures are supported if they are
if (gl_target != GL_TEXTURE_2D) created from foreign because some chipsets have trouble with
GL_ARB_texture_non_power_of_two. There is no Cogl call to create
them directly to emphasize the fact that they don't work fully
(for example, no mipmapping and complicated shader support) */
/* Allow 2-dimensional or rectangle textures only */
if (gl_target != GL_TEXTURE_2D && gl_target != CGL_TEXTURE_RECTANGLE_ARB)
return COGL_INVALID_HANDLE; return COGL_INVALID_HANDLE;
/* Make sure it is a valid GL texture object */ /* Make sure it is a valid GL texture object */
gl_istexture = glIsTexture (gl_handle); gl_istexture = glIsTexture (gl_handle);
if (gl_istexture == GL_FALSE) if (gl_istexture == GL_FALSE)
return COGL_INVALID_HANDLE; return COGL_INVALID_HANDLE;
/* Make sure binding succeeds */ /* Make sure binding succeeds */
gl_error = glGetError (); gl_error = glGetError ();
glBindTexture (gl_target, gl_handle); glBindTexture (gl_target, gl_handle);
@ -1928,8 +1934,7 @@ _cogl_texture_quad_sw (CoglTexture *tex,
GLfloat tex_coords[8]; GLfloat tex_coords[8];
GLfloat quad_coords[8]; GLfloat quad_coords[8];
GLuint gl_handle; GLuint gl_handle;
gulong enable_flags = (COGL_ENABLE_TEXTURE_2D gulong enable_flags = (COGL_ENABLE_VERTEX_ARRAY
| COGL_ENABLE_VERTEX_ARRAY
| COGL_ENABLE_TEXCOORD_ARRAY); | COGL_ENABLE_TEXCOORD_ARRAY);
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _COGL_GET_CONTEXT (ctx, NO_RETVAL);
@ -1937,9 +1942,13 @@ _cogl_texture_quad_sw (CoglTexture *tex,
#if COGL_DEBUG #if COGL_DEBUG
printf("=== Drawing Tex Quad (Software Tiling Mode) ===\n"); printf("=== Drawing Tex Quad (Software Tiling Mode) ===\n");
#endif #endif
/* Prepare GL state */ /* Prepare GL state */
if (tex->gl_target == CGL_TEXTURE_RECTANGLE_ARB)
enable_flags |= COGL_ENABLE_TEXTURE_RECT;
else
enable_flags |= COGL_ENABLE_TEXTURE_2D;
if (ctx->color_alpha < 255 if (ctx->color_alpha < 255
|| tex->bitmap.format & COGL_A_BIT) || tex->bitmap.format & COGL_A_BIT)
{ {
@ -2020,17 +2029,19 @@ _cogl_texture_quad_sw (CoglTexture *tex,
slice_qy2 = first_qy + slice_qy2 = first_qy +
COGL_FIXED_MUL (iter_y.intersect_end - first_ty, tqy); COGL_FIXED_MUL (iter_y.intersect_end - first_ty, tqy);
/* Localize slice texture coordinates */ /* Localize slice texture coordinates */
slice_ty1 = iter_y.intersect_start - iter_y.pos; slice_ty1 = iter_y.intersect_start - iter_y.pos;
slice_ty2 = iter_y.intersect_end - iter_y.pos; slice_ty2 = iter_y.intersect_end - iter_y.pos;
/* Normalize texture coordinates to current slice /* Normalize texture coordinates to current slice
(rectangle texture targets take denormalized) */ (rectangle texture targets take denormalized) */
slice_ty1 /= iter_y.span->size; if (tex->gl_target != CGL_TEXTURE_RECTANGLE_ARB)
slice_ty2 /= iter_y.span->size; {
slice_ty1 /= iter_y.span->size;
slice_ty2 /= iter_y.span->size;
}
/* Iterate until whole quad width covered */ /* Iterate until whole quad width covered */
for (_cogl_span_iter_begin (&iter_x, tex->slice_x_spans, for (_cogl_span_iter_begin (&iter_x, tex->slice_x_spans,
first_tx, tx1, tx2) ; first_tx, tx1, tx2) ;
@ -2050,12 +2061,15 @@ _cogl_texture_quad_sw (CoglTexture *tex,
/* Localize slice texture coordinates */ /* Localize slice texture coordinates */
slice_tx1 = iter_x.intersect_start - iter_x.pos; slice_tx1 = iter_x.intersect_start - iter_x.pos;
slice_tx2 = iter_x.intersect_end - iter_x.pos; slice_tx2 = iter_x.intersect_end - iter_x.pos;
/* Normalize texture coordinates to current slice /* Normalize texture coordinates to current slice
(rectangle texture targets take denormalized) */ (rectangle texture targets take denormalized) */
slice_tx1 /= iter_x.span->size; if (tex->gl_target != CGL_TEXTURE_RECTANGLE_ARB)
slice_tx2 /= iter_x.span->size; {
slice_tx1 /= iter_x.span->size;
slice_tx2 /= iter_x.span->size;
}
#if COGL_DEBUG #if COGL_DEBUG
printf("~~~~~ slice (%d,%d)\n", iter_x.index, iter_y.index); printf("~~~~~ slice (%d,%d)\n", iter_x.index, iter_y.index);
printf("qx1: %f\n", COGL_FIXED_TO_FLOAT (slice_qx1)); printf("qx1: %f\n", COGL_FIXED_TO_FLOAT (slice_qx1));
@ -2111,8 +2125,7 @@ _cogl_texture_quad_hw (CoglTexture *tex,
GLuint gl_handle; GLuint gl_handle;
CoglTexSliceSpan *x_span; CoglTexSliceSpan *x_span;
CoglTexSliceSpan *y_span; CoglTexSliceSpan *y_span;
gulong enable_flags = (COGL_ENABLE_TEXTURE_2D gulong enable_flags = (COGL_ENABLE_VERTEX_ARRAY
| COGL_ENABLE_VERTEX_ARRAY
| COGL_ENABLE_TEXCOORD_ARRAY); | COGL_ENABLE_TEXCOORD_ARRAY);
#if COGL_DEBUG #if COGL_DEBUG
@ -2122,6 +2135,11 @@ _cogl_texture_quad_hw (CoglTexture *tex,
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _COGL_GET_CONTEXT (ctx, NO_RETVAL);
/* Prepare GL state */ /* Prepare GL state */
if (tex->gl_target == CGL_TEXTURE_RECTANGLE_ARB)
enable_flags |= COGL_ENABLE_TEXTURE_RECT;
else
enable_flags |= COGL_ENABLE_TEXTURE_2D;
if (ctx->color_alpha < 255 if (ctx->color_alpha < 255
|| tex->bitmap.format & COGL_A_BIT) || tex->bitmap.format & COGL_A_BIT)
{ {
@ -2162,8 +2180,17 @@ _cogl_texture_quad_hw (CoglTexture *tex,
ty1 = ty1 * (y_span->size - y_span->waste) / y_span->size; ty1 = ty1 * (y_span->size - y_span->waste) / y_span->size;
ty2 = ty2 * (y_span->size - y_span->waste) / y_span->size; ty2 = ty2 * (y_span->size - y_span->waste) / y_span->size;
/* Denormalize texture coordinates for rectangle textures */
if (tex->gl_target == GL_TEXTURE_RECTANGLE_ARB)
{
tx1 *= x_span->size;
tx2 *= x_span->size;
ty1 *= y_span->size;
ty2 *= y_span->size;
}
#define CFX_F(x) COGL_FIXED_TO_FLOAT(x) #define CFX_F(x) COGL_FIXED_TO_FLOAT(x)
/* Draw textured quad */ /* Draw textured quad */
tex_coords[0] = CFX_F(tx1); tex_coords[1] = CFX_F(ty2); tex_coords[0] = CFX_F(tx1); tex_coords[1] = CFX_F(ty2);
tex_coords[2] = CFX_F(tx2); tex_coords[3] = CFX_F(ty2); tex_coords[2] = CFX_F(tx2); tex_coords[3] = CFX_F(ty2);
@ -2215,7 +2242,8 @@ cogl_texture_rectangle (CoglHandle handle,
(no waste) or all of the coordinates are in the range [0,1] then (no waste) or all of the coordinates are in the range [0,1] then
we can use hardware tiling */ we can use hardware tiling */
if (tex->slice_gl_handles->len == 1 if (tex->slice_gl_handles->len == 1
&& (cogl_features_available (COGL_FEATURE_TEXTURE_NPOT) && ((cogl_features_available (COGL_FEATURE_TEXTURE_NPOT)
&& tex->gl_target == GL_TEXTURE_2D)
|| (tx1 >= 0 && tx1 <= COGL_FIXED_1 || (tx1 >= 0 && tx1 <= COGL_FIXED_1
&& tx2 >= 0 && tx2 <= COGL_FIXED_1 && tx2 >= 0 && tx2 <= COGL_FIXED_1
&& ty1 >= 0 && ty1 <= COGL_FIXED_1 && ty1 >= 0 && ty1 <= COGL_FIXED_1
@ -2289,11 +2317,14 @@ cogl_texture_polygon (CoglHandle handle,
} }
/* Prepare GL state */ /* Prepare GL state */
enable_flags = (COGL_ENABLE_TEXTURE_2D enable_flags = (COGL_ENABLE_VERTEX_ARRAY
| COGL_ENABLE_VERTEX_ARRAY
| COGL_ENABLE_TEXCOORD_ARRAY | COGL_ENABLE_TEXCOORD_ARRAY
| COGL_ENABLE_BLEND); | COGL_ENABLE_BLEND);
if (tex->gl_target == CGL_TEXTURE_RECTANGLE_ARB)
enable_flags |= COGL_ENABLE_TEXTURE_RECT;
else
enable_flags |= COGL_ENABLE_TEXTURE_2D;
if (ctx->enable_backface_culling) if (ctx->enable_backface_culling)
enable_flags |= COGL_ENABLE_BACKFACE_CULLING; enable_flags |= COGL_ENABLE_BACKFACE_CULLING;
@ -2335,19 +2366,31 @@ cogl_texture_polygon (CoglHandle handle,
OpenGL */ OpenGL */
for (i = 0, p = ctx->texture_vertices; i < n_vertices; i++, p++) for (i = 0, p = ctx->texture_vertices; i < n_vertices; i++, p++)
{ {
CoglFixed tx, ty;
#define CFX_F COGL_FIXED_TO_FLOAT #define CFX_F COGL_FIXED_TO_FLOAT
tx = ((vertices[i].tx
- (COGL_FIXED_FROM_INT (x_span->start)
/ tex->bitmap.width))
* tex->bitmap.width / x_span->size);
ty = ((vertices[i].ty
- (COGL_FIXED_FROM_INT (y_span->start)
/ tex->bitmap.height))
* tex->bitmap.height / y_span->size);
/* Scale the coordinates up for rectangle textures */
if (tex->gl_target == CGL_TEXTURE_RECTANGLE_ARB)
{
tx *= x_span->size;
ty *= y_span->size;
}
p->v[0] = CFX_F(vertices[i].x); p->v[0] = CFX_F(vertices[i].x);
p->v[1] = CFX_F(vertices[i].y); p->v[1] = CFX_F(vertices[i].y);
p->v[2] = CFX_F(vertices[i].z); p->v[2] = CFX_F(vertices[i].z);
p->t[0] = CFX_F((vertices[i].tx p->t[0] = CFX_F(tx);
- (COGL_FIXED_FROM_INT (x_span->start) p->t[1] = CFX_F(ty);
/ tex->bitmap.width))
* tex->bitmap.width / x_span->size);
p->t[1] = CFX_F((vertices[i].ty
- (COGL_FIXED_FROM_INT (y_span->start)
/ tex->bitmap.height))
* tex->bitmap.height / y_span->size);
p->c[0] = cogl_color_get_red_byte(&vertices[i].color); p->c[0] = cogl_color_get_red_byte(&vertices[i].color);
p->c[1] = cogl_color_get_green_byte(&vertices[i].color); p->c[1] = cogl_color_get_green_byte(&vertices[i].color);
p->c[2] = cogl_color_get_blue_byte(&vertices[i].color); p->c[2] = cogl_color_get_blue_byte(&vertices[i].color);

View File

@ -318,7 +318,13 @@ cogl_enable (gulong flags)
cogl_toggle_flag (ctx, flags, cogl_toggle_flag (ctx, flags,
COGL_ENABLE_BACKFACE_CULLING, COGL_ENABLE_BACKFACE_CULLING,
GL_CULL_FACE); GL_CULL_FACE);
#ifdef GL_TEXTURE_RECTANGLE_ARB
cogl_toggle_flag (ctx, flags,
COGL_ENABLE_TEXTURE_RECT,
GL_TEXTURE_RECTANGLE_ARB);
#endif
cogl_toggle_client_flag (ctx, flags, cogl_toggle_client_flag (ctx, flags,
COGL_ENABLE_VERTEX_ARRAY, COGL_ENABLE_VERTEX_ARRAY,
GL_VERTEX_ARRAY); GL_VERTEX_ARRAY);