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