2 libimago - a multi-format image file input/output library.
3 Copyright (C) 2010-2021 John Tsiombikas <nuclear@member.fsf.org>
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published
7 by the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 /* to avoid dependency to OpenGL, I'll define all the relevant GL macros manually */
21 #define GL_UNSIGNED_BYTE 0x1401
22 #define GL_FLOAT 0x1406
24 #define GL_LUMINANCE 0x1909
26 #define GL_RGBA 0x1908
28 #define GL_SLUMINANCE 0x8c46
29 #define GL_SRGB 0x8c40
30 #define GL_SRGB_ALPHA 0x8c42
32 #define GL_RGBA32F 0x8814
33 #define GL_RGB32F 0x8815
34 #define GL_LUMINANCE32F 0x8818
36 #define GL_TEXTURE_2D 0x0de1
37 #define GL_TEXTURE_WRAP_S 0x2802
38 #define GL_TEXTURE_WRAP_T 0x2803
39 #define GL_TEXTURE_MAG_FILTER 0x2800
40 #define GL_TEXTURE_MIN_FILTER 0x2801
41 #define GL_LINEAR 0x2601
42 #define GL_LINEAR_MIPMAP_LINEAR 0x2703
43 #define GL_REPEAT 0x2901
44 #define GL_GENERATE_MIPMAP_SGIS 0x8191
47 typedef unsigned int GLenum;
48 typedef unsigned int GLuint;
53 /* for the same reason I'll load GL functions dynamically */
55 typedef void (*gl_gen_textures_func)(GLsizei, GLuint*);
56 typedef void (*gl_bind_texture_func)(GLenum, GLuint);
57 typedef void (*gl_tex_parameteri_func)(GLenum, GLenum, GLint);
58 typedef void (*gl_tex_image2d_func)(GLenum, GLint, GLint, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid*);
59 typedef void (*gl_generate_mipmap_func)(GLenum);
60 typedef GLenum (*gl_get_error_func)(void);
62 typedef void (__stdcall *gl_gen_textures_func)(GLsizei, GLuint*);
63 typedef void (__stdcall *gl_bind_texture_func)(GLenum, GLuint);
64 typedef void (__stdcall *gl_tex_parameteri_func)(GLenum, GLenum, GLint);
65 typedef void (__stdcall *gl_tex_image2d_func)(GLenum, GLint, GLint, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid*);
66 typedef void (__stdcall *gl_generate_mipmap_func)(GLenum);
67 typedef GLenum (__stdcall *gl_get_error_func)(void);
70 static gl_gen_textures_func gl_gen_textures;
71 static gl_bind_texture_func gl_bind_texture;
72 static gl_tex_parameteri_func gl_tex_parameteri;
73 static gl_tex_image2d_func gl_tex_image2d;
74 static gl_generate_mipmap_func gl_generate_mipmap;
75 static gl_get_error_func gl_get_error;
77 static int load_glfunc(void);
79 unsigned int img_fmt_glfmt(enum img_fmt fmt)
100 unsigned int img_fmt_gltype(enum img_fmt fmt)
106 return GL_UNSIGNED_BYTE;
119 unsigned int img_fmt_glintfmt(enum img_fmt fmt)
129 return GL_LUMINANCE32F;
140 unsigned int img_fmt_glintfmt_srgb(enum img_fmt fmt)
144 return GL_SLUMINANCE;
148 return GL_SRGB_ALPHA;
150 return GL_LUMINANCE32F;
161 unsigned int img_glfmt(struct img_pixmap *img)
163 return img_fmt_glfmt(img->fmt);
166 unsigned int img_gltype(struct img_pixmap *img)
168 return img_fmt_gltype(img->fmt);
171 unsigned int img_glintfmt(struct img_pixmap *img)
173 return img_fmt_glintfmt(img->fmt);
176 unsigned int img_glintfmt_srgb(struct img_pixmap *img)
178 return img_fmt_glintfmt_srgb(img->fmt);
181 unsigned int img_gltexture(struct img_pixmap *img)
184 unsigned int intfmt, fmt, type;
186 if(!gl_gen_textures) {
187 if(load_glfunc() == -1) {
188 fprintf(stderr, "imago: failed to initialize the OpenGL helpers\n");
193 intfmt = img_glintfmt(img);
194 fmt = img_glfmt(img);
195 type = img_gltype(img);
197 gl_gen_textures(1, &tex);
198 gl_bind_texture(GL_TEXTURE_2D, tex);
199 gl_tex_parameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
200 gl_tex_parameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
201 gl_tex_parameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
202 gl_tex_parameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
203 if(!gl_generate_mipmap) {
204 gl_tex_parameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, 1);
205 gl_get_error(); /* clear errors in case SGIS_generate_mipmap is not supported */
207 gl_tex_image2d(GL_TEXTURE_2D, 0, intfmt, img->width, img->height, 0, fmt, type, img->pixels);
208 if(gl_generate_mipmap) {
209 gl_generate_mipmap(GL_TEXTURE_2D);
214 unsigned int img_gltexture_load(const char *fname)
216 struct img_pixmap img;
220 if(img_load(&img, fname) == -1) {
225 tex = img_gltexture(&img);
230 unsigned int img_gltexture_read_file(FILE *fp)
232 struct img_pixmap img;
236 if(img_read_file(&img, fp) == -1) {
241 tex = img_gltexture(&img);
246 unsigned int img_gltexture_read(struct img_io *io)
248 struct img_pixmap img;
252 if(img_read(&img, io) == -1) {
257 tex = img_gltexture(&img);
262 #if defined(__unix__) || defined(__APPLE__)
266 #define RTLD_DEFAULT ((void*)0)
274 static int load_glfunc(void)
276 #if defined(__unix__) || defined(__APPLE__)
277 gl_gen_textures = (gl_gen_textures_func)dlsym(RTLD_DEFAULT, "glGenTextures");
278 gl_bind_texture = (gl_bind_texture_func)dlsym(RTLD_DEFAULT, "glBindTexture");
279 gl_tex_parameteri = (gl_tex_parameteri_func)dlsym(RTLD_DEFAULT, "glTexParameteri");
280 gl_tex_image2d = (gl_tex_image2d_func)dlsym(RTLD_DEFAULT, "glTexImage2D");
281 gl_generate_mipmap = (gl_generate_mipmap_func)dlsym(RTLD_DEFAULT, "glGenerateMipmap");
282 gl_get_error = (gl_get_error_func)dlsym(RTLD_DEFAULT, "glGetError");
286 HANDLE dll = LoadLibrary("opengl32.dll");
288 gl_gen_textures = (gl_gen_textures_func)GetProcAddress(dll, "glGenTextures");
289 gl_bind_texture = (gl_bind_texture_func)GetProcAddress(dll, "glBindTexture");
290 gl_tex_parameteri = (gl_tex_parameteri_func)GetProcAddress(dll, "glTexParameteri");
291 gl_tex_image2d = (gl_tex_image2d_func)GetProcAddress(dll, "glTexImage2D");
292 gl_generate_mipmap = (gl_generate_mipmap_func)GetProcAddress(dll, "glGenerateMipmap");
293 gl_get_error = (gl_get_error_func)GetProcAddress(dll, "glGetError");
297 return (gl_gen_textures && gl_bind_texture && gl_tex_parameteri && gl_tex_image2d && gl_get_error) ? 0 : -1;