libresman

annotate examples/imgthumbs/src/thumbs.c @ 6:410c19c735b2

- removed the glew dependency - initial thread pool implementation
author John Tsiombikas <nuclear@member.fsf.org>
date Mon, 03 Feb 2014 05:22:09 +0200
parents 026cdd1737ff
children bebc065a941f
rev   line source
nuclear@1 1 #include <stdio.h>
nuclear@1 2 #include <stdlib.h>
nuclear@1 3 #include <string.h>
nuclear@1 4 #include <errno.h>
nuclear@1 5 #include <dirent.h>
nuclear@1 6 #include <imago2.h>
nuclear@1 7 #include "opengl.h"
nuclear@1 8 #include "thumbs.h"
nuclear@1 9
nuclear@6 10 #ifndef GL_COMPRESSED_RGB
nuclear@6 11 #define GL_COMPRESSED_RGB 0x84ed
nuclear@6 12 #endif
nuclear@6 13
nuclear@1 14 struct thumbnail *create_thumbs(const char *dirpath)
nuclear@1 15 {
nuclear@1 16 DIR *dir;
nuclear@1 17 struct dirent *dent;
nuclear@1 18 struct thumbnail *list = 0;
nuclear@1 19
nuclear@2 20 unsigned int intfmt = GL_COMPRESSED_RGB;
nuclear@6 21 if(!strstr(glGetString(GL_EXTENSIONS), "GL_ARB_texture_compression")) {
nuclear@2 22 printf("warning, no texture compression available.\n");
nuclear@2 23 intfmt = GL_RGB;
nuclear@2 24 }
nuclear@2 25
nuclear@1 26 if(!(dir = opendir(dirpath))) {
nuclear@1 27 fprintf(stderr, "failed to open directory: %s: %s\n", dirpath, strerror(errno));
nuclear@1 28 return 0;
nuclear@1 29 }
nuclear@1 30
nuclear@1 31 while((dent = readdir(dir))) {
nuclear@1 32 int xsz, ysz;
nuclear@1 33 unsigned char *pixels;
nuclear@1 34 struct thumbnail *node;
nuclear@1 35
nuclear@1 36 if(!(node = malloc(sizeof *node))) {
nuclear@1 37 perror("failed to allocate thumbnail list node");
nuclear@1 38 continue;
nuclear@1 39 }
nuclear@1 40
nuclear@1 41 if(!(node->fname = malloc(strlen(dirpath) + strlen(dent->d_name) + 2))) {
nuclear@1 42 free(node);
nuclear@1 43 continue;
nuclear@1 44 }
nuclear@1 45 strcpy(node->fname, dirpath);
nuclear@1 46 if(dirpath[strlen(dirpath) - 1] != '/') {
nuclear@1 47 strcat(node->fname, "/");
nuclear@1 48 }
nuclear@1 49 strcat(node->fname, dent->d_name);
nuclear@1 50
nuclear@1 51 if(!(pixels = img_load_pixels(node->fname, &xsz, &ysz, IMG_FMT_RGBA32))) {
nuclear@1 52 free(node->fname);
nuclear@1 53 free(node);
nuclear@1 54 continue;
nuclear@1 55 }
nuclear@1 56
nuclear@1 57 printf("loaded image: %s\n", node->fname);
nuclear@1 58
nuclear@1 59 glGenTextures(1, &node->tex);
nuclear@1 60 glBindTexture(GL_TEXTURE_2D, node->tex);
nuclear@1 61 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
nuclear@1 62 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
nuclear@2 63 glTexImage2D(GL_TEXTURE_2D, 0, intfmt, xsz, ysz, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
nuclear@1 64 img_free_pixels(pixels);
nuclear@1 65
nuclear@1 66 node->aspect = (float)xsz / (float)ysz;
nuclear@1 67
nuclear@1 68 node->next = list;
nuclear@1 69 list = node;
nuclear@1 70 }
nuclear@1 71 closedir(dir);
nuclear@1 72
nuclear@1 73 return list;
nuclear@1 74 }
nuclear@1 75
nuclear@1 76 void free_thumbs(struct thumbnail *thumbs)
nuclear@1 77 {
nuclear@1 78 if(!thumbs) return;
nuclear@1 79
nuclear@1 80 while(thumbs) {
nuclear@1 81 struct thumbnail *tmp = thumbs;
nuclear@1 82 thumbs = thumbs->next;
nuclear@1 83
nuclear@1 84 free(tmp->fname);
nuclear@1 85 free(tmp);
nuclear@1 86 }
nuclear@1 87 }
nuclear@1 88
nuclear@1 89
nuclear@1 90 void draw_thumbs(struct thumbnail *thumbs, float thumb_sz, float start_y)
nuclear@1 91 {
nuclear@1 92 int vp[4];
nuclear@1 93 float gap = thumb_sz / 4.0;
nuclear@1 94 float x = gap;
nuclear@1 95 float y = gap + start_y;
nuclear@1 96 float view_aspect;
nuclear@1 97
nuclear@1 98 glGetIntegerv(GL_VIEWPORT, vp);
nuclear@1 99 view_aspect = (float)(vp[2] - vp[0]) / (vp[3] - vp[1]);
nuclear@1 100
nuclear@1 101 glMatrixMode(GL_PROJECTION);
nuclear@1 102 glPushMatrix();
nuclear@1 103 glLoadIdentity();
nuclear@1 104 glOrtho(0, 1, 1.0 / view_aspect, 0, -1, 1);
nuclear@1 105
nuclear@1 106 glMatrixMode(GL_MODELVIEW);
nuclear@1 107
nuclear@1 108 while(thumbs) {
nuclear@1 109
nuclear@1 110 glPushMatrix();
nuclear@1 111 glTranslatef(x, y, 0);
nuclear@1 112
nuclear@1 113 glScalef(thumb_sz, thumb_sz, 1);
nuclear@1 114
nuclear@1 115 glBegin(GL_QUADS);
nuclear@1 116 glColor3f(0.25, 0.25, 0.25);
nuclear@1 117 glTexCoord2f(0, 0); glVertex2f(0, 0);
nuclear@1 118 glTexCoord2f(1, 0); glVertex2f(1, 0);
nuclear@1 119 glTexCoord2f(1, 1); glVertex2f(1, 1);
nuclear@1 120 glTexCoord2f(0, 1); glVertex2f(0, 1);
nuclear@1 121 glEnd();
nuclear@1 122
nuclear@1 123 if(thumbs->aspect >= 1.0) {
nuclear@1 124 glTranslatef(0, 0.5 - 0.5 / thumbs->aspect, 0);
nuclear@1 125 glScalef(1, 1.0 / thumbs->aspect, 1);
nuclear@1 126 } else {
nuclear@1 127 glTranslatef(0.5 - thumbs->aspect / 2.0, 0, 0);
nuclear@1 128 glScalef(thumbs->aspect, 1, 1);
nuclear@1 129 }
nuclear@1 130
nuclear@1 131 glEnable(GL_TEXTURE_2D);
nuclear@1 132 glBindTexture(GL_TEXTURE_2D, thumbs->tex);
nuclear@1 133
nuclear@1 134 glBegin(GL_QUADS);
nuclear@1 135 glColor3f(1, 1, 1);
nuclear@1 136 glTexCoord2f(0, 0); glVertex2f(0, 0);
nuclear@1 137 glTexCoord2f(1, 0); glVertex2f(1, 0);
nuclear@1 138 glTexCoord2f(1, 1); glVertex2f(1, 1);
nuclear@1 139 glTexCoord2f(0, 1); glVertex2f(0, 1);
nuclear@1 140 glEnd();
nuclear@1 141
nuclear@1 142 glPopMatrix();
nuclear@1 143 glDisable(GL_TEXTURE_2D);
nuclear@1 144
nuclear@1 145 thumbs->layout_pos[0] = x;
nuclear@1 146 thumbs->layout_pos[1] = y;
nuclear@1 147 thumbs->layout_size[0] = thumb_sz;
nuclear@1 148 thumbs->layout_size[1] = thumb_sz;
nuclear@1 149
nuclear@1 150 x += thumb_sz + gap;
nuclear@1 151 if(x >= 1.0 - thumb_sz) {
nuclear@1 152 x = gap;
nuclear@1 153 y += thumb_sz + gap;
nuclear@1 154 }
nuclear@1 155
nuclear@1 156 thumbs = thumbs->next;
nuclear@1 157 }
nuclear@1 158
nuclear@1 159 glMatrixMode(GL_PROJECTION);
nuclear@1 160 glPopMatrix();
nuclear@1 161 glMatrixMode(GL_MODELVIEW);
nuclear@1 162 }