initial import
[dosrtxon] / libs / imago / src / imago_gl.c
1 #include "imago2.h"
2
3 /* to avoid dependency to OpenGL, I'll define all the relevant GL macros manually */
4 #define GL_UNSIGNED_BYTE                0x1401
5 #define GL_FLOAT                                0x1406
6
7 #define GL_LUMINANCE                    0x1909
8 #define GL_RGB                                  0x1907
9 #define GL_RGBA                                 0x1908
10
11 #define GL_RGBA32F                              0x8814
12 #define GL_RGB32F                               0x8815
13 #define GL_LUMINANCE32F                 0x8818
14
15 #define GL_TEXTURE_2D                   0x0de1
16 #define GL_TEXTURE_WRAP_S               0x2802
17 #define GL_TEXTURE_WRAP_T               0x2803
18 #define GL_TEXTURE_MAG_FILTER   0x2800
19 #define GL_TEXTURE_MIN_FILTER   0x2801
20 #define GL_LINEAR                               0x2601
21 #define GL_REPEAT                               0x2901
22
23
24 typedef unsigned int GLenum;
25 typedef unsigned int GLuint;
26 typedef int GLint;
27 typedef int GLsizei;
28 typedef void GLvoid;
29
30 /* for the same reason I'll load GL functions dynamically */
31 #ifndef WIN32
32 typedef void (*gl_gen_textures_func)(GLsizei, GLuint*);
33 typedef void (*gl_bind_texture_func)(GLenum, GLuint);
34 typedef void (*gl_tex_parameteri_func)(GLenum, GLenum, GLint);
35 typedef void (*gl_tex_image2d_func)(GLenum, GLint, GLint, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid*);
36 #else
37 typedef void (__stdcall *gl_gen_textures_func)(GLsizei, GLuint*);
38 typedef void (__stdcall *gl_bind_texture_func)(GLenum, GLuint);
39 typedef void (__stdcall *gl_tex_parameteri_func)(GLenum, GLenum, GLint);
40 typedef void (__stdcall *gl_tex_image2d_func)(GLenum, GLint, GLint, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid*);
41 #endif
42
43 static gl_gen_textures_func gl_gen_textures;
44 static gl_bind_texture_func gl_bind_texture;
45 static gl_tex_parameteri_func gl_tex_parameteri;
46 static gl_tex_image2d_func gl_tex_image2d;
47
48 static int load_glfunc(void);
49
50 unsigned int img_fmt_glfmt(enum img_fmt fmt)
51 {
52         switch(fmt) {
53         case IMG_FMT_GREY8:
54         case IMG_FMT_GREYF:
55                 return GL_LUMINANCE;
56
57         case IMG_FMT_RGB24:
58         case IMG_FMT_RGBF:
59                 return GL_RGB;
60
61         case IMG_FMT_RGBA32:
62         case IMG_FMT_RGBAF:
63                 return GL_RGBA;
64
65         default:
66                 break;
67         }
68         return 0;
69 }
70
71 unsigned int img_fmt_gltype(enum img_fmt fmt)
72 {
73         switch(fmt) {
74         case IMG_FMT_GREY8:
75         case IMG_FMT_RGB24:
76         case IMG_FMT_RGBA32:
77                 return GL_UNSIGNED_BYTE;
78
79         case IMG_FMT_GREYF:
80         case IMG_FMT_RGBF:
81         case IMG_FMT_RGBAF:
82                 return GL_FLOAT;
83
84         default:
85                 break;
86         }
87         return 0;
88 }
89
90 unsigned int img_fmt_glintfmt(enum img_fmt fmt)
91 {
92         switch(fmt) {
93         case IMG_FMT_GREY8:
94                 return GL_LUMINANCE;
95         case IMG_FMT_RGB24:
96                 return GL_RGB;
97         case IMG_FMT_RGBA32:
98                 return GL_RGBA;
99         case IMG_FMT_GREYF:
100                 return GL_LUMINANCE32F;
101         case IMG_FMT_RGBF:
102                 return GL_RGB32F;
103         case IMG_FMT_RGBAF:
104                 return GL_RGBA32F;
105         default:
106                 break;
107         }
108         return 0;
109 }
110
111 unsigned int img_glfmt(struct img_pixmap *img)
112 {
113         return img_fmt_glfmt(img->fmt);
114 }
115
116 unsigned int img_gltype(struct img_pixmap *img)
117 {
118         return img_fmt_gltype(img->fmt);
119 }
120
121 unsigned int img_glintfmt(struct img_pixmap *img)
122 {
123         return img_fmt_glintfmt(img->fmt);
124 }
125
126 unsigned int img_gltexture(struct img_pixmap *img)
127 {
128         unsigned int tex;
129         unsigned int intfmt, fmt, type;
130
131         if(!gl_gen_textures) {
132                 if(load_glfunc() == -1) {
133                         fprintf(stderr, "imago: failed to initialize the OpenGL helpers\n");
134                         return 0;
135                 }
136         }
137
138         intfmt = img_glintfmt(img);
139         fmt = img_glfmt(img);
140         type = img_gltype(img);
141
142         gl_gen_textures(1, &tex);
143         gl_bind_texture(GL_TEXTURE_2D, tex);
144         gl_tex_parameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
145         gl_tex_parameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
146         gl_tex_parameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
147         gl_tex_parameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
148         gl_tex_image2d(GL_TEXTURE_2D, 0, intfmt, img->width, img->height, 0, fmt, type, img->pixels);
149         return tex;
150 }
151
152 unsigned int img_gltexture_load(const char *fname)
153 {
154         struct img_pixmap img;
155         unsigned int tex;
156
157         img_init(&img);
158         if(img_load(&img, fname) == -1) {
159                 img_destroy(&img);
160                 return 0;
161         }
162
163         tex = img_gltexture(&img);
164         img_destroy(&img);
165         return tex;
166 }
167
168 unsigned int img_gltexture_read_file(FILE *fp)
169 {
170         struct img_pixmap img;
171         unsigned int tex;
172
173         img_init(&img);
174         if(img_read_file(&img, fp) == -1) {
175                 img_destroy(&img);
176                 return 0;
177         }
178
179         tex = img_gltexture(&img);
180         img_destroy(&img);
181         return tex;
182 }
183
184 unsigned int img_gltexture_read(struct img_io *io)
185 {
186         struct img_pixmap img;
187         unsigned int tex;
188
189         img_init(&img);
190         if(img_read(&img, io) == -1) {
191                 img_destroy(&img);
192                 return 0;
193         }
194
195         tex = img_gltexture(&img);
196         img_destroy(&img);
197         return tex;
198 }
199
200 #if defined(__unix__) || defined(__APPLE__)
201 #ifndef __USE_GNU
202 #define __USE_GNU
203 #endif
204
205 #include <dlfcn.h>
206 #endif
207 #ifdef WIN32
208 #include <windows.h>
209 #endif
210
211 static int load_glfunc(void)
212 {
213 #if defined(__unix__) || defined(__APPLE__)
214         gl_gen_textures = (gl_gen_textures_func)dlsym(RTLD_DEFAULT, "glGenTextures");
215         gl_bind_texture = (gl_bind_texture_func)dlsym(RTLD_DEFAULT, "glBindTexture");
216         gl_tex_parameteri = (gl_tex_parameteri_func)dlsym(RTLD_DEFAULT, "glTexParameteri");
217         gl_tex_image2d = (gl_tex_image2d_func)dlsym(RTLD_DEFAULT, "glTexImage2D");
218 #endif
219
220 #ifdef WIN32
221         HANDLE dll = LoadLibrary("opengl32.dll");
222         if(dll) {
223                 gl_gen_textures = (gl_gen_textures_func)GetProcAddress(dll, "glGenTextures");
224                 gl_bind_texture = (gl_bind_texture_func)GetProcAddress(dll, "glBindTexture");
225                 gl_tex_parameteri = (gl_tex_parameteri_func)GetProcAddress(dll, "glTexParameteri");
226                 gl_tex_image2d = (gl_tex_image2d_func)GetProcAddress(dll, "glTexImage2D");
227         }
228 #endif
229
230         return (gl_gen_textures && gl_bind_texture && gl_tex_parameteri && gl_tex_image2d) ? 0 : -1;
231 }