summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor.andersson@artifex.com>2015-08-28 14:39:52 +0200
committerTor Andersson <tor.andersson@artifex.com>2015-10-06 11:21:23 +0200
commitf8215528acb5c33a5364e55448ce8036887ff373 (patch)
treeccfa0a1a3a75f15cda25d7afb4376f77dd16bd22
parenta148b8a3f2457f9286f2dc49c5ea96b32e9cb56c (diff)
downloadmupdf-f8215528acb5c33a5364e55448ce8036887ff373.tar.xz
gl: Don't require ARB_texture_non_power_of_two extension.
-rw-r--r--platform/gl/gl-main.c71
1 files changed, 52 insertions, 19 deletions
diff --git a/platform/gl/gl-main.c b/platform/gl/gl-main.c
index 21f7aa26..f990d8d5 100644
--- a/platform/gl/gl-main.c
+++ b/platform/gl/gl-main.c
@@ -11,6 +11,10 @@ struct ui ui;
static GLFWwindow *window;
+/* OpenGL capabilities */
+static int has_ARB_texture_non_power_of_two = 1;
+static GLint max_texture_size = 8192;
+
// TODO: event queue and handle key/mouse based on 'active' inside display()
static int ui_should_display = 0;
@@ -86,7 +90,7 @@ void ogl_assert(fz_context *ctx, const char *msg)
}
}
-void draw_image(int tex, fz_rect *r)
+void draw_image(int tex, float x0, float y0, float x1, float y1, float s0, float t0, float s1, float t1)
{
glBindTexture(GL_TEXTURE_2D, tex);
@@ -94,20 +98,20 @@ void draw_image(int tex, fz_rect *r)
glBegin(GL_TRIANGLE_STRIP);
{
glColor4f(1, 1, 1, 1);
- glTexCoord2f(0, 1);
- glVertex2f(r->x0, r->y1);
+ glTexCoord2f(s0, t1);
+ glVertex2f(x0, y1);
glColor4f(1, 1, 1, 1);
- glTexCoord2f(0, 0);
- glVertex2f(r->x0, r->y0);
+ glTexCoord2f(s0, t0);
+ glVertex2f(x0, y0);
glColor4f(1, 1, 1, 1);
- glTexCoord2f(1, 1);
- glVertex2f(r->x1, r->y1);
+ glTexCoord2f(s1, t1);
+ glVertex2f(x1, y1);
glColor4f(1, 1, 1, 1);
- glTexCoord2f(1, 0);
- glVertex2f(r->x1, r->y0);
+ glTexCoord2f(s1, t0);
+ glVertex2f(x1, y0);
}
glEnd();
glDisable(GL_TEXTURE_2D);
@@ -147,7 +151,7 @@ static fz_link *links = NULL;
static int number = 0;
static unsigned int page_tex = 0;
-static int page_x, page_y, page_w, page_h;
+static int page_x, page_y, page_w, page_h, page_w2, page_h2;
static int scroll_x = 0, scroll_y = 0;
static int canvas_x = 0, canvas_w = 100;
static int canvas_y = 0, canvas_h = 100;
@@ -178,6 +182,17 @@ static int search_hit_page = -1;
static int search_hit_count = 0;
static fz_rect search_hit_bbox[500];
+static unsigned int next_power_of_two(unsigned int n)
+{
+ --n;
+ n |= n >> 1;
+ n |= n >> 2;
+ n |= n >> 4;
+ n |= n >> 8;
+ n |= n >> 16;
+ return ++n;
+}
+
static void update_title(void)
{
static char buf[256];
@@ -218,15 +233,30 @@ void render_page(int pagenumber, float zoom, float rotate)
page_x = pix->x;
page_y = pix->y;
- page_w = pix->w;
- page_h = pix->h;
+ page_w = page_w2 = pix->w;
+ page_h = page_h2 = pix->h;
if (!page_tex)
glGenTextures(1, &page_tex);
glBindTexture(GL_TEXTURE_2D, page_tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, page_w, page_h, 0, GL_RGBA, GL_UNSIGNED_BYTE, pix->samples);
+
+ if (has_ARB_texture_non_power_of_two)
+ {
+ if (page_w > max_texture_size || page_h > max_texture_size)
+ fz_warn(ctx, "page size (%d x %d) exceeds OpenGL implementation limit (%d)", page_w, page_h, max_texture_size);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, page_w, page_h, 0, GL_RGBA, GL_UNSIGNED_BYTE, pix->samples);
+ }
+ else
+ {
+ page_w2 = next_power_of_two(page_w);
+ page_h2 = next_power_of_two(page_h);
+ if (page_w2 > max_texture_size || page_h2 > max_texture_size)
+ fz_warn(ctx, "page size (%d x %d) exceeds OpenGL implementation limit (%d)", page_w2, page_h2, max_texture_size);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, page_w2, page_h2, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, page_w, page_h, GL_RGBA, GL_UNSIGNED_BYTE, pix->samples);
+ }
fz_drop_pixmap(ctx, pix);
fz_drop_page(ctx, page);
@@ -1030,7 +1060,6 @@ static void on_reshape(GLFWwindow *window, int w, int h)
static void on_display(GLFWwindow *window)
{
- fz_rect r;
float x, y;
static int saved_scroll_x = 0;
@@ -1152,12 +1181,10 @@ static void on_display(GLFWwindow *window)
y = canvas_y - scroll_y;
}
- r.x0 = x;
- r.y0 = y;
- r.x1 = x + page_w;
- r.y1 = y + page_h;
+ draw_image(page_tex,
+ x, y, x + page_w, y + page_h,
+ 0, 0, (float)page_w / page_w2, (float)page_h / page_h2);
- draw_image(page_tex, &r);
draw_links(links, x, y, currentzoom, currentrotate);
draw_page_selection(x, y, x+page_w, y+page_h, currentzoom, currentrotate);
@@ -1435,6 +1462,12 @@ int main(int argc, char **argv)
ctx = fz_new_context(NULL, NULL, 0);
fz_register_document_handlers(ctx);
+ has_ARB_texture_non_power_of_two = glfwExtensionSupported("GL_ARB_texture_non_power_of_two");
+ if (!has_ARB_texture_non_power_of_two)
+ fz_warn(ctx, "OpenGL implementation does not support non-power of two texture sizes");
+
+ glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size);
+
ui.fontsize = 15;
ui.baseline = 14;
ui.lineheight = 18;