7 static void conv_idx8(void *pixels);
8 static void conv_rgb15(void *pixels);
9 static void conv_rgb16(void *pixels);
10 static void conv_rgb24(void *pixels);
11 static void conv_rgba32(void *pixels);
12 static unsigned int next_pow2(unsigned int x);
14 static int width, height, scansz;
15 static enum glfb_pixel_format pixfmt;
16 static unsigned int min_filt = GL_NEAREST, mag_filt = GL_NEAREST;
17 static uint32_t *convbuf;
18 static int convbuf_size;
20 static uint32_t cmap[256];
22 static unsigned int tex;
23 static int tex_width, tex_height;
24 static float tex_sx, tex_sy;
26 static void (*convert[])(void*) = {
27 conv_idx8, conv_rgb15, conv_rgb16, conv_rgb24, conv_rgba32
31 void glfb_setup(int x, int y, enum glfb_pixel_format fmt, int pitch)
38 if(!tex || tx < tex_width || ty < height || fmt != pixfmt) {
40 glGenTextures(1, &tex);
41 glBindTexture(GL_TEXTURE_2D, tex);
42 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filt);
43 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filt);
44 glEnable(GL_TEXTURE_2D);
46 glBindTexture(GL_TEXTURE_2D, tex);
47 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tx, ty, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
53 tex_sx = (float)x / tex_width;
54 tex_sy = (float)y / tex_height;
59 if(convbuf_size < newsz) {
61 if(!(convbuf = malloc(newsz))) {
62 fprintf(stderr, "glfb: failed to allocate conversion buffer\n");
73 void glfb_filter(enum glfb_filter filt)
77 min_filt = mag_filt = GL_NEAREST;
80 min_filt = mag_filt = GL_LINEAR;
86 void glfb_color(int idx, int r, int g, int b)
88 if(idx < 0 || idx >= 255) return;
90 cmap[idx] = (b << 16) | (g << 8) | r;
93 void glfb_update(void *pixels)
95 convert[pixfmt](pixels);
96 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, convbuf);
99 void glfb_display(void)
101 glClearColor(0.2, 0.2, 0.2, 1);
102 glClear(GL_COLOR_BUFFER_BIT);
104 glBegin(GL_TRIANGLES);
105 glTexCoord2f(0, tex_sy * 2.0f);
107 glTexCoord2f(tex_sx * 2.0f, 0);
114 static void conv_idx8(void *pixels)
117 unsigned char *sptr = pixels;
118 uint32_t *dptr = convbuf;
120 for(i=0; i<height; i++) {
121 for(j=0; j<width; j++) {
122 *dptr++ = cmap[sptr[j]];
128 static void conv_rgb15(void *pixels)
133 uint16_t *sptr = pixels;
134 uint32_t *dptr = convbuf;
136 for(i=0; i<height; i++) {
137 for(j=0; j<width; j++) {
139 r = ((pix & 0x1f) << 3) | (pix & 7);
140 g = ((pix & 0x3e0) >> 2) | ((pix >> 5) & 7);
141 b = ((pix & 0x7c00) >> 7) | ((pix >> 10) & 7);
142 *dptr++ = r | (g << 8) | (b << 16);
144 sptr = (uint16_t*)((char*)sptr + scansz);
148 static void conv_rgb16(void *pixels)
153 uint16_t *sptr = pixels;
154 uint32_t *dptr = convbuf;
156 for(i=0; i<height; i++) {
157 for(j=0; j<width; j++) {
159 r = ((pix & 0x1f) << 3) | (pix & 7);
160 g = ((pix & 0x7e0) >> 3) | ((pix >> 5) & 3);
161 b = ((pix & 0xf800) >> 8) | ((pix >> 11) & 7);
162 *dptr++ = r | (g << 8) | (b << 16);
164 sptr = (uint16_t*)((char*)sptr + scansz);
168 static void conv_rgb24(void *pixels)
172 unsigned char *sptr, *scanptr = pixels;
173 uint32_t *dptr = convbuf;
175 for(i=0; i<height; i++) {
177 for(j=0; j<width; j++) {
182 *dptr++ = r | (g << 8) | (b << 16);
188 static void conv_rgba32(void *pixels)
191 uint32_t pix, r, g, b;
192 uint32_t *sptr = pixels;
193 uint32_t *dptr = convbuf;
195 for(i=0; i<height; i++) {
196 for(j=0; j<width; j++) {
198 r = (pix >> 16) & 0xff;
199 g = (pix >> 8) & 0xff;
201 *dptr++ = r | (g << 8) | (b << 16);
203 sptr = (uint32_t*)((char*)sptr + scansz);
207 static unsigned int next_pow2(unsigned int x)