diff --git a/gl/cogl-texture.c b/gl/cogl-texture.c index b1b654c58..5a202ae6b 100644 --- a/gl/cogl-texture.c +++ b/gl/cogl-texture.c @@ -1427,16 +1427,22 @@ cogl_texture_new_from_foreign (GLuint gl_handle, CoglTexture *tex; CoglTexSliceSpan x_span; CoglTexSliceSpan y_span; - - /* Allow 2-dimensional textures only */ - if (gl_target != GL_TEXTURE_2D) + + /* GL_ARB_texture_rectangle textures are supported if they are + 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; - + /* Make sure it is a valid GL texture object */ gl_istexture = glIsTexture (gl_handle); if (gl_istexture == GL_FALSE) return COGL_INVALID_HANDLE; - + /* Make sure binding succeeds */ gl_error = glGetError (); glBindTexture (gl_target, gl_handle); @@ -1928,8 +1934,7 @@ _cogl_texture_quad_sw (CoglTexture *tex, GLfloat tex_coords[8]; GLfloat quad_coords[8]; GLuint gl_handle; - gulong enable_flags = (COGL_ENABLE_TEXTURE_2D - | COGL_ENABLE_VERTEX_ARRAY + gulong enable_flags = (COGL_ENABLE_VERTEX_ARRAY | COGL_ENABLE_TEXCOORD_ARRAY); _COGL_GET_CONTEXT (ctx, NO_RETVAL); @@ -1937,9 +1942,13 @@ _cogl_texture_quad_sw (CoglTexture *tex, #if COGL_DEBUG printf("=== Drawing Tex Quad (Software Tiling Mode) ===\n"); #endif - - + /* 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 || tex->bitmap.format & COGL_A_BIT) { @@ -2020,17 +2029,19 @@ _cogl_texture_quad_sw (CoglTexture *tex, slice_qy2 = first_qy + COGL_FIXED_MUL (iter_y.intersect_end - first_ty, tqy); - + /* Localize slice texture coordinates */ slice_ty1 = iter_y.intersect_start - iter_y.pos; slice_ty2 = iter_y.intersect_end - iter_y.pos; - + /* Normalize texture coordinates to current slice (rectangle texture targets take denormalized) */ - slice_ty1 /= iter_y.span->size; - slice_ty2 /= iter_y.span->size; - - + if (tex->gl_target != CGL_TEXTURE_RECTANGLE_ARB) + { + slice_ty1 /= iter_y.span->size; + slice_ty2 /= iter_y.span->size; + } + /* Iterate until whole quad width covered */ for (_cogl_span_iter_begin (&iter_x, tex->slice_x_spans, first_tx, tx1, tx2) ; @@ -2050,12 +2061,15 @@ _cogl_texture_quad_sw (CoglTexture *tex, /* Localize slice texture coordinates */ slice_tx1 = iter_x.intersect_start - iter_x.pos; slice_tx2 = iter_x.intersect_end - iter_x.pos; - + /* Normalize texture coordinates to current slice (rectangle texture targets take denormalized) */ - slice_tx1 /= iter_x.span->size; - slice_tx2 /= iter_x.span->size; - + if (tex->gl_target != CGL_TEXTURE_RECTANGLE_ARB) + { + slice_tx1 /= iter_x.span->size; + slice_tx2 /= iter_x.span->size; + } + #if COGL_DEBUG printf("~~~~~ slice (%d,%d)\n", iter_x.index, iter_y.index); printf("qx1: %f\n", COGL_FIXED_TO_FLOAT (slice_qx1)); @@ -2111,8 +2125,7 @@ _cogl_texture_quad_hw (CoglTexture *tex, GLuint gl_handle; CoglTexSliceSpan *x_span; CoglTexSliceSpan *y_span; - gulong enable_flags = (COGL_ENABLE_TEXTURE_2D - | COGL_ENABLE_VERTEX_ARRAY + gulong enable_flags = (COGL_ENABLE_VERTEX_ARRAY | COGL_ENABLE_TEXCOORD_ARRAY); #if COGL_DEBUG @@ -2122,6 +2135,11 @@ _cogl_texture_quad_hw (CoglTexture *tex, _COGL_GET_CONTEXT (ctx, NO_RETVAL); /* 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 || 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; 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) - + /* Draw textured quad */ tex_coords[0] = CFX_F(tx1); tex_coords[1] = 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 we can use hardware tiling */ 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 && tx2 >= 0 && tx2 <= COGL_FIXED_1 && ty1 >= 0 && ty1 <= COGL_FIXED_1 @@ -2289,11 +2317,14 @@ cogl_texture_polygon (CoglHandle handle, } /* Prepare GL state */ - enable_flags = (COGL_ENABLE_TEXTURE_2D - | COGL_ENABLE_VERTEX_ARRAY + enable_flags = (COGL_ENABLE_VERTEX_ARRAY | COGL_ENABLE_TEXCOORD_ARRAY | 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) enable_flags |= COGL_ENABLE_BACKFACE_CULLING; @@ -2335,19 +2366,31 @@ cogl_texture_polygon (CoglHandle handle, OpenGL */ for (i = 0, p = ctx->texture_vertices; i < n_vertices; i++, p++) { + CoglFixed tx, ty; + #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[1] = CFX_F(vertices[i].y); p->v[2] = CFX_F(vertices[i].z); - p->t[0] = CFX_F((vertices[i].tx - - (COGL_FIXED_FROM_INT (x_span->start) - / 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->t[0] = CFX_F(tx); + p->t[1] = CFX_F(ty); p->c[0] = cogl_color_get_red_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); diff --git a/gl/cogl.c b/gl/cogl.c index 9bd14d113..64bd6faf3 100644 --- a/gl/cogl.c +++ b/gl/cogl.c @@ -318,7 +318,13 @@ cogl_enable (gulong flags) cogl_toggle_flag (ctx, flags, COGL_ENABLE_BACKFACE_CULLING, 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_ENABLE_VERTEX_ARRAY, GL_VERTEX_ARRAY);