libresman

view examples/imgthumbs/src/thumbs.c @ 14:2fcd1fbb0d18

buggy piece of shit
author John Tsiombikas <nuclear@member.fsf.org>
date Mon, 10 Feb 2014 12:11:02 +0200
parents a42888d26839
children 43a9fe4a80ee
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;
17 struct thumbnail *dbg;
19 static int load_res_texture(const char *fname, int id, void *cls);
20 static int done_res_texture(int id, void *cls);
21 static void free_res_texture(int id, void *cls);
24 struct thumbnail *create_thumbs(const char *dirpath)
25 {
26 DIR *dir;
27 struct dirent *dent;
28 /* allocate dummy head node */
29 struct thumbnail *list = calloc(1, sizeof *list);
30 dbg = list;
32 /*unsigned int intfmt = GL_COMPRESSED_RGB;
33 if(!strstr((char*)glGetString(GL_EXTENSIONS), "GL_ARB_texture_compression")) {
34 printf("warning, no texture compression available.\n");
35 intfmt = GL_RGB;
36 }*/
38 if(!texman) {
39 texman = resman_create();
40 resman_set_load_func(texman, load_res_texture, 0);
41 resman_set_done_func(texman, done_res_texture, 0);
42 resman_set_destroy_func(texman, free_res_texture, 0);
43 }
45 if(!(dir = opendir(dirpath))) {
46 fprintf(stderr, "failed to open directory: %s: %s\n", dirpath, strerror(errno));
47 return 0;
48 }
50 while((dent = readdir(dir))) {
51 /*int xsz, ysz;
52 unsigned char *pixels;*/
53 struct thumbnail *node;
55 if(!(node = malloc(sizeof *node))) {
56 perror("failed to allocate thumbnail list node");
57 continue;
58 }
59 memset(node, 0, sizeof *node);
61 if(!(node->fname = malloc(strlen(dirpath) + strlen(dent->d_name) + 2))) {
62 free(node);
63 continue;
64 }
65 strcpy(node->fname, dirpath);
66 if(dirpath[strlen(dirpath) - 1] != '/') {
67 strcat(node->fname, "/");
68 }
69 strcat(node->fname, dent->d_name);
71 node->aspect = 1.0;/*(float)xsz / (float)ysz;*/
73 resman_lookup(texman, node->fname, node);
75 /*if(!(pixels = img_load_pixels(node->fname, &xsz, &ysz, IMG_FMT_RGBA32))) {
76 free(node->fname);
77 free(node);
78 continue;
79 }
81 printf("loaded image: %s\n", node->fname);
83 glGenTextures(1, &node->tex);
84 glBindTexture(GL_TEXTURE_2D, node->tex);
85 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
86 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
87 glTexImage2D(GL_TEXTURE_2D, 0, intfmt, xsz, ysz, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
88 img_free_pixels(pixels);
89 */
91 node->next = list->next;
92 node->prev = list;
93 list->next = node;
94 }
95 closedir(dir);
97 return list;
98 }
100 void free_thumbs(struct thumbnail *thumbs)
101 {
102 if(!thumbs) return;
104 while(thumbs) {
105 struct thumbnail *tmp = thumbs;
106 thumbs = thumbs->next;
108 free(tmp->fname);
109 free(tmp);
110 }
111 }
114 void update_thumbs(void)
115 {
116 resman_poll(texman);
117 }
119 void draw_thumbs(struct thumbnail *thumbs, float thumb_sz, float start_y)
120 {
121 int vp[4];
122 float gap = thumb_sz / 4.0;
123 float x = gap;
124 float y = gap + start_y;
125 float view_aspect;
127 glGetIntegerv(GL_VIEWPORT, vp);
128 view_aspect = (float)(vp[2] - vp[0]) / (float)(vp[3] - vp[1]);
130 glMatrixMode(GL_PROJECTION);
131 glPushMatrix();
132 glLoadIdentity();
133 glOrtho(0, 1, 1.0 / view_aspect, 0, -1, 1);
135 glMatrixMode(GL_MODELVIEW);
137 thumbs = thumbs->next; /* skip dummy node */
138 while(thumbs) {
139 printf("drawing thumb: %s\n", thumbs->fname);
140 glPushMatrix();
141 glTranslatef(x, y, 0);
143 glScalef(thumb_sz, thumb_sz, 1);
145 glBegin(GL_QUADS);
146 glColor3f(0.25, 0.25, 0.25);
147 glTexCoord2f(0, 0); glVertex2f(0, 0);
148 glTexCoord2f(1, 0); glVertex2f(1, 0);
149 glTexCoord2f(1, 1); glVertex2f(1, 1);
150 glTexCoord2f(0, 1); glVertex2f(0, 1);
151 glEnd();
153 if(thumbs->tex) {
154 if(thumbs->aspect >= 1.0) {
155 glTranslatef(0, 0.5 - 0.5 / thumbs->aspect, 0);
156 glScalef(1, 1.0 / thumbs->aspect, 1);
157 } else {
158 glTranslatef(0.5 - thumbs->aspect / 2.0, 0, 0);
159 glScalef(thumbs->aspect, 1, 1);
160 }
162 if(glIsTexture(thumbs->tex)) {
163 glEnable(GL_TEXTURE_2D);
164 glBindTexture(GL_TEXTURE_2D, thumbs->tex);
166 glBegin(GL_QUADS);
167 glColor3f(1, 1, 1);
168 glTexCoord2f(0, 0); glVertex2f(0, 0);
169 glTexCoord2f(1, 0); glVertex2f(1, 0);
170 glTexCoord2f(1, 1); glVertex2f(1, 1);
171 glTexCoord2f(0, 1); glVertex2f(0, 1);
172 glEnd();
173 } else {
174 fprintf(stderr, "invalid texture: %u\n", thumbs->tex);
175 }
177 glPopMatrix();
178 glDisable(GL_TEXTURE_2D);
179 }
181 thumbs->layout_pos[0] = x;
182 thumbs->layout_pos[1] = y;
183 thumbs->layout_size[0] = thumb_sz;
184 thumbs->layout_size[1] = thumb_sz;
186 x += thumb_sz + gap;
187 if(x >= 1.0 - thumb_sz) {
188 x = gap;
189 y += thumb_sz + gap;
190 }
192 thumbs = thumbs->next;
193 }
195 glMatrixMode(GL_PROJECTION);
196 glPopMatrix();
197 glMatrixMode(GL_MODELVIEW);
198 }
200 static int load_res_texture(const char *fname, int id, void *cls)
201 {
202 struct thumbnail *rdata = resman_get_res_data(texman, id);
204 assert(rdata);
205 if(!rdata->img) {
206 if(!(rdata->img = img_create())) {
207 return -1;
208 }
209 }
211 if(img_load(rdata->img, fname) == -1) {
212 img_free(rdata->img);
213 rdata->img = 0;
214 return -1;
215 }
216 rdata->aspect = (float)rdata->img->width / (float)rdata->img->height;
218 /* set the resource's data to the loaded image, so that we can use
219 * it in the done callback */
220 resman_set_res_data(texman, id, rdata);
221 return 0;
222 }
224 static int done_res_texture(int id, void *cls)
225 {
226 struct thumbnail *rdata = resman_get_res_data(texman, id);
227 int load_result = resman_get_res_result(texman, id);
229 if(load_result == -1) {
230 /* returning -1 will remove this resource, the free_res_texture
231 * destroy handler will be called, which will remove the node
232 * from the list
233 */
234 return -1;
235 }
237 if(resman_get_res_result(texman, id) != 0 || !rdata) {
238 fprintf(stderr, "failed to load resource %d (%s)\n", id, resman_get_res_name(texman, id));
239 } else {
240 printf("done loading resource %d (%s)\n", id, resman_get_res_name(texman, id));
241 }
243 if(!rdata->tex) {
244 glGenTextures(1, &rdata->tex);
245 }
246 glBindTexture(GL_TEXTURE_2D, rdata->tex);
247 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
248 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
249 glTexImage2D(GL_TEXTURE_2D, 0, img_glintfmt(rdata->img),
250 rdata->img->width, rdata->img->height, 0, img_glfmt(rdata->img),
251 img_gltype(rdata->img), rdata->img->pixels);
252 return 0;
253 }
255 static void free_res_texture(int id, void *cls)
256 {
257 struct thumbnail *thumb = resman_get_res_data(texman, id);
259 printf("deleting thumb %d: %s\n", id, thumb->fname);
261 if(thumb) {
262 if(thumb->tex) {
263 glDeleteTextures(1, &thumb->tex);
264 }
265 if(thumb->img) {
266 img_free(thumb->img);
267 }
268 }
270 /* remove from the list */
271 if(thumb->prev) {
272 thumb->prev->next = thumb->next;
273 }
274 if(thumb->next) {
275 thumb->next->prev = thumb->prev;
276 }
277 free(thumb);
278 }