libresman

annotate examples/imgthumbs/src/thumbs.c @ 11:bebc065a941f

doesn't work yet
author John Tsiombikas <nuclear@member.fsf.org>
date Fri, 07 Feb 2014 07:50:02 +0200
parents 410c19c735b2
children 84f55eab27cb
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@11 5 #include <assert.h>
nuclear@1 6 #include <dirent.h>
nuclear@1 7 #include <imago2.h>
nuclear@1 8 #include "opengl.h"
nuclear@1 9 #include "thumbs.h"
nuclear@11 10 #include "resman.h"
nuclear@1 11
nuclear@6 12 #ifndef GL_COMPRESSED_RGB
nuclear@6 13 #define GL_COMPRESSED_RGB 0x84ed
nuclear@6 14 #endif
nuclear@6 15
nuclear@11 16 struct resman *texman;
nuclear@11 17
nuclear@11 18 static int load_res_texture(const char *fname, int id, void *cls);
nuclear@11 19 static int done_res_texture(int id, void *cls);
nuclear@11 20 static void free_res_texture(int id, void *cls);
nuclear@11 21
nuclear@11 22
nuclear@1 23 struct thumbnail *create_thumbs(const char *dirpath)
nuclear@1 24 {
nuclear@1 25 DIR *dir;
nuclear@1 26 struct dirent *dent;
nuclear@1 27 struct thumbnail *list = 0;
nuclear@1 28
nuclear@11 29 /*unsigned int intfmt = GL_COMPRESSED_RGB;
nuclear@11 30 if(!strstr((char*)glGetString(GL_EXTENSIONS), "GL_ARB_texture_compression")) {
nuclear@2 31 printf("warning, no texture compression available.\n");
nuclear@2 32 intfmt = GL_RGB;
nuclear@11 33 }*/
nuclear@11 34
nuclear@11 35 if(!texman) {
nuclear@11 36 texman = resman_create();
nuclear@11 37 resman_set_load_func(texman, load_res_texture, 0);
nuclear@11 38 resman_set_done_func(texman, done_res_texture, 0);
nuclear@11 39 resman_set_destroy_func(texman, free_res_texture, 0);
nuclear@2 40 }
nuclear@2 41
nuclear@1 42 if(!(dir = opendir(dirpath))) {
nuclear@1 43 fprintf(stderr, "failed to open directory: %s: %s\n", dirpath, strerror(errno));
nuclear@1 44 return 0;
nuclear@1 45 }
nuclear@1 46
nuclear@1 47 while((dent = readdir(dir))) {
nuclear@11 48 /*int xsz, ysz;
nuclear@11 49 unsigned char *pixels;*/
nuclear@1 50 struct thumbnail *node;
nuclear@1 51
nuclear@1 52 if(!(node = malloc(sizeof *node))) {
nuclear@1 53 perror("failed to allocate thumbnail list node");
nuclear@1 54 continue;
nuclear@1 55 }
nuclear@11 56 memset(node, 0, sizeof *node);
nuclear@1 57
nuclear@1 58 if(!(node->fname = malloc(strlen(dirpath) + strlen(dent->d_name) + 2))) {
nuclear@1 59 free(node);
nuclear@1 60 continue;
nuclear@1 61 }
nuclear@1 62 strcpy(node->fname, dirpath);
nuclear@1 63 if(dirpath[strlen(dirpath) - 1] != '/') {
nuclear@1 64 strcat(node->fname, "/");
nuclear@1 65 }
nuclear@1 66 strcat(node->fname, dent->d_name);
nuclear@1 67
nuclear@11 68 node->aspect = 1.0;/*(float)xsz / (float)ysz;*/
nuclear@11 69
nuclear@11 70 resman_lookup(texman, node->fname, 0);
nuclear@11 71
nuclear@11 72 /*if(!(pixels = img_load_pixels(node->fname, &xsz, &ysz, IMG_FMT_RGBA32))) {
nuclear@1 73 free(node->fname);
nuclear@1 74 free(node);
nuclear@1 75 continue;
nuclear@1 76 }
nuclear@1 77
nuclear@1 78 printf("loaded image: %s\n", node->fname);
nuclear@1 79
nuclear@1 80 glGenTextures(1, &node->tex);
nuclear@1 81 glBindTexture(GL_TEXTURE_2D, node->tex);
nuclear@1 82 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
nuclear@1 83 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
nuclear@2 84 glTexImage2D(GL_TEXTURE_2D, 0, intfmt, xsz, ysz, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
nuclear@1 85 img_free_pixels(pixels);
nuclear@11 86 */
nuclear@1 87
nuclear@1 88 node->next = list;
nuclear@1 89 list = node;
nuclear@1 90 }
nuclear@1 91 closedir(dir);
nuclear@1 92
nuclear@1 93 return list;
nuclear@1 94 }
nuclear@1 95
nuclear@1 96 void free_thumbs(struct thumbnail *thumbs)
nuclear@1 97 {
nuclear@1 98 if(!thumbs) return;
nuclear@1 99
nuclear@1 100 while(thumbs) {
nuclear@1 101 struct thumbnail *tmp = thumbs;
nuclear@1 102 thumbs = thumbs->next;
nuclear@1 103
nuclear@1 104 free(tmp->fname);
nuclear@1 105 free(tmp);
nuclear@1 106 }
nuclear@1 107 }
nuclear@1 108
nuclear@1 109
nuclear@11 110 void update_thumbs(void)
nuclear@11 111 {
nuclear@11 112 resman_poll(texman);
nuclear@11 113 }
nuclear@11 114
nuclear@1 115 void draw_thumbs(struct thumbnail *thumbs, float thumb_sz, float start_y)
nuclear@1 116 {
nuclear@1 117 int vp[4];
nuclear@1 118 float gap = thumb_sz / 4.0;
nuclear@1 119 float x = gap;
nuclear@1 120 float y = gap + start_y;
nuclear@1 121 float view_aspect;
nuclear@1 122
nuclear@1 123 glGetIntegerv(GL_VIEWPORT, vp);
nuclear@1 124 view_aspect = (float)(vp[2] - vp[0]) / (vp[3] - vp[1]);
nuclear@1 125
nuclear@1 126 glMatrixMode(GL_PROJECTION);
nuclear@1 127 glPushMatrix();
nuclear@1 128 glLoadIdentity();
nuclear@1 129 glOrtho(0, 1, 1.0 / view_aspect, 0, -1, 1);
nuclear@1 130
nuclear@1 131 glMatrixMode(GL_MODELVIEW);
nuclear@1 132
nuclear@1 133 while(thumbs) {
nuclear@11 134 if(!thumbs->tex) {
nuclear@11 135 thumbs = thumbs->next;
nuclear@11 136 continue;
nuclear@11 137 }
nuclear@1 138
nuclear@1 139 glPushMatrix();
nuclear@1 140 glTranslatef(x, y, 0);
nuclear@1 141
nuclear@1 142 glScalef(thumb_sz, thumb_sz, 1);
nuclear@1 143
nuclear@1 144 glBegin(GL_QUADS);
nuclear@1 145 glColor3f(0.25, 0.25, 0.25);
nuclear@1 146 glTexCoord2f(0, 0); glVertex2f(0, 0);
nuclear@1 147 glTexCoord2f(1, 0); glVertex2f(1, 0);
nuclear@1 148 glTexCoord2f(1, 1); glVertex2f(1, 1);
nuclear@1 149 glTexCoord2f(0, 1); glVertex2f(0, 1);
nuclear@1 150 glEnd();
nuclear@1 151
nuclear@1 152 if(thumbs->aspect >= 1.0) {
nuclear@1 153 glTranslatef(0, 0.5 - 0.5 / thumbs->aspect, 0);
nuclear@1 154 glScalef(1, 1.0 / thumbs->aspect, 1);
nuclear@1 155 } else {
nuclear@1 156 glTranslatef(0.5 - thumbs->aspect / 2.0, 0, 0);
nuclear@1 157 glScalef(thumbs->aspect, 1, 1);
nuclear@1 158 }
nuclear@1 159
nuclear@1 160 glEnable(GL_TEXTURE_2D);
nuclear@1 161 glBindTexture(GL_TEXTURE_2D, thumbs->tex);
nuclear@1 162
nuclear@1 163 glBegin(GL_QUADS);
nuclear@1 164 glColor3f(1, 1, 1);
nuclear@1 165 glTexCoord2f(0, 0); glVertex2f(0, 0);
nuclear@1 166 glTexCoord2f(1, 0); glVertex2f(1, 0);
nuclear@1 167 glTexCoord2f(1, 1); glVertex2f(1, 1);
nuclear@1 168 glTexCoord2f(0, 1); glVertex2f(0, 1);
nuclear@1 169 glEnd();
nuclear@1 170
nuclear@1 171 glPopMatrix();
nuclear@1 172 glDisable(GL_TEXTURE_2D);
nuclear@1 173
nuclear@1 174 thumbs->layout_pos[0] = x;
nuclear@1 175 thumbs->layout_pos[1] = y;
nuclear@1 176 thumbs->layout_size[0] = thumb_sz;
nuclear@1 177 thumbs->layout_size[1] = thumb_sz;
nuclear@1 178
nuclear@1 179 x += thumb_sz + gap;
nuclear@1 180 if(x >= 1.0 - thumb_sz) {
nuclear@1 181 x = gap;
nuclear@1 182 y += thumb_sz + gap;
nuclear@1 183 }
nuclear@1 184
nuclear@1 185 thumbs = thumbs->next;
nuclear@1 186 }
nuclear@1 187
nuclear@1 188 glMatrixMode(GL_PROJECTION);
nuclear@1 189 glPopMatrix();
nuclear@1 190 glMatrixMode(GL_MODELVIEW);
nuclear@1 191 }
nuclear@11 192
nuclear@11 193 static int load_res_texture(const char *fname, int id, void *cls)
nuclear@11 194 {
nuclear@11 195 struct resman *rman = cls;
nuclear@11 196 struct thumbnail *rdata = resman_get_res_data(rman, id);
nuclear@11 197
nuclear@11 198 assert(rdata);
nuclear@11 199 if(!rdata->img) {
nuclear@11 200 if(!(rdata->img = img_create())) {
nuclear@11 201 return -1;
nuclear@11 202 }
nuclear@11 203 }
nuclear@11 204
nuclear@11 205 if(!img_load(rdata->img, fname) == -1) {
nuclear@11 206 img_free(rdata->img);
nuclear@11 207 return -1;
nuclear@11 208 }
nuclear@11 209 rdata->aspect = (float)rdata->img->width / (float)rdata->img->height;
nuclear@11 210
nuclear@11 211 /* set the resource's data to the loaded image, so that we can use
nuclear@11 212 * it in the done callback */
nuclear@11 213 resman_set_res_data(rman, id, rdata);
nuclear@11 214 return 0;
nuclear@11 215 }
nuclear@11 216
nuclear@11 217 static int done_res_texture(int id, void *cls)
nuclear@11 218 {
nuclear@11 219 struct thumbnail *rdata;
nuclear@11 220 struct resman *rman = cls;
nuclear@11 221
nuclear@11 222 rdata = resman_get_res_data(rman, id);
nuclear@11 223
nuclear@11 224 if(resman_get_res_result(rman, id) != 0 || !rdata) {
nuclear@11 225 fprintf(stderr, "failed to load resource %d (%s)\n", id, resman_get_res_name(rman, id));
nuclear@11 226 } else {
nuclear@11 227 printf("done loading resource %d (%s)\n", id, resman_get_res_name(rman, id));
nuclear@11 228 }
nuclear@11 229
nuclear@11 230 if(!rdata->tex) {
nuclear@11 231 glGenTextures(1, &rdata->tex);
nuclear@11 232 }
nuclear@11 233 glBindTexture(GL_TEXTURE_2D, rdata->tex);
nuclear@11 234 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
nuclear@11 235 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
nuclear@11 236 glTexImage2D(GL_TEXTURE_2D, 0, img_glintfmt(rdata->img),
nuclear@11 237 rdata->img->width, rdata->img->height, 0, img_glfmt(rdata->img),
nuclear@11 238 img_gltype(rdata->img), rdata->img->pixels);
nuclear@11 239 return 0;
nuclear@11 240 }
nuclear@11 241
nuclear@11 242 static void free_res_texture(int id, void *cls)
nuclear@11 243 {
nuclear@11 244 struct resman *rman = cls;
nuclear@11 245 struct thumbnail *rdata = resman_get_res_data(rman, id);
nuclear@11 246
nuclear@11 247 if(rdata) {
nuclear@11 248 if(rdata->tex) {
nuclear@11 249 glDeleteTextures(1, &rdata->tex);
nuclear@11 250 }
nuclear@11 251 if(rdata->img) {
nuclear@11 252 img_free(rdata->img);
nuclear@11 253 }
nuclear@11 254 }
nuclear@11 255 }