libresman

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