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