libresman
view examples/imgthumbs/src/thumbs.c @ 2:026cdd1737ff
added spaceball controls to the example and needless GLEW dependency
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Fri, 31 Jan 2014 03:40:00 +0200 |
parents | 469ce01809bc |
children | 410c19c735b2 |
line source
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <errno.h>
5 #include <dirent.h>
6 #include <imago2.h>
7 #include "opengl.h"
8 #include "thumbs.h"
10 struct thumbnail *create_thumbs(const char *dirpath)
11 {
12 DIR *dir;
13 struct dirent *dent;
14 struct thumbnail *list = 0;
16 unsigned int intfmt = GL_COMPRESSED_RGB;
17 if(!GLEW_ARB_texture_compression) {
18 printf("warning, no texture compression available.\n");
19 intfmt = GL_RGB;
20 }
22 if(!(dir = opendir(dirpath))) {
23 fprintf(stderr, "failed to open directory: %s: %s\n", dirpath, strerror(errno));
24 return 0;
25 }
27 while((dent = readdir(dir))) {
28 int xsz, ysz;
29 unsigned char *pixels;
30 struct thumbnail *node;
32 if(!(node = malloc(sizeof *node))) {
33 perror("failed to allocate thumbnail list node");
34 continue;
35 }
37 if(!(node->fname = malloc(strlen(dirpath) + strlen(dent->d_name) + 2))) {
38 free(node);
39 continue;
40 }
41 strcpy(node->fname, dirpath);
42 if(dirpath[strlen(dirpath) - 1] != '/') {
43 strcat(node->fname, "/");
44 }
45 strcat(node->fname, dent->d_name);
47 if(!(pixels = img_load_pixels(node->fname, &xsz, &ysz, IMG_FMT_RGBA32))) {
48 free(node->fname);
49 free(node);
50 continue;
51 }
53 printf("loaded image: %s\n", node->fname);
55 glGenTextures(1, &node->tex);
56 glBindTexture(GL_TEXTURE_2D, node->tex);
57 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
58 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
59 glTexImage2D(GL_TEXTURE_2D, 0, intfmt, xsz, ysz, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
60 img_free_pixels(pixels);
62 node->aspect = (float)xsz / (float)ysz;
64 node->next = list;
65 list = node;
66 }
67 closedir(dir);
69 return list;
70 }
72 void free_thumbs(struct thumbnail *thumbs)
73 {
74 if(!thumbs) return;
76 while(thumbs) {
77 struct thumbnail *tmp = thumbs;
78 thumbs = thumbs->next;
80 free(tmp->fname);
81 free(tmp);
82 }
83 }
86 void draw_thumbs(struct thumbnail *thumbs, float thumb_sz, float start_y)
87 {
88 int vp[4];
89 float gap = thumb_sz / 4.0;
90 float x = gap;
91 float y = gap + start_y;
92 float view_aspect;
94 glGetIntegerv(GL_VIEWPORT, vp);
95 view_aspect = (float)(vp[2] - vp[0]) / (vp[3] - vp[1]);
97 glMatrixMode(GL_PROJECTION);
98 glPushMatrix();
99 glLoadIdentity();
100 glOrtho(0, 1, 1.0 / view_aspect, 0, -1, 1);
102 glMatrixMode(GL_MODELVIEW);
104 while(thumbs) {
106 glPushMatrix();
107 glTranslatef(x, y, 0);
109 glScalef(thumb_sz, thumb_sz, 1);
111 glBegin(GL_QUADS);
112 glColor3f(0.25, 0.25, 0.25);
113 glTexCoord2f(0, 0); glVertex2f(0, 0);
114 glTexCoord2f(1, 0); glVertex2f(1, 0);
115 glTexCoord2f(1, 1); glVertex2f(1, 1);
116 glTexCoord2f(0, 1); glVertex2f(0, 1);
117 glEnd();
119 if(thumbs->aspect >= 1.0) {
120 glTranslatef(0, 0.5 - 0.5 / thumbs->aspect, 0);
121 glScalef(1, 1.0 / thumbs->aspect, 1);
122 } else {
123 glTranslatef(0.5 - thumbs->aspect / 2.0, 0, 0);
124 glScalef(thumbs->aspect, 1, 1);
125 }
127 glEnable(GL_TEXTURE_2D);
128 glBindTexture(GL_TEXTURE_2D, thumbs->tex);
130 glBegin(GL_QUADS);
131 glColor3f(1, 1, 1);
132 glTexCoord2f(0, 0); glVertex2f(0, 0);
133 glTexCoord2f(1, 0); glVertex2f(1, 0);
134 glTexCoord2f(1, 1); glVertex2f(1, 1);
135 glTexCoord2f(0, 1); glVertex2f(0, 1);
136 glEnd();
138 glPopMatrix();
139 glDisable(GL_TEXTURE_2D);
141 thumbs->layout_pos[0] = x;
142 thumbs->layout_pos[1] = y;
143 thumbs->layout_size[0] = thumb_sz;
144 thumbs->layout_size[1] = thumb_sz;
146 x += thumb_sz + gap;
147 if(x >= 1.0 - thumb_sz) {
148 x = gap;
149 y += thumb_sz + gap;
150 }
152 thumbs = thumbs->next;
153 }
155 glMatrixMode(GL_PROJECTION);
156 glPopMatrix();
157 glMatrixMode(GL_MODELVIEW);
158 }